✨ hijack dynamic document appending in evalling code (#1052)
This commit is contained in:
parent
798f3437b9
commit
3fa008be96
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isBoundedFunction } from '../../utils';
|
import { isBoundedFunction } from '../../utils';
|
||||||
import { documentAttachProxyMap } from '../common';
|
import { getCurrentRunningSandboxProxy } from '../common';
|
||||||
import ProxySandbox from '../proxySandbox';
|
import ProxySandbox from '../proxySandbox';
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
|
|
@ -201,26 +201,42 @@ test('hasOwnProperty should always returns same reference', () => {
|
||||||
expect(proxy.testA.hasOwnProperty).toBe(proxy.testB.hasOwnProperty);
|
expect(proxy.testA.hasOwnProperty).toBe(proxy.testB.hasOwnProperty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('document accessing should modify the attachDocProxySymbol value every time', () => {
|
test('document and eval accessing should modify the attachDocProxySymbol value every time', () => {
|
||||||
const proxy1 = new ProxySandbox('doc-access-test1').proxy;
|
const proxy1 = new ProxySandbox('doc-access-test1').proxy;
|
||||||
const proxy2 = new ProxySandbox('doc-access-test2').proxy;
|
const proxy2 = new ProxySandbox('doc-access-test2').proxy;
|
||||||
|
const proxy3 = new ProxySandbox('eval-access-test1').proxy;
|
||||||
|
const proxy4 = new ProxySandbox('eval-access-test2').proxy;
|
||||||
|
|
||||||
const d1 = proxy1.document;
|
const d1 = proxy1.document;
|
||||||
expect(documentAttachProxyMap.get(d1)).toBe(proxy1);
|
expect(getCurrentRunningSandboxProxy()).toBe(proxy1);
|
||||||
const d2 = proxy2.document;
|
const d2 = proxy2.document;
|
||||||
expect(documentAttachProxyMap.get(d2)).toBe(proxy2);
|
expect(getCurrentRunningSandboxProxy()).toBe(proxy2);
|
||||||
|
|
||||||
expect(d1).toBe(d2);
|
expect(d1).toBe(d2);
|
||||||
expect(d1).toBe(document);
|
expect(d1).toBe(document);
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const eval1 = proxy3.eval;
|
||||||
|
expect(getCurrentRunningSandboxProxy()).toBe(proxy3);
|
||||||
|
// @ts-ignore
|
||||||
|
const eval2 = proxy4.eval;
|
||||||
|
expect(getCurrentRunningSandboxProxy()).toBe(proxy4);
|
||||||
|
|
||||||
|
expect(eval1).toBe(eval2);
|
||||||
|
// eslint-disable-next-line no-eval
|
||||||
|
expect(eval1).toBe(eval);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('document attachDocProxySymbol mark should be remove before next tasl', (done) => {
|
test('document attachDocProxySymbol mark should be remove before next task', (done) => {
|
||||||
const { proxy } = new ProxySandbox('doc-symbol');
|
const { proxy } = new ProxySandbox('doc-symbol');
|
||||||
|
// just access
|
||||||
|
// @ts-ignore
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const d1 = proxy.document;
|
const d1 = proxy.document;
|
||||||
expect(documentAttachProxyMap.get(d1)).toBe(proxy);
|
expect(getCurrentRunningSandboxProxy()).toBe(proxy);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(documentAttachProxyMap.get(d1)).toBeUndefined();
|
expect(getCurrentRunningSandboxProxy()).toBeNull();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,14 @@
|
||||||
|
|
||||||
import { isBoundedFunction, isCallable, isConstructable } from '../utils';
|
import { isBoundedFunction, isCallable, isConstructable } from '../utils';
|
||||||
|
|
||||||
export const documentAttachProxyMap = new WeakMap<HTMLDocument, WindowProxy>();
|
let currentRunningSandboxProxy: WindowProxy | null;
|
||||||
|
export function getCurrentRunningSandboxProxy() {
|
||||||
|
return currentRunningSandboxProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setCurrentRunningSandboxProxy(proxy: WindowProxy | null) {
|
||||||
|
currentRunningSandboxProxy = proxy;
|
||||||
|
}
|
||||||
|
|
||||||
const functionBoundedValueMap = new WeakMap<Function, Function>();
|
const functionBoundedValueMap = new WeakMap<Function, Function>();
|
||||||
export function getTargetValue(target: any, value: any): any {
|
export function getTargetValue(target: any, value: any): any {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Freer } from '../../../interfaces';
|
import { Freer } from '../../../interfaces';
|
||||||
import { documentAttachProxyMap } from '../../common';
|
import { getCurrentRunningSandboxProxy } from '../../common';
|
||||||
import {
|
import {
|
||||||
ContainerConfig,
|
ContainerConfig,
|
||||||
isHijackingTag,
|
isHijackingTag,
|
||||||
|
|
@ -27,11 +27,9 @@ function patchDocumentCreateElement() {
|
||||||
): HTMLElement {
|
): HTMLElement {
|
||||||
const element = rawDocumentCreateElement.call(this, tagName, options);
|
const element = rawDocumentCreateElement.call(this, tagName, options);
|
||||||
if (isHijackingTag(tagName)) {
|
if (isHijackingTag(tagName)) {
|
||||||
// 这里使用document来获取比this更加健壮,因为之前set的时候是传入的document:
|
const currentRunningSandboxProxy = getCurrentRunningSandboxProxy();
|
||||||
// 因为document不一定是原生的document,这种情况出现在qiankun本身就在另一个沙箱下运行的情况,而那个沙箱可能连document都重写了。
|
if (currentRunningSandboxProxy) {
|
||||||
const attachProxy = documentAttachProxyMap.get(document);
|
const proxyContainerConfig = proxyAttachContainerConfigMap.get(currentRunningSandboxProxy);
|
||||||
if (attachProxy) {
|
|
||||||
const proxyContainerConfig = proxyAttachContainerConfigMap.get(attachProxy);
|
|
||||||
if (proxyContainerConfig) {
|
if (proxyContainerConfig) {
|
||||||
elementAttachContainerConfigMap.set(element, proxyContainerConfig);
|
elementAttachContainerConfigMap.set(element, proxyContainerConfig);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
import { SandBox, SandBoxType } from '../interfaces';
|
import { SandBox, SandBoxType } from '../interfaces';
|
||||||
import { nextTick } from '../utils';
|
import { nextTick } from '../utils';
|
||||||
import { documentAttachProxyMap, getTargetValue } from './common';
|
import { getTargetValue, setCurrentRunningSandboxProxy } from './common';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fastest(at most time) unique array method
|
* fastest(at most time) unique array method
|
||||||
|
|
@ -50,7 +50,6 @@ const unscopables = {
|
||||||
String: true,
|
String: true,
|
||||||
Boolean: true,
|
Boolean: true,
|
||||||
Math: true,
|
Math: true,
|
||||||
eval: true,
|
|
||||||
Number: true,
|
Number: true,
|
||||||
Symbol: true,
|
Symbol: true,
|
||||||
parseFloat: true,
|
parseFloat: true,
|
||||||
|
|
@ -223,13 +222,20 @@ export default class ProxySandbox implements SandBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark the symbol to document while accessing as document.createElement could know is invoked by which sandbox for dynamic append patcher
|
// mark the symbol to document while accessing as document.createElement could know is invoked by which sandbox for dynamic append patcher
|
||||||
if (p === 'document') {
|
if (p === 'document' || p === 'eval') {
|
||||||
documentAttachProxyMap.set(document, proxy);
|
setCurrentRunningSandboxProxy(proxy);
|
||||||
|
// FIXME if you have any other good ideas
|
||||||
// remove the mark in next tick, thus we can identify whether it in micro app or not
|
// remove the mark in next tick, thus we can identify whether it in micro app or not
|
||||||
// this approach is just a workaround, it could not cover all the complex scenarios, such as the micro app runs in the same task context with master in som case
|
// this approach is just a workaround, it could not cover all complex cases, such as the micro app runs in the same task context with master in some case
|
||||||
// fixme if you have any other good ideas
|
nextTick(() => setCurrentRunningSandboxProxy(null));
|
||||||
nextTick(() => documentAttachProxyMap.delete(document));
|
switch (p) {
|
||||||
|
case 'document':
|
||||||
return document;
|
return document;
|
||||||
|
case 'eval':
|
||||||
|
// eslint-disable-next-line no-eval
|
||||||
|
return eval;
|
||||||
|
// no default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-bitwise
|
// eslint-disable-next-line no-bitwise
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user