buffers: handle bad length argument in constructor
authorBen Noordhuis <info@bnoordhuis.nl>
Sat, 24 Sep 2011 03:07:35 +0000 (05:07 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Sat, 24 Sep 2011 16:27:03 +0000 (18:27 +0200)
Coerce fractional, negative and non-numeric length arguments to numbers.
Fractional numbers are rounded up, negative numbers and non-numeric values
are set to zero.

lib/buffer.js
test/simple/test-buffer.js

index 91fd677..25dfaab 100644 (file)
@@ -196,6 +196,15 @@ SlowBuffer.prototype.slice = function(start, end) {
 };
 
 
+function coerce(length) {
+  // Coerce length to a number (possibly NaN), round up
+  // in case it's fractional (e.g. 123.456) then do a
+  // double negate to coerce a NaN to 0. Easy, right?
+  length = ~~Math.ceil(+length);
+  return length < 0 ? 0 : length;
+}
+
+
 // Buffer
 
 function Buffer(subject, encoding, offset) {
@@ -207,14 +216,14 @@ function Buffer(subject, encoding, offset) {
 
   // Are we slicing?
   if (typeof offset === 'number') {
-    this.length = encoding;
+    this.length = coerce(encoding);
     this.parent = subject;
     this.offset = offset;
   } else {
     // Find the length
     switch (type = typeof subject) {
       case 'number':
-        this.length = subject;
+        this.length = coerce(subject);
         break;
 
       case 'string':
@@ -222,7 +231,7 @@ function Buffer(subject, encoding, offset) {
         break;
 
       case 'object': // Assume object is an array
-        this.length = subject.length;
+        this.length = coerce(subject.length);
         break;
 
       default:
index 4152c28..fdd3a36 100644 (file)
@@ -689,3 +689,16 @@ buf.write('123456', 'base64');
 assert.equal(Buffer._charsWritten, 6);
 buf.write('00010203040506070809', 'hex');
 assert.equal(Buffer._charsWritten, 18);
+
+// Check for fractional length args, junk length args, etc.
+// https://github.com/joyent/node/issues/1758
+Buffer(3.3).toString(); // throws bad argument error in commit 43cb4ec
+assert.equal(Buffer(-1).length, 0);
+assert.equal(Buffer(NaN).length, 0);
+assert.equal(Buffer(3.3).length, 4);
+assert.equal(Buffer({length:3.3}).length, 4);
+assert.equal(Buffer({length:"BAM"}).length, 0);
+
+// Make sure that strings are not coerced to numbers.
+assert.equal(Buffer("99").length, 2);
+assert.equal(Buffer("13.37").length, 5);
\ No newline at end of file