Browse Source

lib: fix max size check in Buffer constructor

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>
v1.8.0-commit
Ben Noordhuis 10 years ago
parent
commit
0767c2feb1
  1. 10
      lib/buffer.js
  2. 3
      test/parallel/test-buffer.js

10
lib/buffer.js

@ -31,7 +31,7 @@ function Buffer(subject, encoding) {
return new Buffer(subject, encoding); return new Buffer(subject, encoding);
if (util.isNumber(subject)) { if (util.isNumber(subject)) {
this.length = subject > 0 ? subject >>> 0 : 0; this.length = +subject;
} else if (util.isString(subject)) { } else if (util.isString(subject)) {
if (!util.isString(encoding) || encoding.length === 0) if (!util.isString(encoding) || encoding.length === 0)
@ -42,8 +42,7 @@ function Buffer(subject, encoding) {
} else if (util.isObject(subject)) { } else if (util.isObject(subject)) {
if (subject.type === 'Buffer' && util.isArray(subject.data)) if (subject.type === 'Buffer' && util.isArray(subject.data))
subject = subject.data; subject = subject.data;
// Must use floor() because array length may be > kMaxLength. this.length = +subject.length;
this.length = +subject.length > 0 ? Math.floor(+subject.length) : 0;
} else { } else {
throw new TypeError('must start with number, buffer, array or string'); 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'); 'size: 0x' + kMaxLength.toString(16) + ' bytes');
} }
if (this.length < 0)
this.length = 0;
else
this.length >>>= 0; // Coerce to uint32.
this.parent = undefined; this.parent = undefined;
if (this.length <= (Buffer.poolSize >>> 1) && this.length > 0) { if (this.length <= (Buffer.poolSize >>> 1) && this.length > 0) {
if (this.length > poolSize - poolOffset) if (this.length > poolSize - poolOffset)

3
test/parallel/test-buffer.js

@ -1163,3 +1163,6 @@ assert.throws(function() {
var b = new Buffer(1); var b = new Buffer(1);
b.equals('abc'); b.equals('abc');
}); });
// Regression test for https://github.com/iojs/io.js/issues/649.
assert.throws(function() { Buffer(1422561062959).toString('utf8'); });

Loading…
Cancel
Save