Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 62b8543

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 #15692
1 parent a0641ea commit 62b8543

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

src/Angular.js

+11
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,17 @@ 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+
var elementCopy = copyElement(source[key], maxDepth);
948+
949+
if (source.propertyIsEnumerable(key)) {
950+
destination[key] = elementCopy;
951+
} else {
952+
Object.defineProperty(destination, key, {value: elementCopy});
953+
}
954+
});
944955
} else if (source && typeof source.hasOwnProperty === 'function') {
945956
// Slow path, which must rely on hasOwnProperty
946957
for (key in source) {

test/AngularSpec.js

+11
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,17 @@ 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 keeping them non-enumerable', 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+
expect(dest.propertyIsEnumerable('getter')).toBe(false);
632+
});
633+
623634
they('should copy source and ignore max depth when maxDepth = $prop',
624635
[NaN, null, undefined, true, false, -1, 0], function(maxDepth) {
625636
var source = {a1: 1, b1: {b2: {b3: 1}}, c1: [1, {c2: 1}], d1: {d2: 1}};

0 commit comments

Comments
 (0)