fs: use signed types for `stat` data
Fixes: https://github.com/nodejs/node/issues/43707, https://github.com/nodejs/node/issues/32369
On Windows, right now we have to choose between pre-1970 and post-2038 dates. Post-2038 seems to be preferable so the fix is not fully applied on this platform.
Observations on different platforms
Casting to unsigned long
, local test:
- expected
355
, got354.999
- EINVAL on
-10000000000000
- EINVAL on
10000000000000
Test results:
- https://ci.nodejs.org/job/node-stress-single-test/352/
- https://ci.nodejs.org/job/node-stress-single-test/353/
Casting to double
, initial test:
- aix71-ppc64: EINVAL
-
osx11: expected
10000000000000
got9223372036854.775
-
rhel8-x64: expected
10000000000000
got2147483647000
Casting to double
or long
, verbose test:
-
aix71-ppc64/ppc64: rounds down to seconds, EINVALs on negative numbers
-
alpine-last-latest-x64, alpine-latest-x64, centos7-ppcle, debian10-x64, rhel7-s390x, ubuntu1804-64: good results, having rounding errors on JS layer and EINVALs on {MIN,MAX}_SAFE_INTEGER
-
fedora-last-latest-x64, fedora-latest-x64, rhel8-s390x, rhel8-x64:
-10000000000000
gets rounded to-2147483648000
,100000000000000
gets rounded to15032385535000
-
freebsd12-x64: messed up atime and mtime?
-
osx1015: never EINVALs, caps at about
9223372036855
-
osx11: defaults to
0
on {under,over}flow -
smartos18-64, smartos20-64: EOVERFLOW before EINVAL
-
ubuntu2004-arm64: never EINVALs, defaults to
0
instead -
win*: not reported due to https://github.com/nodejs/build/issues/2991