diff --git a/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts b/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts index 6f7a620bb..aad4535a2 100644 --- a/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts +++ b/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts @@ -220,6 +220,13 @@ export abstract class HandlebarsNodeVisitors extends Parser { let mustache: ASTv1.MustacheStatement; const { escaped, loc, strip } = rawMustache; + if ('original' in rawMustache.path && rawMustache.path.original === '...attributes') { + throw generateSyntaxError( + 'Illegal use of ...attributes', + this.source.spanFor(rawMustache.loc) + ); + } + if (isHBSLiteral(rawMustache.path)) { mustache = b.mustache({ path: this.acceptNode<(typeof rawMustache.path)['type']>(rawMustache.path), diff --git a/packages/@glimmer/syntax/test/parser-node-test.ts b/packages/@glimmer/syntax/test/parser-node-test.ts index dc8d3e150..5bd0ba57b 100644 --- a/packages/@glimmer/syntax/test/parser-node-test.ts +++ b/packages/@glimmer/syntax/test/parser-node-test.ts @@ -121,6 +121,36 @@ test('a piece of Handlebars with HTML', () => { ); }); +test('attributes are not allowed as values', (assert) => { + let t = '{{...attributes}}'; + assert.throws( + () => { + parse(t, { meta: { moduleName: 'test-module' } }); + }, + syntaxErrorFor('Illegal use of ...attributes', '{{...attributes}}', 'test-module', 1, 0) + ); +}); + +test('attributes are not allowed as modifiers', (assert) => { + let t = '
'; + assert.throws( + () => { + parse(t, { meta: { moduleName: 'test-module' } }); + }, + syntaxErrorFor('Illegal use of ...attributes', '{{...attributes}}', 'test-module', 1, 5) + ); +}); + +test('attributes are not allowed as attribute values', (assert) => { + let t = '
'; + assert.throws( + () => { + parse(t, { meta: { moduleName: 'test-module' } }); + }, + syntaxErrorFor('Illegal use of ...attributes', '{{...attributes}}', 'test-module', 1, 11) + ); +}); + test('Handlebars embedded in an attribute (quoted)', () => { let t = 'some
content
done'; astEqual(