mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix(copy,equals): prevent browser crashes with Scope or Window
Scope and Window instances are special and when copied can crash browser. For this reason it makes sense to compare them only by identity.
This commit is contained in:
parent
0e1fa2aefe
commit
f43c226c67
2 changed files with 33 additions and 2 deletions
|
|
@ -413,6 +413,12 @@ function isWindow(obj) {
|
|||
return obj && obj.document && obj.location && obj.alert && obj.setInterval;
|
||||
}
|
||||
|
||||
|
||||
function isScope(obj) {
|
||||
return obj && obj.$evalAsync && obj.$watch;
|
||||
}
|
||||
|
||||
|
||||
function isBoolean(value) {return typeof value == $boolean;}
|
||||
function isTextNode(node) {return nodeName_(node) == '#text';}
|
||||
|
||||
|
|
@ -580,6 +586,7 @@ function isLeafNode (node) {
|
|||
* @returns {*} The copy or updated `destination`, if `destination` was specified.
|
||||
*/
|
||||
function copy(source, destination){
|
||||
if (isWindow(source) || isScope(source)) throw Error("Can't copy Window or Scope");
|
||||
if (!destination) {
|
||||
destination = source;
|
||||
if (source) {
|
||||
|
|
@ -629,8 +636,7 @@ function copy(source, destination){
|
|||
* During a property comparision, properties of `function` type and properties with names
|
||||
* that begin with `$` are ignored.
|
||||
*
|
||||
* Note: This function is used to augment the Object type in Angular expressions. See
|
||||
* {@link angular.module.ng.$filter} for more information about Angular arrays.
|
||||
* Scope and DOMWindow objects are being compared only be identify (`===`).
|
||||
*
|
||||
* @param {*} o1 Object or value to compare.
|
||||
* @param {*} o2 Object or value to compare.
|
||||
|
|
@ -650,6 +656,7 @@ function equals(o1, o2) {
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
|
||||
keySet = {};
|
||||
for(key in o1) {
|
||||
if (key.charAt(0) !== '$' && !isFunction(o1[key]) && !equals(o1[key], o2[key])) {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,14 @@ describe('angular', function() {
|
|||
expect(copy(123)).toEqual(123);
|
||||
expect(copy([{key:null}])).toEqual([{key:null}]);
|
||||
});
|
||||
|
||||
it('should throw an exception if a Scope is being copied', inject(function($rootScope) {
|
||||
expect(function() { copy($rootScope.$new()); }).toThrow("Can't copy Window or Scope");
|
||||
}));
|
||||
|
||||
it('should throw an exception if a Window is being copied', function() {
|
||||
expect(function() { copy(window); }).toThrow("Can't copy Window or Scope");
|
||||
});
|
||||
});
|
||||
|
||||
describe('equals', function() {
|
||||
|
|
@ -114,6 +122,22 @@ describe('angular', function() {
|
|||
it('should treat two NaNs as equal', function() {
|
||||
expect(equals(NaN, NaN)).toBe(true);
|
||||
});
|
||||
|
||||
it('should compare Scope instances only by identity', inject(function($rootScope) {
|
||||
var scope1 = $rootScope.$new(),
|
||||
scope2 = $rootScope.$new();
|
||||
|
||||
expect(equals(scope1, scope1)).toBe(true);
|
||||
expect(equals(scope1, scope2)).toBe(false);
|
||||
expect(equals($rootScope, scope1)).toBe(false);
|
||||
expect(equals(undefined, scope1)).toBe(false);
|
||||
}));
|
||||
|
||||
it('should compare Window instances only by identity', function() {
|
||||
expect(equals(window, window)).toBe(true);
|
||||
expect(equals(window, window.parent)).toBe(false);
|
||||
expect(equals(window, undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('size', function() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue