From bac5e2ac6973f64464fa7f0068a71e26e075e37a Mon Sep 17 00:00:00 2001 From: Kuitos Date: Fri, 10 Feb 2023 11:34:09 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9Bwindow=20variable=20should=20in=20`?= =?UTF-8?q?with`=20lexical=20scope=20while=20speedy=20mode=20enabled=20(#2?= =?UTF-8?q?390)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/loader.ts | 4 ++-- src/sandbox/common.ts | 5 ++--- src/sandbox/patchers/dynamicAppend/common.ts | 4 ++-- src/sandbox/proxySandbox.ts | 15 ++++++++++++--- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 36cf5b0..0e3f9cf 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ }, "dependencies": { "@babel/runtime": "^7.10.5", - "import-html-entry": "^1.14.0", + "import-html-entry": "^1.14.1", "lodash": "^4.17.11", "single-spa": "^5.9.2" }, diff --git a/src/loader.ts b/src/loader.ts index 4242eb0..ca9c9fd 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -18,7 +18,7 @@ import type { ObjectType, } from './interfaces'; import { createSandboxContainer, css } from './sandbox'; -import { trustedGlobals } from './sandbox/common'; +import { scopedGlobals } from './sandbox/common'; import { Deferred, genAppInstanceIdByName, @@ -345,7 +345,7 @@ export async function loadApp( // get the lifecycle hooks from module exports const scriptExports: any = await execScripts(global, sandbox && !useLooseSandbox, { - scopedGlobalVariables: speedySandbox ? trustedGlobals : [], + scopedGlobalVariables: speedySandbox ? scopedGlobals : [], }); const { bootstrap, mount, unmount, update } = getLifecyclesFromExports( scriptExports, diff --git a/src/sandbox/common.ts b/src/sandbox/common.ts index 063217f..7063064 100644 --- a/src/sandbox/common.ts +++ b/src/sandbox/common.ts @@ -5,7 +5,6 @@ import { isBoundedFunction, isCallable, isConstructable } from '../utils'; import { globals } from './globals'; -import { without } from 'lodash'; type AppInstance = { name: string; window: WindowProxy }; let currentRunningApp: AppInstance | null = null; @@ -22,8 +21,8 @@ export function setCurrentRunningApp(appInstance: { name: string; window: Window currentRunningApp = appInstance; } -const spiedGlobals = ['window', 'self', 'globalThis', 'top', 'parent', 'hasOwnProperty', 'document', 'eval']; -export const trustedGlobals = [...without(globals, ...spiedGlobals), 'requestAnimationFrame']; +export const overwrittenGlobals = ['window', 'self', 'globalThis']; +export const scopedGlobals = Array.from(new Set([...globals, ...overwrittenGlobals, 'requestAnimationFrame'])); const functionBoundedValueMap = new WeakMap(); diff --git a/src/sandbox/patchers/dynamicAppend/common.ts b/src/sandbox/patchers/dynamicAppend/common.ts index b99cb95..8963a1e 100644 --- a/src/sandbox/patchers/dynamicAppend/common.ts +++ b/src/sandbox/patchers/dynamicAppend/common.ts @@ -6,7 +6,7 @@ import { execScripts } from 'import-html-entry'; import { isFunction } from 'lodash'; import { frameworkConfiguration } from '../../../apis'; import { qiankunHeadTagName } from '../../../utils'; -import { trustedGlobals } from '../../common'; +import { scopedGlobals } from '../../common'; import * as css from '../css'; export const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild; @@ -280,7 +280,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: { const { fetch } = frameworkConfiguration; const referenceNode = mountDOM.contains(refChild) ? refChild : null; - const scopedGlobalVariables = speedySandbox ? trustedGlobals : []; + const scopedGlobalVariables = speedySandbox ? scopedGlobals : []; if (src) { let isRedfinedCurrentScript = false; diff --git a/src/sandbox/proxySandbox.ts b/src/sandbox/proxySandbox.ts index 1c312c7..c769e36 100644 --- a/src/sandbox/proxySandbox.ts +++ b/src/sandbox/proxySandbox.ts @@ -1,4 +1,5 @@ /* eslint-disable no-param-reassign */ +import { without } from 'lodash'; /** * @author Kuitos * @since 2020-3-31 @@ -6,7 +7,8 @@ import type { SandBox } from '../interfaces'; import { SandBoxType } from '../interfaces'; import { isPropertyFrozen, nativeGlobal, nextTask } from '../utils'; -import { getCurrentRunningApp, getTargetValue, trustedGlobals, setCurrentRunningApp } from './common'; +import { overwrittenGlobals, getCurrentRunningApp, getTargetValue, setCurrentRunningApp } from './common'; +import { globals } from './globals'; type SymbolTarget = 'target' | 'globalContext'; @@ -45,11 +47,18 @@ const globalVariableWhiteList: string[] = [ ...variableWhiteListInDev, ]; +// these globals should be recorded in every accessing +const accessingSpiedGlobals = ['document', 'top', 'parent', 'hasOwnProperty', 'eval']; /* - variables who are impossible to be overwritten need to be escaped from proxy sandbox for performance reasons + 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 = trustedGlobals.reduce((acc, key) => ({ ...acc, [key]: true }), { __proto__: null }); +const unscopables = without(globals, ...accessingSpiedGlobals, ...overwrittenGlobals).reduce( + (acc, key) => ({ ...acc, [key]: true }), + { + __proto__: null, + }, +); const useNativeWindowForBindingsProps = new Map([ ['fetch', true],