Skip to content

Commit

Permalink
fs: allow passing negative zero fd
Browse files Browse the repository at this point in the history
Fixes: #37122

PR-URL: #37123
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Zijian Liu <lxxyxzj@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
RaisinTen authored and danielleadams committed Feb 16, 2021
1 parent 48a634e commit c302450
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 25 deletions.
50 changes: 25 additions & 25 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const {
Dirent,
getDirents,
getOptions,
getValidatedFd,
getValidatedPath,
getValidMode,
handleErrorFromBinding,
Expand Down Expand Up @@ -128,7 +129,6 @@ const {
validateCallback,
validateFunction,
validateInteger,
validateInt32,
} = require('internal/validators');
// 2 ** 32 - 1
const kMaxUserId = 4294967295;
Expand Down Expand Up @@ -443,7 +443,7 @@ function defaultCloseCallback(err) {
}

function close(fd, callback = defaultCloseCallback) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
if (callback !== defaultCloseCallback)
callback = makeCallback(callback);

Expand All @@ -453,7 +453,7 @@ function close(fd, callback = defaultCloseCallback) {
}

function closeSync(fd) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);

const ctx = {};
binding.close(fd, undefined, ctx);
Expand Down Expand Up @@ -503,7 +503,7 @@ function openSync(path, flags, mode) {
// OR
// fs.read(fd, {}, callback)
function read(fd, buffer, offset, length, position, callback) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);

