Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[PropertyAccess] PropertyPathBuilder remove/append/remove fails by not resetting indexes #30389

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
GregOriol opened this issue Feb 26, 2019 · 1 comment

Comments

@GregOriol
Copy link
Contributor

Symfony version(s) affected: 4.2 and likely older (up to 2.x ?)

Description
I'm trying to use the PropertyPathBuilder and found this strange behavior: when you remove the last item from the path, append a new one and try to remove it, you get the "The offset %s is not within the property path", which doesn't seem correct

How to reproduce

$builder = new PropertyPathBuilder('old1.old2');

$builder->getPropertyPath(); // returns old1.old2
$builder->getLength(); // returns 2

$builder->remove($builder->getLength() - 1); // should remove old2
$builder->getPropertyPath()); // returns old1
$builder->getLength(); // returns 1

$builder->appendProperty('old3');
$builder->getPropertyPath(); // returns old1.old3
$builder->getLength(); // returns 2

// so far everything seems correct

$builder->remove($builder->getLength() - 1); // should remove old3, but fails as offset 1 doesn't exist
$builder->getPropertyPath(); // I expected that this would return old1?

Possible Solution
Having looked at the code of the builder in detail, the elements and isIndex arrays are updated using unset on remove and [] = $ on append, and unset doesn't reset the "next index", making the $builder->appendProperty('old3'); happen at index 2, while there is only index 0 left

In other words, after $builder->appendProperty('old3');, the internal list of elements is:

[
0 => 'old1',
2 => 'old3'
]

instead of what I had expected:

[
0 => 'old1',
1 => 'old3'
]

A solution could be to add:

$this->elements = array_values($this->elements);
$this->isIndex = array_values($this->isIndex);

at the end of the resize method, which is used by remove. This would reset the indexes/offsets.

Additional context
There is no test case for this scenario, so I'm not sure if it was intended like this (maybe I didn't understand correctly how it should be used?) or if nobody has yet tried something like this?

@xabbuh
Copy link
Member

xabbuh commented Feb 27, 2019

Would you like to send a pull request (targetting the 3.4 branch)?

@fabpot fabpot closed this as completed Mar 4, 2019
fabpot added a commit that referenced this issue Mar 4, 2019
…ls to reset internal indexes (GregOriol)

This PR was squashed before being merged into the 3.4 branch (closes #30392).

Discussion
----------

[PropertyAccess] Fixed PropertyPathBuilder remove that fails to reset internal indexes

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #30389
| License       | MIT
| Doc PR        | -

In addition to the fix (first commit), this PR adds \ to all not-yet-prefixed native functions in the PropertyPathBuilder (second commit).

NB: the behavior fixed here actually appeared in 2.2

Commits
-------

479dff4 [PropertyAccess] Fixed PropertyPathBuilder remove that fails to reset internal indexes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants