Skip to content

Commit e2c0c0c

Browse files
committed
lib: rework logic of stripping BOM+Shebang from commonjs
Fixes#27767 PR-URL: #27768 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 73c16b1 commit e2c0c0c

13 files changed

Lines changed: 92 additions & 68 deletions

File tree

‎lib/internal/bootstrap/pre_execution.js‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ function initializePolicy() {
338338
}
339339

340340
functioninitializeCJSLoader(){
341-
require('internal/modules/cjs/loader')._initPaths();
341+
require('internal/modules/cjs/loader').Module._initPaths();
342342
}
343343

344344
functioninitializeESMLoader(){
@@ -387,7 +387,9 @@ function loadPreloadModules() {
387387
constpreloadModules=getOptionValue('--require');
388388
if(preloadModules){
389389
const{
390-
_preloadModules
390+
Module: {
391+
_preloadModules
392+
},
391393
}=require('internal/modules/cjs/loader');
392394
_preloadModules(preloadModules);
393395
}

‎lib/internal/main/check_syntax.js‎

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ const {
1313

1414
const{ pathToFileURL }=require('url');
1515

16-
constvm=require('vm');
1716
const{
18-
stripShebang, stripBOM
17+
stripShebangOrBOM,
1918
}=require('internal/modules/cjs/helpers');
2019

2120
const{
22-
_resolveFilename: resolveCJSModuleName,
23-
wrap: wrapCJSModule
21+
Module: {
22+
_resolveFilename: resolveCJSModuleName,
23+
},
24+
wrapSafe,
2425
}=require('internal/modules/cjs/loader');
2526

2627
// TODO(joyeecheung): not every one of these are necessary
@@ -49,9 +50,6 @@ if (process.argv[1] && process.argv[1] !== '-') {
4950
}
5051

5152
functioncheckSyntax(source,filename){
52-
// Remove Shebang.
53-
source=stripShebang(source);
54-
5553
const{ getOptionValue }=require('internal/options');
5654
constexperimentalModules=getOptionValue('--experimental-modules');
5755
if(experimentalModules){
@@ -70,10 +68,5 @@ function checkSyntax(source, filename) {
7068
}
7169
}
7270

73-
// Remove BOM.
74-
source=stripBOM(source);
75-
// Wrap it.
76-
source=wrapCJSModule(source);
77-
// Compile the script, this will throw if it fails.
78-
newvm.Script(source,{displayErrors: true, filename });
71+
wrapSafe(filename,stripShebangOrBOM(source));
7972
}

‎lib/internal/main/run_main_module.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const {
66

77
prepareMainThreadExecution(true);
88

9-
constCJSModule=require('internal/modules/cjs/loader');
9+
constCJSModule=require('internal/modules/cjs/loader').Module;
1010

1111
markBootstrapComplete();
1212

‎lib/internal/modules/cjs/helpers.js‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ function stripShebang(content) {
7272
returncontent;
7373
}
7474

75+
// Strip either the shebang or UTF BOM of a file.
76+
// Note that this only processes one. If both occur in
77+
// either order, the one that comes second is not
78+
// significant.
79+
functionstripShebangOrBOM(content){
80+
if(content.charCodeAt(0)===0xFEFF){
81+
returncontent.slice(1);
82+
}
83+
returnstripShebang(content);
84+
}
85+
7586
constbuiltinLibs=[
7687
'assert','async_hooks','buffer','child_process','cluster','crypto',
7788
'dgram','dns','domain','events','fs','http','http2','https','net',
@@ -137,5 +148,6 @@ module.exports = {
137148
makeRequireFunction,
138149
normalizeReferrerURL,
139150
stripBOM,
140-
stripShebang
151+
stripShebang,
152+
stripShebangOrBOM,
141153
};

‎lib/internal/modules/cjs/loader.js‎

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const {
4040
makeRequireFunction,
4141
normalizeReferrerURL,
4242
stripBOM,
43-
stripShebang
43+
stripShebangOrBOM,
4444
}=require('internal/modules/cjs/helpers');
4545
const{ getOptionValue }=require('internal/options');
4646
constpreserveSymlinks=getOptionValue('--preserve-symlinks');
@@ -59,7 +59,7 @@ const {
5959
const{ validateString }=require('internal/validators');
6060
constpendingDeprecation=getOptionValue('--pending-deprecation');
6161

62-
module.exports=Module;
62+
module.exports={ wrapSafe,Module};
6363

6464
letasyncESM;
6565
letModuleJob;
@@ -690,22 +690,10 @@ Module.prototype.require = function(id) {
690690
varresolvedArgv;
691691
lethasPausedEntry=false;
692692

693-
// Run the file contents in the correct scope or sandbox. Expose
694-
// the correct helper variables (require, module, exports) to
695-
// the file.
696-
// Returns exception, if any.
697-
Module.prototype._compile=function(content,filename){
698-
if(manifest){
699-
constmoduleURL=pathToFileURL(filename);
700-
manifest.assertIntegrity(moduleURL,content);
701-
}
702-
703-
content=stripShebang(content);
704-
705-
letcompiledWrapper;
693+
functionwrapSafe(filename,content){
706694
if(patched){
707695
constwrapper=Module.wrap(content);
708-
compiledWrapper=vm.runInThisContext(wrapper,{
696+
returnvm.runInThisContext(wrapper,{
709697
filename,
710698
lineOffset: 0,
711699
displayErrors: true,
@@ -714,35 +702,54 @@ Module.prototype._compile = function(content, filename) {
714702
returnloader.import(specifier,normalizeReferrerURL(filename));
715703
} : undefined,
716704
});
717-
}else{
718-
compiledWrapper=compileFunction(
719-
content,
720-
filename,
721-
0,
722-
0,
723-
undefined,
724-
false,
725-
undefined,
726-
[],
727-
[
728-
'exports',
729-
'require',
730-
'module',
731-
'__filename',
732-
'__dirname',
733-
]
734-
);
735-
if(experimentalModules){
736-
const{ callbackMap }=internalBinding('module_wrap');
737-
callbackMap.set(compiledWrapper,{
738-
importModuleDynamically: async(specifier)=>{
739-
constloader=awaitasyncESM.loaderPromise;
740-
returnloader.import(specifier,normalizeReferrerURL(filename));
741-
}
742-
});
743-
}
744705
}
745706

707+
constcompiledWrapper=compileFunction(
708+
content,
709+
filename,
710+
0,
711+
0,
712+
undefined,
713+
false,
714+
undefined,
715+
[],
716+
[
717+
'exports',
718+
'require',
719+
'module',
720+
'__filename',
721+
'__dirname',
722+
]
723+
);
724+
725+
if(experimentalModules){
726+
const{ callbackMap }=internalBinding('module_wrap');
727+
callbackMap.set(compiledWrapper,{
728+
importModuleDynamically: async(specifier)=>{
729+
constloader=awaitasyncESM.loaderPromise;
730+
returnloader.import(specifier,normalizeReferrerURL(filename));
731+
}
732+
});
733+
}
734+
735+
returncompiledWrapper;
736+
}
737+
738+
// Run the file contents in the correct scope or sandbox. Expose
739+
// the correct helper variables (require, module, exports) to
740+
// the file.
741+
// Returns exception, if any.
742+
Module.prototype._compile=function(content,filename){
743+
if(manifest){
744+
constmoduleURL=pathToFileURL(filename);
745+
manifest.assertIntegrity(moduleURL,content);
746+
}
747+
748+
// Strip after manifest integrity check
749+
content=stripShebangOrBOM(content);
750+
751+
constcompiledWrapper=wrapSafe(filename,content);
752+
746753
varinspectorWrapper=null;
747754
if(getOptionValue('--inspect-brk')&&process._eval==null){
748755
if(!resolvedArgv){
@@ -782,7 +789,7 @@ Module.prototype._compile = function(content, filename) {
782789
// Native extension for .js
783790
Module._extensions['.js']=function(module,filename){
784791
constcontent=fs.readFileSync(filename,'utf8');
785-
module._compile(stripBOM(content),filename);
792+
module._compile(content,filename);
786793
};
787794

788795

‎lib/internal/modules/esm/translators.js‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ const {
1111

1212
const{ NativeModule }=require('internal/bootstrap/loaders');
1313
const{
14-
stripShebang,
1514
stripBOM
1615
}=require('internal/modules/cjs/helpers');
17-
constCJSModule=require('internal/modules/cjs/loader');
16+
constCJSModule=require('internal/modules/cjs/loader').Module;
1817
constinternalURLModule=require('internal/url');
1918
constcreateDynamicModule=require(
2019
'internal/modules/esm/create_dynamic_module');
@@ -48,7 +47,7 @@ translators.set('module', async function moduleStrategy(url) {
4847
constsource=`${awaitreadFileAsync(newURL(url))}`;
4948
debug(`Translating StandardModule ${url}`);
5049
const{ ModuleWrap, callbackMap }=internalBinding('module_wrap');
51-
constmodule=newModuleWrap(stripShebang(source),url);
50+
constmodule=newModuleWrap(source,url);
5251
callbackMap.set(module,{
5352
initializeImportMeta,
5453
importModuleDynamically,

‎lib/internal/process/execution.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function evalModule(source, print) {
5353
}
5454

5555
functionevalScript(name,body,breakFirstLine,print){
56-
constCJSModule=require('internal/modules/cjs/loader');
56+
constCJSModule=require('internal/modules/cjs/loader').Module;
5757
const{ kVmBreakFirstLineSymbol }=require('internal/util');
5858

5959
constcwd=tryGetCwd();

‎lib/internal/util/inspector.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function sendInspectorCommand(cb, onError) {
2424
functioninstallConsoleExtensions(commandLineApi){
2525
if(commandLineApi.require){return;}
2626
const{ tryGetCwd }=require('internal/process/execution');
27-
constCJSModule=require('internal/modules/cjs/loader');
27+
constCJSModule=require('internal/modules/cjs/loader').Module;
2828
const{ makeRequireFunction }=require('internal/modules/cjs/helpers');
2929
constconsoleAPIModule=newCJSModule('<inspector console>');
3030
constcwd=tryGetCwd();

‎lib/module.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
'use strict';
22

3-
module.exports=require('internal/modules/cjs/loader');
3+
module.exports=require('internal/modules/cjs/loader').Module;

‎lib/repl.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const path = require('path');
6565
constfs=require('fs');
6666
const{ Interface }=require('readline');
6767
const{ Console }=require('console');
68-
constCJSModule=require('internal/modules/cjs/loader');
68+
constCJSModule=require('internal/modules/cjs/loader').Module;
6969
constdomain=require('domain');
7070
constdebug=require('internal/util/debuglog').debuglog('repl');
7171
const{

0 commit comments

Comments
 (0)