Skip to content

Commit a480965

Browse files
authored
ext/opcache: unwrap reference wrappers in typed by-value returns (#21973)
1 parent d8e7418 commit a480965

4 files changed

Lines changed: 65 additions & 6 deletions

File tree

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ PHP NEWS
9393
. Fix persistent free of non-persistent connect_attr key (David Carlier).
9494

9595
- Opcache:
96+
. Fixed bug GH-21972 (Corrupted variable type when a typed by-value return
97+
contains a reference wrapper). (Weilin Du)
9698
. Fixed tracing JIT crash when a VM interrupt is handled during an observed
9799
user function call. (Levi Morrison)
98100
. Fixed bug GH-22004 (Assertion failure at ext/opcache/jit/zend_jit_trace.c).

Zend/zend_vm_def.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4387,7 +4387,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
43874387
ZVAL_DEREF(retval_ptr);
43884388
}
43894389

4390-
if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
4390+
if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ref)))) {
43914391
ZEND_VM_NEXT_OPCODE();
43924392
}
43934393

@@ -4417,6 +4417,9 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
44174417
}
44184418
retval_ptr = retval_ref;
44194419
}
4420+
if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
4421+
ZEND_VM_NEXT_OPCODE();
4422+
}
44204423
}
44214424

44224425
SAVE_OPLINE();

Zend/zend_vm_execute.h

Lines changed: 20 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/opcache/tests/opt/gh21972.phpt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
GH-21972: Typed by-value return must not leak reference wrapper
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
--EXTENSIONS--
8+
opcache
9+
--FILE--
10+
<?php
11+
declare(strict_types=1);
12+
13+
enum ValueType {
14+
case BOOL;
15+
case MIXED;
16+
}
17+
18+
function applyDefinition(
19+
bool &$lazy = false,
20+
ValueType &$type = ValueType::MIXED,
21+
int &$flags = 0,
22+
?string &$default = null,
23+
): void {
24+
}
25+
26+
function getTypedValue(string $default, bool $lazy, ValueType $type): string {
27+
applyDefinition($lazy, $type, default: $default);
28+
return $default;
29+
}
30+
31+
$value = getTypedValue('false', false, ValueType::BOOL);
32+
var_dump(gettype($value));
33+
var_dump(strtolower($value));
34+
var_dump(strtolower(getTypedValue('FALSE', false, ValueType::BOOL)));
35+
?>
36+
--EXPECT--
37+
string(6) "string"
38+
string(5) "false"
39+
string(5) "false"

0 commit comments

Comments
 (0)