From: Dmitry Stogov Date: Fri, 9 Nov 2007 13:35:22 +0000 (+0000) Subject: Fixed type-hint compatibility check in namespaces X-Git-Tag: RELEASE_2_0_0a1~1403 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cdbeea7e2ea9877aaf0628984931865c6edd111a;p=php Fixed type-hint compatibility check in namespaces --- diff --git a/Zend/tests/ns_055.phpt b/Zend/tests/ns_055.phpt new file mode 100755 index 0000000000..83d0613c1e --- /dev/null +++ b/Zend/tests/ns_055.phpt @@ -0,0 +1,33 @@ +--TEST-- +055: typehints in namespaces +--FILE-- +test1($foo); +$foo->test2($foo); +$foo->test3($ex); +$foo->test4($ex); +?> +--EXPECT-- +ok +ok +ok +ok diff --git a/Zend/tests/ns_056.phpt b/Zend/tests/ns_056.phpt new file mode 100755 index 0000000000..0bc4f0087d --- /dev/null +++ b/Zend/tests/ns_056.phpt @@ -0,0 +1,31 @@ +--TEST-- +056: type-hint compatibility in namespaces +--SKIPIF-- + +--FILE-- +attach($foo); +$foo->update($bar); +?> +--EXPECT-- +ok +ok diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 37d27d7a98..f65cd5a6a6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2372,7 +2372,31 @@ static zend_bool zend_do_perform_implementation_check(zend_function *fe, zend_fu (fe->common.arg_info[i].class_name_len != proto->common.arg_info[i].class_name_len || (!UG(unicode) && zend_binary_strcasecmp(fe->common.arg_info[i].class_name.s, fe->common.arg_info[i].class_name_len, proto->common.arg_info[i].class_name.s, proto->common.arg_info[i].class_name_len) != 0) || (UG(unicode) && zend_u_binary_strcasecmp(fe->common.arg_info[i].class_name.u, fe->common.arg_info[i].class_name_len, proto->common.arg_info[i].class_name.u, proto->common.arg_info[i].class_name_len) != 0))) { - return 0; + + zstr colon; + + if (fe->common.type == ZEND_USER_FUNCTION && + ((UG(unicode) && + u_strchr(proto->common.arg_info[i].class_name.u, ':') == NULL && + (colon.u = u_memrchr(fe->common.arg_info[i].class_name.u, ':', fe->common.arg_info[i].class_name_len)) != NULL && + fe->common.arg_info[i].class_name_len - (colon.u + 1 - fe->common.arg_info[i].class_name.u) == proto->common.arg_info[i].class_name_len && + zend_u_binary_strcasecmp(colon.u + 1, proto->common.arg_info[i].class_name_len, proto->common.arg_info[i].class_name.u, proto->common.arg_info[i].class_name_len) == 0) || + (!UG(unicode) && + strchr(proto->common.arg_info[i].class_name.s, ':') == NULL && + (colon.s = zend_memrchr(fe->common.arg_info[i].class_name.s, ':', fe->common.arg_info[i].class_name_len)) != NULL && + fe->common.arg_info[i].class_name_len - (colon.s + 1 - fe->common.arg_info[i].class_name.s) == proto->common.arg_info[i].class_name_len && + zend_binary_strcasecmp(colon.s + 1, proto->common.arg_info[i].class_name_len, proto->common.arg_info[i].class_name.s, proto->common.arg_info[i].class_name_len) == 0))) { + + efree((char*)fe->common.arg_info[i].class_name.v); + if (UG(unicode)) { + fe->common.arg_info[i].class_name.u = eustrndup(proto->common.arg_info[i].class_name.u, proto->common.arg_info[i].class_name_len); + } else { + fe->common.arg_info[i].class_name.s = estrndup(proto->common.arg_info[i].class_name.s, proto->common.arg_info[i].class_name_len); + } + fe->common.arg_info[i].class_name_len = proto->common.arg_info[i].class_name_len; + } else { + return 0; + } } if (fe->common.arg_info[i].array_type_hint != proto->common.arg_info[i].array_type_hint) { /* Only one has an array type hint and the other one doesn't */