mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-06-12 16:18:11 +08:00
fix(ngRepeat): make allowed aliasAs expressions more strict
Ensure that aliasAs expressions are valid simple identifiers. These are still assigned to $scope in the same way
that they were previously, however now you won't accidentally create a property named "filtered.collection".
This change additionally restricts identifiers to prevent the use of certain ECMAScript reserved words ("null",
"undefined", "this" --- should probably add "super", "try", "catch" and "finally" there too), as well as certain
properties used by $scope or ngRepeat, including $parent, $index, $even, $odd, $first, $middle, or $last.
Closes #8438
Closes #8440
This commit is contained in:
39
docs/content/error/ngRepeat/badident.ngdoc
Normal file
39
docs/content/error/ngRepeat/badident.ngdoc
Normal file
@@ -0,0 +1,39 @@
|
||||
@ngdoc error
|
||||
@name ngRepeat:badident
|
||||
@fullName Invalid identifier expression
|
||||
@description
|
||||
|
||||
Occurs when an invalid identifier is specified in an {@link ng.directive:ngRepeat ngRepeat} expression.
|
||||
|
||||
The {@link ng.directive:ngRepeat ngRepeat} directive's `alias as` syntax is used to assign an alias for the processed collection in scope.
|
||||
|
||||
If the expression is not a simple identifier (such that you could declare it with `var {name}`, or if the expression is a reserved name,
|
||||
this error is thrown.
|
||||
|
||||
Reserved names include:
|
||||
|
||||
- `null`
|
||||
- `this`
|
||||
- `undefined`
|
||||
- `$parent`
|
||||
- `$even`
|
||||
- `$odd`
|
||||
- `$first`
|
||||
- `$last`
|
||||
- `$middle`
|
||||
|
||||
Invalid expressions might look like this:
|
||||
|
||||
```html
|
||||
<li ng-repeat="item in items | filter:searchString as this">{{item}}</li>
|
||||
<li ng-repeat="item in items | filter:searchString as some.objects["property"]">{{item}}</li>
|
||||
<li ng-repeat="item in items | filter:searchString as resultOfSomeMethod()">{{item}}</li>
|
||||
<li ng-repeat="item in items | filter:searchString as foo=6">{{item}}</li>
|
||||
```
|
||||
|
||||
Valid expressions might look like this:
|
||||
|
||||
```html
|
||||
<li ng-repeat="item in items | filter:searchString as collections">{{item}}</li>
|
||||
<li ng-repeat="item in items | filter:searchString as filteredCollection">{{item}}</li>
|
||||
```
|
||||
@@ -266,6 +266,12 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
||||
var valueIdentifier = match[3] || match[1];
|
||||
var keyIdentifier = match[2];
|
||||
|
||||
if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) ||
|
||||
/^null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent$/.test(aliasAs))) {
|
||||
throw ngRepeatMinErr('badident', "alias '{0}' is invalid --- must be a valid JS identifier which is not a reserved name.",
|
||||
aliasAs);
|
||||
}
|
||||
|
||||
var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn;
|
||||
var hashFnLocals = {$id: hashKey};
|
||||
|
||||
|
||||
@@ -416,6 +416,52 @@ describe('ngRepeat', function() {
|
||||
|
||||
expect(trim(element.text())).toEqual('No results found...');
|
||||
});
|
||||
|
||||
|
||||
it('should throw if alias identifier is not a simple identifier', inject(function($exceptionHandler) {
|
||||
scope.x = 'bl';
|
||||
scope.items = [
|
||||
{ name : 'red' },
|
||||
{ name : 'blue' },
|
||||
{ name : 'green' },
|
||||
{ name : 'black' },
|
||||
{ name : 'orange' },
|
||||
{ name : 'blonde' }
|
||||
];
|
||||
|
||||
forEach([
|
||||
'null',
|
||||
'this',
|
||||
'undefined',
|
||||
'$parent',
|
||||
'$index',
|
||||
'$first',
|
||||
'$middle',
|
||||
'$last',
|
||||
'$even',
|
||||
'$odd',
|
||||
'obj[key]',
|
||||
'obj["key"]',
|
||||
'obj[\'key\']',
|
||||
'obj.property',
|
||||
'foo=6'
|
||||
], function(expr) {
|
||||
var expression = ('item in items | filter:x as ' + expr + ' track by $index').replace(/"/g, '"');
|
||||
element = $compile(
|
||||
'<div>' +
|
||||
' <div ng-repeat="' + expression + '">{{item}}</div>' +
|
||||
'</div>')(scope);
|
||||
|
||||
var expected = new RegExp('^\\[ngRepeat:badident\\] alias \'' + escape(expr) + '\' is invalid --- must be a valid JS identifier which is not a reserved name');
|
||||
expect($exceptionHandler.errors.shift()[0].message).
|
||||
toMatch(expected);
|
||||
dealoc(element);
|
||||
});
|
||||
|
||||
function escape(text) {
|
||||
return text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user