🐛 document proxy in strict sandbox mode replaces receiver with target in methods args (#2450)
This commit is contained in:
parent
38fa818273
commit
8bb5c948be
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { SandBoxType } from '../../../../interfaces';
|
||||||
|
import { noop } from 'lodash';
|
||||||
|
import { patchStrictSandbox } from '../forStrictSandbox';
|
||||||
|
|
||||||
|
jest.mock('import-html-entry', () => ({
|
||||||
|
execScripts: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('forStrictSandbox test', () => {
|
||||||
|
const {
|
||||||
|
prototype: { createTreeWalker: originalCreateTreeWalker },
|
||||||
|
} = Document;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
Document.prototype.createTreeWalker = function createTreeWalker(
|
||||||
|
this: Document,
|
||||||
|
root: Node,
|
||||||
|
whatToShow?: number | undefined,
|
||||||
|
filter?: NodeFilter | null | undefined,
|
||||||
|
) {
|
||||||
|
if (document !== root) {
|
||||||
|
throw new TypeError('error');
|
||||||
|
}
|
||||||
|
return originalCreateTreeWalker.call(this, root, whatToShow, filter);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
Document.prototype.createTreeWalker = originalCreateTreeWalker;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not throw on patched document', () => {
|
||||||
|
let patchedDocument!: Document;
|
||||||
|
const appName = 'test-app';
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
const sandbox = {
|
||||||
|
name: appName,
|
||||||
|
type: SandBoxType.Proxy,
|
||||||
|
proxy: window,
|
||||||
|
sandboxRunning: true,
|
||||||
|
latestSetProp: null,
|
||||||
|
patchDocument: (patched: Document) => {
|
||||||
|
patchedDocument = patched;
|
||||||
|
},
|
||||||
|
active: noop,
|
||||||
|
inactive: noop,
|
||||||
|
};
|
||||||
|
patchStrictSandbox(appName, () => wrapper, sandbox, true, false, undefined, true);
|
||||||
|
|
||||||
|
expect(patchedDocument).toBeDefined();
|
||||||
|
expect(() => patchedDocument?.createTreeWalker(patchedDocument)).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -53,7 +53,7 @@ function patchDocument(cfg: { sandbox: SandBox; speedy: boolean }) {
|
||||||
(<any>target)[p] = value;
|
(<any>target)[p] = value;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
get: (target, p) => {
|
get: (target, p, receiver) => {
|
||||||
if (p === 'createElement') {
|
if (p === 'createElement') {
|
||||||
// Must store the original createElement function to avoid error in nested sandbox
|
// Must store the original createElement function to avoid error in nested sandbox
|
||||||
const targetCreateElement = target.createElement;
|
const targetCreateElement = target.createElement;
|
||||||
|
|
@ -67,7 +67,9 @@ function patchDocument(cfg: { sandbox: SandBox; speedy: boolean }) {
|
||||||
const value = (<any>target)[p];
|
const value = (<any>target)[p];
|
||||||
// must rebind the function to the target otherwise it will cause illegal invocation error
|
// must rebind the function to the target otherwise it will cause illegal invocation error
|
||||||
if (typeof value === 'function' && !isBoundedFunction(value)) {
|
if (typeof value === 'function' && !isBoundedFunction(value)) {
|
||||||
return value.bind(target);
|
return function proxiedFunction(...args: unknown[]) {
|
||||||
|
return value.call(target, ...args.map((arg) => (arg === receiver ? target : arg)));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user