Skip to content

Commit

Permalink
src: use new V8 API in vm module
Browse files Browse the repository at this point in the history
Remove the CopyProperties() hack in the vm module, i.e., Contextify.
Use different V8 API methods, that allow interception of
DefineProperty() and do not flatten accessor descriptors to
property descriptors.

Move many known issues to test cases. Factor out the last test in
test-vm-context.js for
nodejs#10223
into its own file, test-vm-strict-assign.js.

Part of this CL is taken from a stalled PR by
https://github.com/AnnaMag
nodejs#13265

This PR requires a backport of
https://chromium.googlesource.com/v8/v8/+/37a3a15c3e52e2146e45f41c427f24414e4d7f6f

Refs: nodejs#6283
Refs: nodejs#15114
Refs: nodejs#13265

Fixes: nodejs#2734
Fixes: nodejs#10223
Fixes: nodejs#11803
Fixes: nodejs#11902
  • Loading branch information
fhinkel committed Oct 23, 2017
1 parent 801e61a commit f7d22e5
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 195 deletions.
303 changes: 183 additions & 120 deletions src/node_contextify.cc

Large diffs are not rendered by default.

25 changes: 0 additions & 25 deletions test/known_issues/test-vm-attributes-property-not-on-sandbox.js

This file was deleted.

18 changes: 18 additions & 0 deletions test/parallel/test-vm-attributes-property-not-on-sandbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
require('../common');
const assert = require('assert');
const vm = require('vm');

// Assert that accessor descriptors are not flattened on the sandbox.
// Issue: https://github.com/nodejs/node/issues/2734
const sandbox = {};
vm.createContext(sandbox);
const code = `Object.defineProperty(
this,
'foo',
{ get: function() {return 17} }
);
var desc = Object.getOwnPropertyDescriptor(this, 'foo');`;

vm.runInContext(code, sandbox);
assert.strictEqual(typeof sandbox.desc.get, 'function');
13 changes: 0 additions & 13 deletions test/parallel/test-vm-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,3 @@ assert.throws(() => {
// https://github.com/nodejs/node/issues/6158
ctx = new Proxy({}, {});
assert.strictEqual(typeof vm.runInNewContext('String', ctx), 'function');

// https://github.com/nodejs/node/issues/10223
ctx = vm.createContext();
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx);
assert.strictEqual(ctx.x, 42);
assert.strictEqual(vm.runInContext('x', ctx), 42);

vm.runInContext('x = 0', ctx); // Does not throw but x...
assert.strictEqual(vm.runInContext('x', ctx), 42); // ...should be unaltered.

assert.throws(() => vm.runInContext('"use strict"; x = 0', ctx),
/Cannot assign to read only property 'x'/);
assert.strictEqual(vm.runInContext('x', ctx), 42);
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,22 @@ const assert = require('assert');

const context = vm.createContext({});

const code = `
let code = `
Object.defineProperty(this, 'foo', {value: 5});
Object.getOwnPropertyDescriptor(this, 'foo');
`;

const desc = vm.runInContext(code, context);
let desc = vm.runInContext(code, context);

assert.strictEqual(desc.writable, false);

// Check that interceptors work for symbols.
code = `
const bar = Symbol('bar');
Object.defineProperty(this, bar, {value: 6});
Object.getOwnPropertyDescriptor(this, bar);
`;

desc = vm.runInContext(code, context);

assert.strictEqual(desc.value, 6);
File renamed without changes.
2 changes: 1 addition & 1 deletion test/parallel/test-vm-global-define-property.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ assert(res);
assert.strictEqual(typeof res, 'object');
assert.strictEqual(res, x);
assert.strictEqual(o.f, res);
assert.deepStrictEqual(Object.keys(o), ['console', 'x', 'g', 'f']);
assert.deepStrictEqual(Object.keys(o), ['console', 'x', 'f', 'g']);
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const vm = require('vm');

const ctx = vm.createContext();
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx);
assert.strictEqual(ctx.x, undefined); // Not copied out by cloneProperty().
assert.strictEqual(vm.runInContext('x', ctx), 42);
vm.runInContext('x = 0', ctx); // Does not throw but x...
assert.strictEqual(vm.runInContext('x', ctx), 42); // ...should be unaltered.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
'use strict';

// Sandbox throws in CopyProperties() despite no code being run
// Issue: https://github.com/nodejs/node/issues/11902


require('../common');
const assert = require('assert');
const vm = require('vm');

// Check that we do not accidentally query attributes.
// Issue: https://github.com/nodejs/node/issues/11902
const handler = {
getOwnPropertyDescriptor: (target, prop) => {
throw new Error('whoops');
Expand All @@ -16,5 +13,4 @@ const handler = {
const sandbox = new Proxy({ foo: 'bar' }, handler);
const context = vm.createContext(sandbox);


assert.doesNotThrow(() => vm.runInContext('', context));
20 changes: 20 additions & 0 deletions test/parallel/test-vm-strict-assign.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';
require('../common');
const assert = require('assert');

const vm = require('vm');

// https://github.com/nodejs/node/issues/10223
const ctx = vm.createContext();

// Define x with writable = false.
vm.runInContext('Object.defineProperty(this, "x", { value: 42 })', ctx);
assert.strictEqual(ctx.x, 42);
assert.strictEqual(vm.runInContext('x', ctx), 42);

vm.runInContext('x = 0', ctx); // Does not throw but x...
assert.strictEqual(vm.runInContext('x', ctx), 42); // ...should be unaltered.

assert.throws(() => vm.runInContext('"use strict"; x = 0', ctx),
/Cannot assign to read only property 'x'/);
assert.strictEqual(vm.runInContext('x', ctx), 42);
27 changes: 0 additions & 27 deletions test/parallel/test-vm-strict-mode.js

This file was deleted.

0 comments on commit f7d22e5

Please sign in to comment.