if (arguments.length <= 3) {
// Assume fs.read(fd, options, callback)
Expand Down Expand Up @@ -576,7 +576,7 @@ ObjectDefineProperty(read, internalUtil.customPromisifyArgs,
// OR
// fs.readSync(fd, buffer, {}) or fs.readSync(fd, buffer)
function readSync(fd, buffer, offset, length, position) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);

if (arguments.length <= 3) {
// Assume fs.read(fd, buffer, options)
Expand Down Expand Up @@ -623,7 +623,7 @@ function readv(fd, buffers, position, callback) {
callback(err, read || 0, buffers);
}

validateInt32(fd, 'fd', /* min */ 0);
fd = getValidatedFd(fd);
validateBufferArray(buffers);
callback = maybeCallback(callback || position);

Expand All @@ -640,7 +640,7 @@ ObjectDefineProperty(readv, internalUtil.customPromisifyArgs,
{ value: ['bytesRead', 'buffers'], enumerable: false });

function readvSync(fd, buffers, position) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
validateBufferArray(buffers);

const ctx = {};
Expand All @@ -663,7 +663,7 @@ function write(fd, buffer, offset, length, position, callback) {
callback(err, written || 0, buffer);
}

validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);

if (isArrayBufferView(buffer)) {
callback = maybeCallback(callback || position || length || offset);
Expand Down Expand Up @@ -709,7 +709,7 @@ ObjectDefineProperty(write, internalUtil.customPromisifyArgs,
// OR
// fs.writeSync(fd, string[, position[, encoding]]);
function writeSync(fd, buffer, offset, length, position) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
const ctx = {};
let result;
if (isArrayBufferView(buffer)) {
Expand Down Expand Up @@ -744,7 +744,7 @@ function writev(fd, buffers, position, callback) {
callback(err, written || 0, buffers);
}

validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
validateBufferArray(buffers);
callback = maybeCallback(callback || position);

Expand All @@ -763,7 +763,7 @@ ObjectDefineProperty(writev, internalUtil.customPromisifyArgs, {
});

function writevSync(fd, buffers, position) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
validateBufferArray(buffers);

const ctx = {};
Expand Down Expand Up @@ -849,7 +849,7 @@ function ftruncate(fd, len = 0, callback) {
callback = len;
len = 0;
}
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
validateInteger(len, 'len');
len = MathMax(0, len);
callback = makeCallback(callback);
Expand All @@ -860,7 +860,7 @@ function ftruncate(fd, len = 0, callback) {
}

function ftruncateSync(fd, len = 0) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
validateInteger(len, 'len');
len = MathMax(0, len);
const ctx = {};
Expand Down Expand Up @@ -942,28 +942,28 @@ function rmSync(path, options) {
}

function fdatasync(fd, callback) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
const req = new FSReqCallback();
req.oncomplete = makeCallback(callback);
binding.fdatasync(fd, req);
}

function fdatasyncSync(fd) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
const ctx = {};
binding.fdatasync(fd, undefined, ctx);
handleErrorFromBinding(ctx);
}

function fsync(fd, callback) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
const req = new FSReqCallback();
req.oncomplete = makeCallback(callback);
binding.fsync(fd, req);
}

function fsyncSync(fd) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
const ctx = {};
binding.fsync(fd, undefined, ctx);
handleErrorFromBinding(ctx);
Expand Down Expand Up @@ -1054,7 +1054,7 @@ function fstat(fd, options = { bigint: false }, callback) {
callback = options;
options = {};
}
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
callback = makeStatsCallback(callback);

const req = new FSReqCallback(options.bigint);
Expand Down Expand Up @@ -1102,7 +1102,7 @@ function hasNoEntryError(ctx) {
}

function fstatSync(fd, options = { bigint: false, throwIfNoEntry: true }) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
const ctx = { fd };
const stats = binding.fstat(fd, options.bigint, undefined, ctx);
handleErrorFromBinding(ctx);
Expand Down Expand Up @@ -1255,7 +1255,7 @@ function unlinkSync(path) {
}

function fchmod(fd, mode, callback) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
mode = parseFileMode(mode, 'mode');
callback = makeCallback(callback);

Expand All @@ -1265,7 +1265,7 @@ function fchmod(fd, mode, callback) {
}

function fchmodSync(fd, mode) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
mode = parseFileMode(mode, 'mode');
const ctx = {};
binding.fchmod(fd, mode, undefined, ctx);
Expand Down Expand Up @@ -1343,7 +1343,7 @@ function lchownSync(path, uid, gid) {
}

function fchown(fd, uid, gid, callback) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
validateInteger(uid, 'uid', -1, kMaxUserId);
validateInteger(gid, 'gid', -1, kMaxUserId);
callback = makeCallback(callback);
Expand All @@ -1354,7 +1354,7 @@ function fchown(fd, uid, gid, callback) {
}

function fchownSync(fd, uid, gid) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
validateInteger(uid, 'uid', -1, kMaxUserId);
validateInteger(gid, 'gid', -1, kMaxUserId);

Expand Down Expand Up @@ -1405,7 +1405,7 @@ function utimesSync(path, atime, mtime) {
}

function futimes(fd, atime, mtime, callback) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
atime = toUnixTimestamp(atime, 'atime');
mtime = toUnixTimestamp(mtime, 'mtime');
callback = makeCallback(callback);
Expand All @@ -1416,7 +1416,7 @@ function futimes(fd, atime, mtime, callback) {
}

function futimesSync(fd, atime, mtime) {
validateInt32(fd, 'fd', 0);
fd = getValidatedFd(fd);
atime = toUnixTimestamp(atime, 'atime');
mtime = toUnixTimestamp(mtime, 'mtime');
const ctx = {};
Expand Down
12 changes: 12 additions & 0 deletions lib/internal/fs/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const {
NumberIsFinite,
NumberIsInteger,
MathMin,
ObjectIs,
ObjectPrototypeHasOwnProperty,
ObjectSetPrototypeOf,
ReflectApply,
Expand Down Expand Up @@ -649,6 +650,16 @@ const getValidatedPath = hideStackFrames((fileURLOrPath, propName = 'path') => {
return path;
});

const getValidatedFd = hideStackFrames((fd, propName = 'fd') => {
if (ObjectIs(fd, -0)) {
return 0;
}

validateInt32(fd, propName, 0);

return fd;
});

const validateBufferArray = hideStackFrames((buffers, propName = 'buffers') => {
if (!ArrayIsArray(buffers))
throw new ERR_INVALID_ARG_TYPE(propName, 'ArrayBufferView[]', buffers);
Expand Down Expand Up @@ -843,6 +854,7 @@ module.exports = {
getDirent,
getDirents,
getOptions,
getValidatedFd,
getValidatedPath,
getValidMode,
handleErrorFromBinding,
Expand Down
2 changes: 2 additions & 0 deletions test/parallel/test-fs-stat.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ fs.lstat('.', common.mustSucceed(function(stats) {
fs.open('.', 'r', undefined, common.mustSucceed(function(fd) {
assert.ok(fd);

fs.fstat(-0, common.mustSucceed());

fs.fstat(fd, common.mustSucceed(function(stats) {
assert.ok(stats.mtime instanceof Date);
fs.close(fd, assert.ifError);
Expand Down

0 comments on commit c302450

Please sign in to comment.