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

url: Cannot load ESM module with newline in file name #23696

Closed
demurgos opened this issue Oct 16, 2018 · 11 comments
Closed

url: Cannot load ESM module with newline in file name #23696

demurgos opened this issue Oct 16, 2018 · 11 comments
Labels
confirmed-bug Issues with confirmed bugs. whatwg-url Issues and PRs related to the WHATWG URL implementation.

Comments

@demurgos
Copy link
Contributor

  • Version: 10.12.0
  • Platform: Linux 64 bit
  • Subsystem: Modules

Node fails to load ESM entry points if their filename contains a newline character. This is a regression compared to the current commonjs modules.

The following code fails:

fs.writeFileSync("foo\nbar.mjs", "console.log('Hello, World!');\n");
const spawnRes = cp.spawnSync(process.execPath, ["--experimental-modules", "foo\nbar.mjs"]);
assert(spawnRes.status === 0);
console.error(spawnRew.stderr.toString("UTF-8"));

Expected: no failed assertion, nothing in stderr (appart from the warning that ESM is experimental).
Actual: Failed assertion. Stderr contains:

Error: Cannot find module /tmp/tmp-59206v9LQ3sEjvCA/foobar.mjs
    at search (internal/modules/esm/default_resolve.js:28:12)
    at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:64:11)
    at Loader.resolve (internal/modules/esm/loader.js:58:33)
    at Loader.getModuleJob (internal/modules/esm/loader.js:113:40)
    at Loader.import (internal/modules/esm/loader.js:99:28)
    at asyncESM.loaderPromise.then (internal/modules/cjs/loader.js:734:27)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:745:11)
    at startup (internal/bootstrap/node.js:279:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:752:3) code: 'MODULE_NOT_FOUND'

Note that the error message does not even contain the newline in the file name.

For comparison, the following code using commonJS works fine:

fs.writeFileSync("foo\nbar.js", "console.log('Hello, World!');\n");
const spawnRes = cp.spawnSync(process.execPath, ["foo\nbar.js"]);
assert(spawnRes.status === 0);
console.error(spawnRew.stderr.toString("UTF-8"));
@devsnek
Copy link
Member

devsnek commented Oct 16, 2018

esm uses urls which apparently normalize out newlines, so you'll need to use %0A when you spawn

cp.spawnSync(process.execPath, ["--experimental-modules", "foo%0Abar.mjs"]

@demurgos
Copy link
Contributor Author

demurgos commented Oct 16, 2018

Using your code seems to lead to double-escaping. It still fails. Here is the error message:

Error: Cannot find module /tmp/tmp-59206v9LQ3sEjvCA/foo%250Abar.mjs
...

Furthermore, requiring to escape newlines when spawning a process would not be consistent: am I supplying a relative URL or a system-dependent path? I assume it is a system path. I can successfully pass foo#bar.mjs, foo?bar.mjs, foo bar.mjs (without escaping: as I would for CJS modules).

I am writing a module to convert import.meta.url to the corresponding __filename (file URL to sys-path) and trying a few edge cases. Only newlines cause errors.

@guybedford
Copy link
Contributor

This sounds like a bug to me - the conversion into a URL of the initial path should be /tmp/tmp-59206v9LQ3sEjvCA/foo%0Abar.mjs, which is supposed to be done at https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L752.

@demurgos
Copy link
Contributor Author

The bug is in the URL#pathname setter:

const url = new URL("file://");
url.pathname = "/foo\nbar";
console.log(url.toString());
// actual: file:///foobar
// expected: file:///foo%0Abar

@targos targos added the whatwg-url Issues and PRs related to the WHATWG URL implementation. label Oct 16, 2018
@targos
Copy link
Member

targos commented Oct 16, 2018

/cc @nodejs/url

Given:

var url = new URL("http://www.example.com/")
url.pathname = 'foo\nbar';
url.href
  • Node and the whatwg-url output 'http://www.example.com/foobar'
  • Chrome outputs 'http://www.example.com/foo%0Abar'

@jasnell
Copy link
Member

jasnell commented Oct 16, 2018

Interesting... yeah Edge, Firefox, and Chrome all produce foo%0Abar for this.

/cc @nodejs/url

@jasnell jasnell added the confirmed-bug Issues with confirmed bugs. label Oct 16, 2018
@domenic
Copy link
Contributor

domenic commented Oct 16, 2018

If 3/4 browsers all give an answer different from the spec, filing an issue at https://github.com/whatwg/url is a good idea.

That said, in general I'm not sure you should expect arbitrary strings to round-trip through URL parsing and serialization, so there may be a more fundamental issue here. (I haven't read the whole thread.)

@demurgos
Copy link
Contributor Author

demurgos commented Oct 16, 2018

Seems to be related to this line in the spec:

<li><p>Remove all <a>ASCII tab or newline</a> from <var>input</var>.

I confirm that files with a tab in their name also fail. I'll open a issue on the whatwg repo. Chrome and Firefox do not remove tabs and newlines.

Edit: whatwg/url#419

@demurgos demurgos changed the title Modules: Cannot load ESM module with new line in file name Modules: Cannot load ESM module with newline in file name Oct 16, 2018
@demurgos
Copy link
Contributor Author

This bug also occurs with TAB and CR characters. I have a patch that fixes it by percent-encoding these characters before passing them to the pathname setter.

@demurgos demurgos changed the title Modules: Cannot load ESM module with newline in file name url: Cannot load ESM module with newline in file name Oct 17, 2018
@Trott
Copy link
Member

Trott commented Nov 18, 2018

Am I correct to conclude that Node.js is spec-compliant in its treatment of newlines in ES Module paths, although multiple browsers are not? (If so, should this be closed, as the bug is either in the spec or in the browser implementations and not Node.js?)

@guybedford
Copy link
Contributor

@Trott it's a spec concern at this point, yes. But this issue should stay open while the root spec issue at whatwg/url#419 remains unresolved, as which way that goes would determine whether or not this should be a Node bug.

demurgos added a commit to demurgos/node that referenced this issue Nov 22, 2018
@Trott Trott closed this as completed in ef0c178 Dec 5, 2018
BridgeAR pushed a commit that referenced this issue Dec 6, 2018
Fixes: #23696

PR-URL: #23720
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Guy Bedford <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
BridgeAR pushed a commit that referenced this issue Dec 7, 2018
Fixes: #23696

PR-URL: #23720
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Guy Bedford <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
BridgeAR pushed a commit that referenced this issue Dec 7, 2018
Fixes: #23696

PR-URL: #23720
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Guy Bedford <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
refack pushed a commit to refack/node that referenced this issue Jan 14, 2019
Fixes: nodejs#23696

PR-URL: nodejs#23720
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Guy Bedford <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
BethGriggs pushed a commit that referenced this issue Apr 8, 2019
Fixes: #23696

PR-URL: #23720
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Guy Bedford <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. whatwg-url Issues and PRs related to the WHATWG URL implementation.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants