Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buffer: throw on failed fill attempts #17427

Merged
merged 1 commit into from
Dec 6, 2017
Merged

buffer: throw on failed fill attempts #17427

merged 1 commit into from
Dec 6, 2017

Conversation

cjihrig
Copy link
Contributor

@cjihrig cjihrig commented Dec 2, 2017

If fill() attempts to write a string to a buffer, but fails silently, then uninitialized memory could be leaked. This commit causes fill() to throw if the string write operation fails.

This also addresses an existing TODO comment.

Fixes: #17423

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

buffer

@nodejs-github-bot nodejs-github-bot added buffer Issues and PRs related to the buffer subsystem. c++ Issues and PRs that require attention from people who are familiar with C++. labels Dec 2, 2017
if (str_length == 0)
return;
return env->ThrowError("Buffer could not be filled");
Copy link
Member

@apapirovski apapirovski Dec 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super familiar with this code but could this return a non-undefined value (that is, not from this return statement but the usual args.GetReturnValue().Set()) and then throw in JS? Then we could have an error code for it and document it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing from JavaScript would be ideal

@addaleax addaleax added the semver-major PRs that contain breaking changes and should be released in the next major version. label Dec 2, 2017
addaleax added a commit to addaleax/node that referenced this pull request Dec 2, 2017
Zero-fill when `Buffer.alloc()` receives invalid fill data.

A solution like nodejs#17427 which switches
to throwing makes sense, but is likely a breaking change.

This suggestion leaves the behaviour of `buffer.fill()` untouched,
since any change to it would be a breaking change, and lets
`Buffer.alloc()` check whether any filling took place or not.

Refs: nodejs#17427
Refs: nodejs#17423
@jasnell
Copy link
Member

jasnell commented Dec 5, 2017

I'm good with this but the new error needs to have an internal/errors error code assigned.

addaleax added a commit that referenced this pull request Dec 5, 2017
Zero-fill when `Buffer.alloc()` receives invalid fill data.

A solution like #17427 which switches
to throwing makes sense, but is likely a breaking change.

This suggestion leaves the behaviour of `buffer.fill()` untouched,
since any change to it would be a breaking change, and lets
`Buffer.alloc()` check whether any filling took place or not.

PR-URL: #17428
Refs: #17427
Refs: #17423
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
addaleax added a commit to addaleax/node that referenced this pull request Dec 5, 2017
Zero-fill when `Buffer.alloc()` receives invalid fill data.

A solution like nodejs#17427 which switches
to throwing makes sense, but is likely a breaking change.

This suggestion leaves the behaviour of `buffer.fill()` untouched,
since any change to it would be a breaking change, and lets
`Buffer.alloc()` check whether any filling took place or not.

PR-URL: nodejs#17428
Refs: nodejs#17427
Refs: nodejs#17423
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
@cjihrig cjihrig force-pushed the 17423 branch 5 times, most recently from 7209946 to 8b7ad01 Compare December 5, 2017 15:21
@cjihrig
Copy link
Contributor Author

cjihrig commented Dec 5, 2017

Updated to throw in JavaScript.

Copy link
Member

@BridgeAR BridgeAR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation in buffer.md has to be updated as well and it would be good to switch to a TypeError.

Besides that this is the right approach out of my perspective and LGTM and we should do this, even if it is a BC.

lib/buffer.js Outdated

return bindingFill(buf, val, start, end, encoding);
if (fillLength === -1)
throw new errors.Error('ERR_INVALID_ARG_VALUE', 'value', val);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a TypeError as far as I see it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1... TypeError would be better here.

@BridgeAR
Copy link
Member

BridgeAR commented Dec 5, 2017

Oh, it seems the alternative already landed. I personally think this is actually the better approach but as that was already decided, I am closing this.

@BridgeAR BridgeAR closed this Dec 5, 2017
@apapirovski
Copy link
Member

@BridgeAR I think this was still open because this might be the direction for 10.x while the other PR takes care of all other active release lines. I think it should be re-opened potentially?

@cjihrig
Copy link
Contributor Author

cjihrig commented Dec 5, 2017

buffer.md was already updated. I don't know that a TypeError is necessarily correct in this case. And yes, this is intended for Node 10.x.

@cjihrig cjihrig reopened this Dec 5, 2017
@BridgeAR
Copy link
Member

BridgeAR commented Dec 5, 2017

Thanks, seems like I did not look closely enough in the other one. The documentation needs another update though. There is a example that would throw now in buffer.fill.

Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if changed to use TypeError

@cjihrig
Copy link
Contributor Author

cjihrig commented Dec 6, 2017

Updated to a TypeError, fixed the documentation example.

CI: https://ci.nodejs.org/job/node-test-pull-request/11912/

