@@ -488,6 +488,62 @@ describe('parser', function() {
488
488
expect ( scope . b ) . toEqual ( 234 ) ;
489
489
} ) ;
490
490
491
+ it ( 'should allow use of locals in the left side of an assignment' , inject ( function ( $rootScope ) {
492
+ $rootScope . a = { } ;
493
+ $rootScope . key = "value" ;
494
+ var localA = { } ;
495
+
496
+ //getterFn
497
+ $rootScope . $eval ( 'a.value = 1' , { a : localA } ) ;
498
+ expect ( localA . value ) . toBe ( 1 ) ;
499
+
500
+ $rootScope . $eval ( 'w.a.value = 2' , { w : { a : localA } } ) ;
501
+ expect ( localA . value ) . toBe ( 2 ) ;
502
+
503
+ //field access
504
+ $rootScope . $eval ( '(a).value = 3' , { a : localA } ) ;
505
+ expect ( localA . value ) . toBe ( 3 ) ;
506
+
507
+ $rootScope . $eval ( '{c: {b: a}}.c.b.value = 4' , { a : localA } ) ;
508
+ expect ( localA . value ) . toBe ( 4 ) ;
509
+
510
+ //object index
511
+ $rootScope . $eval ( 'a[key] = 5' , { a : localA } ) ;
512
+ expect ( localA . value ) . toBe ( 5 ) ;
513
+
514
+ $rootScope . $eval ( 'w.a[key] = 6' , { w : { a : localA } } ) ;
515
+ expect ( localA . value ) . toBe ( 6 ) ;
516
+
517
+ $rootScope . $eval ( '{c: {b: a}}.c.b[key] = 7' , { a : localA } ) ;
518
+ expect ( localA . value ) . toBe ( 7 ) ;
519
+
520
+ //Nothing should have touched the $rootScope.a
521
+ expect ( $rootScope . a . value ) . toBeUndefined ( ) ;
522
+ } ) ) ;
523
+
524
+ it ( 'should allow use of locals in sub expressions of the left side of an assignment' , inject ( function ( $rootScope , $parse ) {
525
+ delete $rootScope . x ;
526
+ $rootScope . $eval ( 'x[a][b] = true' , { a : 'foo' , b : 'bar' } ) ;
527
+ expect ( $rootScope . x . foo . bar ) . toBe ( true ) ;
528
+
529
+ delete $rootScope . x ;
530
+ $rootScope . $eval ( 'x.foo[b] = true' , { b : 'bar' } ) ;
531
+ expect ( $rootScope . x . foo . bar ) . toBe ( true ) ;
532
+
533
+ delete $rootScope . x ;
534
+ $rootScope . $eval ( 'x[a].bar = true' , { a : 'foo' } ) ;
535
+ expect ( $rootScope . x . foo . bar ) . toBe ( true ) ;
536
+ } ) ) ;
537
+
538
+ it ( 'should ignore locals beyond the root object of an assignment expression' , inject ( function ( $rootScope ) {
539
+ var a = { } ;
540
+ var locals = { a : a } ;
541
+ $rootScope . b = { a : { value : 123 } } ;
542
+ $rootScope . $eval ( 'b.a.value = 1' , locals ) ;
543
+ expect ( a . value ) . toBeUndefined ( ) ;
544
+ expect ( $rootScope . b . a . value ) . toBe ( 1 ) ;
545
+ } ) ) ;
546
+
491
547
it ( 'should evaluate assignments in ternary operator' , function ( ) {
492
548
scope . $eval ( 'a = 1 ? 2 : 3' ) ;
493
549
expect ( scope . a ) . toBe ( 2 ) ;
@@ -799,6 +855,12 @@ describe('parser', function() {
799
855
} ) . toThrowMinErr (
800
856
'$parse' , 'isecfn' , 'Referencing Function in Angular expressions is disallowed! ' +
801
857
'Expression: a.toString.constructor' ) ;
858
+
859
+ expect ( function ( ) {
860
+ scope . $eval ( "c.a = 1" , { c : Function . prototype . constructor } ) ;
861
+ } ) . toThrowMinErr (
862
+ '$parse' , 'isecfn' , 'Referencing Function in Angular expressions is disallowed! ' +
863
+ 'Expression: c.a' ) ;
802
864
} ) ;
803
865
804
866
it ( 'should disallow traversing the Function object in a setter: E02' , function ( ) {
@@ -933,6 +995,14 @@ describe('parser', function() {
933
995
'$parse' , 'isecobj' , 'Referencing Object in Angular expressions is disallowed! ' +
934
996
'Expression: foo["bar"]["keys"](foo)' ) ;
935
997
} ) ;
998
+
999
+ it ( 'should NOT allow access to Object constructor in assignment locals' , function ( ) {
1000
+ expect ( function ( ) {
1001
+ scope . $eval ( "O.constructor.a = 1" , { O : Object } ) ;
1002
+ } ) . toThrowMinErr (
1003
+ '$parse' , 'isecobj' , 'Referencing Object in Angular expressions is disallowed! ' +
1004
+ 'Expression: O.constructor.a' ) ;
1005
+ } ) ;
936
1006
} ) ;
937
1007
938
1008
describe ( 'Window and $element/node' , function ( ) {
0 commit comments