Fix an empty destructuring pattern triggering a PHP fatal error instead of a SyntaxError

This commit is contained in:
Fabien Potencier
2026-08-23 09:50:46 +02:00
parent cd25fe5b98
commit a2b023397e
3 changed files with 23 additions and 0 deletions
+1
View File
@@ -1,6 +1,7 @@
# 3.29.0 (2026-XX-XX)
* Add documentation comments to attach metadata to nodes (experimental)
* Fix an empty destructuring pattern triggering a PHP fatal error instead of a `SyntaxError`
* Fix sequence destructuring of iterators throwing a `TypeError`
* Add `TempestMarkdown` to use `tempest/markdown` as the `markdown_to_html` converter
* Fix imported macros not resolving their own template-level macro imports
@@ -50,6 +50,9 @@ class AssignmentExpressionParser extends BinaryOperatorExpressionParser
};
if ($left instanceof ArrayExpression) {
if (!$left->getKeyValuePairs()) {
throw new SyntaxError('Cannot destructure to an empty list of variables.', $token->getLine(), $parser->getStream()->getSourceContext());
}
foreach ($left->getKeyValuePairs() as $i => $pair) {
if ($pair['value'] instanceof ContextVariable && !$pair['value'] instanceof AssignContextVariable) {
$left->setNode(2 * $i + 1, new AssignContextVariable($pair['value']->getAttribute('name'), $pair['value']->getTemplateLine()));
+19
View File
@@ -268,6 +268,25 @@ class ExpressionParserTest extends TestCase
$this->assertSame('third', $pairs[2]['value']->getAttribute('name'));
}
/**
* @dataProvider getEmptyDestructuringTests
*/
#[DataProvider('getEmptyDestructuringTests')]
public function testEmptyDestructuringThrows(string $template): void
{
$env = new Environment(new ArrayLoader(), ['cache' => false, 'autoescape' => false]);
$this->expectException(SyntaxError::class);
$this->expectExceptionMessage('Cannot destructure to an empty list of variables');
$env->compileSource(new Source($template, 'index'));
}
public static function getEmptyDestructuringTests()
{
yield ['{% do [] = values %}'];
yield ['{% do {} = values %}'];
}
public function testObjectDestructuringUsesAssignmentTargets(): void
{
$env = new Environment(new ArrayLoader(), ['cache' => false, 'autoescape' => false]);