fix($parse): properly handle dots at the end of identifiers

Fixes #4613
Fixes #4912
Closes #8559
This commit is contained in:
Pawel Kozlowski
2014-08-09 22:55:21 +02:00
parent 525a8f851e
commit 8ac90357a6
2 changed files with 39 additions and 0 deletions

View File

@@ -276,6 +276,16 @@ Lexer.prototype = {
this.index++;
}
//check if the identifier ends with . and if so move back one char
if (lastDot && ident[ident.length - 1] === '.') {
this.index--;
ident = ident.slice(0, -1);
lastDot = ident.lastIndexOf('.');
if (lastDot === -1) {
lastDot = undefined;
}
}
//check if this is not a method invocation and if it is back out to last dot
if (lastDot) {
peekIndex = this.index;

View File

@@ -71,6 +71,13 @@ describe('parser', function() {
expect(tokens[i].string).toEqual('d"e');
});
it('should tokenize identifiers with spaces after dots', function () {
var tokens = lex('foo. bar');
expect(tokens[0].text).toEqual('foo');
expect(tokens[1].text).toEqual('.');
expect(tokens[2].text).toEqual('bar');
});
it('should tokenize undefined', function() {
var tokens = lex("undefined");
var i = 0;
@@ -349,6 +356,28 @@ describe('parser', function() {
expect(scope.$eval("x.y.z", scope)).not.toBeDefined();
});
it('should handle white-spaces around dots in paths', function () {
scope.a = {b: 4};
expect(scope.$eval("a . b", scope)).toEqual(4);
expect(scope.$eval("a. b", scope)).toEqual(4);
expect(scope.$eval("a .b", scope)).toEqual(4);
expect(scope.$eval("a . \nb", scope)).toEqual(4);
});
it('should throw syntax error exception for identifiers ending with a dot', function () {
scope.a = {b: 4};
expect(function() {
scope.$eval("a.", scope);
}).toThrowMinErr('$parse', 'syntax',
"Token 'null' is an unexpected token at column 2 of the expression [a.] starting at [.].");
expect(function() {
scope.$eval("a .", scope);
}).toThrowMinErr('$parse', 'syntax',
"Token 'null' is an unexpected token at column 3 of the expression [a .] starting at [.].");
});
it('should resolve deeply nested paths (important for CSP mode)', function() {
scope.a = {b: {c: {d: {e: {f: {g: {h: {i: {j: {k: {l: {m: {n: 'nooo!'}}}}}}}}}}}}};
expect(scope.$eval("a.b.c.d.e.f.g.h.i.j.k.l.m.n", scope)).toBe('nooo!');