mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
vm: reject in importModuleDynamically without --experimental-vm-modules
Users cannot access any API that can be used to return a module or module namespace in this callback without --experimental-vm-modules anyway, so this would eventually lead to a rejection. This patch rejects in this case with our own error message and use a constant host-defined option for the rejection, so that scripts with the same source can still be compiled using the compilation cache if no `import()` is actually called in the script. PR-URL: https://github.com/nodejs/node/pull/50137 Refs: https://github.com/nodejs/node/issues/35375 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
committed by
Node.js GitHub Bot
parent
a3407b4ee8
commit
c2d79208d6
@@ -2981,6 +2981,12 @@ An attempt was made to use something that was already closed.
|
||||
While using the Performance Timing API (`perf_hooks`), no valid performance
|
||||
entry types are found.
|
||||
|
||||
<a id="ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG"></a>
|
||||
|
||||
### `ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`
|
||||
|
||||
A dynamic import callback was invoked without `--experimental-vm-modules`.
|
||||
|
||||
<a id="ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING"></a>
|
||||
|
||||
### `ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`
|
||||
|
||||
@@ -98,7 +98,9 @@ changes:
|
||||
when `import()` is called. If this option is not specified, calls to
|
||||
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
|
||||
This option is part of the experimental modules API. We do not recommend
|
||||
using it in a production environment.
|
||||
using it in a production environment. If `--experimental-vm-modules` isn't
|
||||
set, this callback will be ignored and calls to `import()` will reject with
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`][].
|
||||
* `specifier` {string} specifier passed to `import()`
|
||||
* `script` {vm.Script}
|
||||
* `importAssertions` {Object} The `"assert"` value passed to the
|
||||
@@ -760,6 +762,9 @@ changes:
|
||||
* `importModuleDynamically` {Function} Called during evaluation of this module
|
||||
when `import()` is called. If this option is not specified, calls to
|
||||
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
|
||||
If `--experimental-vm-modules` isn't set, this callback will be ignored
|
||||
and calls to `import()` will reject with
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`][].
|
||||
* `specifier` {string} specifier passed to `import()`
|
||||
* `module` {vm.Module}
|
||||
* `importAssertions` {Object} The `"assert"` value passed to the
|
||||
@@ -1018,7 +1023,9 @@ changes:
|
||||
when `import()` is called. If this option is not specified, calls to
|
||||
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
|
||||
This option is part of the experimental modules API, and should not be
|
||||
considered stable.
|
||||
considered stable. If `--experimental-vm-modules` isn't
|
||||
set, this callback will be ignored and calls to `import()` will reject with
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`][].
|
||||
* `specifier` {string} specifier passed to `import()`
|
||||
* `function` {Function}
|
||||
* `importAssertions` {Object} The `"assert"` value passed to the
|
||||
@@ -1242,7 +1249,9 @@ changes:
|
||||
when `import()` is called. If this option is not specified, calls to
|
||||
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
|
||||
This option is part of the experimental modules API. We do not recommend
|
||||
using it in a production environment.
|
||||
using it in a production environment. If `--experimental-vm-modules` isn't
|
||||
set, this callback will be ignored and calls to `import()` will reject with
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`][].
|
||||
* `specifier` {string} specifier passed to `import()`
|
||||
* `script` {vm.Script}
|
||||
* `importAssertions` {Object} The `"assert"` value passed to the
|
||||
@@ -1341,7 +1350,9 @@ changes:
|
||||
when `import()` is called. If this option is not specified, calls to
|
||||
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
|
||||
This option is part of the experimental modules API. We do not recommend
|
||||
using it in a production environment.
|
||||
using it in a production environment. If `--experimental-vm-modules` isn't
|
||||
set, this callback will be ignored and calls to `import()` will reject with
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`][].
|
||||
* `specifier` {string} specifier passed to `import()`
|
||||
* `script` {vm.Script}
|
||||
* `importAssertions` {Object} The `"assert"` value passed to the
|
||||
@@ -1421,7 +1432,9 @@ changes:
|
||||
when `import()` is called. If this option is not specified, calls to
|
||||
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
|
||||
This option is part of the experimental modules API. We do not recommend
|
||||
using it in a production environment.
|
||||
using it in a production environment. If `--experimental-vm-modules` isn't
|
||||
set, this callback will be ignored and calls to `import()` will reject with
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`][].
|
||||
* `specifier` {string} specifier passed to `import()`
|
||||
* `script` {vm.Script}
|
||||
* `importAssertions` {Object} The `"assert"` value passed to the
|
||||
@@ -1585,6 +1598,7 @@ are not controllable through the timeout either.
|
||||
[Source Text Module Record]: https://tc39.es/ecma262/#sec-source-text-module-records
|
||||
[Synthetic Module Record]: https://heycam.github.io/webidl/#synthetic-module-records
|
||||
[V8 Embedder's Guide]: https://v8.dev/docs/embed#contexts
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG`]: errors.md#err_vm_dynamic_import_callback_missing_flag
|
||||
[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`]: errors.md#err_vm_dynamic_import_callback_missing
|
||||
[`ERR_VM_MODULE_STATUS`]: errors.md#err_vm_module_status
|
||||
[`Error`]: errors.md#class-error
|
||||
|
||||
@@ -1821,6 +1821,9 @@ E('ERR_VALID_PERFORMANCE_ENTRY_TYPE',
|
||||
'At least one valid performance entry type is required', Error);
|
||||
E('ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING',
|
||||
'A dynamic import callback was not specified.', TypeError);
|
||||
E('ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG',
|
||||
'A dynamic import callback was invoked without --experimental-vm-modules',
|
||||
TypeError);
|
||||
E('ERR_VM_MODULE_ALREADY_LINKED', 'Module has already been linked', Error);
|
||||
E('ERR_VM_MODULE_CANNOT_CREATE_CACHED_DATA',
|
||||
'Cached data cannot be created for a module which has been evaluated', Error);
|
||||
|
||||
@@ -14,9 +14,11 @@ const {
|
||||
} = internalBinding('util');
|
||||
const {
|
||||
default_host_defined_options,
|
||||
vm_dynamic_import_missing_flag,
|
||||
} = internalBinding('symbols');
|
||||
|
||||
const {
|
||||
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG,
|
||||
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
|
||||
ERR_INVALID_ARG_VALUE,
|
||||
} = require('internal/errors').codes;
|
||||
@@ -132,7 +134,8 @@ const moduleRegistries = new SafeWeakMap();
|
||||
*/
|
||||
function registerModule(referrer, registry) {
|
||||
const idSymbol = referrer[host_defined_option_symbol];
|
||||
if (idSymbol === default_host_defined_options) {
|
||||
if (idSymbol === default_host_defined_options ||
|
||||
idSymbol === vm_dynamic_import_missing_flag) {
|
||||
// The referrer is compiled without custom callbacks, so there is
|
||||
// no registry to hold on to. We'll throw
|
||||
// ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING when a callback is
|
||||
@@ -173,6 +176,9 @@ async function importModuleDynamicallyCallback(symbol, specifier, attributes) {
|
||||
return importModuleDynamically(specifier, callbackReferrer, attributes);
|
||||
}
|
||||
}
|
||||
if (symbol === vm_dynamic_import_missing_flag) {
|
||||
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG();
|
||||
}
|
||||
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ const {
|
||||
} = ContextifyScript.prototype;
|
||||
const {
|
||||
default_host_defined_options,
|
||||
vm_dynamic_import_missing_flag,
|
||||
} = internalBinding('symbols');
|
||||
const {
|
||||
validateFunction,
|
||||
@@ -22,6 +23,11 @@ const {
|
||||
kValidateObjectAllowArray,
|
||||
} = require('internal/validators');
|
||||
|
||||
const {
|
||||
getOptionValue,
|
||||
} = require('internal/options');
|
||||
|
||||
|
||||
function isContext(object) {
|
||||
validateObject(object, 'object', kValidateObjectAllowArray);
|
||||
|
||||
@@ -41,6 +47,16 @@ function getHostDefinedOptionId(importModuleDynamically, filename) {
|
||||
// compilation cache can be hit.
|
||||
return default_host_defined_options;
|
||||
}
|
||||
// We should've thrown here immediately when we introduced
|
||||
// --experimental-vm-modules and importModuleDynamically, but since
|
||||
// users are already using this callback to throw a similar error,
|
||||
// we also defer the error to the time when an actual import() is called
|
||||
// to avoid breaking them. To ensure that the isolate compilation
|
||||
// cache can still be hit, use a constant sentinel symbol here.
|
||||
if (!getOptionValue('--experimental-vm-modules')) {
|
||||
return vm_dynamic_import_missing_flag;
|
||||
}
|
||||
|
||||
return Symbol(filename);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
V(owner_symbol, "owner_symbol") \
|
||||
V(onpskexchange_symbol, "onpskexchange") \
|
||||
V(resource_symbol, "resource_symbol") \
|
||||
V(trigger_async_id_symbol, "trigger_async_id_symbol")
|
||||
V(trigger_async_id_symbol, "trigger_async_id_symbol") \
|
||||
V(vm_dynamic_import_missing_flag, "vm_dynamic_import_missing_flag")
|
||||
|
||||
// Strings are per-isolate primitives but Environment proxies them
|
||||
// for the sake of convenience. Strings should be ASCII-only.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const { Script, compileFunction } = require('vm');
|
||||
const assert = require('assert');
|
||||
|
||||
assert(
|
||||
!process.execArgv.includes('--experimental-vm-modules'),
|
||||
'This test must be run without --experimental-vm-modules');
|
||||
|
||||
assert.rejects(async () => {
|
||||
const script = new Script('import("fs")', {
|
||||
importModuleDynamically: common.mustNotCall(),
|
||||
});
|
||||
const imported = script.runInThisContext();
|
||||
await imported;
|
||||
}, {
|
||||
code: 'ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG'
|
||||
}).then(common.mustCall());
|
||||
|
||||
assert.rejects(async () => {
|
||||
const imported = compileFunction('return import("fs")', [], {
|
||||
importModuleDynamically: common.mustNotCall(),
|
||||
})();
|
||||
await imported;
|
||||
}, {
|
||||
code: 'ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG'
|
||||
}).then(common.mustCall());
|
||||
Reference in New Issue
Block a user