Skip to content

Commit f971566

Browse files
seppevsaddaleax
authored andcommitted
module: standardize strip shebang behaviour
When loading a module, Node needs to finds the end of a shebang comment by searching for a \r or \n character. This behaviour is now standardized into a dedicated internal module function Refs: #12180 PR-URL: #12202 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent a2843f2 commit f971566

File tree

3 files changed

+41
-29
lines changed

3 files changed

+41
-29
lines changed

lib/internal/bootstrap_node.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,10 @@
449449
const vm = NativeModule.require('vm');
450450
const internalModule = NativeModule.require('internal/module');
451451

452-
// remove shebang and BOM
453-
source = internalModule.stripBOM(source.replace(/^#!.*/, ''));
452+
// remove Shebang
453+
source = internalModule.stripShebang(source);
454+
// remove BOM
455+
source = internalModule.stripBOM(source);
454456
// wrap it
455457
source = Module.wrap(source);
456458
// compile the script, this will throw if it fails

lib/internal/module.js

+35
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
exports = module.exports = {
44
makeRequireFunction,
55
stripBOM,
6+
stripShebang,
67
addBuiltinLibsToObject
78
};
89

@@ -50,6 +51,40 @@ function stripBOM(content) {
5051
return content;
5152
}
5253

54+
/**
55+
* Find end of shebang line and slice it off
56+
*/
57+
function stripShebang(content) {
58+
// Remove shebang
59+
var contLen = content.length;
60+
if (contLen >= 2) {
61+
if (content.charCodeAt(0) === 35/*#*/ &&
62+
content.charCodeAt(1) === 33/*!*/) {
63+
if (contLen === 2) {
64+
// Exact match
65+
content = '';
66+
} else {
67+
// Find end of shebang line and slice it off
68+
var i = 2;
69+
for (; i < contLen; ++i) {
70+
var code = content.charCodeAt(i);
71+
if (code === 10/*\n*/ || code === 13/*\r*/)
72+
break;
73+
}
74+
if (i === contLen)
75+
content = '';
76+
else {
77+
// Note that this actually includes the newline character(s) in the
78+
// new output. This duplicates the behavior of the regular expression
79+
// that was previously used to replace the shebang line
80+
content = content.slice(i);
81+
}
82+
}
83+
}
84+
}
85+
return content;
86+
}
87+
5388
exports.builtinLibs = [
5489
'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns',
5590
'domain', 'events', 'fs', 'http', 'https', 'net', 'os', 'path', 'punycode',

lib/module.js

+2-27
Original file line numberDiff line numberDiff line change
@@ -537,33 +537,8 @@ var resolvedArgv;
537537
// the file.
538538
// Returns exception, if any.
539539
Module.prototype._compile = function(content, filename) {
540-
// Remove shebang
541-
var contLen = content.length;
542-
if (contLen >= 2) {
543-
if (content.charCodeAt(0) === 35/*#*/ &&
544-
content.charCodeAt(1) === 33/*!*/) {
545-
if (contLen === 2) {
546-
// Exact match
547-
content = '';
548-
} else {
549-
// Find end of shebang line and slice it off
550-
var i = 2;
551-
for (; i < contLen; ++i) {
552-
var code = content.charCodeAt(i);
553-
if (code === 10/*\n*/ || code === 13/*\r*/)
554-
break;
555-
}
556-
if (i === contLen)
557-
content = '';
558-
else {
559-
// Note that this actually includes the newline character(s) in the
560-
// new output. This duplicates the behavior of the regular expression
561-
// that was previously used to replace the shebang line
562-
content = content.slice(i);
563-
}
564-
}
565-
}
566-
}
540+
541+
content = internalModule.stripShebang(content);
567542

568543
// create wrapper function
569544
var wrapper = Module.wrap(content);

0 commit comments

Comments
 (0)