diff --git a/packages/compiler/src/render3/r3_control_flow.ts b/packages/compiler/src/render3/r3_control_flow.ts index 9a13ddb52e44..cc4e3b568817 100644 --- a/packages/compiler/src/render3/r3_control_flow.ts +++ b/packages/compiler/src/render3/r3_control_flow.ts @@ -20,7 +20,7 @@ const FOR_LOOP_EXPRESSION_PATTERN = /^\s*([0-9A-Za-z_$]*)\s+of\s+([\S\s]*)/; const FOR_LOOP_TRACK_PATTERN = /^track\s+([\S\s]*)/; /** Pattern for the `as` expression in a conditional block. */ -const CONDITIONAL_ALIAS_PATTERN = /^(as\s)+(.*)/; +const CONDITIONAL_ALIAS_PATTERN = /^(as\s+)(.*)/; /** Pattern used to identify an `else if` block. */ const ELSE_IF_PATTERN = /^else[^\S\r\n]+if/; @@ -28,6 +28,9 @@ const ELSE_IF_PATTERN = /^else[^\S\r\n]+if/; /** Pattern used to identify a `let` parameter. */ const FOR_LOOP_LET_PATTERN = /^let\s+([\S\s]*)/; +/** Pattern used to validate a JavaScript identifier. */ +const IDENTIFIER_PATTERN = /^[$A-Z_][0-9A-Z_$]*$/i; + /** * Pattern to group a string into leading whitespace, non whitespace, and trailing whitespace. * Useful for getting the variable name span when a span can contain leading and trailing space. @@ -630,9 +633,16 @@ function parseConditionalBlockParameters( ); } else { const name = aliasMatch[2].trim(); - const variableStart = param.sourceSpan.start.moveBy(aliasMatch[1].length); - const variableSpan = new ParseSourceSpan(variableStart, variableStart.moveBy(name.length)); - expressionAlias = new t.Variable(name, name, variableSpan, variableSpan); + + if (IDENTIFIER_PATTERN.test(name)) { + const variableStart = param.sourceSpan.start.moveBy(aliasMatch[1].length); + const variableSpan = new ParseSourceSpan(variableStart, variableStart.moveBy(name.length)); + expressionAlias = new t.Variable(name, name, variableSpan, variableSpan); + } else { + errors.push( + new ParseError(param.sourceSpan, '"as" expression must be a valid JavaScript identifier'), + ); + } } } diff --git a/packages/compiler/test/render3/r3_template_transform_spec.ts b/packages/compiler/test/render3/r3_template_transform_spec.ts index 18865568b8f6..6d55febb9fdb 100644 --- a/packages/compiler/test/render3/r3_template_transform_spec.ts +++ b/packages/compiler/test/render3/r3_template_transform_spec.ts @@ -2361,6 +2361,14 @@ describe('R3 template transform', () => { `), ).toThrowError(/@else block must be last inside the conditional/); }); + + it('should throw if "as" expression is not a valid identifier', () => { + expect(() => + parse(` + @if (foo; as foo && bar) {hello} + `), + ).toThrowError(/"as" expression must be a valid JavaScript identifier/); + }); }); });