X Tutup
The Wayback Machine - https://web.archive.org/web/20220323011133/https://github.com/nodejs/node/pull/35275
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

module: fix crash on multiline named cjs imports #35275

Closed

Conversation

ctavan
Copy link
Contributor

@ctavan ctavan commented Sep 20, 2020

The node process crashes when trying to parse a multiline import
statement for named exports of a CommonJS module:

TypeError: Cannot read property '0' of null
      at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77)
      at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
      at async Loader.import (internal/modules/esm/loader.js:165:24)
      at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
      at async waitForActual (assert.js:721:5)
      at async rejects (assert.js:830:25),

The reason is that the regexp that is currently used to decorate the
original error fails for multi line import statements.

Unfortunately the undecorated error stack only contains the single line
which causes the import to fail:

file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2
  comeOn,
  ^^^^^^
SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn'
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:141:5)
    at async Loader.import (internal/modules/esm/loader.js:165:24)
    at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
    at async waitForActual (assert.js:721:5)
    at async rejects (assert.js:830:25)

Hence, for multiline import statements we cannot create an equivalent
piece of code that uses default import followed by an object
destructuring assignment.

In any case the node process should definitely not crash. So until we
have a more sophisticated way of extracting the entire problematic
multiline import statement, show the code example only for single-line
imports where the current regexp approach works well.

Refs: #35259

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added the esm label Sep 20, 2020
@nodejs-github-bot
Copy link
Contributor

@nodejs-github-bot nodejs-github-bot commented Sep 20, 2020

Review requested:

Copy link
Member

@mcollina mcollina left a comment

lgtm

@addaleax addaleax added author ready request-ci labels Sep 20, 2020
@github-actions github-actions bot removed the request-ci label Sep 20, 2020
@nodejs-github-bot
Copy link
Contributor

@nodejs-github-bot nodejs-github-bot commented Sep 20, 2020

Copy link
Member

@MylesBorins MylesBorins left a comment

LGTM

tiny nit with the test to keep with the homestar runner theme, no need to land it 🤣

ctavan and others added 3 commits Sep 20, 2020
The node process crashes when trying to parse a multiline import
statement for named exports of a CommonJS module:

    TypeError: Cannot read property '0' of null
          at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77)
          at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
          at async Loader.import (internal/modules/esm/loader.js:165:24)
          at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
          at async waitForActual (assert.js:721:5)
          at async rejects (assert.js:830:25),

The reason is that the regexp that is currently used to decorate the
original error fails for multi line import statements.

Unfortunately the undecorated error stack only contains the single line
which causes the import to fail:

    file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2
      comeOn,
      ^^^^^^
    SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn'
        at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
        at async ModuleJob.run (internal/modules/esm/module_job.js:141:5)
        at async Loader.import (internal/modules/esm/loader.js:165:24)
        at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
        at async waitForActual (assert.js:721:5)
        at async rejects (assert.js:830:25)

Hence, for multiline import statements we cannot create an equivalent
piece of code that uses default import followed by an object
destructuring assignment.

In any case the node process should definitely not crash. So until we
have a more sophisticated way of extracting the entire problematic
multiline import statement, show the code example only for single-line
imports where the current regexp approach works well.

Refs: nodejs#35259
Co-authored-by: Myles Borins <mylesborins@github.com>
Co-authored-by: Myles Borins <mylesborins@github.com>
@ctavan ctavan force-pushed the fix-multiline-named-imports-of-cjs branch from e311be4 to af3b991 Compare Sep 20, 2020
Trott
Trott approved these changes Sep 22, 2020
@Trott Trott added request-ci and removed request-ci labels Sep 22, 2020
@github-actions github-actions bot removed the request-ci label Sep 22, 2020
@nodejs-github-bot
Copy link
Contributor

@nodejs-github-bot nodejs-github-bot commented Sep 22, 2020

MylesBorins added a commit that referenced this issue Sep 22, 2020
The node process crashes when trying to parse a multiline import
statement for named exports of a CommonJS module:

    TypeError: Cannot read property '0' of null
          at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77)
          at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
          at async Loader.import (internal/modules/esm/loader.js:165:24)
          at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
          at async waitForActual (assert.js:721:5)
          at async rejects (assert.js:830:25),

