Skip to content

Commit 7a83627

Browse files
committed
Fix SCCP evaluation of isset()/empty() on dimension of non-escaping object
`ct_eval_isset_dim()` treated partial objects like scalars and folded the result to false/true. But using an object as an array either calls `ArrayAccess::offsetExists()` or throws an Error.
1 parent 026bb4e commit 7a83627

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

‎Zend/Optimizer/sccp.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,9 @@ static inline zend_result ct_eval_isset_dim(zval *result, uint32_t extended_valu
436436
} else if (Z_TYPE_P(op1) == IS_STRING) {
437437
// TODO
438438
return FAILURE;
439+
} else if (IS_PARTIAL_OBJECT(op1)) {
440+
/* Objects may implement ArrayAccess or throw. */
441+
return FAILURE;
439442
} else {
440443
ZVAL_BOOL(result, (extended_value & ZEND_ISEMPTY));
441444
return SUCCESS;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
SCCP: isset()/empty() on dimension of non-escaping object must not be evaluated
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+
class P {}
12+
13+
function f() {
14+
$o = new P;
15+
return isset($o[1]);
16+
}
17+
18+
function g() {
19+
$o = new P;
20+
return empty($o[1]);
21+
}
22+
23+
try {
24+
var_dump(f());
25+
} catch (Error $e) {
26+
echo $e->getMessage(), "\n";
27+
}
28+
try {
29+
var_dump(g());
30+
} catch (Error $e) {
31+
echo $e->getMessage(), "\n";
32+
}
33+
?>
34+
--EXPECT--
35+
Cannot use object of type P as array
36+
Cannot use object of type P as array

0 commit comments

Comments
 (0)