Sandbox: Patch array vector prototype methods inside the sandbox (#75835)

This commit is contained in:
Esteban Beltran 2023-10-03 09:02:55 +02:00 committed by GitHub
parent 0c404a4cd9
commit 677a2ad4d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 33 deletions

View File

@ -13,42 +13,46 @@ declare global {
// JS original sin // JS original sin
// this if condition is because Jest will re-exec this block multiple times (in a browser this only runs once) // this if condition is because Jest will re-exec this block multiple times (in a browser this only runs once)
if (!Object.getOwnPropertyDescriptor(Array.prototype, 'toArray')) { export function patchArrayVectorProrotypeMethods() {
Object.defineProperties(Array.prototype, { if (!Object.getOwnPropertyDescriptor(Array.prototype, 'toArray')) {
get: { Object.defineProperties(Array.prototype, {
value: function (idx: number) { get: {
return this[idx]; value: function (idx: number) {
return this[idx];
},
writable: true,
enumerable: false,
configurable: true,
}, },
writable: true, set: {
enumerable: false, value: function (idx: number, value: unknown) {
configurable: true, this[idx] = value;
}, },
set: { writable: true,
value: function (idx: number, value: unknown) { enumerable: false,
this[idx] = value; configurable: true,
}, },
writable: true, add: {
enumerable: false, value: function (value: unknown) {
configurable: true, this.push(value);
}, },
add: { writable: true,
value: function (value: unknown) { enumerable: false,
this.push(value); configurable: true,
}, },
writable: true, toArray: {
enumerable: false, value: function () {
configurable: true, return this;
}, },
toArray: { writable: true,
value: function () { enumerable: false,
return this; configurable: true,
}, },
writable: true, });
enumerable: false, }
configurable: true,
},
});
} }
//this function call is intentional
patchArrayVectorProrotypeMethods();
/** @deprecated use a simple Array<T> */ /** @deprecated use a simple Array<T> */
export interface Vector<T = any> extends Array<T> { export interface Vector<T = any> extends Array<T> {

View File

@ -1,4 +1,4 @@
import { PluginMeta } from '@grafana/data'; import { PluginMeta, patchArrayVectorProrotypeMethods } from '@grafana/data';
import { transformPluginSourceForCDN } from '../cdn/utils'; import { transformPluginSourceForCDN } from '../cdn/utils';
import { resolveWithCache } from '../loader/cache'; import { resolveWithCache } from '../loader/cache';
@ -91,3 +91,11 @@ function patchPluginSourceMap(meta: PluginMeta, pluginCode: string): string {
} }
return pluginCode; return pluginCode;
} }
export function patchSandboxEnvironmentPrototype(sandboxEnvironment: SandboxEnvironment) {
// same as https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/types/vector.ts#L16
// Array is a "reflective" type in Near-membrane and doesn't get an identify continuity
sandboxEnvironment.evaluate(
`${patchArrayVectorProrotypeMethods.toString()};${patchArrayVectorProrotypeMethods.name}()`
);
}

View File

@ -7,7 +7,7 @@ import { defaultTrustedTypesPolicy } from 'app/core/trustedTypePolicies';
import { getPluginSettings } from '../pluginSettings'; import { getPluginSettings } from '../pluginSettings';
import { getPluginCode } from './code_loader'; import { getPluginCode, patchSandboxEnvironmentPrototype } from './code_loader';
import { getGeneralSandboxDistortionMap, distortLiveApis } from './distortion_map'; import { getGeneralSandboxDistortionMap, distortLiveApis } from './distortion_map';
import { import {
getSafeSandboxDomElement, getSafeSandboxDomElement,
@ -179,6 +179,8 @@ async function doImportPluginModuleInSandbox(meta: PluginMeta): Promise<System.M
}, },
}); });
patchSandboxEnvironmentPrototype(sandboxEnvironment);
// fetch plugin's code // fetch plugin's code
let pluginCode = ''; let pluginCode = '';
try { try {