buffer: use a default offset

If none is provided, use zero as a default offset for all read/write
operations on the buffer.

PR-URL: https://github.com/nodejs/node/pull/19749
Refs: https://github.com/nodejs/node/pull/18395
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
Ruben Bridgewater 2018-04-02 13:44:26 +02:00
parent a25f56730e
commit d5495e859c
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
8 changed files with 134 additions and 70 deletions

View File

@ -19,7 +19,9 @@ const float64Array = new Float64Array(1);
const uInt8Float64Array = new Uint8Array(float64Array.buffer);
// Check endianness.
float32Array[0] = -1;
float32Array[0] = -1; // 0xBF800000
// Either it is [0, 0, 128, 191] or [191, 128, 0, 0]. It is not possible to
// check this with `os.endianness()` because that is determined at compile time.
const bigEndian = uInt8Float32Array[3] === 0;
function checkBounds(buf, offset, byteLength) {
@ -67,13 +69,13 @@ function readUIntLE(offset, byteLength) {
return this.readUInt32LE(offset);
if (byteLength === 2)
return this.readUInt16LE(offset);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return this.readUInt8(offset);
boundsError(byteLength, 6, 'byteLength');
}
function readUInt48LE(buf, offset) {
function readUInt48LE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 5];
@ -87,7 +89,7 @@ function readUInt48LE(buf, offset) {
(buf[++offset] + last * 2 ** 8) * 2 ** 32;
}
function readUInt40LE(buf, offset) {
function readUInt40LE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 4];
@ -101,7 +103,7 @@ function readUInt40LE(buf, offset) {
last * 2 ** 32;
}
function readUInt32LE(offset) {
function readUInt32LE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 3];
@ -114,7 +116,7 @@ function readUInt32LE(offset) {
last * 2 ** 24;
}
function readUInt24LE(buf, offset) {
function readUInt24LE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 2];
@ -124,7 +126,7 @@ function readUInt24LE(buf, offset) {
return first + buf[++offset] * 2 ** 8 + last * 2 ** 16;
}
function readUInt16LE(offset) {
function readUInt16LE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 1];
@ -134,7 +136,7 @@ function readUInt16LE(offset) {
return first + last * 2 ** 8;
}
function readUInt8(offset) {
function readUInt8(offset = 0) {
checkNumberType(offset);
const val = this[offset];
if (val === undefined)
@ -154,13 +156,13 @@ function readUIntBE(offset, byteLength) {
return this.readUInt32BE(offset);
if (byteLength === 2)
return this.readUInt16BE(offset);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return this.readUInt8(offset);
boundsError(byteLength, 6, 'byteLength');
}
function readUInt48BE(buf, offset) {
function readUInt48BE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 5];
@ -174,7 +176,7 @@ function readUInt48BE(buf, offset) {
last;
}
function readUInt40BE(buf, offset) {
function readUInt40BE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 4];
@ -188,7 +190,7 @@ function readUInt40BE(buf, offset) {
last;
}
function readUInt32BE(offset) {
function readUInt32BE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 3];
@ -201,7 +203,7 @@ function readUInt32BE(offset) {
last;
}
function readUInt24BE(buf, offset) {
function readUInt24BE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 2];
@ -211,7 +213,7 @@ function readUInt24BE(buf, offset) {
return first * 2 ** 16 + buf[++offset] * 2 ** 8 + last;
}
function readUInt16BE(offset) {
function readUInt16BE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 1];
@ -232,13 +234,13 @@ function readIntLE(offset, byteLength) {
return this.readInt32LE(offset);
if (byteLength === 2)
return this.readInt16LE(offset);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return this.readInt8(offset);
boundsError(byteLength, 6, 'byteLength');
}
function readInt48LE(buf, offset) {
function readInt48LE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 5];
@ -253,7 +255,7 @@ function readInt48LE(buf, offset) {
buf[++offset] * 2 ** 24;
}
function readInt40LE(buf, offset) {
function readInt40LE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 4];
@ -267,7 +269,7 @@ function readInt40LE(buf, offset) {
buf[++offset] * 2 ** 24;
}
function readInt32LE(offset) {
function readInt32LE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 3];
@ -280,7 +282,7 @@ function readInt32LE(offset) {
(last << 24); // Overflow
}
function readInt24LE(buf, offset) {
function readInt24LE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 2];
@ -291,7 +293,7 @@ function readInt24LE(buf, offset) {
return val | (val & 2 ** 23) * 0x1fe;
}
function readInt16LE(offset) {
function readInt16LE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 1];
@ -302,7 +304,7 @@ function readInt16LE(offset) {
return val | (val & 2 ** 15) * 0x1fffe;
}
function readInt8(offset) {
function readInt8(offset = 0) {
checkNumberType(offset);
const val = this[offset];
if (val === undefined)
@ -322,13 +324,13 @@ function readIntBE(offset, byteLength) {
return this.readInt32BE(offset);
if (byteLength === 2)
return this.readInt16BE(offset);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return this.readInt8(offset);
boundsError(byteLength, 6, 'byteLength');
}
function readInt48BE(buf, offset) {
function readInt48BE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 5];
@ -343,7 +345,7 @@ function readInt48BE(buf, offset) {
last;
}
function readInt40BE(buf, offset) {
function readInt40BE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 4];
@ -357,7 +359,7 @@ function readInt40BE(buf, offset) {
last;
}
function readInt32BE(offset) {
function readInt32BE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 3];
@ -370,7 +372,7 @@ function readInt32BE(offset) {
last;
}
function readInt24BE(buf, offset) {
function readInt24BE(buf, offset = 0) {
checkNumberType(offset);
const first = buf[offset];
const last = buf[offset + 2];
@ -381,7 +383,7 @@ function readInt24BE(buf, offset) {
return val | (val & 2 ** 23) * 0x1fe;
}
function readInt16BE(offset) {
function readInt16BE(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 1];
@ -393,7 +395,7 @@ function readInt16BE(offset) {
}
// Read floats
function readFloatBackwards(offset) {
function readFloatBackwards(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 3];
@ -407,7 +409,7 @@ function readFloatBackwards(offset) {
return float32Array[0];
}
function readFloatForwards(offset) {
function readFloatForwards(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 3];
@ -421,7 +423,7 @@ function readFloatForwards(offset) {
return float32Array[0];
}
function readDoubleBackwards(offset) {
function readDoubleBackwards(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 7];
@ -439,7 +441,7 @@ function readDoubleBackwards(offset) {
return float64Array[0];
}
function readDoubleForwards(offset) {
function readDoubleForwards(offset = 0) {
checkNumberType(offset);
const first = this[offset];
const last = this[offset + 7];
@ -458,7 +460,7 @@ function readDoubleForwards(offset) {
}
// Write integers.
function writeUIntLE(value, offset, byteLength) {
function writeUIntLE(value, offset = 0, byteLength) {
if (byteLength === 6)
return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff);
if (byteLength === 5)
@ -469,7 +471,7 @@ function writeUIntLE(value, offset, byteLength) {
return writeU_Int32LE(this, value, offset, 0, 0xffffffff);
if (byteLength === 2)
return writeU_Int16LE(this, value, offset, 0, 0xffff);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return writeU_Int8(this, value, offset, 0, 0xff);
boundsError(byteLength, 6, 'byteLength');
@ -522,7 +524,7 @@ function writeU_Int32LE(buf, value, offset, min, max) {
return offset;
}
function writeUInt32LE(value, offset) {
function writeUInt32LE(value, offset = 0) {
return writeU_Int32LE(this, value, offset, 0, 0xffffffff);
}
@ -547,7 +549,7 @@ function writeU_Int16LE(buf, value, offset, min, max) {
return offset;
}
function writeUInt16LE(value, offset) {
function writeUInt16LE(value, offset = 0) {
return writeU_Int16LE(this, value, offset, 0, 0xffff);
}
@ -565,11 +567,11 @@ function writeU_Int8(buf, value, offset, min, max) {
return offset + 1;
}
function writeUInt8(value, offset) {
function writeUInt8(value, offset = 0) {
return writeU_Int8(this, value, offset, 0, 0xff);
}
function writeUIntBE(value, offset, byteLength) {
function writeUIntBE(value, offset = 0, byteLength) {
if (byteLength === 6)
return writeU_Int48BE(this, value, offset, 0, 0xffffffffffffff);
if (byteLength === 5)
@ -580,7 +582,7 @@ function writeUIntBE(value, offset, byteLength) {
return writeU_Int32BE(this, value, offset, 0, 0xffffffff);
if (byteLength === 2)
return writeU_Int16BE(this, value, offset, 0, 0xffff);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return writeU_Int8(this, value, offset, 0, 0xff);
boundsError(byteLength, 6, 'byteLength');
@ -632,7 +634,7 @@ function writeU_Int32BE(buf, value, offset, min, max) {
return offset + 4;
}
function writeUInt32BE(value, offset) {
function writeUInt32BE(value, offset = 0) {
return writeU_Int32BE(this, value, offset, 0, 0xffffffff);
}
@ -657,11 +659,11 @@ function writeU_Int16BE(buf, value, offset, min, max) {
return offset;
}
function writeUInt16BE(value, offset) {
function writeUInt16BE(value, offset = 0) {
return writeU_Int16BE(this, value, offset, 0, 0xffffffff);
}
function writeIntLE(value, offset, byteLength) {
function writeIntLE(value, offset = 0, byteLength) {
if (byteLength === 6)
return writeU_Int48LE(this, value, offset, -0x800000000000, 0x7fffffffffff);
if (byteLength === 5)
@ -672,25 +674,25 @@ function writeIntLE(value, offset, byteLength) {
return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff);
if (byteLength === 2)
return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return writeU_Int8(this, value, offset, -0x80, 0x7f);
boundsError(byteLength, 6, 'byteLength');
}
function writeInt32LE(value, offset) {
function writeInt32LE(value, offset = 0) {
return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff);
}
function writeInt16LE(value, offset) {
function writeInt16LE(value, offset = 0) {
return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff);
}
function writeInt8(value, offset) {
function writeInt8(value, offset = 0) {
return writeU_Int8(this, value, offset, -0x80, 0x7f);
}
function writeIntBE(value, offset, byteLength) {
function writeIntBE(value, offset = 0, byteLength) {
if (byteLength === 6)
return writeU_Int48BE(this, value, offset, -0x800000000000, 0x7fffffffffff);
if (byteLength === 5)
@ -701,22 +703,22 @@ function writeIntBE(value, offset, byteLength) {
return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff);
if (byteLength === 2)
return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff);
if (byteLength === 1)
if (byteLength === 1 || byteLength === undefined)
return writeU_Int8(this, value, offset, -0x80, 0x7f);
boundsError(byteLength, 6, 'byteLength');
}
function writeInt32BE(value, offset) {
function writeInt32BE(value, offset = 0) {
return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff);
}
function writeInt16BE(value, offset) {
function writeInt16BE(value, offset = 0) {
return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff);
}
// Write floats.
function writeDoubleForwards(val, offset) {
function writeDoubleForwards(val, offset = 0) {
val = +val;
checkBounds(this, offset, 7);
@ -732,7 +734,7 @@ function writeDoubleForwards(val, offset) {
return offset;
}
function writeDoubleBackwards(val, offset) {
function writeDoubleBackwards(val, offset = 0) {
val = +val;
checkBounds(this, offset, 7);
@ -748,7 +750,7 @@ function writeDoubleBackwards(val, offset) {
return offset;
}
function writeFloatForwards(val, offset) {
function writeFloatForwards(val, offset = 0) {
val = +val;
checkBounds(this, offset, 3);
@ -760,7 +762,7 @@ function writeFloatForwards(val, offset) {
return offset;
}
function writeFloatBackwards(val, offset) {
function writeFloatBackwards(val, offset = 0) {
val = +val;
checkBounds(this, offset, 3);

View File

@ -99,7 +99,12 @@ assert.strictEqual(buffer.readDoubleBE(0), 3.04814e-319);
assert.strictEqual(buffer.readDoubleLE(0), -Infinity);
['readDoubleLE', 'readDoubleBE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
// Verify that default offset works fine.
buffer[fn](undefined);
buffer[fn]();
['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
assert.throws(
() => buffer[fn](off),
{ code: 'ERR_INVALID_ARG_TYPE' }

View File

@ -62,7 +62,12 @@ assert.strictEqual(buffer.readFloatBE(0), 4.627507918739843e-41);
assert.strictEqual(buffer.readFloatLE(0), -Infinity);
['readFloatLE', 'readFloatBE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
// Verify that default offset works fine.
buffer[fn](undefined);
buffer[fn]();
['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
assert.throws(
() => buffer[fn](off),
{ code: 'ERR_INVALID_ARG_TYPE' }

View File

@ -8,7 +8,12 @@ const assert = require('assert');
const buffer = Buffer.alloc(4);
['Int8', 'Int16BE', 'Int16LE', 'Int32BE', 'Int32LE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
// Verify that default offset works fine.
buffer[`read${fn}`](undefined);
buffer[`read${fn}`]();
['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
assert.throws(
() => buffer[`read${fn}`](o),
{
@ -129,7 +134,13 @@ const assert = require('assert');
// Check byteLength.
['readIntBE', 'readIntLE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((len) => {
// Verify that default offset & byteLength works fine.
buffer[fn](undefined, undefined);
buffer[fn](undefined);
buffer[fn]();
['', '0', null, {}, [], () => {}, true, false].forEach((len) => {
assert.throws(
() => buffer[fn](0, len),
{ code: 'ERR_INVALID_ARG_TYPE' });
@ -160,7 +171,7 @@ const assert = require('assert');
// Test 1 to 6 bytes.
for (let i = 1; i < 6; i++) {
['readIntBE', 'readIntLE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
assert.throws(
() => buffer[fn](o, i),
{

View File

@ -80,6 +80,11 @@ assert.ok(Number.isNaN(buffer.readDoubleLE(8)));
const small = Buffer.allocUnsafe(1);
['writeDoubleLE', 'writeDoubleBE'].forEach((fn) => {
// Verify that default offset works fine.
buffer[fn](23, undefined);
buffer[fn](23);
assert.throws(
() => small[fn](11.11, 0),
{
@ -88,7 +93,7 @@ assert.ok(Number.isNaN(buffer.readDoubleLE(8)));
message: 'Attempt to write outside buffer bounds'
});
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
assert.throws(
() => small[fn](23, off),
{ code: 'ERR_INVALID_ARG_TYPE' });

View File

@ -61,6 +61,11 @@ assert.ok(Number.isNaN(buffer.readFloatLE(4)));
const small = Buffer.allocUnsafe(1);
['writeFloatLE', 'writeFloatBE'].forEach((fn) => {
// Verify that default offset works fine.
buffer[fn](23, undefined);
buffer[fn](23);
assert.throws(
() => small[fn](11.11, 0),
{
@ -69,7 +74,7 @@ assert.ok(Number.isNaN(buffer.readFloatLE(4)));
message: 'Attempt to write outside buffer bounds'
});
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
assert.throws(
() => small[fn](23, off),
{ code: 'ERR_INVALID_ARG_TYPE' }

View File

@ -31,7 +31,11 @@ const errorOutOfBounds = common.expectsError({
buffer.writeInt8(-0x80 - 1, 0);
}, errorOutOfBounds);
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
// Verify that default offset works fine.
buffer.writeInt8(23, undefined);
buffer.writeInt8(23);
['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
assert.throws(
() => buffer.writeInt8(23, off),
{ code: 'ERR_INVALID_ARG_TYPE' });
@ -70,6 +74,11 @@ const errorOutOfBounds = common.expectsError({
assert.ok(buffer.equals(new Uint8Array([ 0xff, 0x7f, 0x00, 0x80 ])));
['writeInt16BE', 'writeInt16LE'].forEach((fn) => {
// Verify that default offset works fine.
buffer[fn](23, undefined);
buffer[fn](23);
assert.throws(() => {
buffer[fn](0x7fff + 1, 0);
}, errorOutOfBounds);
@ -77,7 +86,7 @@ const errorOutOfBounds = common.expectsError({
buffer[fn](-0x8000 - 1, 0);
}, errorOutOfBounds);
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
assert.throws(
() => buffer[fn](23, off),
{ code: 'ERR_INVALID_ARG_TYPE' });
@ -127,6 +136,11 @@ const errorOutOfBounds = common.expectsError({
])));
['writeInt32BE', 'writeInt32LE'].forEach((fn) => {
// Verify that default offset works fine.
buffer[fn](23, undefined);
buffer[fn](23);
assert.throws(() => {
buffer[fn](0x7fffffff + 1, 0);
}, errorOutOfBounds);
@ -134,7 +148,7 @@ const errorOutOfBounds = common.expectsError({
buffer[fn](-0x80000000 - 1, 0);
}, errorOutOfBounds);
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => {
['', '0', null, {}, [], () => {}, true, false].forEach((off) => {
assert.throws(
() => buffer[fn](23, off),
{ code: 'ERR_INVALID_ARG_TYPE' });
@ -154,9 +168,15 @@ const errorOutOfBounds = common.expectsError({
// Check byteLength.
['writeIntBE', 'writeIntLE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
// Verify that default offset & byteLength works fine.
data[fn](undefined, undefined);
data[fn](undefined);
data[fn]();
['', '0', null, {}, [], () => {}, true, false].forEach((bl) => {
assert.throws(
() => data[fn](23, 0, o),
() => data[fn](23, 0, bl),
{ code: 'ERR_INVALID_ARG_TYPE' });
});
@ -200,7 +220,7 @@ const errorOutOfBounds = common.expectsError({
});
});
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
assert.throws(
() => data[fn](min, o, i),
{

View File

@ -14,7 +14,12 @@ const assert = require('assert');
{ // OOB
const data = Buffer.alloc(8);
['UInt8', 'UInt16BE', 'UInt16LE', 'UInt32BE', 'UInt32LE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
// Verify that default offset works fine.
data[`write${fn}`](23, undefined);
data[`write${fn}`](23);
['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
assert.throws(
() => data[`write${fn}`](23, o),
{ code: 'ERR_INVALID_ARG_TYPE' });
@ -112,9 +117,15 @@ const assert = require('assert');
// Check byteLength.
['writeUIntBE', 'writeUIntLE'].forEach((fn) => {
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
// Verify that default offset & byteLength works fine.
data[fn](undefined, undefined);
data[fn](undefined);
data[fn]();
['', '0', null, {}, [], () => {}, true, false].forEach((bl) => {
assert.throws(
() => data[fn](23, 0, o),
() => data[fn](23, 0, bl),
{ code: 'ERR_INVALID_ARG_TYPE' });
});
@ -153,7 +164,7 @@ const assert = require('assert');
`It must be >= 0 and <= ${val - 1}. Received ${val}`
});
['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => {
['', '0', null, {}, [], () => {}, true, false].forEach((o) => {
assert.throws(
() => data[fn](23, o, i),
{