fs.read into zero buffer should not throw exception #4518
Conversation
@@ -1098,7 +1098,7 @@ static void Read(const FunctionCallbackInfo<Value>& args) { | |||
size_t buffer_length = Buffer::Length(buffer_obj); | |||
|
|||
size_t off = args[2]->Int32Value(); | |||
if (off >= buffer_length) { | |||
if (off > buffer_length) { |
feross
Jan 3, 2016
Author
Contributor
This should be safe because the following if-statement will catch if offset + length would be out-of-bounds of the buffer.
This should be safe because the following if-statement will catch if offset + length would be out-of-bounds of the buffer.
bnoordhuis
Jan 3, 2016
Member
I don't think it is. If buffer_length == 0
, then it's possible for buffer_data == nullptr
. nullptr + 0
is technically defined behavior (in C++, not C) but passing that pointer onto the kernel can - but does not have to - fail.
If zero-sized reads are desirable, I would handle them in lib/fs.js
.
I don't think it is. If buffer_length == 0
, then it's possible for buffer_data == nullptr
. nullptr + 0
is technically defined behavior (in C++, not C) but passing that pointer onto the kernel can - but does not have to - fail.
If zero-sized reads are desirable, I would handle them in lib/fs.js
.
feross
Jan 3, 2016
Author
Contributor
Done.
Done.
bufferSync = new Buffer(0), | ||
readCalled = 0; | ||
|
||
fs.read(fd, bufferAsync, 0, 0, 0, function(err, bytesRead) { |
thefourtheye
Jan 3, 2016
Contributor
Use common.mustCall
instead of using readCalled
Use common.mustCall
instead of using readCalled
feross
Jan 3, 2016
Author
Contributor
I just copied this from another test. Will update.
I just copied this from another test. Will update.
What could be the possible use-case which would need this? |
@thefourtheye Yep, what @Trott said. Zero-length files are valid files. If the user passes one into our module, I think it's reasonable to expect |
@thefourtheye Just addressed your comment by updating the PR. |
|
Re-running CI since force push: https://ci.nodejs.org/job/node-test-commit/1612/ |
I just force pushed again to address @bnoordhuis's comments. I moved the logic to @Trott You might want to re-run the CI again ;) |
CI round three: https://ci.nodejs.org/job/node-test-pull-request/1136/ |
CI looks good (minus the occasional flaky tests). LGTM |
@@ -609,6 +609,12 @@ fs.read = function(fd, buffer, offset, length, position, callback) { | |||
}; | |||
} | |||
|
|||
if (length === 0) { | |||
return process.nextTick(function() { |
thefourtheye
Jan 4, 2016
Contributor
Hmmm, this is not right. There is actually a deprecated fs.read
form which returns string
.
So,
- This will actually return a buffer and the deprecated
fs.read
will collapse.
- The order of parameters to the callback, in string form, is actually string and the bytesRead.
Hmmm, this is not right. There is actually a deprecated fs.read
form which returns string
.
So,
- This will actually return a buffer and the deprecated
fs.read
will collapse. - The order of parameters to the callback, in string form, is actually string and the bytesRead.
feross
Jan 4, 2016
Author
Contributor
Actually, this calls the redefined callback
function (that starts on line 600), so the right arguments should be passed to the callback function, namely: null
, ''
, and 0
.
Unless I'm missing something.
Actually, this calls the redefined callback
function (that starts on line 600), so the right arguments should be passed to the callback function, namely: null
, ''
, and 0
.
Unless I'm missing something.
feross
Jan 4, 2016
Author
Contributor
You comment prompted me to check the fs.readSync
case and the issue you describe exists there. I'll fix it and add a test.
You comment prompted me to check the fs.readSync
case and the issue you describe exists there. I'll fix it and add a test.
Caught one additional bug in the legacy usage of Please take a look at the changes and re-run CI. |
fd = fs.openSync(filepath, 'r'), | ||
expected = ''; | ||
|
||
fs.read(fd, 0, 0, 'utf-8', common.mustCall(function(err, str, bytesRead) { |
thefourtheye
Jan 4, 2016
Contributor
Make length consistent with this and the readSync
case.
Make length consistent with this and the readSync
case.
feross
Jan 6, 2016
Author
Contributor
Done!
Done!
@@ -648,6 +654,14 @@ fs.readSync = function(fd, buffer, offset, length, position) { | |||
offset = 0; | |||
} | |||
|
|||
if (length === 0) { |
thefourtheye
Jan 4, 2016
Contributor
The check here means that even if the file doesn't exist/inaccessible, if the length is zero, we will return valid values.
The check here means that even if the file doesn't exist/inaccessible, if the length is zero, we will return valid values.
feross
Jan 5, 2016
Author
Contributor
How do you propose to solve this? @bnoordhuis asked me to move the checks to lib/fs.js
to avoid some kernel edge case.
Thoughts?
How do you propose to solve this? @bnoordhuis asked me to move the checks to lib/fs.js
to avoid some kernel edge case.
Thoughts?
trevnorris
Jan 6, 2016
Contributor
@thefourtheye Since the fd itself is passed best we can attempt to do is read directly from it. But as @feross mentioned, there are cross platform issues that prevents this being done correctly. I don't think that assuming the fd is alright is a problem in this case.
@thefourtheye Since the fd itself is passed best we can attempt to do is read directly from it. But as @feross mentioned, there are cross platform issues that prevents this being done correctly. I don't think that assuming the fd is alright is a problem in this case.
thefourtheye
Jan 6, 2016
Contributor
@trevnorris Ah, you are right. I totally missed that. Then this will not be a problem here.
@trevnorris Ah, you are right. I totally missed that. Then this will not be a problem here.
Defensively marking as |
Updated PR to make the test more consistent, per @thefourtheye's comment. I think this is ready to be landed |
'use strict'; | ||
var common = require('../common'); | ||
var assert = require('assert'); | ||
var path = require('path'), |
jasnell
Jan 6, 2016
Member
these should use const
these should use const
feross
Jan 6, 2016
Author
Contributor
You guys should really add an eslint
rule for this. So much overhead for contributors to deal with the back-and-forth.
You guys should really add an eslint
rule for this. So much overhead for contributors to deal with the back-and-forth.
fd = fs.openSync(filepath, 'r'), | ||
bufferAsync = new Buffer(0), | ||
bufferSync = new Buffer(0); | ||
|
jasnell
Jan 6, 2016
Member
Nit: would prefer the decl's to be separated but not critical
Nit: would prefer the decl's to be separated but not critical
feross
Jan 6, 2016
Author
Contributor
This was copied from another test file. Will change.
This was copied from another test file. Will change.
var common = require('../common'); | ||
var assert = require('assert'); | ||
var path = require('path'), | ||
fs = require('fs'), |
jasnell
Jan 6, 2016
Member
const
please :-)
const
please :-)
feross
Jan 6, 2016
Author
Contributor
Yep.
Yep.
Force pushed again to address @jasnell's comments. fingers crossed |
thank you @feross ... and thank you for bearing with us ;-) the contribution is very appreciated. |
Thanks @jasnell, I appreciate the attention to detail. |
CI failures look unrelated! Will get this landed |
Landed in 2b15e68 |
Nice! |
Fixes: nodejs#4517. PR-URL: nodejs#4518 Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: James M Snell <jasnell@gmail.com>
The following significant (semver-major) changes have been made since the previous Node v5.0.0 release. * Buffer * New Buffer constructors have been added [#4682](#4682) * Previously deprecated Buffer APIs are removed [#5048](#5048), [#4594](#4594) * Improved error handling [#4514](#4514) * Cluster * Worker emitted as first argument in 'message' event [#5361](#5361). * Crypto * Improved error handling [#3100](#3100), [#5611](#5611) * Simplified Certificate class bindings [#5382](#5382) * Improved control over FIPS mode [#5181](#5181) * pbkdf2 digest overloading is deprecated [#4047](#4047) * Dependencies * Reintroduce shared c-ares build support [#5775](#5775). * V8 updated to 5.0.71.31 [#6111](#6111). * DNS * Add resolvePtr API to query plain DNS PTR records [#4921](#4921). * Domains * Clear stack when no error handler [#4659](#4659). * File System * The `fs.realpath()` and `fs.realpathSync()` methods have been updated to use a more efficient libuv implementation. This change includes the removal of the `cache` argument and the method can throw new errors [#3594](#3594) * FS apis can now accept and return paths as Buffers [#5616](#5616). * Error handling and type checking improvements [#5616](#5616), [#5590](#5590), [#4518](#4518), [#3917](#3917). * fs.read's string interface is deprecated [#4525](#4525) * HTTP * 'clientError' can now be used to return custom errors from an HTTP server [#4557](#4557). * Modules * Current directory is now prioritized for local lookups [#5689](#5689) * Symbolic links are preserved when requiring modules [#5950](#5950) * Net * DNS hints no longer implicitly set [#6021](#6021). * Improved error handling and type checking [#5981](#5981), [#5733](#5733), [#2904](#2904) * Path * Improved type checking [#5348](#5348). * Process * Introduce process warnings API [#4782](#4782). * Throw exception when non-function passed to nextTick [#3860](#3860). * Readline * Emit key info unconditionally [#6024](#6024) * REPL * Assignment to `_` will emit a warning. [#5535](#5535) * Timers * Fail early when callback is not a function [#4362](#4362) * TLS * Rename 'clientError' to 'tlsClientError' [#4557](#4557) * SHA1 used for sessionIdContext [#3866](#3866) * TTY * Previously deprecated setRawMode wrapper is removed [#2528](#2528). * Util * Changes to Error object formatting [#4582](#4582). * Windows * Windows XP and Vista are no longer supported [#5167](#5167), [#5167](#5167).
The following significant (semver-major) changes have been made since the previous Node v5.0.0 release. * Buffer * New Buffer constructors have been added [#4682](#4682) * Previously deprecated Buffer APIs are removed [#5048](#5048), [#4594](#4594) * Improved error handling [#4514](#4514) * Cluster * Worker emitted as first argument in 'message' event [#5361](#5361). * Crypto * Improved error handling [#3100](#3100), [#5611](#5611) * Simplified Certificate class bindings [#5382](#5382) * Improved control over FIPS mode [#5181](#5181) * pbkdf2 digest overloading is deprecated [#4047](#4047) * Dependencies * Reintroduce shared c-ares build support [#5775](#5775). * V8 updated to 5.0.71.31 [#6111](#6111). * DNS * Add resolvePtr API to query plain DNS PTR records [#4921](#4921). * Domains * Clear stack when no error handler [#4659](#4659). * File System * The `fs.realpath()` and `fs.realpathSync()` methods have been updated to use a more efficient libuv implementation. This change includes the removal of the `cache` argument and the method can throw new errors [#3594](#3594) * FS apis can now accept and return paths as Buffers [#5616](#5616). * Error handling and type checking improvements [#5616](#5616), [#5590](#5590), [#4518](#4518), [#3917](#3917). * fs.read's string interface is deprecated [#4525](#4525) * HTTP * 'clientError' can now be used to return custom errors from an HTTP server [#4557](#4557). * Modules * Current directory is now prioritized for local lookups [#5689](#5689) * Symbolic links are preserved when requiring modules [#5950](#5950) * Net * DNS hints no longer implicitly set [#6021](#6021). * Improved error handling and type checking [#5981](#5981), [#5733](#5733), [#2904](#2904) * Path * Improved type checking [#5348](#5348). * Process * Introduce process warnings API [#4782](#4782). * Throw exception when non-function passed to nextTick [#3860](#3860). * Readline * Emit key info unconditionally [#6024](#6024) * REPL * Assignment to `_` will emit a warning. [#5535](#5535) * Timers * Fail early when callback is not a function [#4362](#4362) * TLS * Rename 'clientError' to 'tlsClientError' [#4557](#4557) * SHA1 used for sessionIdContext [#3866](#3866) * TTY * Previously deprecated setRawMode wrapper is removed [#2528](#2528). * Util * Changes to Error object formatting [#4582](#4582). * Windows * Windows XP and Vista are no longer supported [#5167](#5167), [#5167](#5167).
The following significant (semver-major) changes have been made since the previous Node v5.0.0 release. * Buffer * New Buffer constructors have been added [#4682](#4682) * Previously deprecated Buffer APIs are removed [#5048](#5048), [#4594](#4594) * Improved error handling [#4514](#4514) * Cluster * Worker emitted as first argument in 'message' event [#5361](#5361). * Crypto * Improved error handling [#3100](#3100), [#5611](#5611) * Simplified Certificate class bindings [#5382](#5382) * Improved control over FIPS mode [#5181](#5181) * pbkdf2 digest overloading is deprecated [#4047](#4047) * Dependencies * Reintroduce shared c-ares build support [#5775](#5775). * V8 updated to 5.0.71.31 [#6111](#6111). * DNS * Add resolvePtr API to query plain DNS PTR records [#4921](#4921). * Domains * Clear stack when no error handler [#4659](#4659). * File System * The `fs.realpath()` and `fs.realpathSync()` methods have been updated to use a more efficient libuv implementation. This change includes the removal of the `cache` argument and the method can throw new errors [#3594](#3594) * FS apis can now accept and return paths as Buffers [#5616](#5616). * Error handling and type checking improvements [#5616](#5616), [#5590](#5590), [#4518](#4518), [#3917](#3917). * fs.read's string interface is deprecated [#4525](#4525) * HTTP * 'clientError' can now be used to return custom errors from an HTTP server [#4557](#4557). * Modules * Current directory is now prioritized for local lookups [#5689](#5689) * Symbolic links are preserved when requiring modules [#5950](#5950) * Net * DNS hints no longer implicitly set [#6021](#6021). * Improved error handling and type checking [#5981](#5981), [#5733](#5733), [#2904](#2904) * OS X * MACOSX_DEPLOYMENT_TARGET has been bumped up to 10.7 [#6402](#6402). * Path * Improved type checking [#5348](#5348). * Process * Introduce process warnings API [#4782](#4782). * Throw exception when non-function passed to nextTick [#3860](#3860). * Readline * Emit key info unconditionally [#6024](#6024) * REPL * Assignment to `_` will emit a warning. [#5535](#5535) * Timers * Fail early when callback is not a function [#4362](#4362) * TLS * Rename 'clientError' to 'tlsClientError' [#4557](#4557) * SHA1 used for sessionIdContext [#3866](#3866) * TTY * Previously deprecated setRawMode wrapper is removed [#2528](#2528). * Util * Changes to Error object formatting [#4582](#4582). * Windows * Windows XP and Vista are no longer supported [#5167](#5167), [#5167](#5167).
The following significant (semver-major) changes have been made since the previous Node v5.0.0 release. * Buffer * New Buffer constructors have been added [#4682](#4682) * Previously deprecated Buffer APIs are removed [#5048](#5048), [#4594](#4594) * Improved error handling [#4514](#4514) * Cluster * Worker emitted as first argument in 'message' event [#5361](#5361). * Crypto * Improved error handling [#3100](#3100), [#5611](#5611) * Simplified Certificate class bindings [#5382](#5382) * Improved control over FIPS mode [#5181](#5181) * pbkdf2 digest overloading is deprecated [#4047](#4047) * Dependencies * Reintroduce shared c-ares build support [#5775](#5775). * V8 updated to 5.0.71.31 [#6111](#6111). * DNS * Add resolvePtr API to query plain DNS PTR records [#4921](#4921). * Domains * Clear stack when no error handler [#4659](#4659). * File System * The `fs.realpath()` and `fs.realpathSync()` methods have been updated to use a more efficient libuv implementation. This change includes the removal of the `cache` argument and the method can throw new errors [#3594](#3594) * FS apis can now accept and return paths as Buffers [#5616](#5616). * Error handling and type checking improvements [#5616](#5616), [#5590](#5590), [#4518](#4518), [#3917](#3917). * fs.read's string interface is deprecated [#4525](#4525) * HTTP * 'clientError' can now be used to return custom errors from an HTTP server [#4557](#4557). * Modules * Current directory is now prioritized for local lookups [#5689](#5689) * Symbolic links are preserved when requiring modules [#5950](#5950) * Net * DNS hints no longer implicitly set [#6021](#6021). * Improved error handling and type checking [#5981](#5981), [#5733](#5733), [#2904](#2904) * OS X * MACOSX_DEPLOYMENT_TARGET has been bumped up to 10.7 [#6402](#6402). * Path * Improved type checking [#5348](#5348). * Process * Introduce process warnings API [#4782](#4782). * Throw exception when non-function passed to nextTick [#3860](#3860). * Readline * Emit key info unconditionally [#6024](#6024) * REPL * Assignment to `_` will emit a warning. [#5535](#5535) * Timers * Fail early when callback is not a function [#4362](#4362) * TLS * Rename 'clientError' to 'tlsClientError' [#4557](#4557) * SHA1 used for sessionIdContext [#3866](#3866) * TTY * Previously deprecated setRawMode wrapper is removed [#2528](#2528). * Util * Changes to Error object formatting [#4582](#4582). * Windows * Windows XP and Vista are no longer supported [#5167](#5167), [#5167](#5167).
The following significant (semver-major) changes have been made since the previous Node v5.0.0 release. * Buffer * New Buffer constructors have been added [#4682](#4682) * Previously deprecated Buffer APIs are removed [#5048](#5048), [#4594](#4594) * Improved error handling [#4514](#4514) * Cluster * Worker emitted as first argument in 'message' event [#5361](#5361). * Crypto * Improved error handling [#3100](#3100), [#5611](#5611) * Simplified Certificate class bindings [#5382](#5382) * Improved control over FIPS mode [#5181](#5181) * pbkdf2 digest overloading is deprecated [#4047](#4047) * Dependencies * Reintroduce shared c-ares build support [#5775](#5775). * V8 updated to 5.0.71.31 [#6111](#6111). * DNS * Add resolvePtr API to query plain DNS PTR records [#4921](#4921). * Domains * Clear stack when no error handler [#4659](#4659). * File System * The `fs.realpath()` and `fs.realpathSync()` methods have been updated to use a more efficient libuv implementation. This change includes the removal of the `cache` argument and the method can throw new errors [#3594](#3594) * FS apis can now accept and return paths as Buffers [#5616](#5616). * Error handling and type checking improvements [#5616](#5616), [#5590](#5590), [#4518](#4518), [#3917](#3917). * fs.read's string interface is deprecated [#4525](#4525) * HTTP * 'clientError' can now be used to return custom errors from an HTTP server [#4557](#4557). * Modules * Current directory is now prioritized for local lookups [#5689](#5689) * Symbolic links are preserved when requiring modules [#5950](#5950) * Net * DNS hints no longer implicitly set [#6021](#6021). * Improved error handling and type checking [#5981](#5981), [#5733](#5733), [#2904](#2904) * OS X * MACOSX_DEPLOYMENT_TARGET has been bumped up to 10.7 [#6402](#6402). * Path * Improved type checking [#5348](#5348). * Process * Introduce process warnings API [#4782](#4782). * Throw exception when non-function passed to nextTick [#3860](#3860). * Readline * Emit key info unconditionally [#6024](#6024) * REPL * Assignment to `_` will emit a warning. [#5535](#5535) * Timers * Fail early when callback is not a function [#4362](#4362) * TLS * Rename 'clientError' to 'tlsClientError' [#4557](#4557) * SHA1 used for sessionIdContext [#3866](#3866) * TTY * Previously deprecated setRawMode wrapper is removed [#2528](#2528). * Util * Changes to Error object formatting [#4582](#4582). * Windows * Windows XP and Vista are no longer supported [#5167](#5167), [#5167](#5167).
Fixes #4517.