Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added safeWrap() for fs functions that use the binding

Also, change the order in fs.watchFile to prevent putting non-working watchers
in statWatchers.
  • Loading branch information...
commit a37e74ef59cc7bbfa322eecbc20fbac1b34aefab 1 parent 3696a5c
Jann Horn authored
Showing with 91 additions and 60 deletions.
  1. +91 −60 lib/fs.js
151 lib/fs.js
View
@@ -206,7 +206,7 @@ function modeNum(m, def) {
}
}
-fs.open = function(path, flags, mode, callback) {
+fs.open = safeWrap(0, function(path, flags, mode, callback) {
callback = arguments[arguments.length - 1];
if (typeof(callback) !== 'function') {
callback = noop;
@@ -215,12 +215,12 @@ fs.open = function(path, flags, mode, callback) {
mode = modeNum(mode, '0666');
binding.open(path, stringToFlags(flags), mode, callback);
-};
+});
-fs.openSync = function(path, flags, mode) {
+fs.openSync = safeWrap(0, function(path, flags, mode) {
mode = modeNum(mode, '0666');
return binding.open(path, stringToFlags(flags), mode);
-};
+});
fs.read = function(fd, buffer, offset, length, position, callback) {
if (!Buffer.isBuffer(buffer)) {
@@ -313,13 +313,13 @@ fs.writeSync = function(fd, buffer, offset, length, position) {
return binding.write(fd, buffer, offset, length, position);
};
-fs.rename = function(oldPath, newPath, callback) {
+fs.rename = safeWrap(0, 1, function(oldPath, newPath, callback) {
binding.rename(oldPath, newPath, callback || noop);
-};
+});
-fs.renameSync = function(oldPath, newPath) {
+fs.renameSync = safeWrap(0, 1, function(oldPath, newPath) {
return binding.rename(oldPath, newPath);
-};
+});
fs.truncate = function(fd, len, callback) {
binding.truncate(fd, len, callback || noop);
@@ -329,13 +329,13 @@ fs.truncateSync = function(fd, len) {
return binding.truncate(fd, len);
};
-fs.rmdir = function(path, callback) {
+fs.rmdir = safeWrap(0, function(path, callback) {
binding.rmdir(path, callback || noop);
-};
+});
-fs.rmdirSync = function(path) {
+fs.rmdirSync = safeWrap(0, function(path) {
return binding.rmdir(path);
-};
+});
fs.fdatasync = function(fd, callback) {
binding.fdatasync(fd, callback || noop);
@@ -353,13 +353,13 @@ fs.fsyncSync = function(fd) {
return binding.fsync(fd);
};
-fs.mkdir = function(path, mode, callback) {
+fs.mkdir = safeWrap(0, function(path, mode, callback) {
binding.mkdir(path, modeNum(mode), callback || noop);
-};
+});
-fs.mkdirSync = function(path, mode) {
+fs.mkdirSync = safeWrap(0, function(path, mode) {
return binding.mkdir(path, modeNum(mode));
-};
+});
fs.sendfile = function(outFd, inFd, inOffset, length, callback) {
binding.sendfile(outFd, inFd, inOffset, length, callback || noop);
@@ -369,69 +369,69 @@ fs.sendfileSync = function(outFd, inFd, inOffset, length) {
return binding.sendfile(outFd, inFd, inOffset, length);
};
-fs.readdir = function(path, callback) {
+fs.readdir = safeWrap(0, function(path, callback) {
binding.readdir(path, callback || noop);
-};
+});
-fs.readdirSync = function(path) {
+fs.readdirSync = safeWrap(0, function(path) {
return binding.readdir(path);
-};
+});
fs.fstat = function(fd, callback) {
binding.fstat(fd, callback || noop);
};
-fs.lstat = function(path, callback) {
+fs.lstat = safeWrap(0, function(path, callback) {
binding.lstat(path, callback || noop);
-};
+});
-fs.stat = function(path, callback) {
+fs.stat = safeWrap(0, function(path, callback) {
binding.stat(path, callback || noop);
-};
+});
fs.fstatSync = function(fd) {
return binding.fstat(fd);
};
-fs.lstatSync = function(path) {
+fs.lstatSync = safeWrap(0, function(path) {
return binding.lstat(path);
-};
+});
-fs.statSync = function(path) {
+fs.statSync = safeWrap(0, function(path) {
return binding.stat(path);
-};
+});
-fs.readlink = function(path, callback) {
+fs.readlink = safeWrap(0, function(path, callback) {
binding.readlink(path, callback || noop);
-};
+});
-fs.readlinkSync = function(path) {
+fs.readlinkSync = safeWrap(0, function(path) {
return binding.readlink(path);
-};
+});
-fs.symlink = function(destination, path, callback) {
+fs.symlink = safeWrap(0, 1, function(destination, path, callback) {
binding.symlink(destination, path, callback || noop);
-};
+});
-fs.symlinkSync = function(destination, path) {
+fs.symlinkSync = safeWrap(0, 1, function(destination, path) {
return binding.symlink(destination, path);
-};
+});
-fs.link = function(srcpath, dstpath, callback) {
+fs.link = safeWrap(0, 1, function(srcpath, dstpath, callback) {
binding.link(srcpath, dstpath, callback || noop);
-};
+});
-fs.linkSync = function(srcpath, dstpath) {
+fs.linkSync = safeWrap(0, 1, function(srcpath, dstpath) {
return binding.link(srcpath, dstpath);
-};
+});
-fs.unlink = function(path, callback) {
+fs.unlink = safeWrap(0, function(path, callback) {
binding.unlink(path, callback || noop);
-};
+});
-fs.unlinkSync = function(path) {
+fs.unlinkSync = safeWrap(0, function(path) {
return binding.unlink(path);
-};
+});
fs.fchmod = function(fd, mode, callback) {
binding.fchmod(fd, modeNum(mode), callback || noop);
@@ -460,13 +460,13 @@ if (constants.hasOwnProperty('O_SYMLINK')) {
}
-fs.chmod = function(path, mode, callback) {
+fs.chmod = safeWrap(0, function(path, mode, callback) {
binding.chmod(path, modeNum(mode), callback || noop);
-};
+});
-fs.chmodSync = function(path, mode) {
+fs.chmodSync = safeWrap(0, function(path, mode) {
return binding.chmod(path, modeNum(mode));
-};
+});
if (constants.hasOwnProperty('O_SYMLINK')) {
fs.lchown = function(path, uid, gid, callback) {
@@ -494,13 +494,13 @@ fs.fchownSync = function(fd, uid, gid) {
return binding.fchown(fd, uid, gid);
};
-fs.chown = function(path, uid, gid, callback) {
+fs.chown = safeWrap(0, function(path, uid, gid, callback) {
binding.chown(path, uid, gid, callback || noop);
-};
+});
-fs.chownSync = function(path, uid, gid) {
+fs.chownSync = safeWrap(0, function(path, uid, gid) {
return binding.chown(path, uid, gid);
-};
+});
// converts Date or number to a fractional UNIX timestamp
function toUnixTimestamp(time) {
@@ -517,17 +517,17 @@ function toUnixTimestamp(time) {
// exported for unit tests, not for public consumption
fs._toUnixTimestamp = toUnixTimestamp;
-fs.utimes = function(path, atime, mtime, callback) {
+fs.utimes = safeWrap(0, function(path, atime, mtime, callback) {
atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.utimes(path, atime, mtime, callback || noop);
-};
+});
-fs.utimesSync = function(path, atime, mtime) {
+fs.utimesSync = safeWrap(0, function(path, atime, mtime) {
atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime);
binding.utimes(path, atime, mtime);
-};
+});
fs.futimes = function(fd, atime, mtime, callback) {
atime = toUnixTimestamp(atime);
@@ -603,9 +603,9 @@ function StatWatcher() {
util.inherits(StatWatcher, EventEmitter);
-StatWatcher.prototype.start = function(filename, persistent, interval) {
+StatWatcher.prototype.start = safeWrap(0, function(filename, persistent, interval) {
this._handle.start(filename, persistent, interval);
-};
+});
StatWatcher.prototype.stop = function() {
@@ -639,9 +639,9 @@ fs.watchFile = function(filename) {
if (statWatchers[filename]) {
stat = statWatchers[filename];
} else {
- statWatchers[filename] = new StatWatcher();
- stat = statWatchers[filename];
+ stat = new StatWatcher();
stat.start(filename, options.persistent, options.interval);
+ statWatchers[filename] = stat;
}
stat.addListener('change', listener);
return stat;
@@ -1253,6 +1253,37 @@ WriteStream.prototype.destroy = function(cb) {
}
};
+function safeWrap() {
+ var unsafeArgs = [].slice.call(arguments, 0, arguments.length-1);
+ var f = arguments[arguments.length-1];
+ function fail(n) {
+ var err = new Error("fs function was called with a nullbyte in argument #"+n);
+ if (typeof arguments[arguments.length-1] === 'function') {
+ arguments[arguments.length-1](err);
+ } else {
+ throw err;
+ }
+ }
+ if (unsafeArgs.length === 1) {
+ var unsafeArg = unsafeArgs[0];
+ return function() {
+ if (arguments[unsafeArg].indexOf('\0') !== -1) {
+ return fail(unsafeArg);
+ }
+ return f.apply(this, arguments);
+ };
+ } else {
+ return function() {
+ for (var i=0; i<unsafeArgs.length; i++) {
+ if (arguments[unsafeArgs[i]].indexOf('\0') !== -1) {
+ return fail(unsafeArgs[i]);
+ }
+ }
+ return f.apply(this, arguments);
+ };
+ }
+}
+
// There is no shutdown() for files.
WriteStream.prototype.destroySoon = WriteStream.prototype.end;
Please sign in to comment.
Something went wrong with that request. Please try again.