You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
but the strings str and member are actually equal content-wise (their pointers are different, but the characters are the same: both the empty string). This shouldn't happen because of the string equality check above. Later we execute the following:
But it turns out that the hash of str is zero here! I did a quick test by changing ZSTR_H(str) to zend_string_hash_val(str) and now the OP's code no longer crashes, indicating that the hash being zero is indeed the problem.
I would expect that any empty string to be "optimized" to the interned zend_empty_string zend_string which has the hash precomputed. So it seems the is an issue with the bitwise & operator (which might be generalized to other operators)
The line comparing hashes should just be dropped. member is not guaranteed to have a hash, and member is assigned to str, so it doesn't necessarily have a hash either. (Or else we'd have to force a hash calculation when assigning str.)
Activity
ndossche commentedon Jan 6, 2023
I confirm this happens on 8.1 and higher.
Analysis:
Upon attempting to store the empty string in the magic set method we first reach this code
php-src/Zend/zend_object_handlers.c
Lines 549 to 551 in 047c978
but the strings str and member are actually equal content-wise (their pointers are different, but the characters are the same: both the empty string). This shouldn't happen because of the string equality check above. Later we execute the following:
php-src/Zend/zend_object_handlers.c
Line 571 in 047c978
And now a new entry isn't actually added because the first snippet I linked added it. Therefore the assertion fails.
Cause:
The following check should've prevented this:
php-src/Zend/zend_object_handlers.c
Lines 537 to 540 in 047c978
But it turns out that the hash of
stris zero here! I did a quick test by changingZSTR_H(str)tozend_string_hash_val(str)and now the OP's code no longer crashes, indicating that the hash being zero is indeed the problem.Girgias commentedon Jan 7, 2023
I would expect that any empty string to be "optimized" to the interned
zend_empty_stringzend_string which has the hash precomputed. So it seems the is an issue with the bitwise&operator (which might be generalized to other operators)ndossche commentedon Jan 7, 2023
Yeah it also breaks with bitwise
|.nikic commentedon Jan 7, 2023
The line comparing hashes should just be dropped.
memberis not guaranteed to have a hash, andmemberis assigned tostr, so it doesn't necessarily have a hash either. (Or else we'd have to force a hash calculation when assigningstr.)ndossche commentedon Jan 7, 2023
I see, I'll make a PR for that change this afternoon.
Fix phpGH-10251: Assertion `(flag & (1<<3)) == 0' failed.
Add a regression test for phpGH-10251
Fix GH-10251: Assertion `(flag & (1<<3)) == 0' failed.
Merge branch 'PHP-8.1' into PHP-8.2
Merge branch 'PHP-8.2'
Prevent dynamic property deprecation for test phpGH-10251