]> granicus.if.org Git - php/commitdiff
fix #39003 (__autoload() is called for type hinting)
authorAntony Dovgal <tony2001@php.net>
Mon, 2 Oct 2006 11:05:02 +0000 (11:05 +0000)
committerAntony Dovgal <tony2001@php.net>
Mon, 2 Oct 2006 11:05:02 +0000 (11:05 +0000)
Zend/tests/bug39003.phpt [new file with mode: 0644]
Zend/zend_execute.c
tests/classes/type_hinting_002.phpt

diff --git a/Zend/tests/bug39003.phpt b/Zend/tests/bug39003.phpt
new file mode 100644 (file)
index 0000000..7a3da84
--- /dev/null
@@ -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
index 3c3decd3136bb4e865df616d3f5ab89035802e45..ce8376580940d816c92489e0a602a15f51c8ff31 100644 (file)
@@ -472,11 +472,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, zstr *class_name, zend_class_entry **pce TSRMLS_DC)
 {
-       *pce = zend_u_fetch_class(UG(unicode) ? IS_UNICODE : IS_STRING, cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
+       *pce = zend_u_fetch_class(UG(unicode) ? IS_UNICODE : IS_STRING, 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 ";
@@ -518,21 +519,22 @@ 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.v) {
-               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", EMPTY_ZSTR 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);
-                       }
-               } 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), EMPTY_ZSTR TSRMLS_CC);
-               }
+    if (cur_arg_info->class_name.v) {
+        zstr class_name;
+
+        if (!arg) {
+            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", EMPTY_ZSTR TSRMLS_CC);
+        }
+        if (Z_TYPE_P(arg) == IS_OBJECT) {
+            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, &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), EMPTY_ZSTR TSRMLS_CC);
+        }
        } else if (cur_arg_info->array_type_hint) {
                if (!arg) {
                        return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", EMPTY_ZSTR, "none", EMPTY_ZSTR TSRMLS_CC);
index 4cb75b1b8f84a6952528e0af0c2beeadd4bdcb9a..7c685bfdba3e39aef3832f6c08e4906e84a8f7ca 100755 (executable)
@@ -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