-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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: fix fill
with encoding in Buffer.alloc()
#9238
buffer: fix fill
with encoding in Buffer.alloc()
#9238
Conversation
Previously, the implementation of Buffer.alloc() called Buffer#fill() with another Buffer as an argument. However, in v4.x, Buffer#fill does not support a Buffer as a parameter. As a workaround, call binding.fill() directly in the Buffer.alloc() implementation. Fixes: nodejs#9226
ci: https://ci.nodejs.org/job/node-test-pull-request/4616/ /cc @jasnell @nodejs/buffer |
// issue GH-9226 | ||
{ | ||
const buf = Buffer.alloc(4, 'YQ==', 'base64'); | ||
const expectedBuf = new Buffer([97, 97, 97, 97]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't this be Buffer.from()
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea; I had been under the impression that Buffer.from()
had different behavior in v4, but it seems like that's not an issue here.
} | ||
{ | ||
const buf = Buffer.alloc(4, 'ab', 'ascii'); | ||
const expectedBuf = new Buffer([97, 98, 97, 98]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
@@ -1060,6 +1060,17 @@ assert.throws(function() { | |||
Buffer.allocUnsafe(0xFFFFFFFFF); | |||
}, RangeError); | |||
|
|||
// issue GH-9226 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be better to provide a URL instead (or at least in addition).
It should be noted that this change will put the function over the default code inlining limit (600 characters). This may not be very desirable since Buffers get used so much, inside and outside of core. |
That's inconvenient. Should I try to reduce the size to under the limit, or extract the added code into a separate private function? |
If it's feasible, maybe we can just backport the required Or maybe move both sets of comments before the function? |
I think backporting would be the more elegant fix, but for this PR I wanted to avoid touching the public API at all. Moving the comments seems like it should work. |
* | ||
* Only pay attention to encoding if it's a string. This | ||
* prevents accidentally sending in a number that would | ||
* be interpretted as a start offset. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this was copied, but there is a typo here: s/interpretted/interpreted/
@@ -1060,6 +1060,8 @@ assert.throws(function() { | |||
Buffer.allocUnsafe(0xFFFFFFFFF); | |||
}, RangeError); | |||
|
|||
assert(Buffer.alloc.toString().length < 600, 'Buffer.alloc is not inlineable'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this. There was some discussion awhile back about linting for this, but maybe it would be easier or just as easy to do it this way.
I'm wondering though since it's not really a test per se that we might just put all of these kinds of checks in a separate file where we check the lengths of various commonly used functions? /cc @nodejs/collaborators
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to do this for all functions, then I think linting would be easier. But I would assume we have a lot of longer functions that aren't worth shortening.
For what it's worth, apparently TurboFan doesn't take function length into account when inlining (source).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it wouldn't be for all functions, just select ones.
That's interesting about TurboFan, but Crankshaft is still used quite a bit.
EDIT: It looks like that change was reverted shortly after? It was relanded after that heh...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, in that case linting for it might be kind of annoying, because we would have to explicitly state the list of functions somewhere.
Should we move this discussion to a separate issue? In terms of making sure Buffer.alloc
can be inlined, I think this test works fine. Having a separate file for inlining checks might be a good idea, but it seems like it's out of scope for this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine, my main concern was about adding this particular instance now. Hopefully we can get some input from other @nodejs/collaborators and see what they think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not opposed to having this somewhere, but I don't think it should be part of our standard test suite. This seems very coupled to V8, and potentially specific versions of V8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we find out later on that function length is no longer a concern, then we can always remove this test. At the moment, though, while we apparently consider it worthwhile to keep commonly-used functions under 600 characters, we're relying on code review to make sure that happens. If it's worth making changes to the standard library's code to fulfill this requirement, I think it's also worth adding a test to make it easier to notice that the function is too long.
(Also, keep in mind that this fix is specific to v4.x, so it seems unlikely that it will make it into a different version of V8.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just in case if we want to lint against this, there is a ready ESLint plugin for that https://www.npmjs.com/package/eslint-plugin-v8-func-inline which we could enable for select functions using comment-based rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and yes, in TurboFan this should be fixed now - it has limit only on AST complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RReverser I tried out that ESLint plugin, but it seems to check the length of the entire file, rather than the length of a function itself. So if a file has many small functions, they will all get reported.
so do we want to land this or backport the original change? |
If we backport the There is also a slight chance of breakage if someone was confused and passed a buffer to I think it would be simpler to just use this fix and not backport the semver-minor change, but I would be fine with either. |
/cc @nodejs/ctc and @nodejs/lts Are you happy with this landing in the current state? |
SGTM |
LGTM |
all failures are infra related |
Previously, the implementation of Buffer.alloc() called Buffer#fill() with another Buffer as an argument. However, in v4.x, Buffer#fill does not support a Buffer as a parameter. As a workaround, call binding.fill() directly in the Buffer.alloc() implementation. Fixes: #9226 PR-URL: #9238 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
landed in dc3e45f |
Previously, the implementation of Buffer.alloc() called Buffer#fill() with another Buffer as an argument. However, in v4.x, Buffer#fill does not support a Buffer as a parameter. As a workaround, call binding.fill() directly in the Buffer.alloc() implementation. Fixes: #9226 PR-URL: #9238 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This LTS release comes with 219 commits. This includes 80 commits that are docs related, 58 commits that are test related, 20 commits that are build / tool related, and 9 commits that are updates to dependencies. Notable Changes * build: - It is now possible to build the documentation from the release tarball (Anna Henningsen) #8413 * buffer: - Buffer will no longer incorrectly return a zero filled buffer when an encoding is passed (Teddy Katz) #9238 * deps: - upgrade npm in LTS to 2.15.11 (Kat Marchán) #8928 * repl: - Enable tab completion for global properties (Lance Ball) #7369 * url: - `url.format()` will now encode all `#` in `search` (Ilkka Myller) #8072 PR-URL: #9298
This LTS release comes with 219 commits. This includes 80 commits that are docs related, 58 commits that are test related, 20 commits that are build / tool related, and 9 commits that are updates to dependencies. Notable Changes * build: - It is now possible to build the documentation from the release tarball (Anna Henningsen) #8413 * buffer: - Buffer.alloc() will no longer incorrectly return a zero filled buffer when an encoding is passed (Teddy Katz) #9238 * deps: - upgrade npm in LTS to 2.15.11 (Kat Marchán) #8928 * repl: - Enable tab completion for global properties (Lance Ball) #7369 * url: - `url.format()` will now encode all `#` in `search` (Ilkka Myller) #8072 PR-URL: #9298
This LTS release comes with 219 commits. This includes 80 commits that are docs related, 58 commits that are test related, 20 commits that are build / tool related, and 9 commits that are updates to dependencies. Notable Changes * build: - It is now possible to build the documentation from the release tarball (Anna Henningsen) #8413 * buffer: - Buffer.alloc() will no longer incorrectly return a zero filled buffer when an encoding is passed (Teddy Katz) #9238 * deps: - upgrade npm in LTS to 2.15.11 (Kat Marchán) #8928 * repl: - Enable tab completion for global properties (Lance Ball) #7369 * url: - `url.format()` will now encode all `#` in `search` (Ilkka Myller) #8072 PR-URL: #9298
This LTS release comes with 219 commits. This includes 80 commits that are docs related, 58 commits that are test related, 20 commits that are build / tool related, and 9 commits that are updates to dependencies. Notable Changes * build: - It is now possible to build the documentation from the release tarball (Anna Henningsen) #8413 * buffer: - Buffer.alloc() will no longer incorrectly return a zero filled buffer when an encoding is passed (Teddy Katz) #9238 * deps: - upgrade npm in LTS to 2.15.11 (Kat Marchán) #8928 * repl: - Enable tab completion for global properties (Lance Ball) #7369 * url: - `url.format()` will now encode all `#` in `search` (Ilkka Myller) #8072 PR-URL: #9298
This LTS release comes with 219 commits. This includes 80 commits that are docs related, 58 commits that are test related, 20 commits that are build / tool related, and 9 commits that are updates to dependencies. Notable Changes * build: - It is now possible to build the documentation from the release tarball (Anna Henningsen) nodejs/node#8413 * buffer: - Buffer.alloc() will no longer incorrectly return a zero filled buffer when an encoding is passed (Teddy Katz) nodejs/node#9238 * deps: - upgrade npm in LTS to 2.15.11 (Kat Marchan) nodejs/node#8928 * repl: - Enable tab completion for global properties (Lance Ball) nodejs/node#7369 * url: - `url.format()` will now encode all `#` in `search` (Ilkka Myller) nodejs/node#8072 PR-URL: nodejs/node#9298 Signed-off-by: Ilkka Myller <ilkka.myller@nodefield.com>
Checklist
make -j8 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
buffer
Description of change
Previously, the implementation of Buffer.alloc() called Buffer#fill()
with another Buffer as an argument. However, in v4.x, Buffer#fill does
not support a Buffer as an argument. As a workaround, call
binding.fill() directly in the Buffer.alloc() implementation.
Fixes: #9226