Skip to content
Permalink
Browse files

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 <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 4, 2017
1 parent a2843f2 commit f97156623a140c3bbeee91a038bb727f39fc5948
Showing with 41 additions and 29 deletions.
  1. +4 −2 lib/internal/bootstrap_node.js
  2. +35 −0 lib/internal/module.js
  3. +2 −27 lib/module.js
@@ -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
@@ -3,6 +3,7 @@
exports = module.exports = {
makeRequireFunction,
stripBOM,
stripShebang,
addBuiltinLibsToObject
};

@@ -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',
@@ -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);

0 comments on commit f971566

Please sign in to comment.
You can’t perform that action at this time.