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

Cannot redefine onmessage in strict mode from Node.js 18 #3546

Closed
Enet4 opened this issue May 10, 2023 · 1 comment
Closed

Cannot redefine onmessage in strict mode from Node.js 18 #3546

Enet4 opened this issue May 10, 2023 · 1 comment

Comments

@Enet4
Copy link

Enet4 commented May 10, 2023

Basic info:

  • Node.js version: 18.16.0
  • jsdom version: 22.0.0

The short description is that assignments such as window.onmessage = null; will raise an error when in a scope with "use strict", but only starting from Node.js 18.

Minimal reproduction case

const {JSDOM} = require('jsdom');
const virtualConsole = new jsdom.VirtualConsole();

virtualConsole.on("jsdomError", (e) => {
    console.error("JS DOM error:", e);
});

const dom = new JSDOM(`
<!doctype html>
<script>
"use strict";
var onMessage = window.onmessage;
window.onmessage = onMessage;
</script>
`, {
    virtualConsole,
    runScripts: 'dangerously'
});

This code raises a jsdom error when run in Node.js 18, although it completes fine in Node.js 16.20.0.
The error reported is:

JS DOM error: Error: Uncaught [TypeError: Cannot redefine property: onmessage]
    at reportException (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
    at processJavaScript (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:240:7)
    at HTMLScriptElementImpl._innerEval (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:173:5)
    at ...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:114:12
    at ResourceQueue.push (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\browser\resources\resource-queue.js:53:16)
    at HTMLScriptElementImpl._fetchInternalScript (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:113:21)
    at HTMLScriptElementImpl._eval (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:167:12) 
    at HTMLScriptElementImpl._poppedOffStackOfOpenElements (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:130:10)
    at JSDOMParse5Adapter.onItemPop (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\browser\parser\html.js:175:43)
    at Parser.onItemPop (...\use-jsdom-setimmediate\node_modules\parse5\dist\cjs\parser\index.js:158:90) {
  detail: TypeError: Cannot redefine property: onmessage
      at about:blank:5:18
      at Script.runInContext (node:vm:141:12)
      at Object.runInContext (node:vm:291:6)
      at processJavaScript (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:238:10)
      at HTMLScriptElementImpl._innerEval (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:173:5)
      at ...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:114:12
      at ResourceQueue.push (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\browser\resources\resource-queue.js:53:16)
      at HTMLScriptElementImpl._fetchInternalScript (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:113:21)
      at HTMLScriptElementImpl._eval (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:167:12)
      at HTMLScriptElementImpl._poppedOffStackOfOpenElements (...\use-jsdom-setimmediate\node_modules\jsdom\lib\jsdom\living\nodes\HTMLScriptElement-impl.js:130:10),
  type: 'unhandled exception'
}

How does similar code behave in browsers?

The equivalent code in a jsbin snippet runs without problems in Chrome and Firefox: https://jsbin.com/zexenokozi/1/edit?html,output

It is worth noting that this is a simplification of what happens in package setimmediate to detect the capabilities of the global function postMessage. The module setImmediate.js hasn't changed in 7 years, and I could not find anything suggesting that this assignment should be illegal in strict mode.

@domenic
Copy link
Member

domenic commented May 11, 2023

Yep, I noticed this a while ago. This is a Node.js bug, which does not appear in other versions of Node.js. I wasn't able to create a small reproduction case (using just vm) to file on nodejs/node. But I think it's nodejs/node#47563, which says

That bug was fixed by nodejs/node#46615 but it hasn't been back-ported to v18.x yet. That happens automatically after some time so it'll likely show up in a release in the next few weeks. You can follow the linked pull request to get notified.

Anyway, there's nothing we can do on the jsdom side about this.

@domenic domenic closed this as completed May 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants