Skip to content

Commit d9dd4d9

Browse files
committed
Fix accessibility checks for dynamic properties
A dynamic property may be shadowed by a private/protected property. Make sure we check property accessibility for non-indirect properties as well.
1 parent 251bd9c commit d9dd4d9

File tree

5 files changed

+50
-14
lines changed

5 files changed

+50
-14
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Dynamic property shadowed by private property
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
private $prop = "Test";
8+
9+
function run() {
10+
foreach ($this as $k => $v) {
11+
echo "$k => $v\n";
12+
}
13+
var_dump(get_object_vars($this));
14+
}
15+
}
16+
class Test2 extends Test {
17+
}
18+
19+
$test2 = new Test2;
20+
$test2->prop = "Test2";
21+
$test2->run();
22+
23+
?>
24+
--EXPECT--
25+
prop => Test
26+
array(1) {
27+
["prop"]=>
28+
string(4) "Test"
29+
}

Zend/zend_builtin_functions.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,13 +1198,13 @@ ZEND_FUNCTION(get_object_vars)
11981198
continue;
11991199
}
12001200

1201-
ZEND_ASSERT(key);
1202-
if (zend_check_property_access(zobj, key) == FAILURE) {
1203-
continue;
1204-
}
12051201
unmangle = 1;
12061202
}
12071203

1204+
if (zend_check_property_access(zobj, key) == FAILURE) {
1205+
continue;
1206+
}
1207+
12081208
if (Z_ISREF_P(value) && Z_REFCOUNT_P(value) == 1) {
12091209
value = Z_REFVAL_P(value);
12101210
}

Zend/zend_vm_def.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5848,7 +5848,9 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit):
58485848
&& EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
58495849
break;
58505850
}
5851-
} else {
5851+
} else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
5852+
|| !p->key
5853+
|| zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS) {
58525854
break;
58535855
}
58545856
}
@@ -5998,7 +6000,9 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR)
59986000
&& EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
59996001
break;
60006002
}
6001-
} else {
6003+
} else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
6004+
|| !p->key
6005+
|| zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS) {
60026006
break;
60036007
}
60046008
}

Zend/zend_vm_execute.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21261,7 +21261,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE
2126121261
&& EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
2126221262
break;
2126321263
}
21264-
} else {
21264+
} else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
21265+
|| !p->key
21266+
|| zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS) {
2126521267
break;
2126621268
}
2126721269
}
@@ -21411,7 +21413,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z
2141121413
&& EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
2141221414
break;
2141321415
}
21414-
} else {
21416+
} else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
21417+
|| !p->key
21418+
|| zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS) {
2141521419
break;
2141621420
}
2141721421
}

ext/standard/http.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,13 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
5656
ZEND_HASH_FOREACH_KEY_VAL_IND(ht, idx, key, zdata) {
5757
/* handling for private & protected object properties */
5858
if (key) {
59+
if (type != NULL && zend_check_property_access(Z_OBJ_P(type), key) != SUCCESS) {
60+
/* property not visible in this scope */
61+
continue;
62+
}
63+
5964
if (ZSTR_VAL(key)[0] == '\0' && type != NULL) {
6065
const char *tmp;
61-
62-
zend_object *zobj = Z_OBJ_P(type);
63-
if (zend_check_property_access(zobj, key) != SUCCESS) {
64-
/* private or protected property access outside of the class */
65-
continue;
66-
}
6766
zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len);
6867
} else {
6968
prop_name = ZSTR_VAL(key);

0 commit comments

Comments
 (0)