Skip to content

Commit

Permalink
✨ enable speedy sandbox mode by default (#2320)
Browse files Browse the repository at this point in the history
  • Loading branch information
kuitos authored Oct 30, 2022
1 parent 6544b17 commit 743473a
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 85 deletions.
5 changes: 3 additions & 2 deletions .fatherrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ writeFileSync(versionFilePath, `export const version = '${version}';`);
const globalsFilePath = join(__dirname, './src/sandbox/globals.ts');
writeFileSync(
globalsFilePath,
`// generated from https://github.com/sindresorhus/globals/blob/main/globals.json builtin part
export const globals = ${JSON.stringify(Object.keys(globals.builtin), null, 2)};`,
`// generated from https://github.com/sindresorhus/globals/blob/main/globals.json es2015 part
// only init its values while Proxy is supported
export const globals = window.Proxy ? ${JSON.stringify(Object.keys(globals.es2015), null, 2)} : [];`,
);

export default {
Expand Down
3 changes: 3 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ type QiankunSpecialOpts = {
* @deprecated We use strict mode by default
*/
loose?: boolean;
/**
* use speed sandbox mode, enabled by default from 2.9.0
*/
speedy?: boolean;
patchers?: Patcher[];
};
Expand Down
7 changes: 4 additions & 3 deletions src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type {
ObjectType,
} from './interfaces';
import { createSandboxContainer, css } from './sandbox';
import { lexicalGlobals } from './sandbox/common';
import { trustedGlobals } from './sandbox/common';
import {
Deferred,
genAppInstanceIdByName,
Expand Down Expand Up @@ -311,7 +311,8 @@ export async function loadApp<T extends ObjectType>(
let mountSandbox = () => Promise.resolve();
let unmountSandbox = () => Promise.resolve();
const useLooseSandbox = typeof sandbox === 'object' && !!sandbox.loose;
const speedySandbox = typeof sandbox === 'object' && !!sandbox.speedy;
// enable speedy mode by default
const speedySandbox = typeof sandbox === 'object' ? sandbox.speedy !== false : true;
let sandboxContainer;
if (sandbox) {
sandboxContainer = createSandboxContainer(
Expand Down Expand Up @@ -342,7 +343,7 @@ export async function loadApp<T extends ObjectType>(

// get the lifecycle hooks from module exports
const scriptExports: any = await execScripts(global, sandbox && !useLooseSandbox, {
scopedGlobalVariables: speedySandbox ? lexicalGlobals : [],
scopedGlobalVariables: speedySandbox ? trustedGlobals : [],
});
const { bootstrap, mount, unmount, update } = getLifecyclesFromExports(
scriptExports,
Expand Down
7 changes: 3 additions & 4 deletions src/sandbox/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ export function getCurrentRunningApp() {
}

export function setCurrentRunningApp(appInstance: { name: string; window: WindowProxy } | null) {
// set currentRunningApp and it's proxySandbox to global window, as its only use case is for document.createElement from now on, which hijacked by a global way
// Set currentRunningApp and it's proxySandbox to global window, as its only use case is for document.createElement from now on, which hijacked by a global way
currentRunningApp = appInstance;
}

const scopedGlobals = ['window', 'self', 'globalThis', 'top', 'parent', 'hasOwnProperty', 'document', 'eval'];
export const unscopedGlobals = [...without(globals, ...scopedGlobals), 'requestAnimationFrame'];
export const lexicalGlobals = [...unscopedGlobals, ...scopedGlobals];
const spiedGlobals = ['window', 'self', 'globalThis', 'top', 'parent', 'hasOwnProperty', 'document', 'eval'];
export const trustedGlobals = [...without(globals, ...spiedGlobals), 'requestAnimationFrame'];

const functionBoundedValueMap = new WeakMap<CallableFunction, CallableFunction>();

Expand Down
132 changes: 63 additions & 69 deletions src/sandbox/globals.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,63 @@
// generated from https://github.com/sindresorhus/globals/blob/main/globals.json builtin part
export const globals = [
'AggregateError',
'Array',
'ArrayBuffer',
'Atomics',
'BigInt',
'BigInt64Array',
'BigUint64Array',
'Boolean',
'constructor',
'DataView',
'Date',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
'Error',
'escape',
'eval',
'EvalError',
'FinalizationRegistry',
'Float32Array',
'Float64Array',
'Function',
'globalThis',
'hasOwnProperty',
'Infinity',
'Int16Array',
'Int32Array',
'Int8Array',
'isFinite',
'isNaN',
'isPrototypeOf',
'JSON',
'Map',
'Math',
'NaN',
'Number',
'Object',
'parseFloat',
'parseInt',
'Promise',
'propertyIsEnumerable',
'Proxy',
'RangeError',
'ReferenceError',
'Reflect',
'RegExp',
'Set',
'SharedArrayBuffer',
'String',
'Symbol',
'SyntaxError',
'toLocaleString',
'toString',
'TypeError',
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
'undefined',
'unescape',
'URIError',
'valueOf',
'WeakMap',
'WeakRef',
'WeakSet',
];
// generated from https://github.com/sindresorhus/globals/blob/main/globals.json es2015 part
// only init its values while Proxy is supported
export const globals = window.Proxy
? [
'Array',
'ArrayBuffer',
'Boolean',
'constructor',
'DataView',
'Date',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
'Error',
'escape',
'eval',
'EvalError',
'Float32Array',
'Float64Array',
'Function',
'hasOwnProperty',
'Infinity',
'Int16Array',
'Int32Array',
'Int8Array',
'isFinite',
'isNaN',
'isPrototypeOf',
'JSON',
'Map',
'Math',
'NaN',
'Number',
'Object',
'parseFloat',
'parseInt',
'Promise',
'propertyIsEnumerable',
'Proxy',
'RangeError',
'ReferenceError',
'Reflect',
'RegExp',
'Set',
'String',
'Symbol',
'SyntaxError',
'toLocaleString',
'toString',
'TypeError',
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
'undefined',
'unescape',
'URIError',
'valueOf',
'WeakMap',
'WeakSet',
]
: [];
4 changes: 2 additions & 2 deletions src/sandbox/patchers/dynamicAppend/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { execScripts } from 'import-html-entry';
import { isFunction } from 'lodash';
import { frameworkConfiguration } from '../../../apis';
import { qiankunHeadTagName } from '../../../utils';
import { lexicalGlobals } from '../../common';
import { trustedGlobals } from '../../common';
import * as css from '../css';

export const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
Expand Down Expand Up @@ -280,7 +280,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: {
const { fetch } = frameworkConfiguration;
const referenceNode = mountDOM.contains(refChild) ? refChild : null;

const scopedGlobalVariables = speedySandbox ? lexicalGlobals : [];
const scopedGlobalVariables = speedySandbox ? trustedGlobals : [];

if (src) {
execScripts(null, [src], proxy, {
Expand Down
9 changes: 4 additions & 5 deletions src/sandbox/proxySandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import type { SandBox } from '../interfaces';
import { SandBoxType } from '../interfaces';
import { isPropertyFrozen, nativeGlobal, nextTask } from '../utils';
import { getCurrentRunningApp, getTargetValue, setCurrentRunningApp, unscopedGlobals } from './common';
import { getCurrentRunningApp, getTargetValue, trustedGlobals, setCurrentRunningApp } from './common';

type SymbolTarget = 'target' | 'globalContext';

Expand Down Expand Up @@ -49,7 +49,7 @@ const globalVariableWhiteList: string[] = [
variables who are impossible to be overwritten need to be escaped from proxy sandbox for performance reasons
see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables
*/
const unscopables = unscopedGlobals.reduce((acc, key) => ({ ...acc, [key]: true }), { __proto__: null });
const unscopables = trustedGlobals.reduce((acc, key) => ({ ...acc, [key]: true }), { __proto__: null });

const useNativeWindowForBindingsProps = new Map<PropertyKey, boolean>([
['fetch', true],
Expand Down Expand Up @@ -132,9 +132,6 @@ export default class ProxySandbox implements SandBox {
sandboxRunning = true;
latestSetProp: PropertyKey | null = null;

// the descriptor of global variables in whitelist before it been modified
globalWhitelistPrevDescriptor: { [p in typeof globalVariableWhiteList[number]]: PropertyDescriptor | undefined } = {};

active() {
if (!this.sandboxRunning) activeSandboxCount++;
this.sandboxRunning = true;
Expand Down Expand Up @@ -163,6 +160,8 @@ export default class ProxySandbox implements SandBox {
this.sandboxRunning = false;
}

// the descriptor of global variables in whitelist before it been modified
globalWhitelistPrevDescriptor: { [p in typeof globalVariableWhiteList[number]]: PropertyDescriptor | undefined } = {};
globalContext: typeof window;

constructor(name: string, globalContext = window) {
Expand Down

1 comment on commit 743473a

@vercel
Copy link

@vercel vercel bot commented on 743473a Oct 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.