aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/buffer.js31
-rw-r--r--src/node_internals.h2
2 files changed, 27 insertions, 6 deletions
diff --git a/lib/buffer.js b/lib/buffer.js
index 41f1f4b391..7221f42c5a 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -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;
+
+ 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) {
diff --git a/src/node_internals.h b/src/node_internals.h
index bfe4fced26..e1ba9e2294 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -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();
if (tmp_i < 0)
return false;