laruence Mon, 16 Jan 2012 09:53:45 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=322360
Log: Fixed Bug #60573 (type hinting with "self" keyword causes weird errors) Bug: https://bugs.php.net/60573 (error getting bug information) Changed paths: U php/php-src/trunk/NEWS A php/php-src/trunk/Zend/tests/bug60573.phpt U php/php-src/trunk/Zend/zend_compile.c Modified: php/php-src/trunk/NEWS =================================================================== --- php/php-src/trunk/NEWS 2012-01-16 09:33:06 UTC (rev 322359) +++ php/php-src/trunk/NEWS 2012-01-16 09:53:45 UTC (rev 322360) @@ -5,6 +5,10 @@ - General improvements: . World domination +- Core + . Fixed bug #60573 (type hinting with "self" keyword causes weird errors). + (Laruence) + - cURL: . Added support for CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPT_APPEND, CURLOPT_DIRLISTONLY, CURLOPT_NEW_DIRECTORY_PERMS, CURLOPT_NEW_FILE_PERMS, Added: php/php-src/trunk/Zend/tests/bug60573.phpt =================================================================== --- php/php-src/trunk/Zend/tests/bug60573.phpt (rev 0) +++ php/php-src/trunk/Zend/tests/bug60573.phpt 2012-01-16 09:53:45 UTC (rev 322360) @@ -0,0 +1,84 @@ +--TEST-- +Bug #60573 (type hinting with "self" keyword causes weird errors) +--FILE-- +<?php +class Foo1 { + +public function setSelf(self $s) { } + +} + +class Bar1 extends Foo1 { + +public function setSelf(parent $s) { } + +} + +class Foo2 { + +public function setSelf(Foo2 $s) { } + +} + +class Bar2 extends Foo2 { + +public function setSelf(parent $s) { } + +} + +class Base { +} + +class Foo3 extends Base{ + +public function setSelf(parent $s) { } + +} + +class Bar3 extends Foo3 { + +public function setSelf(Base $s) { } + +} + +class Foo4 { + +public function setSelf(self $s) { } + +} + +class Bar4 extends Foo4 { + +public function setSelf(self $s) { } + +} + +class Foo5 extends Base { + +public function setSelf(parent $s) { } + +} + +class Bar5 extends Foo5 { + +public function setSelf(parent $s) { } + +} + +abstract class Foo6 extends Base { + +abstract public function setSelf(parent $s); + +} + +class Bar6 extends Foo6 { + +public function setSelf(Foo6 $s) { } + +} +--EXPECTF-- +Strict Standards: Declaration of Bar4::setSelf() should be compatible with Foo4::setSelf(Foo4 $s) in %sbug60573.php on line %d + +Strict Standards: Declaration of Bar5::setSelf() should be compatible with Foo5::setSelf(Base $s) in %sbug60573.php on line %d + +Fatal error: Declaration of Bar6::setSelf() must be compatible with Foo6::setSelf(Base $s) in %sbug60573.php on line %d Property changes on: php/php-src/trunk/Zend/tests/bug60573.phpt ___________________________________________________________________ Added: svn:executable + * Modified: php/php-src/trunk/Zend/zend_compile.c =================================================================== --- php/php-src/trunk/Zend/zend_compile.c 2012-01-16 09:33:06 UTC (rev 322359) +++ php/php-src/trunk/Zend/zend_compile.c 2012-01-16 09:53:45 UTC (rev 322360) @@ -2958,30 +2958,57 @@ /* Only one has a type hint and the other one doesn't */ return 0; } - if (fe->common.arg_info[i].class_name - && strcasecmp(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)!=0) { - const char *colon; - if (fe->common.type != ZEND_USER_FUNCTION) { - return 0; - } else if (strchr(proto->common.arg_info[i].class_name, '\\') != NULL || - (colon = zend_memrchr(fe->common.arg_info[i].class_name, '\\', fe->common.arg_info[i].class_name_len)) == NULL || - strcasecmp(colon+1, proto->common.arg_info[i].class_name) != 0) { - zend_class_entry **fe_ce, **proto_ce; - int found, found2; - - found = zend_lookup_class(fe->common.arg_info[i].class_name, fe->common.arg_info[i].class_name_len, &fe_ce TSRMLS_CC); - found2 = zend_lookup_class(proto->common.arg_info[i].class_name, proto->common.arg_info[i].class_name_len, &proto_ce TSRMLS_CC); - - /* Check for class alias */ - if (found != SUCCESS || found2 != SUCCESS || - (*fe_ce)->type == ZEND_INTERNAL_CLASS || - (*proto_ce)->type == ZEND_INTERNAL_CLASS || - *fe_ce != *proto_ce) { + if (fe->common.arg_info[i].class_name) { + const char *fe_class_name, *proto_class_name; + zend_uint fe_class_name_len, proto_class_name_len; + + if (!strcasecmp(fe->common.arg_info[i].class_name, "parent") && proto->common.scope) { + fe_class_name = proto->common.scope->name; + fe_class_name_len = proto->common.scope->name_length; + } else if (!strcasecmp(fe->common.arg_info[i].class_name, "self") && fe->common.scope) { + fe_class_name = fe->common.scope->name; + fe_class_name_len = fe->common.scope->name_length; + } else { + fe_class_name = fe->common.arg_info[i].class_name; + fe_class_name_len = fe->common.arg_info[i].class_name_len; + } + + if (!strcasecmp(proto->common.arg_info[i].class_name, "parent") && proto->common.scope && proto->common.scope->parent) { + proto_class_name = proto->common.scope->parent->name; + proto_class_name_len = proto->common.scope->parent->name_length; + } else if (!strcasecmp(proto->common.arg_info[i].class_name, "self") && proto->common.scope) { + proto_class_name = proto->common.scope->name; + proto_class_name_len = proto->common.scope->name_length; + } else { + proto_class_name = proto->common.arg_info[i].class_name; + proto_class_name_len = proto->common.arg_info[i].class_name_len; + } + + if (strcasecmp(fe_class_name, proto_class_name)!=0) { + const char *colon; + + if (fe->common.type != ZEND_USER_FUNCTION) { return 0; + } else if (strchr(proto_class_name, '\\') != NULL || + (colon = zend_memrchr(fe_class_name, '\\', fe_class_name_len)) == NULL || + strcasecmp(colon+1, proto_class_name) != 0) { + zend_class_entry **fe_ce, **proto_ce; + int found, found2; + + found = zend_lookup_class(fe_class_name, fe_class_name_len, &fe_ce TSRMLS_CC); + found2 = zend_lookup_class(proto_class_name, proto_class_name_len, &proto_ce TSRMLS_CC); + + /* Check for class alias */ + if (found != SUCCESS || found2 != SUCCESS || + (*fe_ce)->type == ZEND_INTERNAL_CLASS || + (*proto_ce)->type == ZEND_INTERNAL_CLASS || + *fe_ce != *proto_ce) { + return 0; + } } - } - } + } + } if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) { /* Incompatible type hint */ return 0; @@ -3043,9 +3070,21 @@ required = fptr->common.required_num_args; for (i = 0; i < fptr->common.num_args;) { if (arg_info->class_name) { - REALLOC_BUF_IF_EXCEED(buf, offset, length, arg_info->class_name_len); - memcpy(offset, arg_info->class_name, arg_info->class_name_len); - offset += arg_info->class_name_len; + const char *class_name; + zend_uint class_name_len; + if (!strcasecmp(arg_info->class_name, "self") && fptr->common.scope ) { + class_name = fptr->common.scope->name; + class_name_len = fptr->common.scope->name_length; + } else if (!strcasecmp(arg_info->class_name, "parent") && fptr->common.scope->parent) { + class_name = fptr->common.scope->parent->name; + class_name_len = fptr->common.scope->parent->name_length; + } else { + class_name = arg_info->class_name; + class_name_len = arg_info->class_name_len; + } + REALLOC_BUF_IF_EXCEED(buf, offset, length, class_name_len); + memcpy(offset, class_name, class_name_len); + offset += class_name_len; *(offset++) = ' '; } else if (arg_info->type_hint) { zend_uint type_name_len;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php