🐛 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;
|
||||
return true;
|
||||
},
|
||||
get: (target, p) => {
|
||||
get: (target, p, receiver) => {
|
||||
if (p === 'createElement') {
|
||||
// Must store the original createElement function to avoid error in nested sandbox
|
||||
const targetCreateElement = target.createElement;
|
||||
|
|
@ -67,7 +67,9 @@ function patchDocument(cfg: { sandbox: SandBox; speedy: boolean }) {
|
|||
const value = (<any>target)[p];
|
||||
// must rebind the function to the target otherwise it will cause illegal invocation error
|
||||
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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user