Skip to content

Commit

Permalink
Merge branch 'PHP-8.1' into PHP-8.2
Browse files Browse the repository at this point in the history
* PHP-8.1:
  Fix phpGH-10011 (Trampoline autoloader will get reregistered and cannot be unregistered)
  • Loading branch information
Girgias committed Dec 2, 2022
2 parents 6b1f4c5 + 608ddb0 commit 334d108
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ PHP NEWS

- SPL:
. Fixed GH-9883 (SplFileObject::__toString() reads next line). (Girgias)
. Fixed GH-10011 (Trampoline autoloader will get reregistered and cannot be
unregistered). (Girgias)

08 Dec 2022, PHP 8.2.0

Expand Down
17 changes: 17 additions & 0 deletions ext/spl/php_spl.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,16 @@ static autoload_func_info *autoload_func_info_from_fci(

static bool autoload_func_info_equals(
const autoload_func_info *alfi1, const autoload_func_info *alfi2) {
if (UNEXPECTED(
(alfi1->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) &&
(alfi2->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)
)) {
return alfi1->obj == alfi2->obj
&& alfi1->ce == alfi2->ce
&& alfi1->closure == alfi2->closure
&& zend_string_equals(alfi1->func_ptr->common.function_name, alfi2->func_ptr->common.function_name)
;
}
return alfi1->func_ptr == alfi2->func_ptr
&& alfi1->obj == alfi2->obj
&& alfi1->ce == alfi2->ce
Expand Down Expand Up @@ -580,6 +590,13 @@ PHP_FUNCTION(spl_autoload_unregister)
RETURN_TRUE;
}

if (!fcc.function_handler) {
/* Call trampoline has been cleared by zpp. Refetch it, because we want to deal
* with it outselves. It is important that it is not refetched on every call,
* because calls may occur from different scopes. */
zend_is_callable_ex(&fci.function_name, NULL, 0, NULL, &fcc, NULL);
}

autoload_func_info *alfi = autoload_func_info_from_fci(&fci, &fcc);
Bucket *p = spl_find_registered_function(alfi);
autoload_func_info_destroy(alfi);
Expand Down
59 changes: 59 additions & 0 deletions ext/spl/tests/gh10011.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
--TEST--
Bug GH-10011 (Trampoline autoloader will get reregistered and cannot be unregistered)
--FILE--
<?php

class TrampolineTest {
public function __call(string $name, array $arguments) {
echo 'Trampoline for ', $name, PHP_EOL;
}
}
$o = new TrampolineTest();
$callback1 = [$o, 'trampoline1'];
$callback2 = [$o, 'trampoline2'];

spl_autoload_register($callback1);
spl_autoload_register($callback2);
spl_autoload_register($callback1); // 2nd call ignored

var_dump(spl_autoload_functions());

var_dump(class_exists("TestClass", true));

echo "Unregister trampoline:\n";
var_dump(spl_autoload_unregister($callback1));
var_dump(spl_autoload_unregister($callback1));
var_dump(spl_autoload_unregister($callback2));

var_dump(spl_autoload_functions());
var_dump(class_exists("TestClass", true));
?>
--EXPECT--
array(2) {
[0]=>
array(2) {
[0]=>
object(TrampolineTest)#1 (0) {
}
[1]=>
string(11) "trampoline1"
}
[1]=>
array(2) {
[0]=>
object(TrampolineTest)#1 (0) {
}
[1]=>
string(11) "trampoline2"
}
}
Trampoline for trampoline1
Trampoline for trampoline2
bool(false)
Unregister trampoline:
bool(true)
bool(false)
bool(true)
array(0) {
}
bool(false)

0 comments on commit 334d108

Please sign in to comment.