Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm: Function declarations should use [[Define]] instead of [[Set]] on the global object #31808

Open
ExE-Boss opened this issue Feb 15, 2020 · 4 comments
Labels
v8 engine Issues and PRs related to the V8 dependency. vm Issues and PRs related to the vm subsystem.

Comments

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Feb 15, 2020

  • Version: v13.8.0
  • Platform: All; tested on Travis CI (Ubuntu 16.04.6 LTS)
  • Subsystem: vm

What steps will reproduce the bug?

const vm = require("vm");

let impl = { status: "" };
let ctx = vm.createContext();
Object.defineProperty(ctx, "status", {
	configurable: true,
	enumerable: true,
	get() {
		return impl.status;
	}
	set(v) {
		impl.status = `${v}`;
	}
};

// https://github.com/web-platform-tests/wpt/blob/master/xhr/status-async.htm
vm.runInContext(`
function statusRequest(...args) {
	console.log(args.map(JSON.stringify).join("\t"));
}
function status(code, text, content, type) {
	statusRequest("GET", code, text, content, type);
	statusRequest("HEAD", code, text, content, type);
	statusRequest("CHICKEN", code, text, content, type);
}
status(204, "UNICORNSWIN", "", "")
status(401, "OH HELLO", "Not today.", "")
status(402, "FIVE BUCKS", "<x>402<\/x>", "text/xml")
status(402, "FREE", "Nice!", "text/doesnotmatter")
status(402, "402 TEH AWESOME", "", "")
status(502, "YO", "", "")
status(502, "lowercase", "SWEET POTATO", "text/plain")
status(503, "HOUSTON WE HAVE A", "503", "text/plain")
status(699, "WAY OUTTA RANGE", "699", "text/plain")
`, ctx);

How often does it reproduce? Is there a required condition?

Always.

What is the expected behavior?

The functions get defined using [[DefineOwnProperty]] as specified in ECMA‑262 § 8.1.1.4.18 CreateGlobalFunctionBinding.

Expected log output
"GET" 204 "UNICORNSWIN" "" ""
"HEAD" 204 "UNICORNSWIN" "" ""
"CHICKEN" 204 "UNICORNSWIN" "" ""
"GET" 401 "OH HELLO" "Not today." ""
"HEAD" 401 "OH HELLO" "Not today." ""
"CHICKEN" 401 "OH HELLO" "Not today." ""
"GET" 402 "FIVE BUCKS" "402" "text/xml"
"HEAD" 402 "FIVE BUCKS" "402" "text/xml"
"CHICKEN" 402 "FIVE BUCKS" "402" "text/xml"
"GET" 402 "FREE" "Nice!" "text/doesnotmatter"
"HEAD" 402 "FREE" "Nice!" "text/doesnotmatter"
"CHICKEN" 402 "FREE" "Nice!" "text/doesnotmatter"
"GET" 402 "402 TEH AWESOME" "" ""
"HEAD" 402 "402 TEH AWESOME" "" ""
"CHICKEN" 402 "402 TEH AWESOME" "" ""
"GET" 502 "YO" "" ""
"HEAD" 502 "YO" "" ""
"CHICKEN" 502 "YO" "" ""
"GET" 502 "lowercase" "SWEET POTATO" "text/plain"
"HEAD" 502 "lowercase" "SWEET POTATO" "text/plain"
"CHICKEN" 502 "lowercase" "SWEET POTATO" "text/plain"
"GET" 503 "HOUSTON WE HAVE A" "503" "text/plain"
"HEAD" 503 "HOUSTON WE HAVE A" "503" "text/plain"
"CHICKEN" 503 "HOUSTON WE HAVE A" "503" "text/plain"
"GET" 699 "WAY OUTTA RANGE" "699" "text/plain"
"HEAD" 699 "WAY OUTTA RANGE" "699" "text/plain"
"CHICKEN" 699 "WAY OUTTA RANGE" "699" "text/plain"

What do you see instead?

evalmachine.<anonymous>:10
status(204, "UNICORNSWIN", "", "")
^

Uncaught TypeError: status is not a function
    at evalmachine.<anonymous>:10:1
    at Script.runInContext (vm.js:131:20)
    at Object.runInContext (vm.js:295:6)
    at repl:1:4
    at Script.runInThisContext (vm.js:120:20)
    at REPLServer.defaultEval (repl.js:432:29)
    at bound (domain.js:429:14)
    at REPLServer.runBound [as eval] (domain.js:442:12)
    at REPLServer.onLine (repl.js:759:10)
    at REPLServer.emit (events.js:333:22)

Additional information

Discovered in: jsdom/jsdom#2835 (comment)

See also

@ExE-Boss
Copy link
Contributor Author

Well, window.status does get replaced by function declarations in browsers, which is why xhr/status‑async.htm passes in web browsers.

@devsnek devsnek added v8 engine Issues and PRs related to the V8 dependency. vm Issues and PRs related to the vm subsystem. labels Feb 15, 2020
@devsnek
Copy link
Member

devsnek commented Feb 15, 2020

This is fixed by 30709

@devsnek devsnek mentioned this issue Feb 15, 2020
4 tasks
@ExE-Boss
Copy link
Contributor Author

#30709 should include tests for this.

devsnek added a commit to devsnek/node that referenced this issue Feb 17, 2020
addaleax pushed a commit that referenced this issue Jul 15, 2020
Refs: #31808

PR-URL: #34032
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
cjihrig pushed a commit that referenced this issue Jul 23, 2020
Refs: #31808

PR-URL: #34032
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
MylesBorins pushed a commit that referenced this issue Jul 27, 2020
Refs: #31808

PR-URL: #34032
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
addaleax pushed a commit that referenced this issue Sep 22, 2020
Refs: #31808

PR-URL: #34032
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
addaleax pushed a commit that referenced this issue Sep 22, 2020
Refs: #31808

PR-URL: #34032
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
@ExE-Boss
Copy link
Contributor Author

@Mesteery Does this test pass?

'use strict';
// https://github.com/nodejs/node/issues/31808
// function declarations currently call [[Set]] instead of [[DefineOwnProperty]]
// in VM contexts, which violates the ECMA-262 specification:
// https://tc39.es/ecma262/#sec-createglobalfunctionbinding
const common = require('../common');
const vm = require('vm');
const assert = require('assert');
const ctx = vm.createContext();
Object.defineProperty(ctx, 'x', {
enumerable: true,
configurable: true,
get: common.mustNotCall('ctx.x getter must not be called'),
set: common.mustNotCall('ctx.x setter must not be called'),
});
vm.runInContext('function x() {}', ctx);
assert.strictEqual(typeof ctx.x, 'function');

If not, then this issue should remain open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v8 engine Issues and PRs related to the V8 dependency. vm Issues and PRs related to the vm subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants