@@ -747,6 +747,58 @@ describe('$location', function() {
747747 } ) ;
748748
749749
750+ //https://github.com/angular/angular.js/issues/16592
751+ it ( 'should not infinitely digest when initial params contain a quote' , function ( ) {
752+ initService ( { html5Mode :true , supportHistory :true } ) ;
753+ mockUpBrowser ( { initialUrl :'http://localhost:9876/?q=\'' , baseHref :'/' } ) ;
754+ inject ( function ( $location , $browser , $rootScope ) {
755+ expect ( function ( ) {
756+ $rootScope . $digest ( ) ;
757+ } ) . not . toThrow ( ) ;
758+ } ) ;
759+ } ) ;
760+
761+
762+ //https://github.com/angular/angular.js/issues/16592
763+ it ( 'should not infinitely digest when initial params contain an escaped quote' , function ( ) {
764+ initService ( { html5Mode :true , supportHistory :true } ) ;
765+ mockUpBrowser ( { initialUrl :'http://localhost:9876/?q=%27' , baseHref :'/' } ) ;
766+ inject ( function ( $location , $browser , $rootScope ) {
767+ expect ( function ( ) {
768+ $rootScope . $digest ( ) ;
769+ } ) . not . toThrow ( ) ;
770+ } ) ;
771+ } ) ;
772+
773+
774+ //https://github.com/angular/angular.js/issues/16592
775+ it ( 'should not infinitely digest when updating params containing a quote (via $browser.url)' , function ( ) {
776+ initService ( { html5Mode :true , supportHistory :true } ) ;
777+ mockUpBrowser ( { initialUrl :'http://localhost:9876/' , baseHref :'/' } ) ;
778+ inject ( function ( $location , $browser , $rootScope ) {
779+ $rootScope . $digest ( ) ;
780+ $browser . url ( 'http://localhost:9876/?q=\'' ) ;
781+ expect ( function ( ) {
782+ $rootScope . $digest ( ) ;
783+ } ) . not . toThrow ( ) ;
784+ } ) ;
785+ } ) ;
786+
787+
788+ //https://github.com/angular/angular.js/issues/16592
789+ it ( 'should not infinitely digest when updating params containing a quote (via window.location + popstate)' , function ( ) {
790+ initService ( { html5Mode :true , supportHistory :true } ) ;
791+ mockUpBrowser ( { initialUrl :'http://localhost:9876/' , baseHref :'/' } ) ;
792+ inject ( function ( $window , $location , $browser , $rootScope ) {
793+ $rootScope . $digest ( ) ;
794+ $window . location . href = 'http://localhost:9876/?q=\'' ;
795+ expect ( function ( ) {
796+ jqLite ( $window ) . triggerHandler ( 'popstate' ) ;
797+ } ) . not . toThrow ( ) ;
798+ } ) ;
799+ } ) ;
800+
801+
750802 describe ( 'when changing the browser URL/history directly during a `$digest`' , function ( ) {
751803
752804 beforeEach ( function ( ) {
@@ -804,10 +856,13 @@ describe('$location', function() {
804856 } ) ;
805857
806858
807- function updatePathOnLocationChangeSuccessTo ( newPath ) {
859+ function updatePathOnLocationChangeSuccessTo ( newPath , newParams ) {
808860 inject ( function ( $rootScope , $location ) {
809861 $rootScope . $on ( '$locationChangeSuccess' , function ( event , newUrl , oldUrl ) {
810862 $location . path ( newPath ) ;
863+ if ( newParams ) {
864+ $location . search ( newParams ) ;
865+ }
811866 } ) ;
812867 } ) ;
813868 }
@@ -950,6 +1005,24 @@ describe('$location', function() {
9501005 expect ( $browserUrl ) . not . toHaveBeenCalled ( ) ;
9511006 } ) ;
9521007 } ) ;
1008+
1009+ //https://github.com/angular/angular.js/issues/16592
1010+ it ( 'should not infinite $digest when going to base URL with trailing slash when $locationChangeSuccess watcher changes query params to contain quote' , function ( ) {
1011+ initService ( { html5Mode : true , supportHistory : true } ) ;
1012+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
1013+ inject ( function ( $rootScope , $injector , $browser ) {
1014+ var $browserUrl = spyOnlyCallsWithArgs ( $browser , 'url' ) . and . callThrough ( ) ;
1015+
1016+ var $location = $injector . get ( '$location' ) ;
1017+ updatePathOnLocationChangeSuccessTo ( '/' , { q : '\'' } ) ;
1018+
1019+ $rootScope . $digest ( ) ;
1020+
1021+ expect ( $location . path ( ) ) . toEqual ( '/' ) ;
1022+ expect ( $location . search ( ) ) . toEqual ( { q : '\'' } ) ;
1023+ expect ( $browserUrl ) . toHaveBeenCalledTimes ( 1 ) ;
1024+ } ) ;
1025+ } ) ;
9531026 } ) ;
9541027
9551028 } ) ;
@@ -1140,6 +1213,40 @@ describe('$location', function() {
11401213 } ) ;
11411214 } ) ;
11421215
1216+ //https://github.com/angular/angular.js/issues/16592
1217+ it ( 'should not infinite $digest on pushState() with quote in param' , function ( ) {
1218+ initService ( { html5Mode : true , supportHistory : true } ) ;
1219+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
1220+ inject ( function ( $rootScope , $injector , $window ) {
1221+ var $location = $injector . get ( '$location' ) ;
1222+ $rootScope . $digest ( ) ; //allow $location initialization to finish
1223+
1224+ $window . history . pushState ( { } , null , 'http://server/app/Home?q=\'' ) ;
1225+ $rootScope . $digest ( ) ;
1226+
1227+ expect ( $location . absUrl ( ) ) . toEqual ( 'http://server/app/Home?q=\'' ) ;
1228+ expect ( $location . path ( ) ) . toEqual ( '/Home' ) ;
1229+ expect ( $location . search ( ) ) . toEqual ( { q : '\'' } ) ;
1230+ } ) ;
1231+ } ) ;
1232+
1233+ //https://github.com/angular/angular.js/issues/16592
1234+ it ( 'should not infinite $digest on popstate event with quote in param' , function ( ) {
1235+ initService ( { html5Mode : true , supportHistory : true } ) ;
1236+ mockUpBrowser ( { initialUrl :'http://server/app/' , baseHref :'/app/' } ) ;
1237+ inject ( function ( $rootScope , $injector , $window ) {
1238+ var $location = $injector . get ( '$location' ) ;
1239+ $rootScope . $digest ( ) ; //allow $location initialization to finish
1240+
1241+ $window . location . href = 'http://server/app/Home?q=\'' ;
1242+ jqLite ( $window ) . triggerHandler ( 'popstate' ) ;
1243+
1244+ expect ( $location . absUrl ( ) ) . toEqual ( 'http://server/app/Home?q=\'' ) ;
1245+ expect ( $location . path ( ) ) . toEqual ( '/Home' ) ;
1246+ expect ( $location . search ( ) ) . toEqual ( { q : '\'' } ) ;
1247+ } ) ;
1248+ } ) ;
1249+
11431250 it ( 'should replace browser url & state when replace() was called at least once' , function ( ) {
11441251 initService ( { html5Mode :true , supportHistory : true } ) ;
11451252 mockUpBrowser ( { initialUrl :'http://new.com/a/b/' , baseHref :'/a/b/' } ) ;
0 commit comments