Skip to content

Commit eb89e21

Browse files
committed
fix(angular.copy): copy own non-enumerable properties
copying object without own non-enumerable properties can lead to bugs when enumerable properties depend on non-enumerable fixes angular#15692
1 parent a0641ea commit eb89e21

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

src/Angular.js

+5
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,11 @@ function copy(source, destination, maxDepth) {
941941
for (key in source) {
942942
destination[key] = copyElement(source[key], maxDepth);
943943
}
944+
// don't use Object.getOwnPropertyNames with RegExp to avoid copying RegExp lastIndex property
945+
} else if (isObject(source) && typeof Object.getOwnPropertyNames === 'function' && !isRegExp(source)) {
946+
Object.getOwnPropertyNames(source).forEach(function(key) {
947+
destination[key] = copyElement(source[key], maxDepth);
948+
});
944949
} else if (source && typeof source.hasOwnProperty === 'function') {
945950
// Slow path, which must rely on hasOwnProperty
946951
for (key in source) {

test/AngularSpec.js

+10
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,16 @@ describe('angular', function() {
620620
expect(dest).toEqual({a1: 1, b1: {b2: {b3: 1}}, c1: [1, {c2: 1}], d1: {d2: 1}});
621621
});
622622

623+
it('should copy own non-enumerable properties', function() {
624+
var getter = function() { return Math.random(); };
625+
var source = {};
626+
var dest;
627+
628+
Object.defineProperty(source, 'getter', {value: getter});
629+
dest = copy(source);
630+
expect(dest.getter).toBe(getter);
631+
});
632+
623633
they('should copy source and ignore max depth when maxDepth = $prop',
624634
[NaN, null, undefined, true, false, -1, 0], function(maxDepth) {
625635
var source = {a1: 1, b1: {b2: {b3: 1}}, c1: [1, {c2: 1}], d1: {d2: 1}};

0 commit comments

Comments
 (0)