Skip to content

Commit eaac77f

Browse files
authored
Fix nested namespaced typed property in gen_stub.php (#7418)
Property escape namespaced class name in property types.
1 parent 52d3af1 commit eaac77f

File tree

4 files changed

+46
-5
lines changed

4 files changed

+46
-5
lines changed

build/gen_stub.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ public function toEscapedName(): string {
395395
return str_replace('\\', '\\\\', $this->name);
396396
}
397397

398+
public function toCVarEscapedName(): string {
399+
$name = str_replace('_', '__', $this->name);
400+
return str_replace('\\', '_', $this->name);
401+
}
402+
398403
public function equals(SimpleType $other): bool {
399404
return $this->name === $other->name && $this->isBuiltin === $other->isBuiltin;
400405
}
@@ -1374,7 +1379,9 @@ public function getDeclaration(): string {
13741379
if (count($arginfoType->classTypes) >= 2) {
13751380
foreach ($arginfoType->classTypes as $classType) {
13761381
$className = $classType->name;
1377-
$code .= "\tzend_string *property_{$propertyName}_class_{$className} = zend_string_init(\"$className\", sizeof(\"$className\") - 1, 1);\n";
1382+
$escapedClassName = $classType->toEscapedName();
1383+
$varEscapedClassName = $classType->toCVarEscapedName();
1384+
$code .= "\tzend_string *property_{$propertyName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\") - 1, 1);\n";
13781385
}
13791386

13801387
$classTypeCount = count($arginfoType->classTypes);
@@ -1383,7 +1390,8 @@ public function getDeclaration(): string {
13831390

13841391
foreach ($arginfoType->classTypes as $k => $classType) {
13851392
$className = $classType->name;
1386-
$code .= "\tproperty_{$propertyName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, 0, 0);\n";
1393+
$escapedClassName = $classType->toEscapedName();
1394+
$code .= "\tproperty_{$propertyName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$escapedClassName}, 0, 0);\n";
13871395
}
13881396

13891397
$typeMaskCode = $this->type->toArginfoType()->toTypeMask();
@@ -1392,9 +1400,11 @@ public function getDeclaration(): string {
13921400
$typeCode = "property_{$propertyName}_type";
13931401
} else {
13941402
$className = $arginfoType->classTypes[0]->name;
1395-
$code .= "\tzend_string *property_{$propertyName}_class_{$className} = zend_string_init(\"$className\", sizeof(\"$className\")-1, 1);\n";
1403+
$escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
1404+
$varEscapedClassName = $arginfoType->classTypes[0]->toCVarEscapedName();
1405+
$code .= "\tzend_string *property_{$propertyName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"${escapedClassName}\")-1, 1);\n";
13961406

1397-
$typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, 0, " . $arginfoType->toTypeMask() . ")";
1407+
$typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
13981408
}
13991409
} else {
14001410
$typeCode = "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";

ext/zend_test/test.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public function method(): void {}
8888
namespace ZendTestNS2 {
8989

9090
class Foo {
91+
public ZendSubNS\Foo $foo;
92+
9193
public function method(): void {}
9294
}
9395

ext/zend_test/test_arginfo.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 93bb8b9120e510e8c3afc29dc0a5d47cb6b5f10e */
2+
* Stub hash: 04d48fa64594bacba57210dcb94381f83951116c */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
55
ZEND_END_ARG_INFO()
@@ -296,6 +296,13 @@ static zend_class_entry *register_class_ZendTestNS2_Foo(void)
296296
INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2", "Foo", class_ZendTestNS2_Foo_methods);
297297
class_entry = zend_register_internal_class_ex(&ce, NULL);
298298

299+
zend_string *property_foo_class_ZendTestNS2_ZendSubNS_Foo = zend_string_init("ZendTestNS2\\ZendSubNS\\Foo", sizeof("ZendTestNS2\\ZendSubNS\\Foo")-1, 1);
300+
zval property_foo_default_value;
301+
ZVAL_UNDEF(&property_foo_default_value);
302+
zend_string *property_foo_name = zend_string_init("foo", sizeof("foo") - 1, 1);
303+
zend_declare_typed_property(class_entry, property_foo_name, &property_foo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_foo_class_ZendTestNS2_ZendSubNS_Foo, 0, 0));
304+
zend_string_release(property_foo_name);
305+
299306
return class_entry;
300307
}
301308

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
gen_stub.php: nested namespaced typed properties test.
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
$foo = new \ZendTestNS2\Foo();
9+
var_dump($foo);
10+
$foo->foo = new \ZendTestNS2\ZendSubNS\Foo();
11+
var_dump($foo);
12+
?>
13+
--EXPECTF--
14+
object(ZendTestNS2\Foo)#%d (%d) {
15+
["foo"]=>
16+
uninitialized(ZendTestNS2\ZendSubNS\Foo)
17+
}
18+
object(ZendTestNS2\Foo)#%d (%d) {
19+
["foo"]=>
20+
object(ZendTestNS2\ZendSubNS\Foo)#%d (%d) {
21+
}
22+
}

0 commit comments

Comments
 (0)