Repository navigation
fs.Stat fails on pre-epoch mtime (<1970-01-01T00:00:00Z) #32369
Copy link
Copy link
Closed
libuv/libuv
#2747Labels
confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.fsIssues and PRs related to file-system APIs and the fs module.Issues and PRs related to file-system APIs and the fs module.libuvIssues and PRs related to the libuv dependency or the uv binding.Issues and PRs related to the libuv dependency or the uv binding.
Description
- Version: v13.10.1
- Platform: Darwin dirac.imetrical.com 18.7.0 Darwin Kernel Version 18.7.0: Sun Dec 1 18:59:03 PST 2019; root:xnu-4903.278.19~1/RELEASE_X86_64 x86_64
- Subsystem: fs.stat
What steps will reproduce the bug?
// statPreEpoch.js
const fs = require('fs')
const path = 'coco.txt'
const { mtime } = fs.statSync(path)
console.log(`mtime of ${path}: ${mtime}`)This is on Darwin (macOS)
# This is correct
$ touch -mt 197001010000.00 coco.txt
$ stat coco.txt
16777220 104232499 -rw-r--r-- 1 daniel staff 0 0 "Mar 19 13:26:22 2020" "Jan 1 00:00:00 1970" "Mar 19 15:01:21 2020" "Dec 31 19:00:00 1969" 4096 0 0 coco.txt
$ node statPreEpoch.js
mtime of coco.txt: Thu Jan 01 1970 00:00:00 GMT-0500 (GMT-05:00)
# This is the bug:
touch -mt 196805160000.00 coco.txt
stat coco.txt
16777220 104232499 -rw-r--r-- 1 daniel staff 0 0 "Mar 19 13:26:22 2020" "May 16 00:00:00 1968" "Mar 19 15:00:23 2020" "Dec 31 19:00:00 1969" 4096 0 0 coco.txt
$ node statPreEpoch.js
mtime of coco.txt: Invalid DateThis is on Linux (in Docker
$ docker run --rm -it -v $(pwd)/statPreEpoch.js:/src/statPreEpoch.js node:13.10 bash
$ uname -a
Linux 38f95bbffb38 4.19.76-linuxkit #1 SMP Thu Oct 17 19:31:58 UTC 2019 x86_64 GNU/Linux
$ touch -mt 197001010000.00 coco.txt
$ stat coco.txt
File: coco.txt
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: abh/171d Inode: 2910905 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-03-19 19:10:48.080137057 +0000
Modify: 1970-01-01 00:00:00.000000000 +0000
Change: 2020-03-19 19:10:48.080137057 +0000
$ node /src/statPreEpoch.js
mtime of coco.txt: Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time)
# This is the bug
$ touch -mt 196805160000.00 coco.txt
$ stat coco.txt
File: coco.txt
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: abh/171d Inode: 2910905 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-03-19 19:10:48.080137057 +0000
Modify: 1968-05-16 00:00:00.000000000 +0000
Change: 2020-03-19 19:12:24.343012135 +0000
Birth: -
$ node /src/statPreEpoch.js
mtime of coco.txt: Invalid DateHow often does it reproduce? Is there a required condition?
Every time that mtime < unix epoch (1970-01-01T00:00:00Z)
What is the expected behavior?
Return a valid Date Object, for example
$ node /src/statPreEpoch.js
mtime of coco.txt: Thu May 16 1968 00:00:00 GMT+0000 (Coordinated Universal Time)> new Date("1968-05-16T00:00:00-04:00")
1968-05-16T04:00:00.000Z
> new Date("1968-05-16T00:00:00-04:00").getTime()
-51393600000What do you see instead?
$ node /src/statPreEpoch.js
mtime of coco.txt: Invalid DateAdditional information
I discovered this behavior by trying to use fs.utimes which is also not able to correctly handle dates before unix epoch, although fs.utimes seems to have a workaround by using the string representation of unix time.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.fsIssues and PRs related to file-system APIs and the fs module.Issues and PRs related to file-system APIs and the fs module.libuvIssues and PRs related to the libuv dependency or the uv binding.Issues and PRs related to the libuv dependency or the uv binding.
Activity
bnoordhuis commentedon Mar 21, 2020
FWIW, the fix is trivial (see below) but I'm still working on a reliable, portable regression test. Not all file systems and operating systems let you set the date that far back.
bnoordhuis commentedon Mar 21, 2020
There's also a secondary libuv bug: conversion from
doubletostruct timespecexhibits rounding errors for large values.E.g.
1969-07-20T02:56:00.00round-trips as1969-07-20T02:56:00.55161.unix: fix utime/futime timestamp rounding errors
lib: remove file timestamp rounding hack
src: make fs functions handle pre-epoch timestamps
daneroo commentedon Mar 22, 2020
Very happy you caught the rounding error too. Great work.
unix: fix utime/futime timestamp rounding errors
unix: fix utime/futime timestamp rounding errors
unix: fix utime/futime timestamp rounding errors
unix: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors
fs: fix utime/futime timestamp rounding errors