Node: fs.ftruncate silently accepts negative offsets rather than failing with ERR_INVALID

Created on 13 Oct 2020  路  4Comments  路  Source: nodejs/node

fs.ftruncate and fd.ftruncateSync both silently ignore negative offsets:

https://github.com/nodejs/node/blob/2cfdf28413fd9a7bfab65cb49cff6e50ab0c21ec/lib/fs.js#L840

This didn't always do behave like this.. looks like it was introduced in 8974df15a973e97a74cf9fb0ccb45c11baa7b54a

What steps will reproduce the bug?

var fs = require("fs");
var fd = fs.openSync("f", 'w+');
console.log(fs.ftruncateSync(fd, -99));

What is the expected behavior?

The ftruncate POSIX function is described as returning EINVAL when given a negative offset:
https://linux.die.net/man/2/ftruncate

In emscripten we emulate a POSIX environment on top of the Web and on top of node and expect ftruncate to fail in the same way.

We can obviously add a check to our code as a workaround but this does seem like a bug in node.

What do you see instead?

Silently assumed 0 length is what the caller really wants.

confirmed-bug fs

Most helpful comment

Node 8.xx.xx throws EINVAL properly for negative offset. Maybe there is no need to handle explicitly. Even len = MathMax(0, len) is not required. The internal system call itself terminates with EINVAL when it sees negative offset. So no need to handle anything explicitly. If you check the source code of 8.xx.xx there is no explicit validation being done.

All 4 comments

Maybe removing len = MathMax(0, len); would fix the issue, or by explicitly handling the negative value case before calling the internal method. Had experienced this issue, a week back ! I solved this by explicitly checking the len before passing it down to the ftruncateSync()

What about adding this sort of a change?

-  len = MathMax(0, len);
+  if (len < 0) {
+    throw new ERR_FS_FILE_TOO_SMALL(len);
+  } else if (len > kIoMaxLength) {
+    throw new ERR_FS_FILE_TOO_LARGE(len);
+  }

where, ERR_FS_FILE_TOO_LARGE already exists and we make a new error code ERR_FS_FILE_TOO_SMALL for negative sizes and this is all about kIoMaxLength:
https://github.com/nodejs/node/blob/999e7d7b44b832210b11d90260dc46560457d30d/lib/fs.js#L27-L29
This would take care of both the upper and the lower limits for the allowed size in ftruncate.

I'm not familiar with node code but isn't there already the simple equivalent of EINVAL? Is it a good idea to add more error codes?

Node 8.xx.xx throws EINVAL properly for negative offset. Maybe there is no need to handle explicitly. Even len = MathMax(0, len) is not required. The internal system call itself terminates with EINVAL when it sees negative offset. So no need to handle anything explicitly. If you check the source code of 8.xx.xx there is no explicit validation being done.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thecodingdude picture thecodingdude  路  158Comments

speakeasypuncture picture speakeasypuncture  路  152Comments

benjamingr picture benjamingr  路  135Comments

nicolo-ribaudo picture nicolo-ribaudo  路  147Comments

mikeal picture mikeal  路  90Comments