Skip to content
This repository has been archived by the owner on Jan 13, 2024. It is now read-only.

Executable broken when called with PKG_EXECPATH set to its own absolute path #1565

Closed
0x2b3bfa0 opened this issue Mar 24, 2022 · 3 comments
Closed

Comments

@0x2b3bfa0
Copy link

0x2b3bfa0 commented Mar 24, 2022

What version of pkg are you using?

5.5.2

What version of Node.js are you using?

16.14.0

What operating system are you using?

Ubuntu 20.04

What CPU architecture are you using?

x86_64

What Node versions, OSs and CPU architectures are you building for?

node16-linux-x64

Describe the Bug

Calling an executable created with pkg with the PKG_EXECPATH environment variable set to the absolute path of the executable produces an error.

Expected Behavior

Setting the PKG_EXECPATH environment variable to the absolute path of the executable should not produce any error:

$ tee test.js <<< "console.log('test');"
console.log('test');
$ pkg test.js --target=node16-linux-x64 --output=test
[email protected]
$ ./test
test
$ PKG_EXECPATH=$(realpath test) ./test
test
$ PKG_EXECPATH=$(realpath test) ./test argument
test

To Reproduce

Setting the PKG_EXECPATH environment variable to the absolute path of the executable produces an error:

$ tee test.js <<< "console.log('test');"
console.log('test');
$ pkg test.js --target=node16-linux-x64 --output=test
[email protected]
$ ./test
test
$ PKG_EXECPATH=$(realpath test) ./test
pkg/prelude/bootstrap.js:1813
      if (error.code !== 'MODULE_NOT_FOUND') throw error;
                                             ^
TypeError: String.prototype.startsWith called on null or undefined
    at startsWith (<anonymous>)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:849:7)
    at Function._resolveFilename (pkg/prelude/bootstrap.js:1811:44)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Function.runMain (pkg/prelude/bootstrap.js:1847:12)
    at node:internal/main/run_main_module:17:47
$ PKG_EXECPATH=$(realpath test) ./test argument
node:internal/modules/cjs/loader:936
  throw err;
  ^
Error: Cannot find module '/path/to/current/directory/argument'
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function._resolveFilename (pkg/prelude/bootstrap.js:1819:46)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Function.runMain (pkg/prelude/bootstrap.js:1847:12)
    at node:internal/main/run_main_module:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}
@0x2b3bfa0
Copy link
Author

0x2b3bfa0 commented Mar 24, 2022

Explanation

pkg/prelude/bootstrap.js

Lines 77 to 89 in 2ef4cd9

if (process.env.PKG_EXECPATH === EXECPATH) {
process.argv.splice(1, 1);
if (process.argv[1] && process.argv[1] !== '-') {
// https://github.com/nodejs/node/blob/1a96d83a223ff9f05f7d942fb84440d323f7b596/lib/internal/bootstrap/node.js#L269
process.argv[1] = path.resolve(process.argv[1]);
}
} else {
process.argv[1] = DEFAULT_ENTRYPOINT;
}
[, ENTRYPOINT] = process.argv;
delete process.env.PKG_EXECPATH;

TypeError: String.prototype.startsWith called on null or undefined

  • Condition at line 77 is true (executable called with PKG_EXECPATH set to its own absolute path)
  • Condition at line 80 is false (executable called without arguments, or the first argument is a hyphen)
  • Value of process.argv[1] remains undefined because no other assignment is being made
  • Value of ENTRYPOINT becomes process.argv[1] at line 88

Error: Cannot find module '/path/to/current/directory/argument'

  • Condition at line 77 is true (executable called with PKG_EXECPATH set to its own absolute path)
  • Condition at line 80 is true (executable called with one or more arguments, and the first argument isn't a hyphen)
  • Value of process.argv[1] becomes path.resolve(process.argv[1])1
  • Value of ENTRYPOINT becomes process.argv[1] at line 88

Module._load(ENTRYPOINT, null, true);

Value of ENTRYPOINT (either undefined or a non–existent path) is used to call the _load function, producing an error.

Footnotes

  1. Namely, '/path/to/current/directory/argument'

@0x2b3bfa0
Copy link
Author

It turns out that there aren't other solutions apart from unsetting PKG_EXECPATH as proposed on #897. At least, I haven't found any.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant