13
13
14
14
var $parseMinErr = minErr ( '$parse' ) ;
15
15
16
+ var ARRAY_CTOR = [ ] . constructor ;
17
+ var BOOLEAN_CTOR = ( false ) . constructor ;
18
+ var FUNCTION_CTOR = Function . constructor ;
19
+ var NUMBER_CTOR = ( 0 ) . constructor ;
20
+ var OBJECT_CTOR = { } . constructor ;
21
+ var STRING_CTOR = '' . constructor ;
22
+ var ARRAY_CTOR_PROTO = ARRAY_CTOR . prototype ;
23
+ var BOOLEAN_CTOR_PROTO = BOOLEAN_CTOR . prototype ;
24
+ var FUNCTION_CTOR_PROTO = FUNCTION_CTOR . prototype ;
25
+ var NUMBER_CTOR_PROTO = NUMBER_CTOR . prototype ;
26
+ var OBJECT_CTOR_PROTO = OBJECT_CTOR . prototype ;
27
+ var STRING_CTOR_PROTO = STRING_CTOR . prototype ;
28
+
29
+ var CALL = FUNCTION_CTOR_PROTO . call ;
30
+ var APPLY = FUNCTION_CTOR_PROTO . apply ;
31
+ var BIND = FUNCTION_CTOR_PROTO . bind ;
32
+
33
+ var objectValueOf = OBJECT_CTOR_PROTO . valueOf ;
34
+
16
35
// Sandboxing Angular Expressions
17
36
// ------------------------------
18
37
// Angular expressions are generally considered safe because these expressions only have direct
@@ -38,9 +57,9 @@ var $parseMinErr = minErr('$parse');
38
57
39
58
40
59
function ensureSafeMemberName ( name , fullExpression ) {
41
- if ( name === " __defineGetter__" || name === " __defineSetter__"
42
- || name === " __lookupGetter__" || name === " __lookupSetter__"
43
- || name === " __proto__" ) {
60
+ if ( name === ' __defineGetter__' || name === ' __defineSetter__'
61
+ || name === ' __lookupGetter__' || name === ' __lookupSetter__'
62
+ || name === ' __proto__' ) {
44
63
throw $parseMinErr ( 'isecfld' ,
45
64
'Attempting to access a disallowed field in Angular expressions! '
46
65
+ 'Expression: {0}' , fullExpression ) ;
@@ -93,10 +112,6 @@ function ensureSafeObject(obj, fullExpression) {
93
112
return obj ;
94
113
}
95
114
96
- var CALL = Function . prototype . call ;
97
- var APPLY = Function . prototype . apply ;
98
- var BIND = Function . prototype . bind ;
99
-
100
115
function ensureSafeFunction ( obj , fullExpression ) {
101
116
if ( obj ) {
102
117
if ( obj . constructor === obj ) {
@@ -113,25 +128,18 @@ function ensureSafeFunction(obj, fullExpression) {
113
128
114
129
function ensureSafeAssignContext ( obj , fullExpression ) {
115
130
if ( obj ) {
116
- var booleanConstructor = ( false ) . constructor ;
117
- var numberConstructor = ( 0 ) . constructor ;
118
- var stringConstructor = '' . constructor ;
119
- var objectConstructor = { } . constructor ;
120
- var arrayConstructor = [ ] . constructor ;
121
- var functionConstructor = Function . constructor ;
122
-
123
- if ( obj === booleanConstructor ||
124
- obj === numberConstructor ||
125
- obj === stringConstructor ||
126
- obj === objectConstructor ||
127
- obj === arrayConstructor ||
128
- obj === functionConstructor ||
129
- obj === booleanConstructor . prototype ||
130
- obj === numberConstructor . prototype ||
131
- obj === stringConstructor . prototype ||
132
- obj === objectConstructor . prototype ||
133
- obj === arrayConstructor . prototype ||
134
- obj === functionConstructor . prototype ) {
131
+ if ( obj === ARRAY_CTOR ||
132
+ obj === BOOLEAN_CTOR ||
133
+ obj === FUNCTION_CTOR ||
134
+ obj === NUMBER_CTOR ||
135
+ obj === OBJECT_CTOR ||
136
+ obj === STRING_CTOR ||
137
+ obj === ARRAY_CTOR_PROTO ||
138
+ obj === BOOLEAN_CTOR_PROTO ||
139
+ obj === FUNCTION_CTOR_PROTO ||
140
+ obj === NUMBER_CTOR_PROTO ||
141
+ obj === OBJECT_CTOR_PROTO ||
142
+ obj === STRING_CTOR_PROTO ) {
135
143
throw $parseMinErr ( 'isecaf' ,
136
144
'Assigning to a constructor or its prototype is disallowed! Expression: {0}' ,
137
145
fullExpression ) ;
@@ -141,7 +149,7 @@ function ensureSafeAssignContext(obj, fullExpression) {
141
149
142
150
var OPERATORS = createMap ( ) ;
143
151
forEach ( '+ - * / % === !== == != < > <= >= && || ! = |' . split ( ' ' ) , function ( operator ) { OPERATORS [ operator ] = true ; } ) ;
144
- var ESCAPE = { "n" : "\n" , "f" : "\f" , "r" : "\r" , "t" : "\t" , "v" : "\v" , "'" : "'" , '"' :'"' } ;
152
+ var ESCAPE = { 'n' : '\n' , 'f' : '\f' , 'r' : '\r' , 't' : '\t' , 'v' : '\v' , '\'' : '\'' , '"' :'"' } ;
145
153
146
154
147
155
/////////////////////////////////////////
@@ -150,7 +158,7 @@ var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'
150
158
/**
151
159
* @constructor
152
160
*/
153
- var Lexer = function ( options ) {
161
+ var Lexer = function Lexer ( options ) {
154
162
this . options = options ;
155
163
} ;
156
164
@@ -164,7 +172,7 @@ Lexer.prototype = {
164
172
165
173
while ( this . index < this . text . length ) {
166
174
var ch = this . text . charAt ( this . index ) ;
167
- if ( ch === '"' || ch === "'" ) {
175
+ if ( ch === '"' || ch === '\'' ) {
168
176
this . readString ( ch ) ;
169
177
} else if ( this . isNumber ( ch ) || ch === '.' && this . isNumber ( this . peek ( ) ) ) {
170
178
this . readNumber ( ) ;
@@ -203,7 +211,7 @@ Lexer.prototype = {
203
211
} ,
204
212
205
213
isNumber : function ( ch ) {
206
- return ( '0' <= ch && ch <= '9' ) && typeof ch === " string" ;
214
+ return ( '0' <= ch && ch <= '9' ) && typeof ch === ' string' ;
207
215
} ,
208
216
209
217
isWhitespace : function ( ch ) {
@@ -236,9 +244,8 @@ Lexer.prototype = {
236
244
237
245
codePointAt : function ( ch ) {
238
246
if ( ch . length === 1 ) return ch . charCodeAt ( 0 ) ;
239
- /*jshint bitwise: false*/
247
+ // eslint-disable-next-line no-bitwise
240
248
return ( ch . charCodeAt ( 0 ) << 10 ) + ch . charCodeAt ( 1 ) - 0x35FDC00 ;
241
- /*jshint bitwise: true*/
242
249
} ,
243
250
244
251
peekMultichar : function ( ) {
@@ -360,7 +367,7 @@ Lexer.prototype = {
360
367
}
361
368
} ;
362
369
363
- var AST = function ( lexer , options ) {
370
+ var AST = function AST ( lexer , options ) {
364
371
this . lexer = lexer ;
365
372
this . options = options ;
366
373
} ;
@@ -628,7 +635,7 @@ AST.prototype = {
628
635
this . consume ( ':' ) ;
629
636
property . value = this . expression ( ) ;
630
637
} else {
631
- this . throwError ( " invalid key" , this . peek ( ) ) ;
638
+ this . throwError ( ' invalid key' , this . peek ( ) ) ;
632
639
}
633
640
properties . push ( property ) ;
634
641
} while ( this . expect ( ',' ) ) ;
@@ -902,7 +909,7 @@ ASTCompiler.prototype = {
902
909
this . watchFns ( ) +
903
910
'return fn;' ;
904
911
905
- /* jshint -W054 */
912
+ // eslint-disable-next-line no-new-func
906
913
var fn = ( new Function ( '$filter' ,
907
914
'ensureSafeMemberName' ,
908
915
'ensureSafeObject' ,
@@ -922,7 +929,6 @@ ASTCompiler.prototype = {
922
929
ifDefined ,
923
930
plusFn ,
924
931
expression ) ;
925
- /* jshint +W054 */
926
932
this . state = this . stage = undefined ;
927
933
fn . literal = isLiteral ( ast ) ;
928
934
fn . constant = isConstant ( ast ) ;
@@ -1042,7 +1048,7 @@ ASTCompiler.prototype = {
1042
1048
self . if_ ( self . stage === 'inputs' || 's' , function ( ) {
1043
1049
if ( create && create !== 1 ) {
1044
1050
self . if_ (
1045
- self . not ( self . nonComputedMember ( 's' , ast . name ) ) ,
1051
+ self . isNull ( self . nonComputedMember ( 's' , ast . name ) ) ,
1046
1052
self . lazyAssign ( self . nonComputedMember ( 's' , ast . name ) , '{}' ) ) ;
1047
1053
}
1048
1054
self . assign ( intoId , self . nonComputedMember ( 's' , ast . name ) ) ;
@@ -1079,7 +1085,7 @@ ASTCompiler.prototype = {
1079
1085
} else {
1080
1086
ensureSafeMemberName ( ast . property . name ) ;
1081
1087
if ( create && create !== 1 ) {
1082
- self . if_ ( self . not ( self . nonComputedMember ( left , ast . property . name ) ) , self . lazyAssign ( self . nonComputedMember ( left , ast . property . name ) , '{}' ) ) ;
1088
+ self . if_ ( self . isNull ( self . nonComputedMember ( left , ast . property . name ) ) , self . lazyAssign ( self . nonComputedMember ( left , ast . property . name ) , '{}' ) ) ;
1083
1089
}
1084
1090
expression = self . nonComputedMember ( left , ast . property . name ) ;
1085
1091
if ( self . state . expensiveChecks || isPossiblyDangerousMemberName ( ast . property . name ) ) {
@@ -1274,6 +1280,10 @@ ASTCompiler.prototype = {
1274
1280
return '!(' + expression + ')' ;
1275
1281
} ,
1276
1282
1283
+ isNull : function ( expression ) {
1284
+ return expression + '==null' ;
1285
+ } ,
1286
+
1277
1287
notNull : function ( expression ) {
1278
1288
return expression + '!=null' ;
1279
1289
} ,
@@ -1354,7 +1364,7 @@ ASTCompiler.prototype = {
1354
1364
} ,
1355
1365
1356
1366
escape : function ( value ) {
1357
- if ( isString ( value ) ) return "'" + value . replace ( this . stringEscapeRegex , this . stringEscapeFn ) + "'" ;
1367
+ if ( isString ( value ) ) return '\'' + value . replace ( this . stringEscapeRegex , this . stringEscapeFn ) + '\'' ;
1358
1368
if ( isNumber ( value ) ) return value . toString ( ) ;
1359
1369
if ( value === true ) return 'true' ;
1360
1370
if ( value === false ) return 'false' ;
@@ -1433,7 +1443,7 @@ ASTInterpreter.prototype = {
1433
1443
} ,
1434
1444
1435
1445
recurse : function ( ast , context , create ) {
1436
- var left , right , self = this , args , expression ;
1446
+ var left , right , self = this , args ;
1437
1447
if ( ast . input ) {
1438
1448
return this . inputs ( ast . input , ast . watchId ) ;
1439
1449
}
@@ -1645,14 +1655,14 @@ ASTInterpreter.prototype = {
1645
1655
} ,
1646
1656
'binary==' : function ( left , right , context ) {
1647
1657
return function ( scope , locals , assign , inputs ) {
1648
- /* jshint eqeqeq:false */
1658
+ // eslint-disable-next-line eqeqeq
1649
1659
var arg = left ( scope , locals , assign , inputs ) == right ( scope , locals , assign , inputs ) ;
1650
1660
return context ? { value : arg } : arg ;
1651
1661
} ;
1652
1662
} ,
1653
1663
'binary!=' : function ( left , right , context ) {
1654
1664
return function ( scope , locals , assign , inputs ) {
1655
- /* jshint eqeqeq:false */
1665
+ // eslint-disable-next-line eqeqeq
1656
1666
var arg = left ( scope , locals , assign , inputs ) != right ( scope , locals , assign , inputs ) ;
1657
1667
return context ? { value : arg } : arg ;
1658
1668
} ;
@@ -1705,7 +1715,7 @@ ASTInterpreter.prototype = {
1705
1715
identifier : function ( name , expensiveChecks , context , create , expression ) {
1706
1716
return function ( scope , locals , assign , inputs ) {
1707
1717
var base = locals && ( name in locals ) ? locals : scope ;
1708
- if ( create && create !== 1 && base && ! ( base [ name ] ) ) {
1718
+ if ( create && create !== 1 && base && base [ name ] == null ) {
1709
1719
base [ name ] = { } ;
1710
1720
}
1711
1721
var value = base ? base [ name ] : undefined ;
@@ -1749,7 +1759,7 @@ ASTInterpreter.prototype = {
1749
1759
var lhs = left ( scope , locals , assign , inputs ) ;
1750
1760
if ( create && create !== 1 ) {
1751
1761
ensureSafeAssignContext ( lhs ) ;
1752
- if ( lhs && ! ( lhs [ right ] ) ) {
1762
+ if ( lhs && lhs [ right ] == null ) {
1753
1763
lhs [ right ] = { } ;
1754
1764
}
1755
1765
}
@@ -1775,7 +1785,7 @@ ASTInterpreter.prototype = {
1775
1785
/**
1776
1786
* @constructor
1777
1787
*/
1778
- var Parser = function ( lexer , $filter , options ) {
1788
+ var Parser = function Parser ( lexer , $filter , options ) {
1779
1789
this . lexer = lexer ;
1780
1790
this . $filter = $filter ;
1781
1791
this . options = options ;
@@ -1796,8 +1806,6 @@ function isPossiblyDangerousMemberName(name) {
1796
1806
return name === 'constructor' ;
1797
1807
}
1798
1808
1799
- var objectValueOf = Object . prototype . valueOf ;
1800
-
1801
1809
function getValueOf ( value ) {
1802
1810
return isFunction ( value . valueOf ) ? value . valueOf ( ) : objectValueOf . call ( value ) ;
1803
1811
}
@@ -1848,6 +1856,7 @@ function getValueOf(value) {
1848
1856
/**
1849
1857
* @ngdoc provider
1850
1858
* @name $parseProvider
1859
+ * @this
1851
1860
*
1852
1861
* @description
1853
1862
* `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse}
@@ -1882,6 +1891,7 @@ function $ParseProvider() {
1882
1891
/**
1883
1892
* @ngdoc method
1884
1893
* @name $parseProvider#setIdentifierFns
1894
+ *
1885
1895
* @description
1886
1896
*
1887
1897
* Allows defining the set of characters that are allowed in Angular expressions. The function
@@ -2023,6 +2033,7 @@ function $ParseProvider() {
2023
2033
}
2024
2034
2025
2035
//Primitive or NaN
2036
+ // eslint-disable-next-line no-self-compare
2026
2037
return newValue === oldValueOfValue || ( newValue !== newValue && oldValueOfValue !== oldValueOfValue ) ;
2027
2038
}
2028
2039
@@ -2072,10 +2083,12 @@ function $ParseProvider() {
2072
2083
function oneTimeWatchDelegate ( scope , listener , objectEquality , parsedExpression , prettyPrintExpression ) {
2073
2084
var unwatch , lastValue ;
2074
2085
if ( parsedExpression . inputs ) {
2075
- return unwatch = inputsWatchDelegate ( scope , oneTimeListener , objectEquality , parsedExpression , prettyPrintExpression ) ;
2086
+ unwatch = inputsWatchDelegate ( scope , oneTimeListener , objectEquality , parsedExpression , prettyPrintExpression ) ;
2076
2087
} else {
2077
- return unwatch = scope . $watch ( oneTimeWatch , oneTimeListener , objectEquality ) ;
2088
+ unwatch = scope . $watch ( oneTimeWatch , oneTimeListener , objectEquality ) ;
2078
2089
}
2090
+ return unwatch ;
2091
+
2079
2092
function oneTimeWatch ( scope ) {
2080
2093
return parsedExpression ( scope ) ;
2081
2094
}
@@ -2096,7 +2109,7 @@ function $ParseProvider() {
2096
2109
2097
2110
function oneTimeLiteralWatchDelegate ( scope , listener , objectEquality , parsedExpression ) {
2098
2111
var unwatch , lastValue ;
2099
- return unwatch = scope . $watch ( function oneTimeWatch ( scope ) {
2112
+ unwatch = scope . $watch ( function oneTimeWatch ( scope ) {
2100
2113
return parsedExpression ( scope ) ;
2101
2114
} , function oneTimeListener ( value , old , scope ) {
2102
2115
lastValue = value ;
@@ -2110,6 +2123,8 @@ function $ParseProvider() {
2110
2123
}
2111
2124
} , objectEquality ) ;
2112
2125
2126
+ return unwatch ;
2127
+
2113
2128
function isAllDefined ( value ) {
2114
2129
var allDefined = true ;
2115
2130
forEach ( value , function ( val ) {
@@ -2120,11 +2135,11 @@ function $ParseProvider() {
2120
2135
}
2121
2136
2122
2137
function constantWatchDelegate ( scope , listener , objectEquality , parsedExpression ) {
2123
- var unwatch ;
2124
- return unwatch = scope . $watch ( function constantWatch ( scope ) {
2138
+ var unwatch = scope . $watch ( function constantWatch ( scope ) {
2125
2139
unwatch ( ) ;
2126
2140
return parsedExpression ( scope ) ;
2127
2141
} , listener , objectEquality ) ;
2142
+ return unwatch ;
2128
2143
}
2129
2144
2130
2145
function addInterceptor ( parsedExpression , interceptorFn ) {
0 commit comments