From e6cebae23334dec8e76a290b00e4c48a50ac6e7d Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 8 Feb 2023 09:24:48 -0800 Subject: [PATCH] fix: ensure red callable functions have undefined 'this' context (#417) --- .../near-membrane-base/src/environment.ts | 46 +++++++++++++++---- packages/near-membrane-base/src/types.ts | 2 +- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/near-membrane-base/src/environment.ts b/packages/near-membrane-base/src/environment.ts index 653558ff..97d9bfa3 100644 --- a/packages/near-membrane-base/src/environment.ts +++ b/packages/near-membrane-base/src/environment.ts @@ -21,6 +21,7 @@ import type { Pointer, VirtualEnvironmentOptions, CallableTrackAsFastTarget, + CallableDescriptorCallback, } from './types'; const LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL = Symbol.for( @@ -248,16 +249,45 @@ export class VirtualEnvironment { this.blueCallableGetPropertyValuePointer = blueCallableGetPropertyValuePointer; this.blueCallableLinkPointers = blueCallableLinkPointers; - this.redGlobalThisPointer = redGlobalThisPointer; - this.redCallableGetPropertyValuePointer = redCallableGetPropertyValuePointer; + // Ensure the `this` context of red callable functions is `undefined`. + this.redGlobalThisPointer = () => redGlobalThisPointer(); + this.redCallableGetPropertyValuePointer = (targetPointer: Pointer, key: PropertyKey) => + redCallableGetPropertyValuePointer(targetPointer, key); this.redCallableEvaluate = signSourceCallback ? (sourceText: string) => redCallableEvaluate(signSourceCallback(sourceText)) - : redCallableEvaluate; - this.redCallableLinkPointers = redCallableLinkPointers; - this.redCallableSetPrototypeOf = redCallableSetPrototypeOf; - this.redCallableDefineProperties = redCallableDefineProperties; - this.redCallableInstallLazyPropertyDescriptors = redCallableInstallLazyPropertyDescriptors; - this.redCallableTrackAsFastTarget = redCallableTrackAsFastTarget; + : (sourceText: string) => redCallableEvaluate(sourceText); + this.redCallableLinkPointers = (targetPointer: Pointer, foreignTargetPointer: Pointer) => + redCallableLinkPointers(targetPointer, foreignTargetPointer); + this.redCallableSetPrototypeOf = ( + targetPointer: Pointer, + protoPointerOrNull: Pointer | null + ) => redCallableSetPrototypeOf(targetPointer, protoPointerOrNull); + this.redCallableDefineProperties = ( + targetPointer: Pointer, + ...descriptorTuples: [...Parameters] + ) => { + const { length } = descriptorTuples; + const args = new ArrayCtor(length + 1); + args[0] = targetPointer; + for (let i = 0; i < length; i += 1) { + args[i + 1] = descriptorTuples[i]; + } + ReflectApply(redCallableDefineProperties, undefined, args); + }; + this.redCallableInstallLazyPropertyDescriptors = ( + targetPointer: Pointer, + ...ownKeysAndUnforgeableGlobalThisKeys: PropertyKey[] + ) => { + const { length } = ownKeysAndUnforgeableGlobalThisKeys; + const args = new ArrayCtor(length + 1); + args[0] = targetPointer; + for (let i = 0; i < length; i += 1) { + args[i + 1] = ownKeysAndUnforgeableGlobalThisKeys[i]; + } + ReflectApply(redCallableInstallLazyPropertyDescriptors, undefined, args); + }; + this.redCallableTrackAsFastTarget = (targetPointer: Pointer) => + redCallableTrackAsFastTarget(targetPointer); } evaluate(sourceText: string): any { diff --git a/packages/near-membrane-base/src/types.ts b/packages/near-membrane-base/src/types.ts index e2d37400..0cbf8ba5 100644 --- a/packages/near-membrane-base/src/types.ts +++ b/packages/near-membrane-base/src/types.ts @@ -69,7 +69,7 @@ export type CallableGet = ( ) => PointerOrPrimitive; export type CallableGetPropertyValue = ( targetPointer: Pointer, - index: PropertyKey + key: PropertyKey ) => PointerOrPrimitive; export type CallableGetLazyPropertyDescriptorStateByTarget = ( targetPointer: Pointer