-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Assertion failure in ext/spl/spl_fixedarray.c #15918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
See #15775 (comment). |
Bruh, and if we change <?php
$foo = new SplFixedArray(1);
$arrayObject = new ArrayObject($foo);
$arrayObject[] = 'x';
$arrayObject[] = 'x';
$arrayObject[] = 'x';
var_dump($foo->getSize()); // Outputs int(1)
var_dump($foo); // Outputs 3 elements 🤦 But hey at least the assertion is then gone 🤔 |
ArrayObject doesn't even know it's operating on an SplFixedArray, it's just going through the properties case and manipulating the properties table... |
Yeah, this class needs to be burned with fire 😄 |
I would close this as a wontfix. We can't account for all the craziness that is possible with |
@iluuu1994 Fixing the assertion would improve stability/fix crash, but won't fix the other issues of course. I think it would be good to at least change that foreach macro but I agree otherwise on burning the class with fire and ignoring semantic issues. |
In my opinion, |
I don't have a big opinion. |
I noticed that PHP 8.2 correctly throws an exception that you're not allowed to use SplFixedArray as input for an ArrayObject. In PHP 8.3 somehow this no longer throws. So I bisected this to c4ecd82. So turns out this is a regression and we should fix it such that using SplFixedArray is not allowed, instead of allowing it and fixing the assert. Looking at the commit, it seems it replaced SplFixedArray's properties handler with a get_properties_for handler, and ArrayObject only checks whether get_properties is overloaded, it doesn't check get_properties_for. I propose fixing it like this: diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 79802454e3f..3fcce1a7682 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -1084,7 +1084,7 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
}
} else {
zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
- if (handler != zend_std_get_properties) {
+ if (handler != zend_std_get_properties || Z_OBJ_HANDLER_P(array, get_properties_for)) {
zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0,
"Overloaded object of type %s is not compatible with %s",
ZSTR_VAL(Z_OBJCE_P(array)->name), ZSTR_VAL(intern->std.ce->name));
This will make one test fail: |
I'm in favour of the proposed fix from @nielsdos |
Good find, @nielsdos! I think your suggested change makes sense, I don't mind the minor BC break, since it fixes problems, and only affects PHP 8.3. For the record, relevant comment from the PR discussion: #9757 (comment) |
SplFixedArray should've never get supported in ArrayObject because it's overloaded, and so that breaks assumptions. This regressed in c4ecd82.
* PHP-8.3: Fix GH-15918: Assertion failure in ext/spl/spl_fixedarray.c
Description
The following code:
Resulted in this output:
PHP Version
PHP 8.4.0-dev
Operating System
ubuntu 22.04
The text was updated successfully, but these errors were encountered: