lib: fix max size check in Buffer constructor
authorBen Noordhuis <info@bnoordhuis.nl>
Thu, 29 Jan 2015 19:57:54 +0000 (20:57 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Sat, 31 Jan 2015 09:13:50 +0000 (10:13 +0100)
A number -> uint32 type coercion bug made buffer sizes
larger than kMaxLength (0x3fffffff) wrap around.

Instead of rejecting the requested size with an exception,
the constructor created a buffer with the wrong size.

PR-URL: https://github.com/iojs/io.js/pull/657
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
lib/buffer.js
test/parallel/test-buffer.js

index 4c87726..41de85e 100644 (file)
@@ -31,7 +31,7 @@ function Buffer(subject, encoding) {
     return new Buffer(subject, encoding);
 
   if (util.isNumber(subject)) {
-    this.length = subject > 0 ? subject >>> 0 : 0;
+    this.length = +subject;
 
   } else if (util.isString(subject)) {
     if (!util.isString(encoding) || encoding.length === 0)
@@ -42,8 +42,7 @@ function Buffer(subject, encoding) {
   } else if (util.isObject(subject)) {
     if (subject.type === 'Buffer' && util.isArray(subject.data))
       subject = subject.data;
-    // Must use floor() because array length may be > kMaxLength.
-    this.length = +subject.length > 0 ? Math.floor(+subject.length) : 0;
+    this.length = +subject.length;
 
   } else {
     throw new TypeError('must start with number, buffer, array or string');
@@ -54,6 +53,11 @@ function Buffer(subject, encoding) {
                          'size: 0x' + kMaxLength.toString(16) + ' bytes');
   }
 
+  if (this.length < 0)
+    this.length = 0;
+  else
+    this.length >>>= 0;  // Coerce to uint32.
+
   this.parent = undefined;
   if (this.length <= (Buffer.poolSize >>> 1) && this.length > 0) {
     if (this.length > poolSize - poolOffset)
index 1188c1f..3c25b8e 100644 (file)
@@ -1163,3 +1163,6 @@ assert.throws(function() {
   var b = new Buffer(1);
   b.equals('abc');
 });
+
+// Regression test for https://github.com/iojs/io.js/issues/649.
+assert.throws(function() { Buffer(1422561062959).toString('utf8'); });