If fill() attempts to write a string to a buffer, but fails
silently, then uninitialized memory could be leaked. This commit
causes fill() to throw if the string write operation fails.

Refs: nodejs#17423
PR-URL: nodejs#17427
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
@cjihrig cjihrig deleted the 17423 branch December 6, 2017 17:04
@BridgeAR
Copy link
Member

BridgeAR commented Dec 6, 2017

@cjihrig even though I guess this is a uncontroversial commit, it did not get two TSC approvals yet.


```js
const buf = Buffer.allocUnsafe(5);
// Prints: <Buffer 61 61 61 61 61>
console.log(buf.fill('a'));
// Prints: <Buffer aa aa aa aa aa>
console.log(buf.fill('aazz', 'hex'));
// Prints: <Buffer aa aa aa aa aa>
// Throws a exception.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Micro-nit: a -> an

@Trott
Copy link
Member

Trott commented Dec 6, 2017

@cjihrig even though I guess this is a uncontroversial commit, it did not get two TSC approvals yet.

Heh, we were just talking about stuff like this (sort of) in Build WG yesterday. One more data point/argument for moving to more automation. @maclover7

@cjihrig
Copy link
Contributor Author

cjihrig commented Dec 6, 2017

I'd like to propose dropping that rule. Or at least provide some type of time boxing where it no longer applies if there are no objections.

@Trott
Copy link
Member

Trott commented Dec 6, 2017

I'd like to propose dropping that rule. Or at least provide some type of time boxing where it no longer applies if there are no objections.

Sounds like re-opening nodejs/TSC#378.

I strongly opposed such a move, although I was in the minority. I still oppose it although I am probably still in the minority.

If two TSC members (out of 20!!!) can't be moved to review a change in a timely fashion, fix the TSC. Our first impulse is always to accommodate disengaged folks. We need to stop that.

In fairness to TSC folks, there wasn't any ping on this one so it may have slipped under the radar for lots of folks. If we want to change the rules for semver-major changes, let's make that change: Require @-mentioning @nodejs/tsc.

@cjihrig
Copy link
Contributor Author

cjihrig commented Dec 6, 2017

Requiring an @ mention sounds fair enough.

Copy link
Member

@Trott Trott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After-the-fact LGTM.

cjihrig added a commit to cjihrig/node that referenced this pull request Dec 6, 2017
Refs: nodejs#17427
PR-URL: nodejs#17501
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@MylesBorins
Copy link
Contributor

rather than @ mentioning I find adding @nodejs/tsc as a reviewer is a much better approach, that way it ends up in peoples github list of issues to review (as well as pinging them)

@BridgeAR
Copy link
Member

BridgeAR commented Dec 6, 2017

That could be both a requirement.

gibfahn pushed a commit that referenced this pull request Dec 6, 2017
Zero-fill when `Buffer.alloc()` receives invalid fill data.

A solution like #17427 which switches
to throwing makes sense, but is likely a breaking change.

This suggestion leaves the behaviour of `buffer.fill()` untouched,
since any change to it would be a breaking change, and lets
`Buffer.alloc()` check whether any filling took place or not.

PR-URL: #17428
Backport-PR-URL: #17467
Refs: #17427
Refs: #17423
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
MylesBorins pushed a commit that referenced this pull request Dec 7, 2017
Zero-fill when `Buffer.alloc()` receives invalid fill data.

A solution like #17427 which switches
to throwing makes sense, but is likely a breaking change.

This suggestion leaves the behaviour of `buffer.fill()` untouched,
since any change to it would be a breaking change, and lets
`Buffer.alloc()` check whether any filling took place or not.

PR-URL: #17428
Backport-PR-URL: #17467
Refs: #17427
Refs: #17423
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
MylesBorins pushed a commit that referenced this pull request Dec 7, 2017
Zero-fill when `Buffer.alloc()` receives invalid fill data.

A solution like #17427 which switches
to throwing makes sense, but is likely a breaking change.

This suggestion leaves the behaviour of `buffer.fill()` untouched,
since any change to it would be a breaking change, and lets
`Buffer.alloc()` check whether any filling took place or not.

PR-URL: #17428
Refs: #17427
Refs: #17423
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
evanlucas pushed a commit that referenced this pull request Dec 7, 2017
Zero-fill when `Buffer.alloc()` receives invalid fill data.

A solution like #17427 which switches
to throwing makes sense, but is likely a breaking change.

This suggestion leaves the behaviour of `buffer.fill()` untouched,
since any change to it would be a breaking change, and lets
`Buffer.alloc()` check whether any filling took place or not.

PR-URL: #17428
Refs: #17427
Refs: #17423
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
buffer Issues and PRs related to the buffer subsystem. c++ Issues and PRs that require attention from people who are familiar with C++. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants