Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit b014607

Browse files
committed
fix($parse): correctly escape unsafe identifier characters
This commit also adds a couple of tests for `$parseProvider.setIdentifierFns()`. Closes #14942
1 parent fd46fc8 commit b014607

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

src/ng/parse.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ ASTCompiler.prototype = {
12611261
},
12621262

12631263
nonComputedMember: function(left, right) {
1264-
var SAFE_IDENTIFIER = /[$_a-zA-Z][$_a-zA-Z0-9]*/;
1264+
var SAFE_IDENTIFIER = /^[$_a-zA-Z][$_a-zA-Z0-9]*$/;
12651265
var UNSAFE_CHARACTERS = /[^$_a-zA-Z0-9]/g;
12661266
if (SAFE_IDENTIFIER.test(right)) {
12671267
return left + '.' + right;

test/ng/parseSpec.js

+88
Original file line numberDiff line numberDiff line change
@@ -3884,4 +3884,92 @@ describe('parser', function() {
38843884
});
38853885
});
38863886
});
3887+
3888+
forEach([true, false], function(cspEnabled) {
3889+
describe('custom identifiers (csp: ' + cspEnabled + ')', function() {
3890+
var isIdentifierStartRe = /[#a-z]/;
3891+
var isIdentifierContinueRe = /[\-a-z]/;
3892+
var isIdentifierStartFn;
3893+
var isIdentifierContinueFn;
3894+
var scope;
3895+
3896+
beforeEach(module(function($parseProvider) {
3897+
isIdentifierStartFn = jasmine.
3898+
createSpy('isIdentifierStart').
3899+
and.callFake(function(ch, cp) { return isIdentifierStartRe.test(ch); });
3900+
isIdentifierContinueFn = jasmine.
3901+
createSpy('isIdentifierContinue').
3902+
and.callFake(function(ch, cp) { return isIdentifierContinueRe.test(ch); });
3903+
3904+
$parseProvider.setIdentifierFns(isIdentifierStartFn, isIdentifierContinueFn);
3905+
csp().noUnsafeEval = cspEnabled;
3906+
}));
3907+
3908+
beforeEach(inject(function($rootScope) {
3909+
scope = $rootScope;
3910+
}));
3911+
3912+
3913+
it('should allow specifying a custom `isIdentifierStart/Continue` functions', function() {
3914+
scope.x = {};
3915+
3916+
scope['#foo'] = 'foo';
3917+
scope.x['#foo'] = 'foo';
3918+
expect(scope.$eval('#foo')).toBe('foo');
3919+
expect(scope.$eval('x.#foo')).toBe('foo');
3920+
3921+
scope['bar--'] = 42;
3922+
scope.x['bar--'] = 42;
3923+
expect(scope.$eval('bar--')).toBe(42);
3924+
expect(scope.$eval('x.bar--')).toBe(42);
3925+
expect(scope['bar--']).toBe(42);
3926+
expect(scope.x['bar--']).toBe(42);
3927+
3928+
scope['#-'] = 'baz';
3929+
scope.x['#-'] = 'baz';
3930+
expect(scope.$eval('#-')).toBe('baz');
3931+
expect(scope.$eval('x.#-')).toBe('baz');
3932+
3933+
expect(function() { scope.$eval('##'); }).toThrow();
3934+
expect(function() { scope.$eval('x.##'); }).toThrow();
3935+
3936+
expect(function() { scope.$eval('--'); }).toThrow();
3937+
expect(function() { scope.$eval('x.--'); }).toThrow();
3938+
});
3939+
3940+
3941+
it('should pass the character and codepoint to the custom functions', function() {
3942+
scope.$eval('#-');
3943+
expect(isIdentifierStartFn).toHaveBeenCalledOnceWith('#', '#'.charCodeAt(0));
3944+
expect(isIdentifierContinueFn).toHaveBeenCalledOnceWith('-', '-'.charCodeAt(0));
3945+
3946+
isIdentifierStartFn.calls.reset();
3947+
isIdentifierContinueFn.calls.reset();
3948+
3949+
scope.$eval('#.foo.#-.bar-');
3950+
expect(isIdentifierStartFn).toHaveBeenCalledTimes(7);
3951+
expect(isIdentifierStartFn.calls.allArgs()).toEqual([
3952+
['#', '#'.charCodeAt(0)],
3953+
['.', '.'.charCodeAt(0)],
3954+
['f', 'f'.charCodeAt(0)],
3955+
['.', '.'.charCodeAt(0)],
3956+
['#', '#'.charCodeAt(0)],
3957+
['.', '.'.charCodeAt(0)],
3958+
['b', 'b'.charCodeAt(0)]
3959+
]);
3960+
expect(isIdentifierContinueFn).toHaveBeenCalledTimes(9);
3961+
expect(isIdentifierContinueFn.calls.allArgs()).toEqual([
3962+
['.', '.'.charCodeAt(0)],
3963+
['o', 'o'.charCodeAt(0)],
3964+
['o', 'o'.charCodeAt(0)],
3965+
['.', '.'.charCodeAt(0)],
3966+
['-', '-'.charCodeAt(0)],
3967+
['.', '.'.charCodeAt(0)],
3968+
['a', 'a'.charCodeAt(0)],
3969+
['r', 'r'.charCodeAt(0)],
3970+
['-', '-'.charCodeAt(0)]
3971+
]);
3972+
});
3973+
});
3974+
});
38873975
});

0 commit comments

Comments
 (0)