From d4693ff4308de3517f064a2c930718a6f37229fe Mon Sep 17 00:00:00 2001 From: Dylan Elliott Date: Mon, 14 Sep 2020 07:44:43 -0400 Subject: [PATCH] fs: add validation for fd and path Adds type validation to options fd & opts in `fs.createWriteStream` and `fs.createReadStream`. Fixes: https://github.com/nodejs/node/issues/35178 PR-URL: https://github.com/nodejs/node/pull/35187 Reviewed-By: Robert Nagy Reviewed-By: Rich Trott Reviewed-By: Matteo Collina Co-authored-by: Antoine du Hamel --- lib/internal/fs/streams.js | 18 ++++++++- test/parallel/test-fs-stream-options.js | 49 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-fs-stream-options.js diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js index 2e79243da8fb5e..57c2304fca82cc 100644 --- a/lib/internal/fs/streams.js +++ b/lib/internal/fs/streams.js @@ -28,6 +28,8 @@ const { Buffer } = require('buffer'); const { copyObject, getOptions, + getValidatedFd, + validatePath, } = require('internal/fs/utils'); const { Readable, Writable, finished } = require('stream'); const { toPathIfFileURL } = require('internal/url'); @@ -119,7 +121,7 @@ function close(stream, err, cb) { function importFd(stream, options) { stream.fd = null; - if (options.fd) { + if (options.fd != null) { if (typeof options.fd === 'number') { // When fd is a raw descriptor, we must keep our fingers crossed // that the descriptor won't get closed, or worse, replaced with @@ -185,6 +187,13 @@ function ReadStream(path, options) { this.pos = this.start; } + // If fd has been set, validate, otherwise validate path. + if (this.fd != null) { + this.fd = getValidatedFd(this.fd); + } else { + validatePath(this.path); + } + if (this.end === undefined) { this.end = Infinity; } else if (this.end !== Infinity) { @@ -344,6 +353,13 @@ function WriteStream(path, options) { this.closed = false; this[kIsPerformingIO] = false; + // If fd has been set, validate, otherwise validate path. + if (this.fd != null) { + this.fd = getValidatedFd(this.fd); + } else { + validatePath(this.path); + } + if (this.start !== undefined) { validateInteger(this.start, 'start', 0); diff --git a/test/parallel/test-fs-stream-options.js b/test/parallel/test-fs-stream-options.js new file mode 100644 index 00000000000000..f1ffaddd28b2a7 --- /dev/null +++ b/test/parallel/test-fs-stream-options.js @@ -0,0 +1,49 @@ +'use strict'; +require('../common'); + +const assert = require('assert'); +const fs = require('fs'); + +{ + const fd = 'k'; + + assert.throws( + () => { + fs.createReadStream(null, { fd }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); + + assert.throws( + () => { + fs.createWriteStream(null, { fd }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); +} + +{ + const path = 46; + + assert.throws( + () => { + fs.createReadStream(path); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); + + assert.throws( + () => { + fs.createWriteStream(path); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); +}