Skip to content

Commit c18c19e

Browse files
committed
harness/propertyHelper.js: Capture primordials that might be affected at runtime by verification
Ref tc39#4234 (comment)
1 parent fcfb11d commit c18c19e

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

harness/propertyHelper.js

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ defines:
1717

1818
// @ts-check
1919

20+
// Capture primordial functions and receiver-uncurried primordial methods that
21+
// are used in verification but might be destroyed *by* that process itself.
22+
var __isArray = Array.isArray;
23+
var __defineProperty = Object.defineProperty;
24+
var __join = Function.prototype.call.bind(Array.prototype.join);
25+
var __push = Function.prototype.call.bind(Array.prototype.push);
26+
var __hasOwnProperty = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
27+
var __propertyIsEnumerable = Function.prototype.call.bind(Object.prototype.propertyIsEnumerable);
28+
var nonIndexNumericPropertyName = Math.pow(2, 32) - 1;
29+
2030
/**
2131
* @param {object} obj
2232
* @param {string|symbol} name
@@ -46,7 +56,7 @@ function verifyProperty(obj, name, desc, options) {
4656
}
4757

4858
assert(
49-
Object.prototype.hasOwnProperty.call(obj, name),
59+
__hasOwnProperty(obj, name),
5060
"obj should have an own property " + nameStr
5161
);
5262

@@ -77,55 +87,56 @@ function verifyProperty(obj, name, desc, options) {
7787

7888
var failures = [];
7989

80-
if (Object.prototype.hasOwnProperty.call(desc, 'value')) {
90+
if (__hasOwnProperty(desc, 'value')) {
8191
if (!isSameValue(desc.value, originalDesc.value)) {
82-
failures.push("descriptor value should be " + desc.value);
92+
__push(failures, "descriptor value should be " + desc.value);
8393
}
8494
if (!isSameValue(desc.value, obj[name])) {
85-
failures.push("object value should be " + desc.value);
95+
__push(failures, "object value should be " + desc.value);
8696
}
8797
}
8898

89-
if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) {
99+
if (__hasOwnProperty(desc, 'enumerable')) {
90100
if (desc.enumerable !== originalDesc.enumerable ||
91101
desc.enumerable !== isEnumerable(obj, name)) {
92-
failures.push('descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
102+
__push(failures, 'descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
93103
}
94104
}
95105

96-
if (Object.prototype.hasOwnProperty.call(desc, 'writable')) {
106+
// Operations past this point are potentially destructive!
107+
108+
if (__hasOwnProperty(desc, 'writable')) {
97109
if (desc.writable !== originalDesc.writable ||
98110
desc.writable !== isWritable(obj, name)) {
99-
failures.push('descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
111+
__push(failures, 'descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
100112
}
101113
}
102114

103-
if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) {
115+
if (__hasOwnProperty(desc, 'configurable')) {
104116
if (desc.configurable !== originalDesc.configurable ||
105117
desc.configurable !== isConfigurable(obj, name)) {
106-
failures.push('descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
118+
__push(failures, 'descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
107119
}
108120
}
109121

110-
assert(!failures.length, failures.join('; '));
122+
assert(!failures.length, __join(failures, '; '));
111123

112124
if (options && options.restore) {
113-
Object.defineProperty(obj, name, originalDesc);
125+
__defineProperty(obj, name, originalDesc);
114126
}
115127

116128
return true;
117129
}
118130

119131
function isConfigurable(obj, name) {
120-
var hasOwnProperty = Object.prototype.hasOwnProperty;
121132
try {
122133
delete obj[name];
123134
} catch (e) {
124135
if (!(e instanceof TypeError)) {
125136
throw new Test262Error("Expected TypeError, got " + e);
126137
}
127138
}
128-
return !hasOwnProperty.call(obj, name);
139+
return !__hasOwnProperty(obj, name);
129140
}
130141

131142
function isEnumerable(obj, name) {
@@ -143,9 +154,7 @@ function isEnumerable(obj, name) {
143154
stringCheck = true;
144155
}
145156

146-
return stringCheck &&
147-
Object.prototype.hasOwnProperty.call(obj, name) &&
148-
Object.prototype.propertyIsEnumerable.call(obj, name);
157+
return stringCheck && __hasOwnProperty(obj, name) && __propertyIsEnumerable(obj, name);
149158
}
150159

151160
function isSameValue(a, b) {
@@ -155,13 +164,12 @@ function isSameValue(a, b) {
155164
return a === b;
156165
}
157166

158-
var __isArray = Array.isArray;
159167
function isWritable(obj, name, verifyProp, value) {
160168
var unlikelyValue = __isArray(obj) && name === "length" ?
161-
Math.pow(2, 32) - 1 :
169+
nonIndexNumericPropertyName :
162170
"unlikelyValue";
163171
var newValue = value || unlikelyValue;
164-
var hadValue = Object.prototype.hasOwnProperty.call(obj, name);
172+
var hadValue = __hasOwnProperty(obj, name);
165173
var oldValue = obj[name];
166174
var writeSucceeded;
167175

0 commit comments

Comments
 (0)