Skip to content

Commit 00c2c3a

Browse files
marcioAlmadanikic
authored andcommitted
fix unintentional bc break with compact('this') behavior
1 parent 2c3408f commit 00c2c3a

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

ext/standard/array.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,6 +1976,14 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
19761976
ZVAL_COPY(&data, value_ptr);
19771977
zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
19781978
}
1979+
if (zend_string_equals_literal(Z_STR_P(entry), "this")) {
1980+
zend_object *object = zend_get_this_object(EG(current_execute_data));
1981+
if (object) {
1982+
GC_REFCOUNT(object)++;
1983+
ZVAL_OBJ(&data, object);
1984+
zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
1985+
}
1986+
}
19791987
} else if (Z_TYPE_P(entry) == IS_ARRAY) {
19801988
if ((Z_ARRVAL_P(entry)->u.v.nApplyCount > 1)) {
19811989
php_error_docref(NULL, E_WARNING, "recursion detected");
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
compact() without object context
3+
--FILE--
4+
<?php
5+
6+
var_dump(
7+
(new class {
8+
function test(){
9+
return (static function(){ return compact('this'); })();
10+
}
11+
})->test()
12+
);
13+
14+
var_dump(compact('this'));
15+
16+
var_dump((function(){ return compact('this'); })());
17+
18+
?>
19+
--EXPECT--
20+
array(0) {
21+
}
22+
array(0) {
23+
}
24+
array(0) {
25+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
compact() with object context
3+
--FILE--
4+
<?php
5+
6+
var_dump(
7+
(new class {
8+
function test(){
9+
return compact('this');
10+
}
11+
})->test()
12+
);
13+
14+
var_dump(
15+
(new class {
16+
function test(){
17+
return compact([['this']]);
18+
}
19+
})->test()
20+
);
21+
22+
var_dump(
23+
(new class {
24+
function test(){
25+
return (function(){ return compact('this'); })();
26+
}
27+
})->test()
28+
);
29+
30+
?>
31+
--EXPECT--
32+
array(1) {
33+
["this"]=>
34+
object(class@anonymous)#1 (0) {
35+
}
36+
}
37+
array(1) {
38+
["this"]=>
39+
object(class@anonymous)#1 (0) {
40+
}
41+
}
42+
array(1) {
43+
["this"]=>
44+
object(class@anonymous)#1 (0) {
45+
}
46+
}

0 commit comments

Comments
 (0)