From d453fac33b0769a12b8b926f0d77e1bbd834b397 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sun, 26 Nov 2017 14:06:50 -0800 Subject: [PATCH] fs: move type checking for fs.ftruncate to js PR-URL: https://github.com/nodejs/node/pull/17334 Reviewed-By: Refael Ackermann Reviewed-By: Timothy Gu Reviewed-By: Jon Moss Reviewed-By: Anna Henningsen Reviewed-By: Joyee Cheung Reviewed-By: Matteo Collina --- lib/fs.js | 8 ++-- src/node_file.cc | 19 ++-------- test/parallel/test-fs-truncate.js | 61 +++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index 9d9ba706127..1a93d0acf2e 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -864,11 +864,11 @@ fs.ftruncate = function(fd, len, callback) { } else if (len === undefined) { len = 0; } - if (typeof fd !== 'number') + if (!Number.isInteger(fd)) throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'number'); if (fd < 0 || fd > 0xFFFFFFFF) throw new errors.RangeError('ERR_OUT_OF_RANGE', 'fd'); - if (typeof len !== 'number') + if (!Number.isInteger(len)) throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'number'); len = Math.max(0, len); const req = new FSReqWrap(); @@ -880,11 +880,11 @@ fs.ftruncateSync = function(fd, len) { if (len === undefined) { len = 0; } - if (typeof fd !== 'number') + if (!Number.isInteger(fd)) throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'fd', 'number'); if (fd < 0 || fd > 0xFFFFFFFF) throw new errors.RangeError('ERR_OUT_OF_RANGE', 'fd'); - if (typeof len !== 'number') + if (!Number.isInteger(len)) throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'len', 'number'); len = Math.max(0, len); return binding.ftruncate(fd, len); diff --git a/src/node_file.cc b/src/node_file.cc index 13155bedb10..c330c95fa67 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -763,24 +763,11 @@ static void Rename(const FunctionCallbackInfo& args) { static void FTruncate(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - if (args.Length() < 2) - return TYPE_ERROR("fd and length are required"); - if (!args[0]->IsInt32()) - return TYPE_ERROR("fd must be a file descriptor"); + CHECK(args[0]->IsInt32()); + CHECK(args[1]->IsNumber()); int fd = args[0]->Int32Value(); - - // FIXME(bnoordhuis) It's questionable to reject non-ints here but still - // allow implicit coercion from null or undefined to zero. Probably best - // handled in lib/fs.js. - Local len_v(args[1]); - if (!len_v->IsUndefined() && - !len_v->IsNull() && - !IsInt64(len_v->NumberValue())) { - return env->ThrowTypeError("Not an integer"); - } - - const int64_t len = len_v->IntegerValue(); + const int64_t len = args[1]->IntegerValue(); if (args[2]->IsObject()) { ASYNC_CALL(ftruncate, args[2], UTF8, fd, len) diff --git a/test/parallel/test-fs-truncate.js b/test/parallel/test-fs-truncate.js index 4119d53c4f8..7690ec7c24d 100644 --- a/test/parallel/test-fs-truncate.js +++ b/test/parallel/test-fs-truncate.js @@ -180,8 +180,69 @@ function testFtruncate(cb) { fs.writeFileSync(file5, 'Hi'); const fd = fs.openSync(file5, 'r+'); process.on('exit', () => fs.closeSync(fd)); + + ['', false, null, {}, []].forEach((i) => { + common.expectsError( + () => fs.ftruncate(fd, i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "len" argument must be of type number' + } + ); + }); + fs.ftruncate(fd, undefined, common.mustCall(function(err) { assert.ifError(err); assert(fs.readFileSync(file5).equals(Buffer.from(''))); })); } + +{ + const file6 = path.resolve(tmp, 'truncate-file-6.txt'); + fs.writeFileSync(file6, 'Hi'); + const fd = fs.openSync(file6, 'r+'); + process.on('exit', () => fs.closeSync(fd)); + fs.ftruncate(fd, -1, common.mustCall(function(err) { + assert.ifError(err); + assert(fs.readFileSync(file6).equals(Buffer.from(''))); + })); +} + +['', false, null, undefined, {}, []].forEach((i) => { + common.expectsError( + () => fs.ftruncate(i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "fd" argument must be of type number' + } + ); + common.expectsError( + () => fs.ftruncateSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "fd" argument must be of type number' + } + ); +}); + +[-1, 0xFFFFFFFF + 1].forEach((i) => { + common.expectsError( + () => fs.ftruncate(i), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "fd" argument is out of range' + } + ); + common.expectsError( + () => fs.ftruncateSync(i), + { + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: 'The "fd" argument is out of range' + } + ); +});