-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
Unreachable code in buffer.js and unsigned bitwise shifts. #2668
Comments
Glad that you brought this. I was mentioning something like this to trevnorris in a comment. I say let's not do coercing and validate the values as they are and throw error if they are invalid. It would keep the code straightforward and easily maintainable. |
As I mentioned in the referenced issue, the conditional and check should be above the value coercion. In the case of We shouldn't throw any more exceptions ATM so that the patch can land in v4. Otherwise it'll have to wait for v5. And there are legitimate bugs here that should be addressed which should propagate to v4. Any other changes should be referenced against documentation. Though I know in several cases where it's just not documented. |
Here's one potential solution for https://github.com/nodejs/node/blob/v3.3.0/lib/buffer.js#L314: if (start < 0) start = 0;
if (start > 0x7fffffff) start = 0x7fffffff; The reason for this is because in As you can see, this mess goes deeper. We should do a full assessment of the code and how all these cases are handled. I'm the one responsible for switching to use the Addressing throwing more often, any place we currently don't throw, we won't start for the time being. First we'll have to make an assessment of how much community breakage it will introduce. Its APIs are in massive use and possibly breaking them for anything short of a security issue would be difficult. |
If `start` is not a valid number in the range, then the default value zero will be used. Same way, if `end` is not a valid number in the accepted range, then, by default, the length of the buffer is assumed. Ref: nodejs#2668 PR-URL: nodejs#2919
This is fixed only partially. |
If `start` is not a valid number in the range, then the default value zero will be used. Same way, if `end` is not a valid number in the accepted range, then, by default, the length of the buffer is assumed. Fixes: nodejs#2668 Ref: nodejs#2919 PR-URL: nodejs#4019 Reviewed-By: Trevor Norris <trev.norris@gmail.com>
I will re-check this in a few days. |
@ChALkeR Any progress? |
@Fishrock123 This is still partially applicable. https://github.com/nodejs/node/blob/master/lib/buffer.js#L725-L726 — |
@ChALkeR Status? |
@bnoordhuis There are still some unreachable lines of code there, but those can be viewed as safeguards. I will take another look shortly to confirm that everything is fine. Perhaps I will file a PR to add some comments there. |
The offset check should either be removed, or a comment should be added that this is a safeguard. Otherwise it will confuse people reading the code and waste their time. |
The coverage.nodejs.org indicates that there is 100% code coverage for buffer.js, so assuming no issues with the coverage reports, all code in buffer.js is reachable now and all conditions are evaluated as both true and false in the course of tests.. Closing. Feel free to re-open if you think that's premature or incorrect. |
Thing to note here:
A >>> B
converts both arguments to unsigned int: http://www.ecma-international.org/ecma-262/6.0/#sec-unsigned-right-shift-operator.buffer.js#L314 is not reachable. If argumentFixed.start
is a number that is less than 0, thenstart >>> 0
makes it a (large) positive number.offset < 0
check that is not reachable, because above it was either set to0
oroffset >>> 0
orlength >>> 0
.buffer.js#L498 haslength < 0
check that is reachable only throughXXX legacy write(string, encoding, offset, length) - remove in v0.13
case, because else it was set to either0
,undefined
, orthis.length
(which should be probably not less than 0 I guess). On a side note: sould that legacy path be removed in 4.0 or not? Btw, in the «legacy write(» case there is no type checking or casting forlength
.Also, on many other lines,
offset = offset >>> 0
and a succeedingcheckInt(this, value, offset
is done.Note that
-30064771000 >>> 0
===72
, which makes-30064771000
a validoffset
input, which could be a bit unexpected. Also,checkInt
doesn't check foroffset
(oroffset + ext
) to be not less than zero. Such check would be unreachable now (becauseoffset
is always cast to unsigned), but it could be usable once this is fixed.Btw, with these negative values the same happens also when
>>
or|
(or any other cast-to-int) is used:-30064771070 >> 0 === 2
,-30064771070 | 0 === 0
. All checks should be probably done before int casting.Maybe it's worth splitting this into two issues — unreachable code and casting before checks.
@trevnorris
The text was updated successfully, but these errors were encountered: