Loading an empty externalized builtin aborts the process
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 122k
- Forks
- 37.3k
- Avg merge
- 4d 2h
- Merged PRs (30d)
- 283
Description
Version
latest main branch
Platform
7.1.4-arch1-1
Subsystem
No response
What steps will reproduce the bug?
Build Node.js using --node-builtin-modules-path:
./configure --node-builtin-modules-path=/path/to/node/source
make -j4
Replace a builtin source file with an empty file, then load that builtin:
/path/to/node/source/lib/path.js
out/Release/node -e "require('path')"
The same issue can occur when an empty file is supplied through one of the
shared builtin path options, such as:
--shared-builtin-undici/undici-path
--shared-builtin-amaro/dist/index-path
How often does it reproduce? Is there a required condition?
Every
What is the expected behavior? Why is that the expected behavior?
An empty builtin source should be represented as an empty V8 string.If the empty source is not a valid implementation of that builtin, Node.js may subsequently report a normal JavaScript compilation or runtime error, but it should not terminate due to a native V8 CHECK.
What do you see instead?
The process aborts in v8::String::NewExternalTwoByte() because V8 checks that the external string resource has a non-null data pointer:
Additional information
That check was removed during the external resource lifetime refactoring in PR #47055.
PR #60518 later changed the --node-builtin-modules-path loader to use AddExternalizedBuiltin(), exposing the same issue through dynamically loaded builtin modules. Before that change, this path used String::NewFromUtf8(),which handled empty source files.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the abort with --node-builtin-modules-path and an empty lib/path.js, then inspect the loader path using AddExternalizedBuiltin(). Check the shared builtin path options as well. Done means an empty builtin becomes an empty V8 string without a native CHECK abort; later JavaScript compilation or runtime errors may remain normal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100