@@ -119,10 +119,6 @@ function $InterpolateProvider() {
119
119
return unwatch ;
120
120
}
121
121
122
- function isConcatenationAllowed ( context ) {
123
- return context === $sce . URL || context === $sce . MEDIA_URL ;
124
- }
125
-
126
122
/**
127
123
* @ngdoc service
128
124
* @name $interpolate
@@ -260,13 +256,13 @@ function $InterpolateProvider() {
260
256
endIndex ,
261
257
index = 0 ,
262
258
expressions = [ ] ,
263
- parseFns = [ ] ,
259
+ parseFns ,
264
260
textLength = text . length ,
265
261
exp ,
266
262
concat = [ ] ,
267
263
expressionPositions = [ ] ,
268
- singleExpression = false ,
269
- contextAllowsConcatenation = isConcatenationAllowed ( trustedContext ) ;
264
+ singleExpression ,
265
+ contextAllowsConcatenation = trustedContext === $sce . URL || trustedContext === $sce . MEDIA_URL ;
270
266
271
267
while ( index < textLength ) {
272
268
if ( ( ( startIndex = text . indexOf ( startSymbol , index ) ) !== - 1 ) &&
@@ -276,7 +272,6 @@ function $InterpolateProvider() {
276
272
}
277
273
exp = text . substring ( startIndex + startSymbolLength , endIndex ) ;
278
274
expressions . push ( exp ) ;
279
- parseFns . push ( $parse ( exp , parseStringifyInterceptor ) ) ;
280
275
index = endIndex + endSymbolLength ;
281
276
expressionPositions . push ( concat . length ) ;
282
277
concat . push ( '' ) ; // Placeholder that will get replaced with the evaluated expression.
@@ -289,9 +284,10 @@ function $InterpolateProvider() {
289
284
}
290
285
}
291
286
292
- if ( concat . length === 1 && expressionPositions . length === 1 ) {
293
- singleExpression = true ;
294
- }
287
+ singleExpression = concat . length === 1 && expressionPositions . length === 1 ;
288
+ parseFns = contextAllowsConcatenation && singleExpression ?
289
+ [ $parse ( expressions [ 0 ] ) ] :
290
+ expressions . map ( function ( exp ) { return $parse ( exp , parseStringifyInterceptor ) ; } ) ;
295
291
296
292
// Concatenating expressions makes it hard to reason about whether some combination of
297
293
// concatenated values are unsafe to use and could easily lead to XSS. By requiring that a
@@ -314,32 +310,14 @@ function $InterpolateProvider() {
314
310
}
315
311
316
312
if ( contextAllowsConcatenation ) {
317
- if ( singleExpression ) {
318
- // The raw value was left as-is by parseStringifyInterceptor
319
- return $sce . getTrusted ( trustedContext , concat [ 0 ] ) ;
320
- } else {
321
- return $sce . getTrusted ( trustedContext , concat . join ( '' ) ) ;
322
- }
323
- } else if ( trustedContext ) {
324
- if ( concat . length > 1 ) {
325
- // there's at least two parts, so expr + string or exp + exp, and this context
326
- // doesn't allow that.
327
- $interpolateMinErr . throwNoconcat ( text ) ;
328
- } else {
329
- return concat . join ( '' ) ;
330
- }
331
- } else { // In an unprivileged context, just concatenate and return.
332
- return concat . join ( '' ) ;
313
+ // If `singleExpression` then `concat[0]` might be a "trusted" value or `null`, rather than a string
314
+ return $sce . getTrusted ( trustedContext , singleExpression ? concat [ 0 ] : concat . join ( '' ) ) ;
315
+ } else if ( trustedContext && concat . length > 1 ) {
316
+ // This context does not allow more than one part, e.g. expr + string or exp + exp.
317
+ $interpolateMinErr . throwNoconcat ( text ) ;
333
318
}
334
- } ;
335
-
336
- var getValue = function ( value ) {
337
- // In concatenable contexts, getTrusted comes at the end, to avoid sanitizing individual
338
- // parts of a full URL. We don't care about losing the trustedness here, that's handled in
339
- // parseStringifyInterceptor below.
340
- return ( trustedContext && ! contextAllowsConcatenation ) ?
341
- $sce . getTrusted ( trustedContext , value ) :
342
- $sce . valueOf ( value ) ;
319
+ // In an unprivileged context or only one part: just concatenate and return.
320
+ return concat . join ( '' ) ;
343
321
} ;
344
322
345
323
return extend ( function interpolationFn ( context ) {
@@ -374,13 +352,14 @@ function $InterpolateProvider() {
374
352
375
353
function parseStringifyInterceptor ( value ) {
376
354
try {
377
- if ( contextAllowsConcatenation && singleExpression ) {
378
- // No stringification in this case, to keep the trusted value until unwrapping.
379
- return value ;
380
- } else {
381
- value = getValue ( value ) ;
382
- return allOrNothing && ! isDefined ( value ) ? value : stringify ( value ) ;
383
- }
355
+ // In concatenable contexts, getTrusted comes at the end, to avoid sanitizing individual
356
+ // parts of a full URL. We don't care about losing the trustedness here.
357
+ // If non-concatenable contexts where there is only one expression then this interceptor
358
+ // is not applied to the expression.
359
+ value = ( trustedContext && ! contextAllowsConcatenation ) ?
360
+ $sce . getTrusted ( trustedContext , value ) :
361
+ $sce . valueOf ( value ) ;
362
+ return allOrNothing && ! isDefined ( value ) ? value : stringify ( value ) ;
384
363
} catch ( err ) {
385
364
$exceptionHandler ( $interpolateMinErr . interr ( text , err ) ) ;
386
365
}
0 commit comments