mirror of
https://github.com/php/php-src.git
synced 2024-09-22 18:37:25 +00:00
Merge branch 'PHP-7.0' into PHP-7.1
* PHP-7.0: Fixed bug #73896 (spl_autoload() crashes when calls magic _call())
This commit is contained in:
commit
5753a753c7
3
NEWS
3
NEWS
@ -20,6 +20,9 @@ PHP NEWS
|
||||
- Session:
|
||||
. Fixed bug #69582 (session not readable by root in CLI). (EvgeniySpinov)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug #73896 (spl_autoload() crashes when calls magic _call()). (Dmitry)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #69442 (closing of fd incorrect when PTS enabled). (jaytaph)
|
||||
. Fixed bug #47021 (SoapClient stumbles over WSDL delivered with
|
||||
|
@ -380,6 +380,11 @@ static void autoload_func_info_dtor(zval *element)
|
||||
if (!Z_ISUNDEF(alfi->closure)) {
|
||||
zval_ptr_dtor(&alfi->closure);
|
||||
}
|
||||
if (alfi->func_ptr &&
|
||||
UNEXPECTED(alfi->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
zend_string_release(alfi->func_ptr->common.function_name);
|
||||
zend_free_trampoline(alfi->func_ptr);
|
||||
}
|
||||
efree(alfi);
|
||||
}
|
||||
|
||||
@ -405,7 +410,15 @@ PHP_FUNCTION(spl_autoload_call)
|
||||
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) {
|
||||
alfi = zend_hash_get_current_data_ptr_ex(SPL_G(autoload_functions), &pos);
|
||||
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);
|
||||
if (UNEXPECTED(alfi->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
zend_function *copy = emalloc(sizeof(zend_op_array));
|
||||
|
||||
memcpy(copy, alfi->func_ptr, sizeof(zend_op_array));
|
||||
copy->op_array.function_name = zend_string_copy(alfi->func_ptr->op_array.function_name);
|
||||
zend_call_method(Z_ISUNDEF(alfi->obj)? NULL : &alfi->obj, alfi->ce, ©, ZSTR_VAL(func_name), ZSTR_LEN(func_name), retval, 1, class_name, NULL);
|
||||
} else {
|
||||
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) {
|
||||
zval_ptr_dtor(retval);
|
||||
@ -567,6 +580,13 @@ PHP_FUNCTION(spl_autoload_register)
|
||||
}
|
||||
}
|
||||
|
||||
if (UNEXPECTED(alfi.func_ptr == &EG(trampoline))) {
|
||||
zend_function *copy = emalloc(sizeof(zend_op_array));
|
||||
|
||||
memcpy(copy, alfi.func_ptr, sizeof(zend_op_array));
|
||||
alfi.func_ptr->common.function_name = NULL;
|
||||
alfi.func_ptr = copy;
|
||||
}
|
||||
if (zend_hash_add_mem(SPL_G(autoload_functions), lc_name, &alfi, sizeof(autoload_func_info)) == NULL) {
|
||||
if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
Z_DELREF(alfi.obj);
|
||||
@ -574,6 +594,10 @@ PHP_FUNCTION(spl_autoload_register)
|
||||
if (!Z_ISUNDEF(alfi.closure)) {
|
||||
Z_DELREF(alfi.closure);
|
||||
}
|
||||
if (UNEXPECTED(alfi.func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
zend_string_release(alfi.func_ptr->common.function_name);
|
||||
zend_free_trampoline(alfi.func_ptr);
|
||||
}
|
||||
}
|
||||
if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) {
|
||||
/* Move the newly created element to the head of the hashtable */
|
||||
|
38
ext/spl/tests/bug73896.phpt
Normal file
38
ext/spl/tests/bug73896.phpt
Normal file
@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
Bug #73896 (spl_autoload() crashes when calls magic _call())
|
||||
--FILE--
|
||||
<?php
|
||||
class Registrator {
|
||||
public static function call($callable, array $args) {
|
||||
return call_user_func_array($callable, [$args]);
|
||||
}
|
||||
}
|
||||
|
||||
class teLoader {
|
||||
public function __construct() {
|
||||
Registrator::call('spl_autoload_register', [$this, 'autoload']);
|
||||
}
|
||||
|
||||
public function __call($method, $args) {
|
||||
$this->doSomething();
|
||||
}
|
||||
|
||||
protected function autoload($class) {
|
||||
die("Protected autoload() called!\n");
|
||||
}
|
||||
|
||||
public function doSomething() {
|
||||
throw new teException();
|
||||
}
|
||||
}
|
||||
|
||||
$teLoader = new teLoader();
|
||||
|
||||
try {
|
||||
new teChild();
|
||||
} catch (Throwable $e) {
|
||||
echo "Exception: ", $e->getMessage() , "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Exception: Class 'teException' not found
|
Loading…
Reference in New Issue
Block a user