summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--Zend/tests/bug39003.phpt24
-rw-r--r--Zend/zend_execute.c23
-rwxr-xr-xtests/classes/type_hinting_002.phpt3
4 files changed, 39 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index a48a14a18f..7861123bf1 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ PHP NEWS
- Fixed mess with CGI/CLI -d option (now it works with cgi; constants are
working exactly like in php.ini; with FastCGI -d affects all requests).
(Dmitry)
+- Fixed bug #39003 (__autoload() is called for type hinting). (Dmitry, Tony)
- Fixed bug #38993 (Fixed safe_mode/open_basedir checks for
session.save_path, allowing them to account for extra parameters). (Ilia)
- Fixed bug #38981 (using FTP URLs in get_headers() causes crash). (Tony)
diff --git a/Zend/tests/bug39003.phpt b/Zend/tests/bug39003.phpt
new file mode 100644
index 0000000000..7a3da849bd
--- /dev/null
+++ b/Zend/tests/bug39003.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #39003 (__autoload() is called for type hinting)
+--FILE--
+<?php
+
+class ClassName
+{
+ public $var = 'bla';
+}
+
+function test (OtherClassName $object) { }
+
+function __autoload($class)
+{
+ var_dump("__autload($class)");
+}
+
+$obj = new ClassName;
+test($obj);
+
+echo "Done\n";
+?>
+--EXPECTF--
+Catchable fatal error: Argument 1 passed to test() must be an instance of OtherClassName, instance of ClassName given, called in %s on line %d and defined in %s on line %d
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 7bc4df78f4..fbaed013b1 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -449,11 +449,12 @@ static inline void make_real_object(zval **object_ptr TSRMLS_DC)
}
}
-static inline char * zend_verify_arg_class_kind(zend_arg_info *cur_arg_info, zend_class_entry **pce TSRMLS_DC)
+static inline char * zend_verify_arg_class_kind(zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce TSRMLS_DC)
{
- *pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
+ *pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
- if ((*pce)->ce_flags & ZEND_ACC_INTERFACE) {
+ *class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
+ if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
return "implement interface ";
} else {
return "be an instance of ";
@@ -497,18 +498,20 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
cur_arg_info = &zf->common.arg_info[arg_num-1];
if (cur_arg_info->class_name) {
+ char *class_name;
+
if (!arg) {
- need_msg = zend_verify_arg_class_kind(cur_arg_info, &ce TSRMLS_CC);
- return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, ce->name, "none", "" TSRMLS_CC);
+ need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
+ return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC);
}
if (Z_TYPE_P(arg) == IS_OBJECT) {
- need_msg = zend_verify_arg_class_kind(cur_arg_info, &ce TSRMLS_CC);
- if (!instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
- return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, ce->name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
+ need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
+ if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
+ return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
}
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
- need_msg = zend_verify_arg_class_kind(cur_arg_info, &ce TSRMLS_CC);
- return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, ce->name, zend_zval_type_name(arg), "" TSRMLS_CC);
+ need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC);
+ return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
}
} else if (cur_arg_info->array_type_hint) {
if (!arg) {
diff --git a/tests/classes/type_hinting_002.phpt b/tests/classes/type_hinting_002.phpt
index 4cb75b1b8f..7c685bfdba 100755
--- a/tests/classes/type_hinting_002.phpt
+++ b/tests/classes/type_hinting_002.phpt
@@ -13,5 +13,4 @@ $o = new Foo;
$o->a($o);
?>
--EXPECTF--
-
-Fatal error: Class 'NonExisting' not found in %stype_hinting_002.php on line %d
+Catchable fatal error: Argument 1 passed to Foo::a() must be an instance of NonExisting, instance of Foo given, called in %s on line %d and defined in %s on line %d