Bug #71266 [Opn->Asn]: Missing separation of properties HT in foreach etc.
| From: | dmitry@php.net | Date: | Mon, 18 Jan 2016 10:20:59 +0000 |
| Subject: | Bug #71266 [Opn->Asn]: Missing separation of properties HT in foreach etc. | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-198751@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=71266&edit=1
ID: 71266
Updated by: dmitry@php.net
Reported by: nikic@php.net
Summary: Missing separation of properties HT in foreach etc.
-Status: Open
+Status: Assigned
Type: Bug
Package: Scripting Engine problem
PHP Version: 7.0Git-2016-01-03 (Git)
-Assigned To:
+Assigned To: dmitry
Block user comment: N
Private report: N
Previous Comments:
------------------------------------------------------------------------
[2016-01-03 13:36:20] laruence@php.net
For case 1:
maybe we should not reset iter->pos if ht is updated(ht != iter->ht).
something like:
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 11034fe..c44c689 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -381,7 +381,6 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTab
ht->u.v.nIteratorsCount++;
}
iter->ht = ht;
- iter->pos = ht->nInternalPointer;
}
return iter->pos;
}
@@ -405,7 +404,6 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval
ht->u.v.nIteratorsCount++;
}
iter->ht = ht;
- iter->pos = ht->nInternalPointer;
}
return iter->pos;
}
for case 2, maybe we could simple separate the array?
thanks
------------------------------------------------------------------------
[2016-01-03 12:08:26] nikic@php.net
Description:
------------
There are currently a number of places in the engine and library where the properties table is not
properly separated. Essentially it's all the cases where get_properties() (or OBJPROP or
HASH_OF) is used in a write context.
Two examples (assuming no immutable arrays):
$obj = (object) ['foo' => 1, 'bar' => 2];
foreach ($obj as $val) {
var_dump($val);
$obj->bar = 42;
}
This outputs 1, 1, 42 instead of 1, 42, because the properties table will be separated at the
assignment, while it should have been separated at the start of the loop.
$arr = ['foo' => 1, 'bar' => 2];
$obj = (object) $arr;
next($obj);
var_dump(current($arr));
This outputs 2 instead of 1, because next() did not separate the properties HT, so it is still
shared with the array.
I'm not sure how we should best fix this. We could always separate in get_properties(), however
not all get_properties() uses are in write context. We can't cleanly separate outside
get_properties(), as we'd have to assume how the properties are stored. The best option would
likely be an extra argument to determine read/write context, but that's not ABI compatible.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=71266&edit=1