Skip to content

Commit b2ba62c

Browse files
LiviaMedeirosaduh95
authored andcommitted
fs: make Date properties on Stats enumerable
Signed-off-by: LiviaMedeiros <livia@cirno.name> PR-URL: #63328 Reviewed-By: René <contact.9a5d6388@renegade334.me.uk> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
1 parent e21b8a4 commit b2ba62c

3 files changed

Lines changed: 22 additions & 10 deletions

File tree

lib/internal/fs/utils.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const {
1313
Number,
1414
NumberIsFinite,
1515
ObjectDefineProperties,
16-
ObjectDefineProperty,
1716
ObjectIs,
1817
ObjectSetPrototypeOf,
1918
ReflectOwnKeys,
@@ -48,6 +47,7 @@ const {
4847
once,
4948
deprecate,
5049
isWindows,
50+
setOwnProperty,
5151
} = require('internal/util');
5252
const { toPathIfFileURL } = require('internal/url');
5353
const {
@@ -449,43 +449,43 @@ const lazyDateFields = {
449449
enumerable: true,
450450
configurable: true,
451451
get() {
452-
return this.atime = dateFromMs(this.atimeMs);
452+
return setOwnProperty(this, 'atime', dateFromMs(this.atimeMs));
453453
},
454454
set(value) {
455-
ObjectDefineProperty(this, 'atime', { __proto__: null, value, writable: true });
455+
setOwnProperty(this, 'atime', value);
456456
},
457457
},
458458
mtime: {
459459
__proto__: null,
460460
enumerable: true,
461461
configurable: true,
462462
get() {
463-
return this.mtime = dateFromMs(this.mtimeMs);
463+
return setOwnProperty(this, 'mtime', dateFromMs(this.mtimeMs));
464464
},
465465
set(value) {
466-
ObjectDefineProperty(this, 'mtime', { __proto__: null, value, writable: true });
466+
setOwnProperty(this, 'mtime', value);
467467
},
468468
},
469469
ctime: {
470470
__proto__: null,
471471
enumerable: true,
472472
configurable: true,
473473
get() {
474-
return this.ctime = dateFromMs(this.ctimeMs);
474+
return setOwnProperty(this, 'ctime', dateFromMs(this.ctimeMs));
475475
},
476476
set(value) {
477-
ObjectDefineProperty(this, 'ctime', { __proto__: null, value, writable: true });
477+
setOwnProperty(this, 'ctime', value);
478478
},
479479
},
480480
birthtime: {
481481
__proto__: null,
482482
enumerable: true,
483483
configurable: true,
484484
get() {
485-
return this.birthtime = dateFromMs(this.birthtimeMs);
485+
return setOwnProperty(this, 'birthtime', dateFromMs(this.birthtimeMs));
486486
},
487487
set(value) {
488-
ObjectDefineProperty(this, 'birthtime', { __proto__: null, value, writable: true });
488+
setOwnProperty(this, 'birthtime', value);
489489
},
490490
},
491491
};

lib/internal/util.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,13 +752,14 @@ function filterOwnProperties(source, keys) {
752752
* @returns {any}
753753
*/
754754
function setOwnProperty(obj, key, value) {
755-
return ObjectDefineProperty(obj, key, {
755+
ObjectDefineProperty(obj, key, {
756756
__proto__: null,
757757
configurable: true,
758758
enumerable: true,
759759
value,
760760
writable: true,
761761
});
762+
return value;
762763
}
763764

764765
let internalGlobal;

test/parallel/test-fs-stat-date.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ function closeEnough(actual, expected, margin) {
4242
`expected ${expected} ± ${margin}, got ${actual}`);
4343
}
4444

45+
// Ensure that accessed atime and mtime are enumerable
46+
function validateEnumerability(stats) {
47+
const keys = Object.keys(stats);
48+
assert.ok(keys.includes('atime'));
49+
assert.ok(keys.includes('mtime'));
50+
}
51+
4552
async function runTest(atime, mtime, margin = 0) {
4653
margin += Number.EPSILON;
4754
try {
@@ -56,24 +63,28 @@ async function runTest(atime, mtime, margin = 0) {
5663
closeEnough(stats.mtimeMs, mtime, margin);
5764
closeEnough(stats.atime.getTime(), new Date(atime).getTime(), margin);
5865
closeEnough(stats.mtime.getTime(), new Date(mtime).getTime(), margin);
66+
validateEnumerability(stats);
5967

6068
const statsBigint = await fsPromises.stat(filepath, { bigint: true });
6169
closeEnough(statsBigint.atimeMs, BigInt(atime), margin);
6270
closeEnough(statsBigint.mtimeMs, BigInt(mtime), margin);
6371
closeEnough(statsBigint.atime.getTime(), new Date(atime).getTime(), margin);
6472
closeEnough(statsBigint.mtime.getTime(), new Date(mtime).getTime(), margin);
73+
validateEnumerability(statsBigint);
6574

6675
const statsSync = fs.statSync(filepath);
6776
closeEnough(statsSync.atimeMs, atime, margin);
6877
closeEnough(statsSync.mtimeMs, mtime, margin);
6978
closeEnough(statsSync.atime.getTime(), new Date(atime).getTime(), margin);
7079
closeEnough(statsSync.mtime.getTime(), new Date(mtime).getTime(), margin);
80+
validateEnumerability(statsSync);
7181

7282
const statsSyncBigint = fs.statSync(filepath, { bigint: true });
7383
closeEnough(statsSyncBigint.atimeMs, BigInt(atime), margin);
7484
closeEnough(statsSyncBigint.mtimeMs, BigInt(mtime), margin);
7585
closeEnough(statsSyncBigint.atime.getTime(), new Date(atime).getTime(), margin);
7686
closeEnough(statsSyncBigint.mtime.getTime(), new Date(mtime).getTime(), margin);
87+
validateEnumerability(statsSyncBigint);
7788
}
7889

7990
// Too high/low numbers produce too different results on different platforms

0 commit comments

Comments
 (0)