-
-
Notifications
You must be signed in to change notification settings - Fork 33.9k
buffer: fix range checking for slowToString #4019
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -327,13 +327,34 @@ Object.defineProperty(Buffer.prototype, 'offset', { | |
| function slowToString(encoding, start, end) { | ||
| var loweredCase = false; | ||
|
|
||
| start = start >>> 0; | ||
| end = end === undefined || end === Infinity ? this.length : end >>> 0; | ||
| // No need to verify that "this.length <= MAX_UINT32" since it's a read-only | ||
| // property of a typed array. | ||
|
|
||
| // This behaves neither like String nor Uint8Array in that we set start/end | ||
| // to their upper/lower bounds if the value passed is out of range. | ||
| // undefined is handled specially as per ECMA-262 6th Edition, | ||
| // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. | ||
| if (start === undefined || start < 0) | ||
| start = 0; | ||
| // Return early if start > this.length. Done here to prevent potential uint32 | ||
| // coercion fail below. | ||
| if (start > this.length) | ||
| return ''; | ||
|
|
||
| if (end === undefined || end > this.length) | ||
| end = this.length; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just after this what about: if (end <= 0)
return '';Then can follow up with end >>>= 0;
start >>>= 0;
if (end <= start)
return '';That take care of all the cases?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe so. The tests all still pass and it's more readable than the inline assignments in the conditional. |
||
|
|
||
| if (end <= 0) | ||
| return ''; | ||
|
|
||
| // Force coersion to uint32. This will also coerce falsey/NaN values to 0. | ||
| end >>>= 0; | ||
| start >>>= 0; | ||
|
|
||
| if (end <= start) | ||
| return ''; | ||
|
|
||
| if (!encoding) encoding = 'utf8'; | ||
| if (start < 0) start = 0; | ||
| if (end > this.length) end = this.length; | ||
| if (end <= start) return ''; | ||
|
|
||
| while (true) { | ||
| switch (encoding) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -172,7 +172,7 @@ inline MUST_USE_RESULT bool ParseArrayIndex(v8::Local<v8::Value> arg, | |
| return true; | ||
| } | ||
|
|
||
| int32_t tmp_i = arg->Int32Value(); | ||
| int32_t tmp_i = arg->Uint32Value(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll discuss this in another PR.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, unfortunately I don't have context on why this change was made in the first place.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah. and the changes you've made so far are excellent and I don't want to hold them back while we discuss how to handle this case.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but for future reference, the idea was to keep the numeric type the same all the way through. Since JS is doing uint32 coercions to the values, wanted to propagate this. Otherwise a uint32 value > max int32 could case to strange behavior. not a problem thus far b/c length can't get that large, but not a great way to be. |
||
|
|
||
| if (tmp_i < 0) | ||
| return false; | ||
|
|
||
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.
May want to make mention here that the reason for only checking
undefinedhere is adhering to ECMA-262 6th Edition, Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. In that if the argument isundefinedthen the "defaultValue" is used. Otherwise other arguments are coerced normally.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.
Done.