]> granicus.if.org Git - php/commitdiff
Fix foreach object property visibility checks
authorNikita Popov <nikic@php.net>
Tue, 22 Nov 2016 20:01:15 +0000 (21:01 +0100)
committerNikita Popov <nikic@php.net>
Tue, 22 Nov 2016 20:01:15 +0000 (21:01 +0100)
Again, check_property_access() does not correctly work for properties
that look like mangled private propert names (but aren't). Fix this
by only checking visibility for INDIRECT properties.

foreach currently still unmangles property names, even if they don't
correspond to declared properties. HHVM does not do this (and I think
this is correct.) As this is done consistently, leaving it alone
for now.

Zend/tests/foreach_018.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/foreach_018.phpt b/Zend/tests/foreach_018.phpt
new file mode 100644 (file)
index 0000000..3c0be7b
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+Foreach on stdClass with properties looking like mangled properties
+--FILE--
+<?php
+
+$obj = (object)[
+    "\0A\0b" => 42,
+    "\0*\0c" => 24,
+];
+
+foreach ($obj as $k => $v) {
+    var_dump($k, $v);
+}
+
+?>
+--EXPECT--
+string(1) "b"
+int(42)
+string(1) "c"
+int(24)
index e828e96ea6eab93ce0ac3015e39587b16dc1fea5..8c9431957042e7ad72d2c91d563f36fde10c1759 100644 (file)
@@ -5772,11 +5772,11 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -5927,11 +5927,11 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -6088,13 +6088,13 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
                                                p++;
                                                continue;
                                        }
+                                       if (UNEXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == FAILURE)) {
+                                               pos++;
+                                               p++;
+                                               continue;
+                                       }
                                }
-                               if (UNEXPECTED(!p->key) ||
-                                   EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
-                                       break;
-                               }
-                               pos++;
-                               p++;
+                               break;
                        }
                        if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
                                if (UNEXPECTED(!p->key)) {
@@ -6116,11 +6116,11 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
                                        break;
                                }
                                p++;
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                        }
index 12176848cde9f78f3e3a89ddf9aab40a67cb7fb5..338d1942793e25916d6880b540e0ad90c2b266a9 100644 (file)
@@ -3525,11 +3525,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -3677,11 +3677,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -12833,11 +12833,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -12986,11 +12986,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -16394,11 +16394,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -16549,11 +16549,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -16710,13 +16710,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE
                                                p++;
                                                continue;
                                        }
+                                       if (UNEXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == FAILURE)) {
+                                               pos++;
+                                               p++;
+                                               continue;
+                                       }
                                }
-                               if (UNEXPECTED(!p->key) ||
-                                   EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
-                                       break;
-                               }
-                               pos++;
-                               p++;
+                               break;
                        }
                        if (opline->result_type & (IS_TMP_VAR|IS_CV)) {
                                if (UNEXPECTED(!p->key)) {
@@ -16738,11 +16738,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE
                                        break;
                                }
                                p++;
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                        }
@@ -35457,11 +35457,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;
@@ -35609,11 +35609,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
                                        Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
                                        ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
                                }
-                               if ((EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
-                                    (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
-                                     EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF))) &&
-                                   (UNEXPECTED(!p->key) ||
-                                    EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS))) {
+                               if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
+                                   (EXPECTED(Z_TYPE(p->val) != IS_INDIRECT) ||
+                                    (EXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF) &&
+                                     EXPECTED(zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)))
+                               ) {
                                        break;
                                }
                                pos++;