vm: Function declarations should use [[Define]] instead of [[Set]] on the global object
- 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)