From bdf0599e4e276e34b6f5c4301e89e570bffc179a Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Tue, 26 Jul 2022 15:32:35 +0200 Subject: [PATCH 1/3] Escape \U and \u in generated stubs This fixes an issue where a namespaced class beginning with "U" or "u" would yield an invalid arginfo file due to the occurrence of a unicode escape sequence, causing a compile error. --- build/gen_stub.php | 7 ++++++- ext/zend_test/test.c | 11 +++++++++++ ext/zend_test/test.stub.php | 6 ++++++ ext/zend_test/test_arginfo.h | 22 +++++++++++++++++++++- ext/zend_test/tests/gen_stub_test_01.phpt | 4 ++++ 5 files changed, 48 insertions(+), 2 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 84e212163bbd9..723cbfbc55076 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -533,7 +533,12 @@ public function toOptimizerTypeMask(): string { } public function toEscapedName(): string { - return str_replace('\\', '\\\\', $this->name); + // Escape \u and \U to avoid compilation errors in generated macros + return str_replace( + ['\\', '\u', '\U'], + ['\\\\', '\\\\165', '\\\\125'], + $this->name + ); } public function toVarEscapedName(): string { diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index bbc196c26c1c6..fedae8fdeb017 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -43,6 +43,7 @@ static zend_class_entry *zend_test_class_with_method_with_parameter_attribute; static zend_class_entry *zend_test_child_class_with_method_with_parameter_attribute; static zend_class_entry *zend_test_forbid_dynamic_call; static zend_class_entry *zend_test_ns_foo_class; +static zend_class_entry *zend_test_ns_unlikely_compile_error_class; static zend_class_entry *zend_test_ns2_foo_class; static zend_class_entry *zend_test_ns2_ns_foo_class; static zend_class_entry *zend_test_unit_enum; @@ -535,6 +536,15 @@ static ZEND_METHOD(ZendTestNS_Foo, method) RETURN_LONG(0); } +static ZEND_METHOD(ZendTestNS_UnlikelyCompileError, method) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + return_value = ZEND_THIS; + + return return_value; +} + static ZEND_METHOD(ZendTestNS2_Foo, method) { ZEND_PARSE_PARAMETERS_NONE(); @@ -698,6 +708,7 @@ PHP_MINIT_FUNCTION(zend_test) zend_test_forbid_dynamic_call = register_class_ZendTestForbidDynamicCall(); zend_test_ns_foo_class = register_class_ZendTestNS_Foo(); + zend_test_ns_unlikely_compile_error_class = register_class_ZendTestNS_UnlikelyCompileError(); zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo(); zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo(); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index 8b26d552e5db0..f346a1a6b0750 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -150,6 +150,12 @@ class Foo { public function method(): int {} } + class UnlikelyCompileError { + /* This method signature would create a compile error due to the string + * "ZendTestNS\UnlikelyCompileError" in the generated macro call */ + public function method(): UnlikelyCompileError {} + } + } namespace ZendTestNS2 { diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index fb3e7943313cc..6be2826ae2acc 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 64a10ff1af71cb2f9024f73ddaa34a924b85b968 */ + * Stub hash: de4b91530a2aaf4c72436b0e8e9628d11a62fa15 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -131,6 +131,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZendTestNS_Foo_method, 0, 0, 0) #endif ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ZendTestNS_UnlikelyCompileError_method, 0, 0, ZendTestNS\\\125nlikelyCompileError, 0) +ZEND_END_ARG_INFO() + #define arginfo_class_ZendTestNS2_Foo_method arginfo_zend_test_void_return #define arginfo_class_ZendTestNS2_ZendSubNS_Foo_method arginfo_zend_test_void_return @@ -173,6 +176,7 @@ static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override) static ZEND_METHOD(ZendTestForbidDynamicCall, call); static ZEND_METHOD(ZendTestForbidDynamicCall, callStatic); static ZEND_METHOD(ZendTestNS_Foo, method); +static ZEND_METHOD(ZendTestNS_UnlikelyCompileError, method); static ZEND_METHOD(ZendTestNS2_Foo, method); static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method); @@ -284,6 +288,12 @@ static const zend_function_entry class_ZendTestNS_Foo_methods[] = { }; +static const zend_function_entry class_ZendTestNS_UnlikelyCompileError_methods[] = { + ZEND_ME(ZendTestNS_UnlikelyCompileError, method, arginfo_class_ZendTestNS_UnlikelyCompileError_method, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + + static const zend_function_entry class_ZendTestNS2_Foo_methods[] = { ZEND_ME(ZendTestNS2_Foo, method, arginfo_class_ZendTestNS2_Foo_method, ZEND_ACC_PUBLIC) ZEND_FE_END @@ -560,6 +570,16 @@ static zend_class_entry *register_class_ZendTestNS_Foo(void) return class_entry; } +static zend_class_entry *register_class_ZendTestNS_UnlikelyCompileError(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ZendTestNS", "UnlikelyCompileError", class_ZendTestNS_UnlikelyCompileError_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + return class_entry; +} + static zend_class_entry *register_class_ZendTestNS2_Foo(void) { zend_class_entry ce, *class_entry; diff --git a/ext/zend_test/tests/gen_stub_test_01.phpt b/ext/zend_test/tests/gen_stub_test_01.phpt index 8b13cbaa034b3..0a020a6f3457c 100644 --- a/ext/zend_test/tests/gen_stub_test_01.phpt +++ b/ext/zend_test/tests/gen_stub_test_01.phpt @@ -9,6 +9,8 @@ $foo = new \ZendTestNS2\Foo(); var_dump($foo); $foo->foo = new \ZendTestNS2\ZendSubNS\Foo(); var_dump($foo); +$foo = new \ZendTestNS\UnlikelyCompileError(); +var_dump($foo); ?> --EXPECTF-- object(ZendTestNS2\Foo)#%d (%d) { @@ -20,3 +22,5 @@ object(ZendTestNS2\Foo)#%d (%d) { object(ZendTestNS2\ZendSubNS\Foo)#%d (%d) { } } +object(ZendTestNS\UnlikelyCompileError)#%d (%d) { +} From 4373b22d09d8b75b51312a3fe3ccf20627848d32 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Wed, 27 Jul 2022 14:40:45 +0200 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Guilliam Xavier --- build/gen_stub.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 723cbfbc55076..d1274fa20fc5a 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -533,9 +533,9 @@ public function toOptimizerTypeMask(): string { } public function toEscapedName(): string { - // Escape \u and \U to avoid compilation errors in generated macros + // Escape backslashes, and also encode \u and \U to avoid compilation errors in generated macros return str_replace( - ['\\', '\u', '\U'], + ['\\', '\\u', '\\U'], ['\\\\', '\\\\165', '\\\\125'], $this->name ); From 2c1191bb714e086b966b086071218f6a77cc09b3 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Thu, 28 Jul 2022 09:28:04 +0200 Subject: [PATCH 3/3] Fix test by making return type nullable --- ext/zend_test/test.c | 4 +--- ext/zend_test/test.stub.php | 2 +- ext/zend_test/test_arginfo.h | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index fedae8fdeb017..bcd56ece59e0f 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -540,9 +540,7 @@ static ZEND_METHOD(ZendTestNS_UnlikelyCompileError, method) { ZEND_PARSE_PARAMETERS_NONE(); - return_value = ZEND_THIS; - - return return_value; + RETURN_NULL(); } static ZEND_METHOD(ZendTestNS2_Foo, method) diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index f346a1a6b0750..5dbd8596546d9 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -153,7 +153,7 @@ public function method(): int {} class UnlikelyCompileError { /* This method signature would create a compile error due to the string * "ZendTestNS\UnlikelyCompileError" in the generated macro call */ - public function method(): UnlikelyCompileError {} + public function method(): ?UnlikelyCompileError {} } } diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index 6be2826ae2acc..186f813e5ddc8 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: de4b91530a2aaf4c72436b0e8e9628d11a62fa15 */ + * Stub hash: 2c654cefda278094fa4cdc25b83ced269e83cadf */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -131,7 +131,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZendTestNS_Foo_method, 0, 0, 0) #endif ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ZendTestNS_UnlikelyCompileError_method, 0, 0, ZendTestNS\\\125nlikelyCompileError, 0) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ZendTestNS_UnlikelyCompileError_method, 0, 0, ZendTestNS\\\125nlikelyCompileError, 1) ZEND_END_ARG_INFO() #define arginfo_class_ZendTestNS2_Foo_method arginfo_zend_test_void_return