fix(parser): detect empty expression in strings to interpolate

Fixes #3412

Closes #3451
This commit is contained in:
Pawel Kozlowski 2015-08-03 12:05:45 +02:00
parent 6eaa09ac20
commit 4422819754
2 changed files with 27 additions and 4 deletions

View File

@ -48,6 +48,13 @@ var _implicitReceiver = new ImplicitReceiver();
// TODO(tbosch): Cannot make this const/final right now because of the transpiler... // TODO(tbosch): Cannot make this const/final right now because of the transpiler...
var INTERPOLATION_REGEXP = /\{\{(.*?)\}\}/g; var INTERPOLATION_REGEXP = /\{\{(.*?)\}\}/g;
class ParseException extends BaseException {
constructor(message: string, input: string, errLocation: string, ctxLocation?: any) {
super(`Parser Error: ${message} ${errLocation} [${input}] in ${ctxLocation}`, null, null,
ctxLocation);
}
}
@Injectable() @Injectable()
export class Parser { export class Parser {
_reflector: Reflector; _reflector: Reflector;
@ -88,14 +95,21 @@ export class Parser {
var expressions = []; var expressions = [];
for (var i = 0; i < parts.length; i++) { for (var i = 0; i < parts.length; i++) {
var part = parts[i]; var part: string = parts[i];
if (i % 2 === 0) { if (i % 2 === 0) {
// fixed string // fixed string
strings.push(part); strings.push(part);
} else { } else if (part.trim().length > 0) {
var tokens = this._lexer.tokenize(part); var tokens = this._lexer.tokenize(part);
var ast = new _ParseAST(input, location, tokens, this._reflector, false).parseChain(); var ast = new _ParseAST(input, location, tokens, this._reflector, false).parseChain();
expressions.push(ast); expressions.push(ast);
} else {
var errLocation = '';
for (var j = 0; j < i; j++) {
errLocation += j % 2 === 0 ? parts[j] : `{{${parts[j]}}}`;
}
throw new ParseException('Blank expressions are not allowed in interpolated strings', input,
`at column ${errLocation.length} in`, location);
} }
} }
return new ASTWithSource(new Interpolation(strings, expressions), input, location); return new ASTWithSource(new Interpolation(strings, expressions), input, location);
@ -596,8 +610,7 @@ export class _ParseAST {
var location = (index < this.tokens.length) ? `at column ${this.tokens[index].index + 1} in` : var location = (index < this.tokens.length) ? `at column ${this.tokens[index].index + 1} in` :
`at the end of the expression`; `at the end of the expression`;
throw new BaseException( throw new ParseException(message, this.input, location, this.location);
`Parser Error: ${message} ${location} [${this.input}] in ${this.location}`);
} }
} }

View File

@ -624,6 +624,16 @@ export function main() {
var ast = parseInterpolation(originalExp).ast; var ast = parseInterpolation(originalExp).ast;
expect(new Unparser().unparse(ast)).toEqual(originalExp); expect(new Unparser().unparse(ast)).toEqual(originalExp);
}); });
it("should throw on empty interpolation expressions", () => {
expect(() => parseInterpolation("{{}}"))
.toThrowError(new RegExp(
"Parser Error: Blank expressions are not allowed in interpolated strings"));
expect(() => parseInterpolation("foo {{ }}"))
.toThrowError(new RegExp(
"Parser Error: Blank expressions are not allowed in interpolated strings"));
});
}); });
describe("parseSimpleBinding", () => { describe("parseSimpleBinding", () => {