-
-
Save abusedmedia/65fbb196bf496b9544f6d683acd74fa7 to your computer and use it in GitHub Desktop.
Create A Javascript sandbox to execute custom code without giving access to things like window and outer contextThey still have a `this` object they can use across multiple executions to persist data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Service from '@ember/service'; | |
const has = () => true; | |
const { console, WeakMap, Proxy, Symbol } = window; | |
const get = (target, key) => key === Symbol.unscopables ? undefined : target[key]; | |
export default Service.extend({ | |
sandboxes: new WeakMap(), | |
globals: { console, Object }, | |
getSandboxKey(context) { | |
return context; | |
// return JSON.stringify(Object.keys(context)); | |
}, | |
createSandbox(/* globals */) { | |
return this.get('globals'); | |
// return Object.assign({}, globals, defaultGlobals); | |
}, | |
compileCode(src) { | |
src = `with (context) { ${src} }`; | |
let sandboxes = this.get('sandboxes'); | |
let code = new Function('context', src); | |
return (context) => { | |
let sandboxKey = this.getSandboxKey(context); | |
if (!sandboxes.has(sandboxKey)) { | |
let global = Object.create(null); | |
let proxy = new Proxy(context, { has, get }); | |
sandboxes.set(sandboxKey, { proxy, global }); | |
} | |
let { proxy, global } = sandboxes.get(sandboxKey); | |
return code.call(global, proxy); | |
}; | |
}, | |
runCode(src, globals) { | |
let sandbox = this.createSandbox(globals); | |
let code = this.compileCode(src); | |
return code(sandbox); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment