summaryrefslogtreecommitdiff
path: root/doc/api/vm.md
diff options
context:
space:
mode:
authorTimothy Gu <timothygu99@gmail.com>2018-08-18 14:04:05 -0400
committerTimothy Gu <timothygu99@gmail.com>2018-08-23 23:09:19 -0400
commit85c356c10eec14f96eaf92ffc9a8481b591e3652 (patch)
treec04257cb8f6770e0d9d5dbfe6e8a1f6e4c617dfe /doc/api/vm.md
parent349612b233a1af261991143b22e59461f075a987 (diff)
downloadandroid-node-v8-85c356c10eec14f96eaf92ffc9a8481b591e3652.tar.gz
android-node-v8-85c356c10eec14f96eaf92ffc9a8481b591e3652.tar.bz2
android-node-v8-85c356c10eec14f96eaf92ffc9a8481b591e3652.zip
src: implement query callbacks for vm
This allows using a Proxy object as the sandbox for a VM context. PR-URL: https://github.com/nodejs/node/pull/22390 Fixes: https://github.com/nodejs/node/issues/17480 Fixes: https://github.com/nodejs/node/issues/17481 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'doc/api/vm.md')
-rw-r--r--doc/api/vm.md42
1 files changed, 42 insertions, 0 deletions
diff --git a/doc/api/vm.md b/doc/api/vm.md
index e2e3eba0c1..defa029821 100644
--- a/doc/api/vm.md
+++ b/doc/api/vm.md
@@ -916,6 +916,48 @@ within which it can operate. The process of creating the V8 Context and
associating it with the `sandbox` object is what this document refers to as
"contextifying" the `sandbox`.
+## vm module and Proxy object
+
+Leveraging a `Proxy` object as the sandbox of a VM context could result in a
+very powerful runtime environment that intercepts all accesses to the global
+object. However, there are some restrictions in the JavaScript engine that one
+needs to be aware of to prevent unexpected results. In particular, providing a
+`Proxy` object with a `get` handler could disallow any access to the original
+global properties of the new VM context, as the `get` hook does not distinguish
+between the `undefined` value and "requested property is not present" &ndash;
+the latter of which would ordinarily trigger a lookup on the context global
+object.
+
+Included below is a sample for how to work around this restriction. It
+initializes the sandbox as a `Proxy` object without any hooks, only to add them
+after the relevant properties have been saved.
+
+```js
+'use strict';
+const { createContext, runInContext } = require('vm');
+
+function createProxySandbox(handlers) {
+ // Create a VM context with a Proxy object with no hooks specified.
+ const sandbox = {};
+ const proxyHandlers = {};
+ const contextifiedProxy = createContext(new Proxy(sandbox, proxyHandlers));
+
+ // Save the initial globals onto our sandbox object.
+ const contextThis = runInContext('this', contextifiedProxy);
+ for (const prop of Reflect.ownKeys(contextThis)) {
+ const descriptor = Object.getOwnPropertyDescriptor(contextThis, prop);
+ Object.defineProperty(sandbox, prop, descriptor);
+ }
+
+ // Now that `sandbox` contains all the initial global properties, assign the
+ // provided handlers to the handlers we used to create the Proxy.
+ Object.assign(proxyHandlers, handlers);
+
+ // Return the created contextified Proxy object.
+ return contextifiedProxy;
+}
+```
+
[`Error`]: errors.html#errors_class_error
[`URL`]: url.html#url_class_url
[`eval()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval