Skip to content

Commit

Permalink
harness/propertyHelper.js: Capture primordials that might be affected…
Browse files Browse the repository at this point in the history
… at runtime by verification

Ref tc39#4234 (comment)
  • Loading branch information
gibson042 committed Sep 23, 2024
1 parent fcfb11d commit c18c19e
Showing 1 changed file with 28 additions and 20 deletions.
48 changes: 28 additions & 20 deletions harness/propertyHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ defines:

// @ts-check

// Capture primordial functions and receiver-uncurried primordial methods that
// are used in verification but might be destroyed *by* that process itself.
var __isArray = Array.isArray;
var __defineProperty = Object.defineProperty;
var __join = Function.prototype.call.bind(Array.prototype.join);
var __push = Function.prototype.call.bind(Array.prototype.push);
var __hasOwnProperty = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
var __propertyIsEnumerable = Function.prototype.call.bind(Object.prototype.propertyIsEnumerable);
var nonIndexNumericPropertyName = Math.pow(2, 32) - 1;

/**
* @param {object} obj
* @param {string|symbol} name
Expand Down Expand Up @@ -46,7 +56,7 @@ function verifyProperty(obj, name, desc, options) {
}

assert(
Object.prototype.hasOwnProperty.call(obj, name),
__hasOwnProperty(obj, name),
"obj should have an own property " + nameStr
);

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

var failures = [];

if (Object.prototype.hasOwnProperty.call(desc, 'value')) {
if (__hasOwnProperty(desc, 'value')) {
if (!isSameValue(desc.value, originalDesc.value)) {
failures.push("descriptor value should be " + desc.value);
__push(failures, "descriptor value should be " + desc.value);
}
if (!isSameValue(desc.value, obj[name])) {
failures.push("object value should be " + desc.value);
__push(failures, "object value should be " + desc.value);
}
}

if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) {
if (__hasOwnProperty(desc, 'enumerable')) {
if (desc.enumerable !== originalDesc.enumerable ||
desc.enumerable !== isEnumerable(obj, name)) {
failures.push('descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
__push(failures, 'descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
}
}

if (Object.prototype.hasOwnProperty.call(desc, 'writable')) {
// Operations past this point are potentially destructive!

if (__hasOwnProperty(desc, 'writable')) {
if (desc.writable !== originalDesc.writable ||
desc.writable !== isWritable(obj, name)) {
failures.push('descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
__push(failures, 'descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
}
}

if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) {
if (__hasOwnProperty(desc, 'configurable')) {
if (desc.configurable !== originalDesc.configurable ||
desc.configurable !== isConfigurable(obj, name)) {
failures.push('descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
__push(failures, 'descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
}
}

assert(!failures.length, failures.join('; '));
assert(!failures.length, __join(failures, '; '));

if (options && options.restore) {
Object.defineProperty(obj, name, originalDesc);
__defineProperty(obj, name, originalDesc);
}

return true;
}

function isConfigurable(obj, name) {
var hasOwnProperty = Object.prototype.hasOwnProperty;
try {
delete obj[name];
} catch (e) {
if (!(e instanceof TypeError)) {
throw new Test262Error("Expected TypeError, got " + e);
}
}
return !hasOwnProperty.call(obj, name);
return !__hasOwnProperty(obj, name);
}

function isEnumerable(obj, name) {
Expand All @@ -143,9 +154,7 @@ function isEnumerable(obj, name) {
stringCheck = true;
}

return stringCheck &&
Object.prototype.hasOwnProperty.call(obj, name) &&
Object.prototype.propertyIsEnumerable.call(obj, name);
return stringCheck && __hasOwnProperty(obj, name) && __propertyIsEnumerable(obj, name);
}

function isSameValue(a, b) {
Expand All @@ -155,13 +164,12 @@ function isSameValue(a, b) {
return a === b;
}

var __isArray = Array.isArray;
function isWritable(obj, name, verifyProp, value) {
var unlikelyValue = __isArray(obj) && name === "length" ?
Math.pow(2, 32) - 1 :
nonIndexNumericPropertyName :
"unlikelyValue";
var newValue = value || unlikelyValue;
var hadValue = Object.prototype.hasOwnProperty.call(obj, name);
var hadValue = __hasOwnProperty(obj, name);
var oldValue = obj[name];
var writeSucceeded;

Expand Down

0 comments on commit c18c19e

Please sign in to comment.