Skip to content

Commit 626d659

Browse files
Fix GH-8841: error on return type check of func declaration isn't removing the function from function_table
1 parent 79a2832 commit 626d659

File tree

3 files changed

+174
-1
lines changed

3 files changed

+174
-1
lines changed

Zend/zend_compile.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6992,7 +6992,16 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
69926992
} else if (uses_ast) {
69936993
zend_compile_closure_uses(uses_ast);
69946994
}
6995-
zend_compile_stmt(stmt_ast);
6995+
6996+
zend_try {
6997+
zend_compile_stmt(stmt_ast);
6998+
} zend_catch {
6999+
if (!is_method && toplevel) {
7000+
zend_hash_del(CG(function_table), CG(active_op_array)->function_name);
7001+
}
7002+
7003+
zend_bailout();
7004+
} zend_end_try();
69967005

69977006
if (is_method) {
69987007
CG(zend_lineno) = decl->start_lineno;

sapi/cli/tests/gh8841_1.phpt

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
--TEST--
2+
GH-8841: Fix invalid return type compilation doesn't register function (without libedit)
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
if (!extension_loaded('readline') || READLINE_LIB !== "readline") {
7+
die ("skip need readline support");
8+
}
9+
?>
10+
--FILE--
11+
<?php
12+
$php = getenv('TEST_PHP_EXECUTABLE');
13+
14+
// disallow console escape sequences that may break the output
15+
putenv('TERM=VT100');
16+
17+
$codes = array();
18+
19+
$codes[1] = <<<EOT
20+
function f(\$x): void { return \$x; }
21+
f(1);
22+
EOT;
23+
24+
$codes[2] = <<<EOT
25+
function f(\$x): void { return \$x; }
26+
function f(\$x): int { return \$x; }
27+
echo f(1);
28+
EOT;
29+
30+
$codes[3] = <<<EOT
31+
function foo() { return \$x[]; }
32+
foo();
33+
EOT;
34+
35+
foreach ($codes as $key => $code) {
36+
echo "\n--------------\nSnippet no. $key:\n--------------\n";
37+
$code = escapeshellarg($code);
38+
echo `echo $code | "$php" -a`, "\n";
39+
}
40+
41+
echo "\nDone\n";
42+
?>
43+
--EXPECT--
44+
--------------
45+
Snippet no. 1:
46+
--------------
47+
Interactive shell
48+
49+
php > function f($x): void { return $x; }
50+
51+
Fatal error: A void function must not return a value in php shell code on line 1
52+
php > f(1);
53+
54+
Warning: Uncaught Error: Call to undefined function f() in php shell code:1
55+
Stack trace:
56+
#0 {main}
57+
thrown in php shell code on line 1
58+
php >
59+
60+
--------------
61+
Snippet no. 2:
62+
--------------
63+
Interactive shell
64+
65+
php > function f($x): void { return $x; }
66+
67+
Fatal error: A void function must not return a value in php shell code on line 1
68+
php > function f($x): int { return $x; }
69+
php > echo f(1);
70+
1
71+
php >
72+
73+
--------------
74+
Snippet no. 3:
75+
--------------
76+
Interactive shell
77+
78+
php > function foo() { return $x[]; }
79+
80+
Fatal error: Cannot use [] for reading in php shell code on line 1
81+
php > foo();
82+
83+
Warning: Uncaught Error: Call to undefined function foo() in php shell code:1
84+
Stack trace:
85+
#0 {main}
86+
thrown in php shell code on line 1
87+
php >
88+
89+
Done

sapi/cli/tests/gh8841_2.phpt

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
--TEST--
2+
GH-8841: Fix invalid return type compilation doesn't register function (with libedit)
3+
--SKIPIF--
4+
<?php
5+
include "skipif.inc";
6+
if (!extension_loaded('readline')) die("skip need readline support");
7+
if (READLINE_LIB !== "libedit") die('skip libedit only');
8+
?>
9+
--FILE--
10+
<?php
11+
$php = getenv('TEST_PHP_EXECUTABLE');
12+
$codes = array();
13+
14+
$codes[1] = <<<EOT
15+
function f(\$x): void { return \$x; }
16+
f(1);
17+
EOT;
18+
19+
$codes[2] = <<<EOT
20+
function f(\$x): void { return \$x; }
21+
function f(\$x): int { return \$x; }
22+
echo f(1);
23+
EOT;
24+
25+
$codes[3] = <<<EOT
26+
function foo() { return \$x[]; }
27+
foo();
28+
EOT;
29+
30+
foreach ($codes as $key => $code) {
31+
echo "\n--------------\nSnippet no. $key:\n--------------\n";
32+
$php = getenv('TEST_PHP_EXECUTABLE');
33+
$ini = getenv('TEST_PHP_EXTRA_ARGS');
34+
$descriptorspec = [['pipe', 'r'], STDOUT, STDERR];
35+
$proc = proc_open("$php $ini -a", $descriptorspec, $pipes);
36+
fwrite($pipes[0], $code);
37+
fclose($pipes[0]);
38+
proc_close($proc);
39+
}
40+
?>
41+
--EXPECT--
42+
--------------
43+
Snippet no. 1:
44+
--------------
45+
Interactive shell
46+
47+
48+
Fatal error: A void function must not return a value in php shell code on line 1
49+
50+
Warning: Uncaught Error: Call to undefined function f() in php shell code:1
51+
Stack trace:
52+
#0 {main}
53+
thrown in php shell code on line 1
54+
55+
--------------
56+
Snippet no. 2:
57+
--------------
58+
Interactive shell
59+
60+
61+
Fatal error: A void function must not return a value in php shell code on line 1
62+
1
63+
64+
--------------
65+
Snippet no. 3:
66+
--------------
67+
Interactive shell
68+
69+
70+
Fatal error: Cannot use [] for reading in php shell code on line 1
71+
72+
Warning: Uncaught Error: Call to undefined function foo() in php shell code:1
73+
Stack trace:
74+
#0 {main}
75+
thrown in php shell code on line 1

0 commit comments

Comments
 (0)