Skip to content

Commit

Permalink
Fix phpGH-10251: Assertion `(flag & (1<<3)) == 0' failed.
Browse files Browse the repository at this point in the history
zend_get_property_guard previously assumed that at least "str" has a
pre-computed hash. This is not always the case, for example when a
string is created by bitwise operations, its hash is not set. Instead of
forcing a computation of the hashes, drop the hash comparison.

Closes phpGH-10254

Co-authored-by: Changochen <[email protected]>

Signed-off-by: George Peter Banyard <[email protected]>
  • Loading branch information
nielsdos authored and Girgias committed Jan 8, 2023
1 parent 8ff2b6a commit d03025b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ PHP NEWS
- Core:
. Fixed bug GH-10072 (PHP crashes when execute_ex is overridden and a __call
trampoline is used from internal code). (Derick)
. Fix GH-10251 (Assertion `(flag & (1<<3)) == 0' failed). (nielsdos)

- Date:
. Fixed bug GH-9891 (DateTime modify with unixtimestamp (@) must work like
Expand Down
24 changes: 24 additions & 0 deletions Zend/tests/gh10251.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
GH-10251 (Assertion `(flag & (1<<3)) == 0' failed.)
--FILE--
<?php
class A
{
function __set($o, $l)
{
$this->$p = $v;
}
}
$a = new A();
$pp = "";
$op = $pp & "";
// Bitwise operators on strings don't compute the hash.
// The code below previously assumed a hash was actually computed, leading to a crash.
$a->$op = 0;
echo "Done\n";
?>
--EXPECTF--
Warning: Undefined variable $v in %s on line %d

Warning: Undefined variable $p in %s on line %d
Done
5 changes: 2 additions & 3 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,9 +535,8 @@ ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *membe
if (EXPECTED(Z_TYPE_P(zv) == IS_STRING)) {
zend_string *str = Z_STR_P(zv);
if (EXPECTED(str == member) ||
/* "str" always has a pre-calculated hash value here */
(EXPECTED(ZSTR_H(str) == zend_string_hash_val(member)) &&
EXPECTED(zend_string_equal_content(str, member)))) {
/* str and member don't necessarily have a pre-calculated hash value here */
EXPECTED(zend_string_equal_content(str, member))) {
return &Z_PROPERTY_GUARD_P(zv);
} else if (EXPECTED(Z_PROPERTY_GUARD_P(zv) == 0)) {
zval_ptr_dtor_str(zv);
Expand Down

0 comments on commit d03025b

Please sign in to comment.