Skip to content

Commit 4de1707

Browse files
committed
Fixed bug #43332 (self and parent as type hint in namespace)
1 parent 678c532 commit 4de1707

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

Zend/tests/bug43332_1.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Bug #43332.1 (self and parent as type hint in namespace)
3+
--FILE--
4+
<?php
5+
namespace foobar;
6+
7+
class foo {
8+
public function bar(self $a) { }
9+
}
10+
11+
$foo = new foo;
12+
$foo->bar($foo); // Ok!
13+
$foo->bar(new stdclass); // Error, ok!
14+
--EXPECTF--
15+
Catchable fatal error: Argument 1 passed to foobar::foo::bar() must be an instance of foobar::foo, instance of stdClass given, called in %sbug43332_1.php on line 10 and defined in %sbug43332_1.php on line 5

Zend/tests/bug43332_2.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Bug #43332.2 (self and parent as type hint in namespace)
3+
--FILE--
4+
<?php
5+
namespace foobar;
6+
7+
class foo {
8+
public function bar(::self $a) { }
9+
}
10+
11+
$foo = new foo;
12+
$foo->bar($foo); // Ok!
13+
$foo->bar(new stdclass); // Error, ok!
14+
--EXPECTF--
15+
Fatal error: '::self' is a wrong class name in %sbug43332_2.php on line 5

Zend/zend_compile.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,9 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
14361436
if (class_type->op_type != IS_UNUSED) {
14371437
cur_arg_info->allow_null = 0;
14381438
if (Z_TYPE(class_type->u.constant) == IS_STRING || Z_TYPE(class_type->u.constant) == IS_UNICODE) {
1439-
zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC);
1439+
if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_TYPE(class_type->u.constant), Z_UNIVAL(class_type->u.constant), Z_UNILEN(class_type->u.constant))) {
1440+
zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC);
1441+
}
14401442
cur_arg_info->class_name = Z_UNIVAL(class_type->u.constant);
14411443
cur_arg_info->class_name_len = Z_UNILEN(class_type->u.constant);
14421444
if (op == ZEND_RECV_INIT) {
@@ -1665,6 +1667,9 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_
16651667
Z_USTRVAL(class_name->u.constant) = eurealloc(
16661668
Z_USTRVAL(class_name->u.constant),
16671669
Z_USTRLEN(class_name->u.constant) + 1);
1670+
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant), Z_UNILEN(class_name->u.constant))) {
1671+
zend_error(E_COMPILE_ERROR, "'::%R' is a wrong class name", Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant));
1672+
}
16681673
} else if (Z_TYPE(class_name->u.constant) == IS_STRING &&
16691674
Z_STRVAL(class_name->u.constant)[0] == ':') {
16701675
/* The STRING name has "::" prefix */
@@ -1673,6 +1678,9 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_
16731678
Z_STRVAL(class_name->u.constant) = erealloc(
16741679
Z_STRVAL(class_name->u.constant),
16751680
Z_STRLEN(class_name->u.constant) + 1);
1681+
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant), Z_UNILEN(class_name->u.constant))) {
1682+
zend_error(E_COMPILE_ERROR, "'::%R' is a wrong class name", Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant));
1683+
}
16761684
} else if (CG(current_import)) {
16771685
if (Z_TYPE(class_name->u.constant) == IS_UNICODE) {
16781686
len = compound.u - Z_USTRVAL(class_name->u.constant);

0 commit comments

Comments
 (0)