Skip to content

Commit 39db98c

Browse files
committed
module: apply null bytes check to module read path
PR-URL: #8277
1 parent de95b66 commit 39db98c

File tree

3 files changed

+73
-34
lines changed

3 files changed

+73
-34
lines changed

lib/fs.js

+3
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ function assertEncoding(encoding) {
130130
}
131131
}
132132

133+
// This is duplicated in module.js and needs to be moved to internal/fs.js
134+
// once it is OK again to include internal/ resources in fs.js.
135+
// See: https://github.com/nodejs/node/pull/6413
133136
function nullCheck(path, callback) {
134137
if (('' + path).indexOf('\u0000') !== -1) {
135138
var er = new Error('Path must be a string without null bytes');

lib/module.js

+18
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ function stat(filename) {
3434
stat.cache = null;
3535

3636

37+
// This is duplicated from fs.js and needs to be moved to internal/fs.js
38+
// once it is OK again to include internal/ resources in fs.js.
39+
// See: https://github.com/nodejs/node/pull/6413
40+
function nullCheck(path, callback) {
41+
if (('' + path).indexOf('\u0000') !== -1) {
42+
var er = new Error('Path must be a string without null bytes');
43+
er.code = 'ENOENT';
44+
if (typeof callback !== 'function')
45+
throw er;
46+
process.nextTick(callback, er);
47+
return false;
48+
}
49+
return true;
50+
}
51+
52+
3753
function Module(id, parent) {
3854
this.id = id;
3955
this.exports = {};
@@ -135,6 +151,8 @@ function tryExtensions(p, exts, isMain) {
135151

136152
var warned = false;
137153
Module._findPath = function(request, paths, isMain) {
154+
nullCheck(request);
155+
138156
if (path.isAbsolute(request)) {
139157
paths = [''];
140158
} else if (!paths || paths.length === 0) {

test/parallel/test-fs-null-bytes.js

+52-34
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,74 @@
22
var common = require('../common');
33
var assert = require('assert');
44
var fs = require('fs');
5+
var expectedError = /Path must be a string without null bytes/;
56

67
function check(async, sync) {
7-
var expected = /Path must be a string without null bytes/;
88
var argsSync = Array.prototype.slice.call(arguments, 2);
99
var argsAsync = argsSync.concat(function(er) {
10-
assert(er && er.message.match(expected));
10+
assert(er && er.message.match(expectedError));
1111
assert.equal(er.code, 'ENOENT');
1212
});
1313

1414
if (sync)
1515
assert.throws(function() {
16-
console.error(sync.name, argsSync);
17-
sync.apply(null, argsSync);
18-
}, expected);
16+
console.error(`fs.${sync}()`, argsSync);
17+
fs[sync].apply(null, argsSync);
18+
}, expectedError);
1919

20-
if (async)
21-
async.apply(null, argsAsync);
20+
if (async) {
21+
console.error(`fs.${async}()`, argsAsync);
22+
fs[async].apply(null, argsAsync);
23+
}
2224
}
2325

24-
check(fs.access, fs.accessSync, 'foo\u0000bar');
25-
check(fs.access, fs.accessSync, 'foo\u0000bar', fs.F_OK);
26-
check(fs.appendFile, fs.appendFileSync, 'foo\u0000bar');
27-
check(fs.chmod, fs.chmodSync, 'foo\u0000bar', '0644');
28-
check(fs.chown, fs.chownSync, 'foo\u0000bar', 12, 34);
29-
check(fs.link, fs.linkSync, 'foo\u0000bar', 'foobar');
30-
check(fs.link, fs.linkSync, 'foobar', 'foo\u0000bar');
31-
check(fs.lstat, fs.lstatSync, 'foo\u0000bar');
32-
check(fs.mkdir, fs.mkdirSync, 'foo\u0000bar', '0755');
33-
check(fs.open, fs.openSync, 'foo\u0000bar', 'r');
34-
check(fs.readFile, fs.readFileSync, 'foo\u0000bar');
35-
check(fs.readdir, fs.readdirSync, 'foo\u0000bar');
36-
check(fs.readlink, fs.readlinkSync, 'foo\u0000bar');
37-
check(fs.realpath, fs.realpathSync, 'foo\u0000bar');
38-
check(fs.rename, fs.renameSync, 'foo\u0000bar', 'foobar');
39-
check(fs.rename, fs.renameSync, 'foobar', 'foo\u0000bar');
40-
check(fs.rmdir, fs.rmdirSync, 'foo\u0000bar');
41-
check(fs.stat, fs.statSync, 'foo\u0000bar');
42-
check(fs.symlink, fs.symlinkSync, 'foo\u0000bar', 'foobar');
43-
check(fs.symlink, fs.symlinkSync, 'foobar', 'foo\u0000bar');
44-
check(fs.truncate, fs.truncateSync, 'foo\u0000bar');
45-
check(fs.unlink, fs.unlinkSync, 'foo\u0000bar');
46-
check(null, fs.unwatchFile, 'foo\u0000bar', common.fail);
47-
check(fs.utimes, fs.utimesSync, 'foo\u0000bar', 0, 0);
48-
check(null, fs.watch, 'foo\u0000bar', common.fail);
49-
check(null, fs.watchFile, 'foo\u0000bar', common.fail);
50-
check(fs.writeFile, fs.writeFileSync, 'foo\u0000bar');
26+
check('access', 'accessSync', 'foo\u0000bar');
27+
check('access', 'accessSync', 'foo\u0000bar', 'F_OK');
28+
check('appendFile', 'appendFileSync', 'foo\u0000bar');
29+
check('chmod', 'chmodSync', 'foo\u0000bar', '0644');
30+
check('chown', 'chownSync', 'foo\u0000bar', 12, 34);
31+
check('link', 'linkSync', 'foo\u0000bar', 'foobar');
32+
check('link', 'linkSync', 'foobar', 'foo\u0000bar');
33+
check('lstat', 'lstatSync', 'foo\u0000bar');
34+
check('mkdir', 'mkdirSync', 'foo\u0000bar', '0755');
35+
check('open', 'openSync', 'foo\u0000bar', 'r');
36+
check('readFile', 'readFileSync', 'foo\u0000bar');
37+
check('readdir', 'readdirSync', 'foo\u0000bar');
38+
check('readlink', 'readlinkSync', 'foo\u0000bar');
39+
check('realpath', 'realpathSync', 'foo\u0000bar');
40+
check('rename', 'renameSync', 'foo\u0000bar', 'foobar');
41+
check('rename', 'renameSync', 'foobar', 'foo\u0000bar');
42+
check('rmdir', 'rmdirSync', 'foo\u0000bar');
43+
check('stat', 'statSync', 'foo\u0000bar');
44+
check('symlink', 'symlinkSync', 'foo\u0000bar', 'foobar');
45+
check('symlink', 'symlinkSync', 'foobar', 'foo\u0000bar');
46+
check('truncate', 'truncateSync', 'foo\u0000bar');
47+
check('unlink', 'unlinkSync', 'foo\u0000bar');
48+
check(null, 'unwatchFile', 'foo\u0000bar', common.fail);
49+
check('utimes', 'utimesSync', 'foo\u0000bar', 0, 0);
50+
check(null, 'watch', 'foo\u0000bar', common.fail);
51+
check(null, 'watchFile', 'foo\u0000bar', common.fail);
52+
check('writeFile', 'writeFileSync', 'foo\u0000bar');
5153

5254
// an 'error' for exists means that it doesn't exist.
5355
// one of many reasons why this file is the absolute worst.
5456
fs.exists('foo\u0000bar', function(exists) {
5557
assert(!exists);
5658
});
5759
assert(!fs.existsSync('foo\u0000bar'));
60+
61+
function checkRequire(arg) {
62+
assert.throws(function() {
63+
console.error(`require(${JSON.stringify(arg)})`);
64+
require(arg);
65+
}, expectedError);
66+
}
67+
68+
checkRequire('\u0000');
69+
checkRequire('foo\u0000bar');
70+
checkRequire('foo\u0000');
71+
checkRequire('foo/\u0000');
72+
checkRequire('foo/\u0000.js');
73+
checkRequire('\u0000/foo');
74+
checkRequire('./foo/\u0000');
75+
checkRequire('./\u0000/foo');

0 commit comments

Comments
 (0)