svn: /php/php-src/trunk/ NEWS Zend/tests/bug60573.phpt Zend/zend_compile.c
| From: | Xinchen Hui | Date: | Mon, 16 Jan 2012 09:53:45 +0000 |
| Subject: | svn: /php/php-src/trunk/ NEWS Zend/tests/bug60573.phpt Zend/zend_compile.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-67449@lists.php.net to get a copy of this message | ||
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;