From bf13d2683d5880b18db00087e80ee0fd5e1f429a Mon Sep 17 00:00:00 2001 From: Shahar Talmi <shahar.talmi@gmail.com> Date: Sat, 21 Jun 2014 19:17:25 +0300 Subject: [PATCH] fix($rootScope): $watchCollection should handle NaN in objects This fixes a potential infinite digest in $watchCollection when one of the values is NaN. This was previously fixed for arrays, but needs to be handled for objects as well. Closes #7930 --- src/ng/rootScope.js | 8 +++++--- test/ng/rootScopeSpec.js | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ng/rootScope.js b/src/ng/rootScope.js index 179983ca7cc0..4114a6501ba8 100644 --- a/src/ng/rootScope.js +++ b/src/ng/rootScope.js @@ -443,7 +443,7 @@ function $RootScopeProvider(){ function $watchCollectionWatch() { newValue = objGetter(self); - var newLength, key; + var newLength, key, bothNaN; if (!isObject(newValue)) { // if primitive if (oldValue !== newValue) { @@ -467,7 +467,7 @@ function $RootScopeProvider(){ } // copy the items to oldValue and look for changes. for (var i = 0; i < newLength; i++) { - var bothNaN = (oldValue[i] !== oldValue[i]) && + bothNaN = (oldValue[i] !== oldValue[i]) && (newValue[i] !== newValue[i]); if (!bothNaN && (oldValue[i] !== newValue[i])) { changeDetected++; @@ -487,7 +487,9 @@ function $RootScopeProvider(){ if (newValue.hasOwnProperty(key)) { newLength++; if (oldValue.hasOwnProperty(key)) { - if (oldValue[key] !== newValue[key]) { + bothNaN = (oldValue[key] !== oldValue[key]) && + (newValue[key] !== newValue[key]); + if (!bothNaN && (oldValue[key] !== newValue[key])) { changeDetected++; oldValue[key] = newValue[key]; } diff --git a/test/ng/rootScopeSpec.js b/test/ng/rootScopeSpec.js index dc2dda2554af..cd86c71d329a 100644 --- a/test/ng/rootScopeSpec.js +++ b/test/ng/rootScopeSpec.js @@ -698,6 +698,14 @@ describe('Scope', function() { $rootScope.$digest(); expect(log.empty()).toEqual([{newVal: {b: {}, c: 'B'}, oldVal: {a: [], b: {}, c: 'B'}}]); }); + + it('should not infinitely digest when current value is NaN', function() { + $rootScope.obj = {a: NaN}; + expect(function() { + $rootScope.$digest(); + }).not.toThrow(); + }); + }); });