Skip to content

Commit e6d2afb

Browse files
crisbetothePunderWoman
authored andcommitted
fix(compiler): throw for invalid "as" expression in if block (angular#60580)
Adds some validation that the "as" expression in an `@if` block is valid. Fixes angular#59939. PR Close angular#60580
1 parent 0cd7d3b commit e6d2afb

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

packages/compiler/src/render3/r3_control_flow.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@ const FOR_LOOP_EXPRESSION_PATTERN = /^\s*([0-9A-Za-z_$]*)\s+of\s+([\S\s]*)/;
2020
const FOR_LOOP_TRACK_PATTERN = /^track\s+([\S\s]*)/;
2121

2222
/** Pattern for the `as` expression in a conditional block. */
23-
const CONDITIONAL_ALIAS_PATTERN = /^(as\s)+(.*)/;
23+
const CONDITIONAL_ALIAS_PATTERN = /^(as\s+)(.*)/;
2424

2525
/** Pattern used to identify an `else if` block. */
2626
const ELSE_IF_PATTERN = /^else[^\S\r\n]+if/;
2727

2828
/** Pattern used to identify a `let` parameter. */
2929
const FOR_LOOP_LET_PATTERN = /^let\s+([\S\s]*)/;
3030

31+
/** Pattern used to validate a JavaScript identifier. */
32+
const IDENTIFIER_PATTERN = /^[$A-Z_][0-9A-Z_$]*$/i;
33+
3134
/**
3235
* Pattern to group a string into leading whitespace, non whitespace, and trailing whitespace.
3336
* Useful for getting the variable name span when a span can contain leading and trailing space.
@@ -630,9 +633,16 @@ function parseConditionalBlockParameters(
630633
);
631634
} else {
632635
const name = aliasMatch[2].trim();
633-
const variableStart = param.sourceSpan.start.moveBy(aliasMatch[1].length);
634-
const variableSpan = new ParseSourceSpan(variableStart, variableStart.moveBy(name.length));
635-
expressionAlias = new t.Variable(name, name, variableSpan, variableSpan);
636+
637+
if (IDENTIFIER_PATTERN.test(name)) {
638+
const variableStart = param.sourceSpan.start.moveBy(aliasMatch[1].length);
639+
const variableSpan = new ParseSourceSpan(variableStart, variableStart.moveBy(name.length));
640+
expressionAlias = new t.Variable(name, name, variableSpan, variableSpan);
641+
} else {
642+
errors.push(
643+
new ParseError(param.sourceSpan, '"as" expression must be a valid JavaScript identifier'),
644+
);
645+
}
636646
}
637647
}
638648

packages/compiler/test/render3/r3_template_transform_spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,6 +2361,14 @@ describe('R3 template transform', () => {
23612361
`),
23622362
).toThrowError(/@else block must be last inside the conditional/);
23632363
});
2364+
2365+
it('should throw if "as" expression is not a valid identifier', () => {
2366+
expect(() =>
2367+
parse(`
2368+
@if (foo; as foo && bar) {hello}
2369+
`),
2370+
).toThrowError(/"as" expression must be a valid JavaScript identifier/);
2371+
});
23642372
});
23652373
});
23662374

0 commit comments

Comments
 (0)