From 818f2927ff3ed51575237b88f3fd90dd3204e16d Mon Sep 17 00:00:00 2001 From: LiviaMedeiros Date: Fri, 27 Jun 2025 00:28:10 +0800 Subject: [PATCH] fs: throw `ERR_INVALID_THIS` on illegal invocations --- lib/internal/fs/dir.js | 3 +++ lib/internal/fs/streams.js | 5 +++++ test/parallel/test-fs-opendir.js | 10 ++++++++++ test/parallel/test-fs-write-stream-autoclose-option.js | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index d734a28b806c3c..6c40aa4f84f848 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -18,6 +18,7 @@ const { codes: { ERR_DIR_CLOSED, ERR_DIR_CONCURRENT_OPERATION, + ERR_INVALID_THIS, ERR_MISSING_ARGS, }, } = require('internal/errors'); @@ -67,6 +68,8 @@ class Dir { } get path() { + if (!(#path in this)) + throw new ERR_INVALID_THIS('Dir'); return this.#path; } diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js index 79345a656ebdeb..5d38085c578d2c 100644 --- a/lib/internal/fs/streams.js +++ b/lib/internal/fs/streams.js @@ -25,6 +25,7 @@ const { validateBoolean, validateFunction, validateInteger, + validateThisInternalField, } = require('internal/validators'); const { errorOrDestroy } = require('internal/streams/destroy'); const fs = require('fs'); @@ -230,9 +231,11 @@ ObjectSetPrototypeOf(ReadStream, Readable); ObjectDefineProperty(ReadStream.prototype, 'autoClose', { __proto__: null, get() { + validateThisInternalField(this, kFs, 'ReadStream'); return this._readableState.autoDestroy; }, set(val) { + validateThisInternalField(this, kFs, 'ReadStream'); this._readableState.autoDestroy = val; }, }); @@ -394,9 +397,11 @@ ObjectSetPrototypeOf(WriteStream, Writable); ObjectDefineProperty(WriteStream.prototype, 'autoClose', { __proto__: null, get() { + validateThisInternalField(this, kFs, 'WriteStream'); return this._writableState.autoDestroy; }, set(val) { + validateThisInternalField(this, kFs, 'WriteStream'); this._writableState.autoDestroy = val; }, }); diff --git a/test/parallel/test-fs-opendir.js b/test/parallel/test-fs-opendir.js index 625a0f75d02c10..f93fe8ae4b75b2 100644 --- a/test/parallel/test-fs-opendir.js +++ b/test/parallel/test-fs-opendir.js @@ -18,6 +18,13 @@ files.forEach(function(filename) { fs.closeSync(fs.openSync(path.join(testDir, filename), 'w')); }); +function assertDir(dir) { + assert(dir instanceof fs.Dir); + assert.throws(() => dir.constructor.prototype.path, { + code: 'ERR_INVALID_THIS', + }); +} + function assertDirent(dirent) { assert(dirent instanceof fs.Dirent); assert.strictEqual(dirent.isFile(), true); @@ -45,6 +52,7 @@ const invalidCallbackObj = { // Check the opendir Sync version { const dir = fs.opendirSync(testDir); + assertDir(dir); const entries = files.map(() => { const dirent = dir.readSync(); assertDirent(dirent); @@ -67,6 +75,7 @@ const invalidCallbackObj = { // Check the opendir async version fs.opendir(testDir, common.mustSucceed((dir) => { + assertDir(dir); let sync = true; dir.read(common.mustSucceed((dirent) => { assert(!sync); @@ -120,6 +129,7 @@ fs.opendir(__filename, common.mustCall(function(e) { async function doPromiseTest() { // Check the opendir Promise version const dir = await fs.promises.opendir(testDir); + assertDir(dir); const entries = []; let i = files.length; diff --git a/test/parallel/test-fs-write-stream-autoclose-option.js b/test/parallel/test-fs-write-stream-autoclose-option.js index fe738091bd6c68..ded45a42945e17 100644 --- a/test/parallel/test-fs-write-stream-autoclose-option.js +++ b/test/parallel/test-fs-write-stream-autoclose-option.js @@ -56,3 +56,7 @@ function next3() { })); })); } + +assert.throws(() => fs.WriteStream.prototype.autoClose, { + code: 'ERR_INVALID_THIS', +});