The reason is that the regexp that is currently used to decorate the
original error fails for multi line import statements.

Unfortunately the undecorated error stack only contains the single line
which causes the import to fail:

    file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2
      comeOn,
      ^^^^^^
    SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn'
        at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
        at async ModuleJob.run (internal/modules/esm/module_job.js:141:5)
        at async Loader.import (internal/modules/esm/loader.js:165:24)
        at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
        at async waitForActual (assert.js:721:5)
        at async rejects (assert.js:830:25)

Hence, for multiline import statements we cannot create an equivalent
piece of code that uses default import followed by an object
destructuring assignment.

In any case the node process should definitely not crash. So until we
have a more sophisticated way of extracting the entire problematic
multiline import statement, show the code example only for single-line
imports where the current regexp approach works well.

Refs: #35259

PR-URL: #35275
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@MylesBorins
Copy link
Member

@MylesBorins MylesBorins commented Sep 22, 2020

Landed in 219e9fe

MylesBorins added a commit that referenced this issue Sep 24, 2020
The node process crashes when trying to parse a multiline import
statement for named exports of a CommonJS module:

    TypeError: Cannot read property '0' of null
          at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77)
          at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
          at async Loader.import (internal/modules/esm/loader.js:165:24)
          at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
          at async waitForActual (assert.js:721:5)
          at async rejects (assert.js:830:25),

The reason is that the regexp that is currently used to decorate the
original error fails for multi line import statements.

Unfortunately the undecorated error stack only contains the single line
which causes the import to fail:

    file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2
      comeOn,
      ^^^^^^
    SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn'
        at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
        at async ModuleJob.run (internal/modules/esm/module_job.js:141:5)
        at async Loader.import (internal/modules/esm/loader.js:165:24)
        at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
        at async waitForActual (assert.js:721:5)
        at async rejects (assert.js:830:25)

Hence, for multiline import statements we cannot create an equivalent
piece of code that uses default import followed by an object
destructuring assignment.

In any case the node process should definitely not crash. So until we
have a more sophisticated way of extracting the entire problematic
multiline import statement, show the code example only for single-line
imports where the current regexp approach works well.

Refs: #35259

PR-URL: #35275
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
guybedford added a commit to guybedford/node that referenced this issue Sep 28, 2020
The node process crashes when trying to parse a multiline import
statement for named exports of a CommonJS module:

    TypeError: Cannot read property '0' of null
          at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77)
          at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
          at async Loader.import (internal/modules/esm/loader.js:165:24)
          at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
          at async waitForActual (assert.js:721:5)
          at async rejects (assert.js:830:25),

The reason is that the regexp that is currently used to decorate the
original error fails for multi line import statements.

Unfortunately the undecorated error stack only contains the single line
which causes the import to fail:

    file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2
      comeOn,
      ^^^^^^
    SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn'
        at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
        at async ModuleJob.run (internal/modules/esm/module_job.js:141:5)
        at async Loader.import (internal/modules/esm/loader.js:165:24)
        at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
        at async waitForActual (assert.js:721:5)
        at async rejects (assert.js:830:25)

Hence, for multiline import statements we cannot create an equivalent
piece of code that uses default import followed by an object
destructuring assignment.

In any case the node process should definitely not crash. So until we
have a more sophisticated way of extracting the entire problematic
multiline import statement, show the code example only for single-line
imports where the current regexp approach works well.

Refs: nodejs#35259

PR-URL: nodejs#35275
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@addaleax addaleax added the backport-open-v12.x label Sep 28, 2020
@MylesBorins MylesBorins mentioned this pull request Sep 29, 2020
codebytere added a commit that referenced this issue Oct 1, 2020
The node process crashes when trying to parse a multiline import
statement for named exports of a CommonJS module:

    TypeError: Cannot read property '0' of null
          at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77)
          at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
          at async Loader.import (internal/modules/esm/loader.js:165:24)
          at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
          at async waitForActual (assert.js:721:5)
          at async rejects (assert.js:830:25),

