Skip to content

Commit

Permalink
@W-16383704: Convert near-membrane's binary data tests to MaxPerf/Max…
Browse files Browse the repository at this point in the history
…Compat (#459)

* Upgrade Karma Firefox Launcher

* Integrate file-fixtures-preprocessor

This is to be able to have real js files for testing in the sandbox

* Renamed `remapTypedArrays` to `maxCompatMode`

* Centralized all the objects that must be from the same global object even when maxCompatMode is false

* Created `maxPerfModeKeys` array and added `Atomics` to it

* Renamed maxCompatMode to maxPerfMode and flipped the logic

Split the maxPerfModeKeys into intrinsics and browser, ok for now, to be improved

* Added .npmrc and .yarnrc

Also removed Husky's commit-msg
  • Loading branch information
manuel-jasso authored Aug 5, 2024
1 parent 75a37d0 commit 565cf51
Show file tree
Hide file tree
Showing 34 changed files with 540 additions and 798 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ dist/
node_modules/
types/
*/**/bundle.js
**/untrusted/**/*.js
4 changes: 0 additions & 4 deletions .husky/commit-msg

This file was deleted.

4 changes: 4 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
registry=https://registry.yarnpkg.com
save-exact=true
package-lock=false
scripts-prepend-node-path=true
1 change: 1 addition & 0 deletions .yarnrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
save-prefix ""
4 changes: 3 additions & 1 deletion karma.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

'use strict';

const path = require('node:path');
const globby = require('globby');
const istanbul = require('rollup-plugin-istanbul');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const path = require('node:path');

process.env.CHROME_BIN = require('puppeteer').executablePath();

Expand Down Expand Up @@ -38,6 +38,7 @@ const customLaunchers = {

module.exports = function (config) {
const bootstrapFilesPattern = 'test/__bootstrap__/**/*.js';
const fileFixturesPattern = '**/untrusted/**/*.js';
const karmaConfig = {
basePath,
browsers: Object.keys(customLaunchers),
Expand All @@ -58,6 +59,7 @@ module.exports = function (config) {
logLevel: config.LOG_ERROR,
preprocessors: {
[bootstrapFilesPattern]: ['rollup'],
[fileFixturesPattern]: ['file-fixtures'],
[testFilesPattern]: ['rollup'],
},
reporters: ['progress'],
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"karma": "6.4.2",
"karma-chrome-launcher": "3.2.0",
"karma-coverage": "2.2.1",
"karma-firefox-launcher": "2.1.2",
"karma-file-fixtures-preprocessor": "^3.0.2",
"karma-firefox-launcher": "2.1.3",
"karma-jasmine": "5.1.0",
"karma-rollup-preprocessor": "7.0.7",
"karma-safari-launcher": "1.0.0",
Expand Down Expand Up @@ -102,8 +103,7 @@
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "yarn commitlint --edit $1"
"pre-commit": "lint-staged"
}
},
"dependencies": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ const ReflectiveIntrinsicObjectNames = [
];

const RemappedIntrinsicObjectNames = [
'Atomics',
'Date',
'Intl',
'Map',
Expand All @@ -100,6 +99,7 @@ const RemappedIntrinsicObjectNames = [

const TypedAraysInstrinsics = [
'ArrayBuffer',
'Atomics',
'BigInt64Array',
'BigUint64Array',
'DataView',
Expand Down
37 changes: 21 additions & 16 deletions packages/near-membrane-base/src/intrinsics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { VirtualEnvironment } from './environment';
* problematic, and requires a lot more work to guarantee that objects from both sides
* can be considered equivalents (without identity discontinuity).
*/
function getESGlobalKeys(remapTypedArrays = true) {
function getESGlobalKeys(maxPerfMode: boolean) {
const ESGlobalKeys = [
// *** 19.1 Value Properties of the Global Object
'globalThis',
Expand Down Expand Up @@ -91,23 +91,31 @@ function getESGlobalKeys(remapTypedArrays = true) {
// 'Intl', // Remapped
];

if (remapTypedArrays === false) {
ESGlobalKeys.push(
// This set is for maxPerfMode, all of these must be from the same global object
const maxPerfModeKeys = {
intrinsics: [
'ArrayBuffer',
'Atomics',
'BigInt64Array',
'BigUint64Array',
'DataView',
'Float32Array',
'Float64Array',
'Int8Array',
'Int16Array',
'Int32Array',
'Int8Array',
'SharedArrayBuffer',
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
'Uint16Array',
'Uint32Array'
);
],
// Ideally these should come from browser-realm, that's a code reorg improvement for later
browser: ['Blob', 'crypto', 'Crypto', 'File', 'FileReader', 'SubtleCrypto', 'URL'],
};

if (maxPerfMode) {
ESGlobalKeys.push(...maxPerfModeKeys.intrinsics, ...maxPerfModeKeys.browser);
}
return ESGlobalKeys;
}
Expand All @@ -131,8 +139,8 @@ const ReflectiveIntrinsicObjectNames = [
'globalThis',
];

function getESGlobalsAndReflectiveIntrinsicObjectNames(remapTypedArrays = true) {
const ESGlobalKeys = getESGlobalKeys(remapTypedArrays);
function getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode: boolean) {
const ESGlobalKeys = getESGlobalKeys(maxPerfMode);
return toSafeArray([...ESGlobalKeys, ...ReflectiveIntrinsicObjectNames]);
}

Expand All @@ -149,10 +157,10 @@ function getGlobalObjectOwnKeys(source: object): PropertyKey[] {

export function assignFilteredGlobalDescriptorsFromPropertyDescriptorMap<
T extends PropertyDescriptorMap
>(descs: T, source: PropertyDescriptorMap, includeTypedArrays?: boolean): T {
>(descs: T, source: PropertyDescriptorMap, maxPerfMode: boolean): T {
const ownKeys = getGlobalObjectOwnKeys(source);
const ESGlobalsAndReflectiveIntrinsicObjectNames =
getESGlobalsAndReflectiveIntrinsicObjectNames(includeTypedArrays);
getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode);
for (let i = 0, { length } = ownKeys; i < length; i += 1) {
const ownKey = ownKeys[i];
// Avoid overriding ECMAScript global names that correspond to
Expand All @@ -172,15 +180,12 @@ export function assignFilteredGlobalDescriptorsFromPropertyDescriptorMap<
return descs;
}

export function getFilteredGlobalOwnKeys(
source: object,
includeTypedArrays?: boolean
): PropertyKey[] {
export function getFilteredGlobalOwnKeys(source: object, maxPerfMode: boolean): PropertyKey[] {
const result: PropertyKey[] = [];
let resultOffset = 0;
const ownKeys = getGlobalObjectOwnKeys(source);
const ESGlobalsAndReflectiveIntrinsicObjectNames =
getESGlobalsAndReflectiveIntrinsicObjectNames(includeTypedArrays);
getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode);
for (let i = 0, { length } = ownKeys; i < length; i += 1) {
const ownKey = ownKeys[i];
// Avoid overriding ECMAScript global names that correspond to global
Expand Down
13 changes: 5 additions & 8 deletions packages/near-membrane-dom/src/browser-realm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function createIframeVirtualEnvironment(
instrumentation,
keepAlive = true,
liveTargetCallback,
remapTypedArrays = true,
maxPerfMode = false,
signSourceCallback,
// eslint-disable-next-line prefer-object-spread
} = ObjectAssign({ __proto__: null }, providedOptions) as BrowserEnvironmentOptions;
Expand All @@ -90,10 +90,7 @@ function createIframeVirtualEnvironment(
)!;
const shouldUseDefaultGlobalOwnKeys =
typeof globalObjectShape !== 'object' || globalObjectShape === null;
const defaultGlobalOwnKeys = filterWindowKeys(
getFilteredGlobalOwnKeys(redWindow, remapTypedArrays),
remapTypedArrays
);
const defaultGlobalOwnKeys = filterWindowKeys(getFilteredGlobalOwnKeys(redWindow, maxPerfMode));
let blueConnector = blueCreateHooksCallbackCache.get(blueRefs.document) as
| Connector
| undefined;
Expand Down Expand Up @@ -142,7 +139,7 @@ function createIframeVirtualEnvironment(
blueRefs.window,
shouldUseDefaultGlobalOwnKeys
? (defaultGlobalOwnKeys as PropertyKey[])
: filterWindowKeys(getFilteredGlobalOwnKeys(globalObjectShape), remapTypedArrays),
: filterWindowKeys(getFilteredGlobalOwnKeys(globalObjectShape, maxPerfMode)),
// Chromium based browsers have a bug that nulls the result of `window`
// getters in detached iframes when the property descriptor of `window.window`
// is retrieved.
Expand All @@ -154,9 +151,9 @@ function createIframeVirtualEnvironment(
assignFilteredGlobalDescriptorsFromPropertyDescriptorMap(
filteredEndowments,
endowments,
remapTypedArrays
maxPerfMode
);
removeWindowDescriptors(filteredEndowments, remapTypedArrays);
removeWindowDescriptors(filteredEndowments);
env.remapProperties(blueRefs.window, filteredEndowments);
}
// We intentionally skip remapping Window.prototype because there is nothing
Expand Down
2 changes: 1 addition & 1 deletion packages/near-membrane-dom/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ export interface BrowserEnvironmentOptions {
instrumentation?: Instrumentation;
keepAlive?: boolean;
liveTargetCallback?: LiveTargetCallback;
remapTypedArrays?: boolean;
maxPerfMode?: boolean;
signSourceCallback?: SignSourceCallback;
}
27 changes: 2 additions & 25 deletions packages/near-membrane-dom/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,8 @@ export function getCachedGlobalObjectReferences(
return record;
}

export function filterWindowKeys(keys: PropertyKey[], remapTypedArrays: boolean): PropertyKey[] {
export function filterWindowKeys(keys: PropertyKey[]): PropertyKey[] {
const excludedKeys = new SetCtor(['document', 'location', 'top', 'window']);
// Crypto and typed arrays must be from the same global object
if (remapTypedArrays === false) {
excludedKeys.add('crypto');
excludedKeys.add('Crypto');
excludedKeys.add('SubtleCrypto');
excludedKeys.add('Blob');
excludedKeys.add('File');
excludedKeys.add('FileReader');
excludedKeys.add('URL');
}
const result: PropertyKey[] = [];
let resultOffset = 0;
for (let i = 0, { length } = keys; i < length; i += 1) {
Expand Down Expand Up @@ -116,27 +106,14 @@ export function filterWindowKeys(keys: PropertyKey[], remapTypedArrays: boolean)
* that will be installed (via the membrane) as global descriptors in
* the red realm.
*/
export function removeWindowDescriptors<T extends PropertyDescriptorMap>(
unsafeDescs: T,
remapTypedArrays: boolean
): T {
export function removeWindowDescriptors<T extends PropertyDescriptorMap>(unsafeDescs: T): T {
// Remove unforgeable descriptors that cannot be installed.
ReflectDeleteProperty(unsafeDescs, 'document');
ReflectDeleteProperty(unsafeDescs, 'location');
ReflectDeleteProperty(unsafeDescs, 'top');
ReflectDeleteProperty(unsafeDescs, 'window');
// Remove other browser specific unforgeables.
ReflectDeleteProperty(unsafeDescs, 'chrome');
// Crypto and typed arrays must be from the same global object
if (remapTypedArrays === false) {
ReflectDeleteProperty(unsafeDescs, 'crypto');
ReflectDeleteProperty(unsafeDescs, 'Crypto');
ReflectDeleteProperty(unsafeDescs, 'SubtleCrypto');
ReflectDeleteProperty(unsafeDescs, 'Blob');
ReflectDeleteProperty(unsafeDescs, 'File');
ReflectDeleteProperty(unsafeDescs, 'FileReader');
ReflectDeleteProperty(unsafeDescs, 'URL');
}
return unsafeDescs;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/near-membrane-node/src/node-realm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function createVirtualEnvironment(
globalObjectShape,
instrumentation,
liveTargetCallback,
remapTypedArrays,
maxPerfMode = false,
signSourceCallback,
} = ObjectAssign({ __proto__: null }, providedOptions) as NodeEnvironmentOptions;
let blueConnector = blueCreateHooksCallbackCache.get(globalObject) as Connector | undefined;
Expand All @@ -60,22 +60,22 @@ export default function createVirtualEnvironment(
const shouldUseDefaultGlobalOwnKeys =
typeof globalObjectShape !== 'object' || globalObjectShape === null;
if (shouldUseDefaultGlobalOwnKeys && defaultGlobalOwnKeys === null) {
defaultGlobalOwnKeys = getFilteredGlobalOwnKeys(redGlobalObject, remapTypedArrays);
defaultGlobalOwnKeys = getFilteredGlobalOwnKeys(redGlobalObject, maxPerfMode);
}

env.lazyRemapProperties(
globalObject,
shouldUseDefaultGlobalOwnKeys
? (defaultGlobalOwnKeys as PropertyKey[])
: getFilteredGlobalOwnKeys(globalObjectShape)
: getFilteredGlobalOwnKeys(globalObjectShape, maxPerfMode)
);

if (endowments) {
const filteredEndowments = {};
assignFilteredGlobalDescriptorsFromPropertyDescriptorMap(
filteredEndowments,
endowments,
remapTypedArrays
maxPerfMode
);
env.remapProperties(globalObject, filteredEndowments);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/near-membrane-node/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export interface NodeEnvironmentOptions {
globalObjectShape?: object;
instrumentation?: Instrumentation;
liveTargetCallback?: LiveTargetCallback;
remapTypedArrays?: boolean;
maxPerfMode?: boolean;
signSourceCallback?: SignSourceCallback;
}
Loading

0 comments on commit 565cf51

Please sign in to comment.