Skip to content

Commit

Permalink
module: standardize strip shebang behaviour
Browse files Browse the repository at this point in the history
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 <info@bnoordhuis.nl>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
seppevs authored and addaleax committed Apr 19, 2017
1 parent a2843f2 commit f971566
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 29 deletions.
6 changes: 4 additions & 2 deletions lib/internal/bootstrap_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,10 @@
const vm = NativeModule.require('vm');
const internalModule = NativeModule.require('internal/module');

// remove shebang and BOM
source = internalModule.stripBOM(source.replace(/^#!.*/, ''));
// remove Shebang
source = internalModule.stripShebang(source);
// remove BOM
source = internalModule.stripBOM(source);
// wrap it
source = Module.wrap(source);
// compile the script, this will throw if it fails
Expand Down
35 changes: 35 additions & 0 deletions lib/internal/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports = module.exports = {
makeRequireFunction,
stripBOM,
stripShebang,
addBuiltinLibsToObject
};

Expand Down Expand Up @@ -50,6 +51,40 @@ function stripBOM(content) {
return content;
}

/**
* Find end of shebang line and slice it off
*/
function stripShebang(content) {
// Remove shebang
var contLen = content.length;
if (contLen >= 2) {
if (content.charCodeAt(0) === 35/*#*/ &&
content.charCodeAt(1) === 33/*!*/) {
if (contLen === 2) {
// Exact match
content = '';
} else {
// Find end of shebang line and slice it off
var i = 2;
for (; i < contLen; ++i) {
var code = content.charCodeAt(i);
if (code === 10/*\n*/ || code === 13/*\r*/)
break;
}
if (i === contLen)
content = '';
else {
// Note that this actually includes the newline character(s) in the
// new output. This duplicates the behavior of the regular expression
// that was previously used to replace the shebang line
content = content.slice(i);
}
}
}
}
return content;
}

exports.builtinLibs = [
'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns',
'domain', 'events', 'fs', 'http', 'https', 'net', 'os', 'path', 'punycode',
Expand Down
29 changes: 2 additions & 27 deletions lib/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -537,33 +537,8 @@ var resolvedArgv;
// the file.
// Returns exception, if any.
Module.prototype._compile = function(content, filename) {
// Remove shebang
var contLen = content.length;
if (contLen >= 2) {
if (content.charCodeAt(0) === 35/*#*/ &&
content.charCodeAt(1) === 33/*!*/) {
if (contLen === 2) {
// Exact match
content = '';
} else {
// Find end of shebang line and slice it off
var i = 2;
for (; i < contLen; ++i) {
var code = content.charCodeAt(i);
if (code === 10/*\n*/ || code === 13/*\r*/)
break;
}
if (i === contLen)
content = '';
else {
// Note that this actually includes the newline character(s) in the
// new output. This duplicates the behavior of the regular expression
// that was previously used to replace the shebang line
content = content.slice(i);
}
}
}
}

content = internalModule.stripShebang(content);

// create wrapper function
var wrapper = Module.wrap(content);
Expand Down

0 comments on commit f971566

Please sign in to comment.