-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Fix GH-8841: error on return type check of func declaration isn't removing the function from function_table #8933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
74d0684
to
8c7512e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR!
While this would obviously fix the reported issue, I think it is too small in scope, since there are many reasons why the compilation of a function declaration might fail. E.g. function foo() {return $a[];} foo();
would still cause the same segfault.
Thank you for your feedback, I'm taking a look to improve the fix! |
8c7512e
to
f320a47
Compare
Alright, so I surrounded the AST compilation in As far as I understood, |
bed8459
to
dd1a3b5
Compare
I think that is much better. Thank you! It seems to be possible to guard the I'm not quite sure about
Yeah, it is similar. |
dd1a3b5
to
01c1475
Compare
Thank you for the feedback!
If I understand correctly, |
@alexandre-daubois, I think you're right regarding sapi/cli/tests/gh8841.phpt--TEST--
GH-8841: Fix invalid return type compilation doesn't register function
--SKIPIF--
<?php
include "skipif.inc";
if (!extension_loaded('readline')) die("skip need readline support");
if (READLINE_LIB !== "libedit") die('skip libedit only');
?>
--FILE--
<?php
$php = getenv('TEST_PHP_EXECUTABLE');
// disallow console escape sequences that may break the output
putenv('TERM=VT100');
$codes = array();
$codes[1] = <<<EOT
function f(\$x): void { return \$x; }
f(1);
EOT;
$codes[2] = <<<EOT
function f(\$x): void { return \$x; }
function f(\$x): int { return \$x; }
echo f(1);
EOT;
$codes[3] = <<<EOT
function foo() { return \$x[]; }
foo();
EOT;
foreach ($codes as $key => $code) {
echo "\n--------------\nSnippet no. $key:\n--------------\n";
$php = getenv('TEST_PHP_EXECUTABLE');
$ini = getenv('TEST_PHP_EXTRA_ARGS');
$descriptorspec = [['pipe', 'r'], STDOUT, STDERR];
$proc = proc_open("$php $ini -a", $descriptorspec, $pipes);
fwrite($pipes[0], $code);
fclose($pipes[0]);
proc_close($proc);
}
?>
--EXPECT--
--------------
Snippet no. 1:
--------------
Interactive shell
Fatal error: A void function must not return a value in php shell code on line 1
Warning: Uncaught Error: Call to undefined function f() in php shell code:1
Stack trace:
#0 {main}
thrown in php shell code on line 1
--------------
Snippet no. 2:
--------------
Interactive shell
Fatal error: A void function must not return a value in php shell code on line 1
1
--------------
Snippet no. 3:
--------------
Interactive shell
Fatal error: Cannot use [] for reading in php shell code on line 1
Warning: Uncaught Error: Call to undefined function foo() in php shell code:1
Stack trace:
#0 {main}
thrown in php shell code on line 1 That would either require a separate test for libreadline, or maybe we could unify the test expectation by inserting |
…removing the function from function_table
01c1475
to
626d659
Compare
An interactive shell shouldn't be necessary to reproduce this at all -- can't you just use a shutdown function? This also doesn't seem like the right way to fix the issue: We should be delaying function registration instead. |
Here's a simple test: https://3v4l.org/XMg3k |
It's actually not php-cli specific, nor SAPI specific. We should delay the registration of the function into the function table until after the compilation was successful, otherwise the function is mistakingly registered and a NULL dereference will happen when trying to call it. I based my test of Nikita's test, so credits to him for the test: php#8933 (comment)
It's actually not php-cli specific, nor SAPI specific. We should delay the registration of the function into the function table until after the compilation was successful, otherwise the function is mistakingly registered and a NULL dereference will happen when trying to call it. I based my test of Nikita's test, so credits to him for the test: #8933 (comment) Closes GH-10989.
This was fixed by an alternative fix in #10989 instead. |
At compile time, if the return type check fails during a function declaration, then the function isn't removed from the global
function_table
in SAPI. It causes 2 problems:function_table
, it is not possible to (try to) redefine the function, as function name is considered as "already in use"Fixes #8841