The reason is that the regexp that is currently used to decorate the
original error fails for multi line import statements.

Unfortunately the undecorated error stack only contains the single line
which causes the import to fail:

    file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2
      comeOn,
      ^^^^^^
    SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn'
        at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
        at async ModuleJob.run (internal/modules/esm/module_job.js:141:5)
        at async Loader.import (internal/modules/esm/loader.js:165:24)
        at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
        at async waitForActual (assert.js:721:5)
        at async rejects (assert.js:830:25)

Hence, for multiline import statements we cannot create an equivalent
piece of code that uses default import followed by an object
destructuring assignment.

In any case the node process should definitely not crash. So until we
have a more sophisticated way of extracting the entire problematic
multiline import statement, show the code example only for single-line
imports where the current regexp approach works well.

Refs: #35259

PR-URL: #35275
Backport-PR-URL: #35385
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@codebytere codebytere mentioned this pull request Oct 4, 2020
ctavan added a commit to ctavan/node that referenced this issue Oct 16, 2020
When trying to import named exports from a CommonJS module an error is
thrown. Unfortunately the V8 error only contains the single line that
causes the error, it is therefore impossible to construct an equivalent
code consisting of default import + object descructuring assignment.

This was the reason why the example code was removed for multi line
import statements in nodejs#35275

To generate a helpful error messages for any case we can parse the file
where the error happens using acorn and construct a valid example code
from the parsed ImportDeclaration. This will work for _any_ valid import
statement.

Since this code is only executed shortly before the node process crashes
anyways performance should not be a concern here.

Fixes: nodejs#35259
Refs: nodejs#35275
joesepi added a commit to joesepi/node that referenced this issue Jan 8, 2021
The node process crashes when trying to parse a multiline import
statement for named exports of a CommonJS module:

    TypeError: Cannot read property '0' of null
          at ModuleJob._instantiate (internal/modules/esm/module_job.js:112:77)
          at async ModuleJob.run (internal/modules/esm/module_job.js:137:5)
          at async Loader.import (internal/modules/esm/loader.js:165:24)
          at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
          at async waitForActual (assert.js:721:5)
          at async rejects (assert.js:830:25),

The reason is that the regexp that is currently used to decorate the
original error fails for multi line import statements.

Unfortunately the undecorated error stack only contains the single line
which causes the import to fail:

    file:///***/node/test/fixtures/es-modules/package-cjs-named-error/multi-line.mjs:2
      comeOn,
      ^^^^^^
    SyntaxError: The requested module './fail.cjs' does not provide an export named 'comeOn'
        at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
        at async ModuleJob.run (internal/modules/esm/module_job.js:141:5)
        at async Loader.import (internal/modules/esm/loader.js:165:24)
        at async rejects.name (file:///***/node/test/es-module/test-esm-cjs-named-error.mjs:56:3)
        at async waitForActual (assert.js:721:5)
        at async rejects (assert.js:830:25)

Hence, for multiline import statements we cannot create an equivalent
piece of code that uses default import followed by an object
destructuring assignment.

In any case the node process should definitely not crash. So until we
have a more sophisticated way of extracting the entire problematic
multiline import statement, show the code example only for single-line
imports where the current regexp approach works well.

Refs: nodejs#35259

PR-URL: nodejs#35275
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
ctavan added a commit to ctavan/node that referenced this issue Jan 29, 2021
When trying to import named exports from a CommonJS module an error is
thrown. Unfortunately the V8 error only contains the single line that
causes the error, it is therefore impossible to construct an equivalent
code consisting of default import + object descructuring assignment.

This was the reason why the example code was removed for multi line
import statements in nodejs#35275

To generate a helpful error messages for any case we can parse the file
where the error happens using acorn and construct a valid example code
from the parsed ImportDeclaration. This will work for _any_ valid import
statement.

Since this code is only executed shortly before the node process crashes
anyways performance should not be a concern here.

Fixes: nodejs#35259
Refs: nodejs#35275
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready backport-open-v12.x esm
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants
X Tutup