]> granicus.if.org Git - php/commitdiff
Fixed bug #71202 (Autoload function registered by another not activated immediately)
authorXinchen Hui <laruence@gmail.com>
Wed, 23 Dec 2015 15:48:00 +0000 (07:48 -0800)
committerXinchen Hui <laruence@gmail.com>
Wed, 23 Dec 2015 15:48:00 +0000 (07:48 -0800)
NEWS
ext/spl/php_spl.c
ext/spl/tests/bug71202.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 4dd6361fa0335dc6228188d1ef97d98e579352fc..50a6bbf1e02734ac119bf92df17bb5f42059abe4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ PHP                                                                        NEWS
 - Core:
   . Added support for new HTTP 451 code. (Julien)
 
+- SPL:
+  . Fixed bug #71202 (Autoload function registered by another not activated
+    immediately). (Laruence)
+
 - Standard:
   . Fixed bug #71190 (substr_replace converts integers in original $search
     array to strings). (Laruence)
index e89caa205914c3a6154d86e5cfafb1921c74f3c1..b2f59328d2b3a7ade7f79fd5a044fe0ca2751634 100644 (file)
@@ -417,11 +417,17 @@ PHP_FUNCTION(spl_autoload_call)
        }
 
        if (SPL_G(autoload_functions)) {
+               HashPosition pos;
+               zend_ulong num_idx;
                int l_autoload_running = SPL_G(autoload_running);
                SPL_G(autoload_running) = 1;
                lc_name = zend_string_alloc(Z_STRLEN_P(class_name), 0);
                zend_str_tolower_copy(ZSTR_VAL(lc_name), Z_STRVAL_P(class_name), Z_STRLEN_P(class_name));
-               ZEND_HASH_FOREACH_STR_KEY_PTR(SPL_G(autoload_functions), func_name, alfi) {
+               zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &pos);
+               while (zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &num_idx, &pos) == HASH_KEY_IS_STRING) {
+                       if ((alfi = zend_hash_get_current_data_ptr_ex(SPL_G(autoload_functions), &pos)) == NULL) {
+                               continue;
+                       }
                        zend_call_method(Z_ISUNDEF(alfi->obj)? NULL : &alfi->obj, alfi->ce, &alfi->func_ptr, ZSTR_VAL(func_name), ZSTR_LEN(func_name), retval, 1, class_name, NULL);
                        zend_exception_save();
                        if (retval) {
@@ -431,7 +437,8 @@ PHP_FUNCTION(spl_autoload_call)
                        if (zend_hash_exists(EG(class_table), lc_name)) {
                                break;
                        }
-               } ZEND_HASH_FOREACH_END();
+                       zend_hash_move_forward_ex(SPL_G(autoload_functions), &pos);
+               }
                zend_exception_restore();
                zend_string_free(lc_name);
                SPL_G(autoload_running) = l_autoload_running;
diff --git a/ext/spl/tests/bug71202.phpt b/ext/spl/tests/bug71202.phpt
new file mode 100644 (file)
index 0000000..d26d7e1
--- /dev/null
@@ -0,0 +1,38 @@
+--TEST--
+Bug #71202 (Autoload function registered by another not activated immediately)
+--FILE--
+<?php
+
+function inner_autoload ($name){
+       if ($name == 'A') {
+               class A {
+                       function __construct(){
+                               echo "okey, ";
+                       }
+               }
+       } else {
+               class B {
+                       function __construct() {
+                               die("error");
+                       }
+               }
+       }
+}
+
+spl_autoload_register(function ($name) {
+       if ($name == 'A') {
+               spl_autoload_register("inner_autoload");
+       } else {
+               spl_autoload_unregister("inner_autoload");
+       }
+});
+
+$c = new A();
+try {
+       $c = new B();
+} catch (Error $e) {
+       echo "done";
+}
+?>
+--EXPECT--
+okey, done