node.js idea of an inode is approximately broken

About the bug: There is a system call stat(2) in Posix, which returns a struct stat as a result. Part of that data structure is a field st_ino, which contains the inode number of that file. That number is a unique file identifier, a 64 bit bit pattern.

Javascript does not have integer types to represent that number, so node.js has been falsely converting it to a float, which can hold 53 bits of precision. So on certain file systems, 2048 different files will be munged together, which is extremely bad.

Possible solutions are obvious: Use a string or use two 32-bit numbers to hold full precision values.

About Javascript: Javascript is a language used in browsers, and changing the specs of Javascript is incredibly hard. Basically, you have to get everybody to update their browsers in order to actually make progress.

There are things that do crypto with Javascript as a target language, and there are compilers from proper programming languages to portable Javascript as a target. But still, Javascript itself is poisonous, and while that take on the language is humorous, this is a serious problem.

About culture: So we are getting a generation of developers now, which have been growing up without hardware or state. They learned programming on AWS and take RDS for granted, which means they have never actually seen hard(-ware related) problems.

They also learned programming with the Javascript framework of the week, and think that real software can be written this way. The result is not only the mess that s npm, but also an attempt at systems programming resulting in constructs such as this.

I cannot for the life of me stand the coddly approach to teaching of Julia Evans (check out her writeups at her blog), but apparently what she does and how she does it is necessary and appropriate for people growing up in a programming environment like this. Well, I’m ok with that if it prevents mindsets and bugs like the one above.

It could also prefix the inode to prevent the conversion, while still making it trivial to compare the value to the one from another system. (While I’m not seeing many use cases for that)

The proper solution would be to have some “large” integer support, but this probably would require v8 to change and I guess that would require ECMAScript’s standard body to derive from the stance that double was the only numeric type needed …

”
st_ctime
Time of creation of file. Valid on NTFS but not on FAT formatted disk drives.
st_dev
Drive number of the disk containing the file (same as st_rdev).
st_ino
Number of the information node (the inode) for the file (UNIX-specific). On UNIX file systems, the inode describes the file date and time stamps, permissions, and content. When files are hard-linked to one another, they share the same inode. The inode, and therefore st_ino, has no meaning in the FAT, HPFS, or NTFS file systems.
”

This is already barely compatible to unix semantics (all three quoted fields have quite different semantics from Unix), so it’s unlikely node.js makes it any worse.

The observed behavior is not specific to Windows NT. It just so happened that Windows has been the first system to trigger it. Other systems have a 64 bit st_ino field as well, but most peoples file systems are not large enough (do not have enough files) to exceed the counter and other file systems happen to use up inodes linearly (an implementation artifact).