Skip to content
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

Sandbox foreachVars in templates #4445

Merged
merged 1 commit into from
Aug 9, 2021
Merged

Conversation

dtdesign
Copy link
Member

@dtdesign dtdesign commented Aug 8, 2021

Nesting the same template inside a foreach loop that is also accessed inside the nested call will overwrite the values from the outer template due to identical identifiers being used.

The sandbox did not protected $this->foreachVars despite being stateful.

See #4431
Fixes #4444

Nesting the same template inside a `foreach` loop that is also accessed inside the nested call will overwrite the values from the outer template due to identical identifiers being used.

The sandbox did not protected `$this->foreachVars` despite being stateful.

See #4431
Fixes #4444
@dtdesign dtdesign requested a review from TimWolla August 8, 2021 09:29
@TimWolla
Copy link
Member

TimWolla commented Aug 9, 2021

I'm not sure whether it is appropriate to tie this to the sandbox. The sandbox can be disabled on-demand, but we must always protect the foreachVars state, no?

@dtdesign
Copy link
Member Author

dtdesign commented Aug 9, 2021

Yes, you got a point there, but frankly I don't see a reasonable approach that does not rely on the sandbox. It is a design flaw of the template engine that cannot be overcome easily, especially not within the scope of a bugfix release.

I'm well aware that this is merely a bandaid for the problem, but considering that it never really surfaced since WCF 1.0, I'm deeming this to be sufficient for the time being.

@TimWolla
Copy link
Member

TimWolla commented Aug 9, 2021

Yes, you got a point there, but frankly I don't see a reasonable approach that does not rely on the sandbox.

I had extending compileIncludeTag in mind.

Before including the template:

$this->metadata[] = [
 'foreach' => $this->foreachVars,
];

After including:

['foreach' => $this->foreachVars] = \array_pop($this->metadata);

This is effectively a separate sandbox and should be reasonable even for a bugfix update?

In any case your PR LGTM in general. I just want to avoid needing to make yet another fix after this one.

@dtdesign
Copy link
Member Author

dtdesign commented Aug 9, 2021

Looking at compileIncludeTag() makes me feel a bit uneasy, because it has two somewhat different code paths. $metaData is also potentially unsafe, it originates from compileString() and can be supplied from the outside.

Recursively including the same template is not really a thing anymore since we started relying on nested iterators instead, therefore it should be fairly uncommon to do this. I'm leaning towards the "cheap" fix in this PR and replacing it in 5.5 with a proper solution, allowing us to have it reasonably tested before rolling it out to production.

@TimWolla
Copy link
Member

TimWolla commented Aug 9, 2021

I'm leaning towards the "cheap" fix in this PR and replacing it in 5.5 with a proper solution, allowing us to have it reasonably tested before rolling it out to production.

That's fair. Feel free to merge.

@dtdesign dtdesign merged commit e738b4a into 5.4 Aug 9, 2021
@dtdesign dtdesign deleted the template-sandbox-foreachvars branch August 9, 2021 10:53
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.

None yet

2 participants