Skip to content

By-ref modification of typed and readonly props through ArrayIterator #10872

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

Closed
wants to merge 1 commit into from

Conversation

iluuu1994
Copy link
Member

@iluuu1994 iluuu1994 commented Mar 17, 2023

Fixes GH-10844

Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, don't have any better either, so this shall do.

Copy link
Member

@arnaud-lb arnaud-lb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spl_array_get_iterator has a by_ref parameter. We could store its value in the iterator, and use that in spl_array_it_get_current_data to find in a more direct way that the data is fetched as a ref.

FFI does something like that in zend_ffi_cdata_get_iterator / zend_ffi_cdata_it_get_current_data.

@iluuu1994
Copy link
Member Author

@arnaud-lb Oh, thank you, let me try that!

@iluuu1994 iluuu1994 changed the title Dirty solution for ref mod to typed and readonly props through ArrayIterator By-ref modification of typed and readonly props through ArrayIterator Mar 24, 2023
@iluuu1994
Copy link
Member Author

That worked, thanks @arnaud-lb 🙂

spl_array_object *array_object = Z_SPLARRAY_P(object);

if (by_ref && (array_object->ar_flags & SPL_ARRAY_OVERLOADED_CURRENT)) {
zend_throw_error(NULL, "An iterator cannot be used with foreach by reference");
return NULL;
}

iterator = emalloc(sizeof(zend_user_iterator));
iterator = emalloc(sizeof(spl_array_iterator));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the style for PHP is, butin other projects the following is preferred:

Suggested change
iterator = emalloc(sizeof(spl_array_iterator));
iterator = emalloc(sizeof(*iterator));

if (array_iter->by_ref
&& Z_TYPE_P(data) != IS_REFERENCE
&& !(object->ar_flags & SPL_ARRAY_IS_SELF)
&& !(object->ar_flags & SPL_ARRAY_USE_OTHER)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two checks could be combined (although the compiler probably takes care of that)

@iluuu1994 iluuu1994 closed this in 9aaa5cd Mar 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants