}
}
- lc_name = do_alloca(func_name_len + 1);
+ lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1);
zend_str_tolower_copy(lc_name, func_name, func_name_len);
efree(func_name);
+
+ if (SPL_G(autoload_functions) && zend_hash_exists(SPL_G(autoload_functions), (char*)lc_name, func_name_len+1)) {
+ goto skip;
+ }
+
if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
+ /* add object id to the hash to ensure uniqueness, for more reference look at bug #40091 */
+ memcpy(lc_name + func_name_len, obj_ptr, sizeof(long));
+ func_name_len += sizeof(long);
+ lc_name[func_name_len] = '\0';
alfi.obj = *obj_ptr;
alfi.obj->refcount++;
} else {
}
zend_hash_add(SPL_G(autoload_functions), lc_name, func_name_len+1, &alfi.func_ptr, sizeof(autoload_func_info), NULL);
-
- free_alloca(lc_name);
+skip:
+ efree(lc_name);
}
if (SPL_G(autoload_functions)) {
zval *zcallable;
int success = FAILURE;
zend_function *spl_func_ptr;
+ zval **obj_ptr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zcallable) == FAILURE) {
return;
}
- if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_SYNTAX_ONLY, &func_name, &func_name_len, NULL, NULL, NULL TSRMLS_CC)) {
+ if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_SYNTAX_ONLY, &func_name, &func_name_len, NULL, NULL, &obj_ptr TSRMLS_CC)) {
if (func_name) {
efree(func_name);
}
} else {
/* remove specific */
success = zend_hash_del(SPL_G(autoload_functions), func_name, func_name_len+1);
+ if (success != SUCCESS && obj_ptr) {
+ func_name = erealloc(func_name, func_name_len + 1 + sizeof(long));
+ memcpy(func_name + func_name_len, obj_ptr, sizeof(long));
+ func_name_len += sizeof(long);
+ func_name[func_name_len] = '\0';
+ success = zend_hash_del(SPL_G(autoload_functions), func_name, func_name_len+1);
+ }
}
} else if (func_name_len == sizeof("spl_autoload")-1 && !strcmp(func_name, "spl_autoload")) {
/* register single spl_autoload() */
--- /dev/null
+--TEST--
+Bug #40091 (issue with spl_autoload_register() and 2 instances of the same class)
+--SKIPIF--
+<?php if (!extension_loaded("spl")) print "skip"; ?>
+--FILE--
+<?php
+class MyAutoloader {
+ function __construct($directory_to_use) {}
+ function autoload($class_name) {
+ // code to autoload based on directory
+ }
+}
+
+$autloader1 = new MyAutoloader('dir1');
+spl_autoload_register(array($autloader1, 'autoload'));
+
+$autloader2 = new MyAutoloader('dir2');
+spl_autoload_register(array($autloader2, 'autoload'));
+
+print_r(spl_autoload_functions());
+?>
+===DONE===
+--EXPECT--
+Array
+(
+ [0] => Array
+ (
+ [0] => MyAutoloader
+ [1] => autoload
+ )
+
+ [1] => Array
+ (
+ [0] => MyAutoloader
+ [1] => autoload
+ )
+
+)
+===DONE===