diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 98e7b303e1091e..eaa9bd145b14cd 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -13,7 +13,6 @@ const { Number, NumberIsFinite, ObjectDefineProperties, - ObjectDefineProperty, ObjectIs, ObjectSetPrototypeOf, ReflectOwnKeys, @@ -48,6 +47,7 @@ const { once, deprecate, isWindows, + setOwnProperty, } = require('internal/util'); const { toPathIfFileURL } = require('internal/url'); const { @@ -449,10 +449,10 @@ const lazyDateFields = { enumerable: true, configurable: true, get() { - return this.atime = dateFromMs(this.atimeMs); + return setOwnProperty(this, 'atime', dateFromMs(this.atimeMs)); }, set(value) { - ObjectDefineProperty(this, 'atime', { __proto__: null, value, writable: true }); + setOwnProperty(this, 'atime', value); }, }, mtime: { @@ -460,10 +460,10 @@ const lazyDateFields = { enumerable: true, configurable: true, get() { - return this.mtime = dateFromMs(this.mtimeMs); + return setOwnProperty(this, 'mtime', dateFromMs(this.mtimeMs)); }, set(value) { - ObjectDefineProperty(this, 'mtime', { __proto__: null, value, writable: true }); + setOwnProperty(this, 'mtime', value); }, }, ctime: { @@ -471,10 +471,10 @@ const lazyDateFields = { enumerable: true, configurable: true, get() { - return this.ctime = dateFromMs(this.ctimeMs); + return setOwnProperty(this, 'ctime', dateFromMs(this.ctimeMs)); }, set(value) { - ObjectDefineProperty(this, 'ctime', { __proto__: null, value, writable: true }); + setOwnProperty(this, 'ctime', value); }, }, birthtime: { @@ -482,10 +482,10 @@ const lazyDateFields = { enumerable: true, configurable: true, get() { - return this.birthtime = dateFromMs(this.birthtimeMs); + return setOwnProperty(this, 'birthtime', dateFromMs(this.birthtimeMs)); }, set(value) { - ObjectDefineProperty(this, 'birthtime', { __proto__: null, value, writable: true }); + setOwnProperty(this, 'birthtime', value); }, }, }; diff --git a/lib/internal/util.js b/lib/internal/util.js index 28bb83e558c426..34af9ca6f61a6f 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -752,13 +752,14 @@ function filterOwnProperties(source, keys) { * @returns {any} */ function setOwnProperty(obj, key, value) { - return ObjectDefineProperty(obj, key, { + ObjectDefineProperty(obj, key, { __proto__: null, configurable: true, enumerable: true, value, writable: true, }); + return value; } let internalGlobal; diff --git a/test/parallel/test-fs-stat-date.mjs b/test/parallel/test-fs-stat-date.mjs index 5f85bff2731e86..489cd4fc20fd9c 100644 --- a/test/parallel/test-fs-stat-date.mjs +++ b/test/parallel/test-fs-stat-date.mjs @@ -42,6 +42,13 @@ function closeEnough(actual, expected, margin) { `expected ${expected} ± ${margin}, got ${actual}`); } +// Ensure that accessed atime and mtime are enumerable +function validateEnumerability(stats) { + const keys = Object.keys(stats); + assert.ok(keys.includes('atime')); + assert.ok(keys.includes('mtime')); +} + async function runTest(atime, mtime, margin = 0) { margin += Number.EPSILON; try { @@ -56,24 +63,28 @@ async function runTest(atime, mtime, margin = 0) { closeEnough(stats.mtimeMs, mtime, margin); closeEnough(stats.atime.getTime(), new Date(atime).getTime(), margin); closeEnough(stats.mtime.getTime(), new Date(mtime).getTime(), margin); + validateEnumerability(stats); const statsBigint = await fsPromises.stat(filepath, { bigint: true }); closeEnough(statsBigint.atimeMs, BigInt(atime), margin); closeEnough(statsBigint.mtimeMs, BigInt(mtime), margin); closeEnough(statsBigint.atime.getTime(), new Date(atime).getTime(), margin); closeEnough(statsBigint.mtime.getTime(), new Date(mtime).getTime(), margin); + validateEnumerability(statsBigint); const statsSync = fs.statSync(filepath); closeEnough(statsSync.atimeMs, atime, margin); closeEnough(statsSync.mtimeMs, mtime, margin); closeEnough(statsSync.atime.getTime(), new Date(atime).getTime(), margin); closeEnough(statsSync.mtime.getTime(), new Date(mtime).getTime(), margin); + validateEnumerability(statsSync); const statsSyncBigint = fs.statSync(filepath, { bigint: true }); closeEnough(statsSyncBigint.atimeMs, BigInt(atime), margin); closeEnough(statsSyncBigint.mtimeMs, BigInt(mtime), margin); closeEnough(statsSyncBigint.atime.getTime(), new Date(atime).getTime(), margin); closeEnough(statsSyncBigint.mtime.getTime(), new Date(mtime).getTime(), margin); + validateEnumerability(statsSyncBigint); } // Too high/low numbers produce too different results on different platforms