From a93830a0ad6a24ba91e9ad79ff4aa9db78147fc2 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 30 Jan 2018 20:27:16 +0100 Subject: [PATCH 1/6] test: remove vulgar language The FIXME is obsolete as it was meant about a indentation issue that got fixed a long time ago. --- test/parallel/test-zerolengthbufferbug.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/parallel/test-zerolengthbufferbug.js b/test/parallel/test-zerolengthbufferbug.js index 0e1e976e568818..c59fc18108c2b9 100644 --- a/test/parallel/test-zerolengthbufferbug.js +++ b/test/parallel/test-zerolengthbufferbug.js @@ -6,7 +6,6 @@ const http = require('http'); const server = http.createServer((req, res) => { const buffer = Buffer.alloc(0); - // FIXME: WTF gjslint want this? res.writeHead(200, { 'Content-Type': 'text/html', 'Content-Length': buffer.length }); res.end(buffer); From 48b4f00d3903a49c65e6c5a3a3db40b70253a57a Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 30 Jan 2018 17:21:28 +0100 Subject: [PATCH 2/6] buffer: move c++ float functions to js This ports the Buffer#write(Double|Float)(B|L)E functions to JS. This fixes a security issue concerning type confusion and fixes another possible crash in combination with `noAssert`. In addition to that it will also significantly improve the write performance. Fixes: https://github.com/nodejs/node/issues/12179 Fixes: https://github.com/nodejs/node/issues/8724 --- lib/buffer.js | 108 ++++++++++++++------ src/node_buffer.cc | 97 +----------------- test/parallel/test-buffer-write-noassert.js | 7 -- 3 files changed, 76 insertions(+), 136 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index 0aa9e2001bd9d7..f36bd76acdcc2e 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -34,10 +34,6 @@ const { swap16: _swap16, swap32: _swap32, swap64: _swap64, - writeDoubleBE: _writeDoubleBE, - writeDoubleLE: _writeDoubleLE, - writeFloatBE: _writeFloatBE, - writeFloatLE: _writeFloatLE, kMaxLength, kStringMaxLength } = process.binding('buffer'); @@ -85,6 +81,12 @@ const constants = Object.defineProperties({}, { } }); +// Temporary buffers to convert numbers. +const float32Array = new Float32Array(1); +const uInt8Float32Array = new Uint8Array(float32Array.buffer); +const float64Array = new Float64Array(1); +const uInt8Float64Array = new Uint8Array(float64Array.buffer); + Buffer.poolSize = 8 * 1024; var poolSize, poolOffset, allocPool; @@ -1297,12 +1299,16 @@ Buffer.prototype.readFloatLE = function(offset, noAssert) { return toFloat(this.readUInt32LE(offset, noAssert)); }; +function checkOOB(buffer, offset, ext) { + if (offset + ext > buffer.length) + throw new errors.RangeError('ERR_INDEX_OUT_OF_RANGE'); +} + function checkInt(buffer, value, offset, ext, max, min) { if (value > max || value < min) throw new errors.RangeError('ERR_INVALID_OPT_VALUE', 'value', value); - if (offset + ext > buffer.length) - throw new errors.RangeError('ERR_INDEX_OUT_OF_RANGE'); + checkOOB(buffer, offset, ext); } @@ -1520,49 +1526,83 @@ Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) { return offset + 4; }; - -Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) { +function writeDoubleForwards(val, offset, noAssert) { val = +val; offset = offset >>> 0; if (!noAssert) - _writeFloatLE(this, val, offset); - else - _writeFloatLE(this, val, offset, true); - return offset + 4; -}; - + checkOOB(this, offset, 8); + + float64Array[0] = val; + this[offset++] = uInt8Float64Array[0]; + this[offset++] = uInt8Float64Array[1]; + this[offset++] = uInt8Float64Array[2]; + this[offset++] = uInt8Float64Array[3]; + this[offset++] = uInt8Float64Array[4]; + this[offset++] = uInt8Float64Array[5]; + this[offset++] = uInt8Float64Array[6]; + this[offset++] = uInt8Float64Array[7]; + return offset; +} -Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) { +function writeDoubleBackwards(val, offset, noAssert) { val = +val; offset = offset >>> 0; if (!noAssert) - _writeFloatBE(this, val, offset); - else - _writeFloatBE(this, val, offset, true); - return offset + 4; -}; - + checkOOB(this, offset, 8); + + float64Array[0] = val; + this[offset++] = uInt8Float64Array[7]; + this[offset++] = uInt8Float64Array[6]; + this[offset++] = uInt8Float64Array[5]; + this[offset++] = uInt8Float64Array[4]; + this[offset++] = uInt8Float64Array[3]; + this[offset++] = uInt8Float64Array[2]; + this[offset++] = uInt8Float64Array[1]; + this[offset++] = uInt8Float64Array[0]; + return offset; +} -Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) { +function writeFloatForwards(val, offset, noAssert) { val = +val; offset = offset >>> 0; if (!noAssert) - _writeDoubleLE(this, val, offset); - else - _writeDoubleLE(this, val, offset, true); - return offset + 8; -}; - + checkOOB(this, offset, 4); + + float32Array[0] = val; + this[offset++] = uInt8Float32Array[0]; + this[offset++] = uInt8Float32Array[1]; + this[offset++] = uInt8Float32Array[2]; + this[offset++] = uInt8Float32Array[3]; + return offset; +} -Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) { +function writeFloatBackwards(val, offset, noAssert) { val = +val; offset = offset >>> 0; if (!noAssert) - _writeDoubleBE(this, val, offset); - else - _writeDoubleBE(this, val, offset, true); - return offset + 8; -}; + checkOOB(this, offset, 4); + + float32Array[0] = val; + this[offset++] = uInt8Float32Array[3]; + this[offset++] = uInt8Float32Array[2]; + this[offset++] = uInt8Float32Array[1]; + this[offset++] = uInt8Float32Array[0]; + return offset; +} + +// Check endianness. +float32Array[0] = -1; +if (uInt8Float32Array[3] === 0) { // Big endian. + Buffer.prototype.writeFloatLE = writeFloatBackwards; + Buffer.prototype.writeFloatBE = writeFloatForwards; + Buffer.prototype.writeDoubleLE = writeDoubleBackwards; + Buffer.prototype.writeDoubleBE = writeDoubleForwards; +} else { // Small endian. + Buffer.prototype.writeFloatLE = writeFloatForwards; + Buffer.prototype.writeFloatBE = writeFloatBackwards; + Buffer.prototype.writeDoubleLE = writeDoubleForwards; + Buffer.prototype.writeDoubleBE = writeDoubleBackwards; +} function swap(b, n, m) { const i = b[n]; diff --git a/src/node_buffer.cc b/src/node_buffer.cc index c44aa692cdacfe..c25fe11b5a4c6a 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -163,8 +163,7 @@ void CallbackInfo::WeakCallback(Isolate* isolate) { // Parse index for external array data. inline MUST_USE_RESULT bool ParseArrayIndex(Local arg, size_t def, - size_t* ret, - size_t needed = 0) { + size_t* ret) { if (arg->IsUndefined()) { *ret = def; return true; @@ -178,7 +177,7 @@ inline MUST_USE_RESULT bool ParseArrayIndex(Local arg, // Check that the result fits in a size_t. const uint64_t kSizeMax = static_cast(static_cast(-1)); // coverity[pointless_expression] - if (static_cast(tmp_i) > kSizeMax - needed) + if (static_cast(tmp_i) > kSizeMax) return false; *ret = static_cast(tmp_i); @@ -686,93 +685,6 @@ void StringWrite(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(written); } - -static inline void Swizzle(char* start, unsigned int len) { - char* end = start + len - 1; - while (start < end) { - char tmp = *start; - *start++ = *end; - *end-- = tmp; - } -} - - -template -void WriteFloatGeneric(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - - bool should_assert = args.Length() < 4; - - if (should_assert) { - THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]); - } - - Local ts_obj = args[0].As(); - ArrayBuffer::Contents ts_obj_c = ts_obj->Buffer()->GetContents(); - const size_t ts_obj_offset = ts_obj->ByteOffset(); - const size_t ts_obj_length = ts_obj->ByteLength(); - char* const ts_obj_data = - static_cast(ts_obj_c.Data()) + ts_obj_offset; - if (ts_obj_length > 0) - CHECK_NE(ts_obj_data, nullptr); - - T val = args[1]->NumberValue(env->context()).FromMaybe(0); - - size_t memcpy_num = sizeof(T); - size_t offset; - - // If the offset is negative or larger than the size of the ArrayBuffer, - // throw an error (if needed) and return directly. - if (!ParseArrayIndex(args[2], 0, &offset, memcpy_num) || - offset >= ts_obj_length) { - if (should_assert) - THROW_AND_RETURN_IF_OOB(false); - return; - } - - // If the offset is too large for the entire value, but small enough to fit - // part of the value, throw an error and return only if should_assert is - // true. Otherwise, write the part of the value that fits. - if (offset + memcpy_num > ts_obj_length) { - if (should_assert) - THROW_AND_RETURN_IF_OOB(false); - else - memcpy_num = ts_obj_length - offset; - } - - union NoAlias { - T val; - char bytes[sizeof(T)]; - }; - - union NoAlias na = { val }; - char* ptr = static_cast(ts_obj_data) + offset; - if (endianness != GetEndianness()) - Swizzle(na.bytes, sizeof(na.bytes)); - memcpy(ptr, na.bytes, memcpy_num); -} - - -void WriteFloatLE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); -} - - -void WriteFloatBE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); -} - - -void WriteDoubleLE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); -} - - -void WriteDoubleBE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); -} - - void ByteLengthUtf8(const FunctionCallbackInfo &args) { CHECK(args[0]->IsString()); @@ -1211,11 +1123,6 @@ void Initialize(Local target, env->SetMethod(target, "indexOfNumber", IndexOfNumber); env->SetMethod(target, "indexOfString", IndexOfString); - env->SetMethod(target, "writeDoubleBE", WriteDoubleBE); - env->SetMethod(target, "writeDoubleLE", WriteDoubleLE); - env->SetMethod(target, "writeFloatBE", WriteFloatBE); - env->SetMethod(target, "writeFloatLE", WriteFloatLE); - env->SetMethod(target, "swap16", Swap16); env->SetMethod(target, "swap32", Swap32); env->SetMethod(target, "swap64", Swap64); diff --git a/test/parallel/test-buffer-write-noassert.js b/test/parallel/test-buffer-write-noassert.js index 0730aaa3544983..a521e01129a094 100644 --- a/test/parallel/test-buffer-write-noassert.js +++ b/test/parallel/test-buffer-write-noassert.js @@ -16,13 +16,6 @@ function write(funx, args, result, res) { writeInvalidOffset(-1); writeInvalidOffset(9); - if (!/Int/.test(funx)) { - assert.throws( - () => Buffer.alloc(9)[funx].apply(new Map(), args), - /^TypeError: argument should be a Buffer$/ - ); - } - { const buf2 = Buffer.alloc(9); assert.strictEqual(buf2[funx](...args, true), result); From 2fc06252f79ab063caaf11f80d3cb03212d2edd0 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 30 Jan 2018 17:38:54 +0100 Subject: [PATCH 3/6] buffer: remove double ln --- lib/buffer.js | 64 --------------------------------------------------- 1 file changed, 64 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index f36bd76acdcc2e..220437f25d7534 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -90,7 +90,6 @@ const uInt8Float64Array = new Uint8Array(float64Array.buffer); Buffer.poolSize = 8 * 1024; var poolSize, poolOffset, allocPool; - setupBufferJS(Buffer.prototype, bindingObj); // |zeroFill| can be undefined when running inside an isolate where we @@ -117,7 +116,6 @@ function createPool() { } createPool(); - function alignPool() { // Ensure aligned slices if (poolOffset & 0x7) { @@ -294,7 +292,6 @@ function SlowBuffer(length) { Object.setPrototypeOf(SlowBuffer.prototype, Uint8Array.prototype); Object.setPrototypeOf(SlowBuffer, Uint8Array); - function allocate(size) { if (size <= 0) { return new FastBuffer(); @@ -311,7 +308,6 @@ function allocate(size) { } } - function fromString(string, encoding) { var length; if (typeof encoding !== 'string' || encoding.length === 0) { @@ -405,14 +401,12 @@ function fromObject(obj) { } } - // Static methods Buffer.isBuffer = function isBuffer(b) { return b instanceof Buffer; }; - Buffer.compare = function compare(a, b) { if (!isUint8Array(a) || !isUint8Array(b)) { throw new errors.TypeError( @@ -427,7 +421,6 @@ Buffer.compare = function compare(a, b) { return _compare(a, b); }; - Buffer.isEncoding = function isEncoding(encoding) { return typeof encoding === 'string' && encoding.length !== 0 && normalizeEncoding(encoding) !== undefined; @@ -477,7 +470,6 @@ Buffer.concat = function concat(list, length) { return buffer; }; - function base64ByteLength(str, bytes) { // Handle padding if (str.charCodeAt(bytes - 1) === 0x3D) @@ -489,7 +481,6 @@ function base64ByteLength(str, bytes) { return (bytes * 3) >>> 2; } - function byteLength(string, encoding) { if (typeof string !== 'string') { if (isArrayBufferView(string) || isAnyArrayBuffer(string)) { @@ -553,7 +544,6 @@ function byteLength(string, encoding) { Buffer.byteLength = byteLength; - // For backwards compatibility. Object.defineProperty(Buffer.prototype, 'parent', { enumerable: true, @@ -572,7 +562,6 @@ Object.defineProperty(Buffer.prototype, 'offset', { } }); - function stringSlice(buf, encoding, start, end) { if (encoding === undefined) return buf.utf8Slice(start, end); encoding += ''; @@ -618,7 +607,6 @@ function stringSlice(buf, encoding, start, end) { throw new errors.TypeError('ERR_UNKNOWN_ENCODING', encoding); } - Buffer.prototype.copy = function copy(target, targetStart, sourceStart, sourceEnd) { return _copy(this, target, targetStart, sourceStart, sourceEnd); @@ -655,7 +643,6 @@ Buffer.prototype.toString = function toString(encoding, start, end) { return stringSlice(this, encoding, start, end); }; - Buffer.prototype.equals = function equals(b) { if (!isUint8Array(b)) { throw new errors.TypeError( @@ -669,7 +656,6 @@ Buffer.prototype.equals = function equals(b) { return _compare(this, b) === 0; }; - // Override how buffers are presented by util.inspect(). Buffer.prototype[customInspectSymbol] = function inspect() { var str = ''; @@ -731,7 +717,6 @@ Buffer.prototype.compare = function compare(target, return compareOffset(this, target, start, thisStart, end, thisEnd); }; - // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, // OR the last index of `val` in `buffer` at offset <= `byteOffset`. // @@ -775,7 +760,6 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) { ); } - function slowIndexOf(buffer, val, byteOffset, encoding, dir) { var loweredCase = false; for (;;) { @@ -807,22 +791,18 @@ function slowIndexOf(buffer, val, byteOffset, encoding, dir) { } } - Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, true); }; - Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, false); }; - Buffer.prototype.includes = function includes(val, byteOffset, encoding) { return this.indexOf(val, byteOffset, encoding) !== -1; }; - // Usage: // buffer.fill(number[, offset[, end]]) // buffer.fill(buffer[, offset[, end]]) @@ -898,7 +878,6 @@ function _fill(buf, val, start, end, encoding) { return buf; } - Buffer.prototype.write = function write(string, offset, length, encoding) { // Buffer#write(string); if (offset === undefined) { @@ -983,7 +962,6 @@ Buffer.prototype.write = function write(string, offset, length, encoding) { throw new errors.TypeError('ERR_UNKNOWN_ENCODING', encoding); }; - Buffer.prototype.toJSON = function toJSON() { if (this.length > 0) { const data = new Array(this.length); @@ -995,7 +973,6 @@ Buffer.prototype.toJSON = function toJSON() { } }; - function adjustOffset(offset, length) { // Use Math.trunc() to convert offset to an integer value that can be larger // than an Int32. Hence, don't use offset | 0 or similar techniques. @@ -1013,7 +990,6 @@ function adjustOffset(offset, length) { return Number.isNaN(offset) ? 0 : length; } - Buffer.prototype.slice = function slice(start, end) { const srcLength = this.length; start = adjustOffset(start, srcLength); @@ -1022,7 +998,6 @@ Buffer.prototype.slice = function slice(start, end) { return new FastBuffer(this.buffer, this.byteOffset + start, newLength); }; - function checkOffset(offset, ext, length) { if (offset + ext > length) throw new errors.RangeError('ERR_INDEX_OUT_OF_RANGE'); @@ -1036,7 +1011,6 @@ function checkByteLength(byteLength) { } } - Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) { offset = offset >>> 0; @@ -1055,7 +1029,6 @@ Buffer.prototype.readUIntLE = return val; }; - Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) { offset = offset >>> 0; @@ -1073,7 +1046,6 @@ Buffer.prototype.readUIntBE = return val; }; - Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1081,7 +1053,6 @@ Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) { return this[offset]; }; - Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1089,7 +1060,6 @@ Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) { return this[offset] | (this[offset + 1] << 8); }; - Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1097,7 +1067,6 @@ Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) { return (this[offset] << 8) | this[offset + 1]; }; - Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1109,7 +1078,6 @@ Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) { (this[offset + 3] * 0x1000000); }; - Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1121,7 +1089,6 @@ Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) { this[offset + 3]); }; - Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) { offset = offset >>> 0; byteLength = byteLength >>> 0; @@ -1144,7 +1111,6 @@ Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) { return val; }; - Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) { offset = offset >>> 0; byteLength = byteLength >>> 0; @@ -1167,7 +1133,6 @@ Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) { return val; }; - Buffer.prototype.readInt8 = function readInt8(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1176,7 +1141,6 @@ Buffer.prototype.readInt8 = function readInt8(offset, noAssert) { return !(val & 0x80) ? val : (0xff - val + 1) * -1; }; - Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1185,7 +1149,6 @@ Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) { return (val & 0x8000) ? val | 0xFFFF0000 : val; }; - Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1194,7 +1157,6 @@ Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) { return (val & 0x8000) ? val | 0xFFFF0000 : val; }; - Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1206,7 +1168,6 @@ Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) { (this[offset + 3] << 24); }; - Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) { offset = offset >>> 0; if (!noAssert) @@ -1218,7 +1179,6 @@ Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) { (this[offset + 3]); }; - // For the casual reader who has not at the current time memorized the // IEEE-754 standard in full detail: floating point numbers consist of // a fraction, an exponent and a sign bit: 23+8+1 bits for single precision @@ -1241,7 +1201,6 @@ Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) { // precision that is not stored but is reconstructed by adding one after // multiplying the fraction with the result of 2**-bits_in_fraction. - function toDouble(x0, x1) { const frac = x0 + 0x100000000 * (x1 & 0xFFFFF); const expt = (x1 >>> 20) & 2047; @@ -1256,7 +1215,6 @@ function toDouble(x0, x1) { return sign * 2 ** (expt - 1023) * (1 + frac * 2 ** -52); } - function toFloat(x) { const frac = x & 0x7FFFFF; const expt = (x >>> 23) & 255; @@ -1271,7 +1229,6 @@ function toFloat(x) { return sign * 2 ** (expt - 127) * (1 + frac * 2 ** -23); } - Buffer.prototype.readDoubleBE = function(offset, noAssert) { offset = offset >>> 0; const x1 = this.readUInt32BE(offset + 0, noAssert); @@ -1279,7 +1236,6 @@ Buffer.prototype.readDoubleBE = function(offset, noAssert) { return toDouble(x0, x1); }; - Buffer.prototype.readDoubleLE = function(offset, noAssert) { offset = offset >>> 0; const x0 = this.readUInt32LE(offset + 0, noAssert); @@ -1287,13 +1243,11 @@ Buffer.prototype.readDoubleLE = function(offset, noAssert) { return toDouble(x0, x1); }; - Buffer.prototype.readFloatBE = function(offset, noAssert) { offset = offset >>> 0; return toFloat(this.readUInt32BE(offset, noAssert)); }; - Buffer.prototype.readFloatLE = function(offset, noAssert) { offset = offset >>> 0; return toFloat(this.readUInt32LE(offset, noAssert)); @@ -1304,14 +1258,12 @@ function checkOOB(buffer, offset, ext) { throw new errors.RangeError('ERR_INDEX_OUT_OF_RANGE'); } - function checkInt(buffer, value, offset, ext, max, min) { if (value > max || value < min) throw new errors.RangeError('ERR_INVALID_OPT_VALUE', 'value', value); checkOOB(buffer, offset, ext); } - Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) { value = +value; @@ -1331,7 +1283,6 @@ Buffer.prototype.writeUIntLE = return offset + byteLength; }; - Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) { value = +value; @@ -1351,7 +1302,6 @@ Buffer.prototype.writeUIntBE = return offset + byteLength; }; - Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) { value = +value; @@ -1362,7 +1312,6 @@ Buffer.prototype.writeUInt8 = return offset + 1; }; - Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) { value = +value; @@ -1374,7 +1323,6 @@ Buffer.prototype.writeUInt16LE = return offset + 2; }; - Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) { value = +value; @@ -1386,7 +1334,6 @@ Buffer.prototype.writeUInt16BE = return offset + 2; }; - Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) { value = +value; @@ -1400,7 +1347,6 @@ Buffer.prototype.writeUInt32LE = return offset + 4; }; - Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) { value = +value; @@ -1414,7 +1360,6 @@ Buffer.prototype.writeUInt32BE = return offset + 4; }; - Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) { value = +value; @@ -1441,7 +1386,6 @@ Buffer.prototype.writeIntLE = return offset + byteLength; }; - Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) { value = +value; @@ -1468,7 +1412,6 @@ Buffer.prototype.writeIntBE = return offset + byteLength; }; - Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) { value = +value; offset = offset >>> 0; @@ -1478,7 +1421,6 @@ Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) { return offset + 1; }; - Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) { value = +value; offset = offset >>> 0; @@ -1489,7 +1431,6 @@ Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) { return offset + 2; }; - Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) { value = +value; offset = offset >>> 0; @@ -1500,7 +1441,6 @@ Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) { return offset + 2; }; - Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) { value = +value; offset = offset >>> 0; @@ -1513,7 +1453,6 @@ Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) { return offset + 4; }; - Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) { value = +value; offset = offset >>> 0; @@ -1610,7 +1549,6 @@ function swap(b, n, m) { b[m] = i; } - Buffer.prototype.swap16 = function swap16() { // For Buffer.length < 128, it's generally faster to // do the swap in javascript. For larger buffers, @@ -1626,7 +1564,6 @@ Buffer.prototype.swap16 = function swap16() { return _swap16(this); }; - Buffer.prototype.swap32 = function swap32() { // For Buffer.length < 192, it's generally faster to // do the swap in javascript. For larger buffers, @@ -1644,7 +1581,6 @@ Buffer.prototype.swap32 = function swap32() { return _swap32(this); }; - Buffer.prototype.swap64 = function swap64() { // For Buffer.length < 192, it's generally faster to // do the swap in javascript. For larger buffers, From 63eb1fc11cb46575d58a44234c9b0d3b9e5025f8 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 30 Jan 2018 17:34:25 +0100 Subject: [PATCH 4/6] buffer: refactor all read/write functions There are a lot of changes in this commit: 1) Remove the `noAssert` argument from all read and write functions. 2) Improve the performance of all read floating point functions significantly. This is done by switching to TypedArrays as the write floating point write functions. 3) No implicit type coercion for offset and byteLength anymore. 4) Adds a lot of tests. 5) Moves the read and write functions to the internal buffer file to split the files in smaller chunks. 6) Reworked a lot of existing tests. 7) Improve the performane of all all read write functions by using a faster input validation and by improving function logic. 8) Significantly improved the performance of all read int functions. This is done by using a implementation without a loop. 9) Improved error handling. --- doc/api/buffer.md | 269 +++--- lib/buffer.js | 555 +------------ lib/internal/buffer.js | 786 +++++++++++++++++- test/parallel/test-buffer-arraybuffer.js | 7 - test/parallel/test-buffer-read.js | 25 +- test/parallel/test-buffer-readdouble.js | 138 +++ test/parallel/test-buffer-readfloat.js | 101 +++ test/parallel/test-buffer-readint.js | 195 +++++ test/parallel/test-buffer-write-noassert.js | 95 --- test/parallel/test-buffer-writedouble.js | 119 +++ test/parallel/test-buffer-writefloat.js | 102 +++ test/parallel/test-buffer-writeint.js | 235 ++++++ test/parallel/test-buffer-writeuint.js | 190 +++++ ...erbug.js => test-http-zerolengthbuffer.js} | 0 test/parallel/test-readdouble.js | 129 --- test/parallel/test-readfloat.js | 92 -- test/parallel/test-readint.js | 119 --- test/parallel/test-writedouble.js | 197 ----- test/parallel/test-writefloat.js | 135 --- test/parallel/test-writeint.js | 194 ----- test/parallel/test-writeuint.js | 171 ---- 21 files changed, 2015 insertions(+), 1839 deletions(-) create mode 100644 test/parallel/test-buffer-readdouble.js create mode 100644 test/parallel/test-buffer-readfloat.js create mode 100644 test/parallel/test-buffer-readint.js delete mode 100644 test/parallel/test-buffer-write-noassert.js create mode 100644 test/parallel/test-buffer-writedouble.js create mode 100644 test/parallel/test-buffer-writefloat.js create mode 100644 test/parallel/test-buffer-writeint.js create mode 100644 test/parallel/test-buffer-writeuint.js rename test/parallel/{test-zerolengthbufferbug.js => test-http-zerolengthbuffer.js} (100%) delete mode 100644 test/parallel/test-readdouble.js delete mode 100644 test/parallel/test-readfloat.js delete mode 100644 test/parallel/test-readint.js delete mode 100644 test/parallel/test-writedouble.js delete mode 100644 test/parallel/test-writefloat.js delete mode 100644 test/parallel/test-writeint.js delete mode 100644 test/parallel/test-writeuint.js diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 510848c3b04635..07362ac139e286 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -1538,31 +1538,32 @@ deprecated: v8.0.0 The `buf.parent` property is a deprecated alias for `buf.buffer`. -### buf.readDoubleBE(offset[, noAssert]) -### buf.readDoubleLE(offset[, noAssert]) +### buf.readDoubleBE(offset) +### buf.readDoubleLE(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 8`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {number} Reads a 64-bit double from `buf` at the specified `offset` with specified endian format (`readDoubleBE()` returns big endian, `readDoubleLE()` returns little endian). -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Examples: ```js const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); -console.log(buf.readDoubleBE()); +console.log(buf.readDoubleBE(0)); // Prints: 8.20788039913184e-304 -console.log(buf.readDoubleLE()); +console.log(buf.readDoubleLE(0)); // Prints: 5.447603722011605e-270 console.log(buf.readDoubleLE(1)); // Throws an exception: RangeError: Index out of range @@ -1571,31 +1572,32 @@ console.log(buf.readDoubleLE(1, true)); // This will result in a segmentation fault! Don't do this! ``` -### buf.readFloatBE(offset[, noAssert]) -### buf.readFloatLE(offset[, noAssert]) +### buf.readFloatBE(offset) +### buf.readFloatLE(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 4`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {number} Reads a 32-bit float from `buf` at the specified `offset` with specified endian format (`readFloatBE()` returns big endian, `readFloatLE()` returns little endian). -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Examples: ```js const buf = Buffer.from([1, 2, 3, 4]); -console.log(buf.readFloatBE()); +console.log(buf.readFloatBE(0)); // Prints: 2.387939260590663e-38 -console.log(buf.readFloatLE()); +console.log(buf.readFloatLE(0)); // Prints: 1.539989614439558e-36 console.log(buf.readFloatLE(1)); // Throws an exception: RangeError: Index out of range @@ -1604,20 +1606,21 @@ console.log(buf.readFloatLE(1, true)); // This will result in a segmentation fault! Don't do this! ``` -### buf.readInt8(offset[, noAssert]) +### buf.readInt8(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 1`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {integer} Reads a signed 8-bit integer from `buf` at the specified `offset`. -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Integers read from a `Buffer` are interpreted as two's complement signed values. Examples: @@ -1633,23 +1636,24 @@ console.log(buf.readInt8(2)); // Throws an exception: RangeError: Index out of range ``` -### buf.readInt16BE(offset[, noAssert]) -### buf.readInt16LE(offset[, noAssert]) +### buf.readInt16BE(offset) +### buf.readInt16LE(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 2`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {integer} Reads a signed 16-bit integer from `buf` at the specified `offset` with the specified endian format (`readInt16BE()` returns big endian, `readInt16LE()` returns little endian). -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Integers read from a `Buffer` are interpreted as two's complement signed values. Examples: @@ -1657,31 +1661,32 @@ Examples: ```js const buf = Buffer.from([0, 5]); -console.log(buf.readInt16BE()); +console.log(buf.readInt16BE(0)); // Prints: 5 -console.log(buf.readInt16LE()); +console.log(buf.readInt16LE(0)); // Prints: 1280 console.log(buf.readInt16LE(1)); // Throws an exception: RangeError: Index out of range ``` -### buf.readInt32BE(offset[, noAssert]) -### buf.readInt32LE(offset[, noAssert]) +### buf.readInt32BE(offset) +### buf.readInt32LE(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 4`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {integer} Reads a signed 32-bit integer from `buf` at the specified `offset` with the specified endian format (`readInt32BE()` returns big endian, `readInt32LE()` returns little endian). -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Integers read from a `Buffer` are interpreted as two's complement signed values. Examples: @@ -1689,32 +1694,33 @@ Examples: ```js const buf = Buffer.from([0, 0, 0, 5]); -console.log(buf.readInt32BE()); +console.log(buf.readInt32BE(0)); // Prints: 5 -console.log(buf.readInt32LE()); +console.log(buf.readInt32LE(0)); // Prints: 83886080 console.log(buf.readInt32LE(1)); // Throws an exception: RangeError: Index out of range ``` -### buf.readIntBE(offset, byteLength[, noAssert]) -### buf.readIntLE(offset, byteLength[, noAssert]) +### buf.readIntBE(offset, byteLength) +### buf.readIntLE(offset, byteLength) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - byteLength`. * `byteLength` {integer} Number of bytes to read. Must satisfy: `0 < byteLength <= 6`. -* `noAssert` {boolean} Skip `offset` and `byteLength` validation? **Default:** `false`. * Returns: {integer} Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as a two's complement signed value. Supports up to 48 bits of accuracy. -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Examples: ```js @@ -1730,20 +1736,21 @@ console.log(buf.readIntBE(1, 0).toString(16)); // Throws ERR_OUT_OF_RANGE: ``` -### buf.readUInt8(offset[, noAssert]) +### buf.readUInt8(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 1`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {integer} Reads an unsigned 8-bit integer from `buf` at the specified `offset`. -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Examples: ```js @@ -1757,23 +1764,24 @@ console.log(buf.readUInt8(2)); // Throws an exception: RangeError: Index out of range ``` -### buf.readUInt16BE(offset[, noAssert]) -### buf.readUInt16LE(offset[, noAssert]) +### buf.readUInt16BE(offset) +### buf.readUInt16LE(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 2`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {integer} Reads an unsigned 16-bit integer from `buf` at the specified `offset` with specified endian format (`readUInt16BE()` returns big endian, `readUInt16LE()` returns little endian). -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Examples: ```js @@ -1791,23 +1799,24 @@ console.log(buf.readUInt16LE(2).toString(16)); // Throws an exception: RangeError: Index out of range ``` -### buf.readUInt32BE(offset[, noAssert]) -### buf.readUInt32LE(offset[, noAssert]) +### buf.readUInt32BE(offset) +### buf.readUInt32LE(offset) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - 4`. -* `noAssert` {boolean} Skip `offset` validation? **Default:** `false` * Returns: {integer} Reads an unsigned 32-bit integer from `buf` at the specified `offset` with specified endian format (`readUInt32BE()` returns big endian, `readUInt32LE()` returns little endian). -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Examples: ```js @@ -1821,24 +1830,25 @@ console.log(buf.readUInt32LE(1).toString(16)); // Throws an exception: RangeError: Index out of range ``` -### buf.readUIntBE(offset, byteLength[, noAssert]) -### buf.readUIntLE(offset, byteLength[, noAssert]) +### buf.readUIntBE(offset, byteLength) +### buf.readUIntLE(offset, byteLength) * `offset` {integer} Number of bytes to skip before starting to read. Must satisfy: `0 <= offset <= buf.length - byteLength`. * `byteLength` {integer} Number of bytes to read. Must satisfy: `0 < byteLength <= 6`. -* `noAssert` {boolean} Skip `offset` and `byteLength` validation? **Default:** `false` * Returns: {integer} Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as an unsigned integer. Supports up to 48 bits of accuracy. -Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but -the resulting behavior is undefined. - Examples: ```js @@ -2149,15 +2159,19 @@ console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); // Prints: 12 bytes: ½ + ¼ = ¾ ``` -### buf.writeDoubleBE(value, offset[, noAssert]) -### buf.writeDoubleLE(value, offset[, noAssert]) +### buf.writeDoubleBE(value, offset) +### buf.writeDoubleLE(value, offset) * `value` {number} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 8`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset` with specified endian @@ -2165,9 +2179,6 @@ format (`writeDoubleBE()` writes big endian, `writeDoubleLE()` writes little endian). `value` *should* be a valid 64-bit double. Behavior is undefined when `value` is anything other than a 64-bit double. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - Examples: ```js @@ -2184,15 +2195,19 @@ console.log(buf); // Prints: ``` -### buf.writeFloatBE(value, offset[, noAssert]) -### buf.writeFloatLE(value, offset[, noAssert]) +### buf.writeFloatBE(value, offset) +### buf.writeFloatLE(value, offset) * `value` {number} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 4`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset` with specified endian @@ -2200,9 +2215,6 @@ format (`writeFloatBE()` writes big endian, `writeFloatLE()` writes little endian). `value` *should* be a valid 32-bit float. Behavior is undefined when `value` is anything other than a 32-bit float. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - Examples: ```js @@ -2219,23 +2231,24 @@ console.log(buf); // Prints: ``` -### buf.writeInt8(value, offset[, noAssert]) +### buf.writeInt8(value, offset) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 1`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset`. `value` *should* be a valid signed 8-bit integer. Behavior is undefined when `value` is anything other than a signed 8-bit integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - `value` is interpreted and written as a two's complement signed integer. Examples: @@ -2250,15 +2263,19 @@ console.log(buf); // Prints: ``` -### buf.writeInt16BE(value, offset[, noAssert]) -### buf.writeInt16LE(value, offset[, noAssert]) +### buf.writeInt16BE(value, offset) +### buf.writeInt16LE(value, offset) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 2`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset` with specified endian @@ -2266,9 +2283,6 @@ format (`writeInt16BE()` writes big endian, `writeInt16LE()` writes little endian). `value` *should* be a valid signed 16-bit integer. Behavior is undefined when `value` is anything other than a signed 16-bit integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - `value` is interpreted and written as a two's complement signed integer. Examples: @@ -2283,15 +2297,19 @@ console.log(buf); // Prints: ``` -### buf.writeInt32BE(value, offset[, noAssert]) -### buf.writeInt32LE(value, offset[, noAssert]) +### buf.writeInt32BE(value, offset) +### buf.writeInt32LE(value, offset) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 4`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset` with specified endian @@ -2299,9 +2317,6 @@ format (`writeInt32BE()` writes big endian, `writeInt32LE()` writes little endian). `value` *should* be a valid signed 32-bit integer. Behavior is undefined when `value` is anything other than a signed 32-bit integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - `value` is interpreted and written as a two's complement signed integer. Examples: @@ -2316,26 +2331,26 @@ console.log(buf); // Prints: ``` -### buf.writeIntBE(value, offset, byteLength[, noAssert]) -### buf.writeIntLE(value, offset, byteLength[, noAssert]) +### buf.writeIntBE(value, offset, byteLength) +### buf.writeIntLE(value, offset, byteLength) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - byteLength`. * `byteLength` {integer} Number of bytes to write. Must satisfy: `0 < byteLength <= 6`. -* `noAssert` {boolean} Skip `value`, `offset`, and `byteLength` validation? - **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `byteLength` bytes of `value` to `buf` at the specified `offset`. Supports up to 48 bits of accuracy. Behavior is undefined when `value` is anything other than a signed integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - Examples: ```js @@ -2352,23 +2367,24 @@ console.log(buf); // Prints: ``` -### buf.writeUInt8(value, offset[, noAssert]) +### buf.writeUInt8(value, offset) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 1`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset`. `value` *should* be a valid unsigned 8-bit integer. Behavior is undefined when `value` is anything other than an unsigned 8-bit integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - Examples: ```js @@ -2383,15 +2399,19 @@ console.log(buf); // Prints: ``` -### buf.writeUInt16BE(value, offset[, noAssert]) -### buf.writeUInt16LE(value, offset[, noAssert]) +### buf.writeUInt16BE(value, offset) +### buf.writeUInt16LE(value, offset) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 2`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset` with specified endian @@ -2399,9 +2419,6 @@ format (`writeUInt16BE()` writes big endian, `writeUInt16LE()` writes little endian). `value` should be a valid unsigned 16-bit integer. Behavior is undefined when `value` is anything other than an unsigned 16-bit integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - Examples: ```js @@ -2420,15 +2437,19 @@ console.log(buf); // Prints: ``` -### buf.writeUInt32BE(value, offset[, noAssert]) -### buf.writeUInt32LE(value, offset[, noAssert]) +### buf.writeUInt32BE(value, offset) +### buf.writeUInt32LE(value, offset) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - 4`. -* `noAssert` {boolean} Skip `value` and `offset` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. Writes `value` to `buf` at the specified `offset` with specified endian @@ -2436,9 +2457,6 @@ format (`writeUInt32BE()` writes big endian, `writeUInt32LE()` writes little endian). `value` should be a valid unsigned 32-bit integer. Behavior is undefined when `value` is anything other than an unsigned 32-bit integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - Examples: ```js @@ -2455,16 +2473,20 @@ console.log(buf); // Prints: ``` -### buf.writeUIntBE(value, offset, byteLength[, noAssert]) -### buf.writeUIntLE(value, offset, byteLength[, noAssert]) +### buf.writeUIntBE(value, offset, byteLength) +### buf.writeUIntLE(value, offset, byteLength) * `value` {integer} Number to be written to `buf`. * `offset` {integer} Number of bytes to skip before starting to write. Must satisfy: `0 <= offset <= buf.length - byteLength`. * `byteLength` {integer} Number of bytes to write. Must satisfy: `0 < byteLength <= 6`. -* `noAssert` {boolean} Skip `value`, `offset`, and `byteLength` validation? **Default:** `false` * Returns: {integer} `offset` plus the number of bytes written. @@ -2472,9 +2494,6 @@ Writes `byteLength` bytes of `value` to `buf` at the specified `offset`. Supports up to 48 bits of accuracy. Behavior is undefined when `value` is anything other than an unsigned integer. -Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond -the end of `buf`, but the resulting behavior is undefined. - Examples: ```js diff --git a/lib/buffer.js b/lib/buffer.js index 220437f25d7534..ead43b453d46ac 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -68,6 +68,10 @@ internalBuffer.FastBuffer = FastBuffer; Buffer.prototype = FastBuffer.prototype; +for (const [name, method] of Object.entries(internalBuffer.readWrites)) { + Buffer.prototype[name] = method; +} + const constants = Object.defineProperties({}, { MAX_LENGTH: { value: kMaxLength, @@ -81,12 +85,6 @@ const constants = Object.defineProperties({}, { } }); -// Temporary buffers to convert numbers. -const float32Array = new Float32Array(1); -const uInt8Float32Array = new Uint8Array(float32Array.buffer); -const float64Array = new Float64Array(1); -const uInt8Float64Array = new Uint8Array(float64Array.buffer); - Buffer.poolSize = 8 * 1024; var poolSize, poolOffset, allocPool; @@ -998,551 +996,6 @@ Buffer.prototype.slice = function slice(start, end) { return new FastBuffer(this.buffer, this.byteOffset + start, newLength); }; -function checkOffset(offset, ext, length) { - if (offset + ext > length) - throw new errors.RangeError('ERR_INDEX_OUT_OF_RANGE'); -} - -function checkByteLength(byteLength) { - if (byteLength < 1 || byteLength > 6) { - throw new errors.RangeError('ERR_OUT_OF_RANGE', - 'byteLength', - '>= 1 and <= 6'); - } -} - -Buffer.prototype.readUIntLE = - function readUIntLE(offset, byteLength, noAssert) { - offset = offset >>> 0; - byteLength = byteLength >>> 0; - if (!noAssert) { - checkByteLength(byteLength); - checkOffset(offset, byteLength, this.length); - } - - var val = this[offset]; - var mul = 1; - var i = 0; - while (++i < byteLength && (mul *= 0x100)) - val += this[offset + i] * mul; - - return val; - }; - -Buffer.prototype.readUIntBE = - function readUIntBE(offset, byteLength, noAssert) { - offset = offset >>> 0; - byteLength = byteLength >>> 0; - if (!noAssert) { - checkByteLength(byteLength); - checkOffset(offset, byteLength, this.length); - } - - var val = this[offset + --byteLength]; - var mul = 1; - while (byteLength > 0 && (mul *= 0x100)) - val += this[offset + --byteLength] * mul; - - return val; - }; - -Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 1, this.length); - return this[offset]; -}; - -Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 2, this.length); - return this[offset] | (this[offset + 1] << 8); -}; - -Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 2, this.length); - return (this[offset] << 8) | this[offset + 1]; -}; - -Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 4, this.length); - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000); -}; - -Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 4, this.length); - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]); -}; - -Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) { - offset = offset >>> 0; - byteLength = byteLength >>> 0; - - if (!noAssert) { - checkByteLength(byteLength); - checkOffset(offset, byteLength, this.length); - } - - var val = this[offset]; - var mul = 1; - var i = 0; - while (++i < byteLength && (mul *= 0x100)) - val += this[offset + i] * mul; - mul *= 0x80; - - if (val >= mul) - val -= Math.pow(2, 8 * byteLength); - - return val; -}; - -Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) { - offset = offset >>> 0; - byteLength = byteLength >>> 0; - - if (!noAssert) { - checkByteLength(byteLength); - checkOffset(offset, byteLength, this.length); - } - - var i = byteLength; - var mul = 1; - var val = this[offset + --i]; - while (i > 0 && (mul *= 0x100)) - val += this[offset + --i] * mul; - mul *= 0x80; - - if (val >= mul) - val -= Math.pow(2, 8 * byteLength); - - return val; -}; - -Buffer.prototype.readInt8 = function readInt8(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 1, this.length); - var val = this[offset]; - return !(val & 0x80) ? val : (0xff - val + 1) * -1; -}; - -Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 2, this.length); - var val = this[offset] | (this[offset + 1] << 8); - return (val & 0x8000) ? val | 0xFFFF0000 : val; -}; - -Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 2, this.length); - var val = this[offset + 1] | (this[offset] << 8); - return (val & 0x8000) ? val | 0xFFFF0000 : val; -}; - -Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 4, this.length); - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24); -}; - -Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) { - offset = offset >>> 0; - if (!noAssert) - checkOffset(offset, 4, this.length); - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]); -}; - -// For the casual reader who has not at the current time memorized the -// IEEE-754 standard in full detail: floating point numbers consist of -// a fraction, an exponent and a sign bit: 23+8+1 bits for single precision -// numbers and 52+11+1 bits for double precision numbers. -// -// A zero exponent is either a positive or negative zero, if the fraction -// is zero, or a denormalized number when it is non-zero. Multiplying the -// fraction by the smallest possible denormal yields the denormalized number. -// -// An all-bits-one exponent is either a positive or negative infinity, if -// the fraction is zero, or NaN when it is non-zero. The standard allows -// both quiet and signaling NaNs but since NaN is a canonical value in -// JavaScript, we cannot (and do not) distinguish between the two. -// -// Other exponents are regular numbers and are computed by subtracting the bias -// from the exponent (127 for single precision, 1023 for double precision), -// yielding an exponent in the ranges -126-127 and -1022-1024 respectively. -// -// Of interest is that the fraction of a normal number has an extra bit of -// precision that is not stored but is reconstructed by adding one after -// multiplying the fraction with the result of 2**-bits_in_fraction. - -function toDouble(x0, x1) { - const frac = x0 + 0x100000000 * (x1 & 0xFFFFF); - const expt = (x1 >>> 20) & 2047; - const sign = (x1 >>> 31) ? -1 : 1; - if (expt === 0) { - if (frac === 0) return sign * 0; - return sign * frac * 2 ** -1074; - } else if (expt === 2047) { - if (frac === 0) return sign * Infinity; - return NaN; - } - return sign * 2 ** (expt - 1023) * (1 + frac * 2 ** -52); -} - -function toFloat(x) { - const frac = x & 0x7FFFFF; - const expt = (x >>> 23) & 255; - const sign = (x >>> 31) ? -1 : 1; - if (expt === 0) { - if (frac === 0) return sign * 0; - return sign * frac * 2 ** -149; - } else if (expt === 255) { - if (frac === 0) return sign * Infinity; - return NaN; - } - return sign * 2 ** (expt - 127) * (1 + frac * 2 ** -23); -} - -Buffer.prototype.readDoubleBE = function(offset, noAssert) { - offset = offset >>> 0; - const x1 = this.readUInt32BE(offset + 0, noAssert); - const x0 = this.readUInt32BE(offset + 4, noAssert); - return toDouble(x0, x1); -}; - -Buffer.prototype.readDoubleLE = function(offset, noAssert) { - offset = offset >>> 0; - const x0 = this.readUInt32LE(offset + 0, noAssert); - const x1 = this.readUInt32LE(offset + 4, noAssert); - return toDouble(x0, x1); -}; - -Buffer.prototype.readFloatBE = function(offset, noAssert) { - offset = offset >>> 0; - return toFloat(this.readUInt32BE(offset, noAssert)); -}; - -Buffer.prototype.readFloatLE = function(offset, noAssert) { - offset = offset >>> 0; - return toFloat(this.readUInt32LE(offset, noAssert)); -}; - -function checkOOB(buffer, offset, ext) { - if (offset + ext > buffer.length) - throw new errors.RangeError('ERR_INDEX_OUT_OF_RANGE'); -} - -function checkInt(buffer, value, offset, ext, max, min) { - if (value > max || value < min) - throw new errors.RangeError('ERR_INVALID_OPT_VALUE', 'value', value); - checkOOB(buffer, offset, ext); -} - -Buffer.prototype.writeUIntLE = - function writeUIntLE(value, offset, byteLength, noAssert) { - value = +value; - offset = offset >>> 0; - byteLength = byteLength >>> 0; - if (!noAssert) { - const maxBytes = Math.pow(2, 8 * byteLength) - 1; - checkInt(this, value, offset, byteLength, maxBytes, 0); - } - - var mul = 1; - var i = 0; - this[offset] = value; - while (++i < byteLength && (mul *= 0x100)) - this[offset + i] = (value / mul) >>> 0; - - return offset + byteLength; - }; - -Buffer.prototype.writeUIntBE = - function writeUIntBE(value, offset, byteLength, noAssert) { - value = +value; - offset = offset >>> 0; - byteLength = byteLength >>> 0; - if (!noAssert) { - const maxBytes = Math.pow(2, 8 * byteLength) - 1; - checkInt(this, value, offset, byteLength, maxBytes, 0); - } - - var i = byteLength - 1; - var mul = 1; - this[offset + i] = value; - while (--i >= 0 && (mul *= 0x100)) - this[offset + i] = (value / mul) >>> 0; - - return offset + byteLength; - }; - -Buffer.prototype.writeUInt8 = - function writeUInt8(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 1, 0xff, 0); - this[offset] = value; - return offset + 1; - }; - -Buffer.prototype.writeUInt16LE = - function writeUInt16LE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 2, 0xffff, 0); - this[offset] = value; - this[offset + 1] = (value >>> 8); - return offset + 2; - }; - -Buffer.prototype.writeUInt16BE = - function writeUInt16BE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 2, 0xffff, 0); - this[offset] = (value >>> 8); - this[offset + 1] = value; - return offset + 2; - }; - -Buffer.prototype.writeUInt32LE = - function writeUInt32LE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 4, 0xffffffff, 0); - this[offset + 3] = (value >>> 24); - this[offset + 2] = (value >>> 16); - this[offset + 1] = (value >>> 8); - this[offset] = value; - return offset + 4; - }; - -Buffer.prototype.writeUInt32BE = - function writeUInt32BE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 4, 0xffffffff, 0); - this[offset] = (value >>> 24); - this[offset + 1] = (value >>> 16); - this[offset + 2] = (value >>> 8); - this[offset + 3] = value; - return offset + 4; - }; - -Buffer.prototype.writeIntLE = - function writeIntLE(value, offset, byteLength, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) { - checkInt(this, - value, - offset, - byteLength, - Math.pow(2, 8 * byteLength - 1) - 1, - -Math.pow(2, 8 * byteLength - 1)); - } - - var i = 0; - var mul = 1; - var sub = 0; - this[offset] = value; - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) - sub = 1; - this[offset + i] = ((value / mul) >> 0) - sub; - } - - return offset + byteLength; - }; - -Buffer.prototype.writeIntBE = - function writeIntBE(value, offset, byteLength, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) { - checkInt(this, - value, - offset, - byteLength, - Math.pow(2, 8 * byteLength - 1) - 1, - -Math.pow(2, 8 * byteLength - 1)); - } - - var i = byteLength - 1; - var mul = 1; - var sub = 0; - this[offset + i] = value; - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) - sub = 1; - this[offset + i] = ((value / mul) >> 0) - sub; - } - - return offset + byteLength; - }; - -Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 1, 0x7f, -0x80); - this[offset] = value; - return offset + 1; -}; - -Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 2, 0x7fff, -0x8000); - this[offset] = value; - this[offset + 1] = (value >>> 8); - return offset + 2; -}; - -Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 2, 0x7fff, -0x8000); - this[offset] = (value >>> 8); - this[offset + 1] = value; - return offset + 2; -}; - -Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); - this[offset] = value; - this[offset + 1] = (value >>> 8); - this[offset + 2] = (value >>> 16); - this[offset + 3] = (value >>> 24); - return offset + 4; -}; - -Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) { - value = +value; - offset = offset >>> 0; - if (!noAssert) - checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); - this[offset] = (value >>> 24); - this[offset + 1] = (value >>> 16); - this[offset + 2] = (value >>> 8); - this[offset + 3] = value; - return offset + 4; -}; - -function writeDoubleForwards(val, offset, noAssert) { - val = +val; - offset = offset >>> 0; - if (!noAssert) - checkOOB(this, offset, 8); - - float64Array[0] = val; - this[offset++] = uInt8Float64Array[0]; - this[offset++] = uInt8Float64Array[1]; - this[offset++] = uInt8Float64Array[2]; - this[offset++] = uInt8Float64Array[3]; - this[offset++] = uInt8Float64Array[4]; - this[offset++] = uInt8Float64Array[5]; - this[offset++] = uInt8Float64Array[6]; - this[offset++] = uInt8Float64Array[7]; - return offset; -} - -function writeDoubleBackwards(val, offset, noAssert) { - val = +val; - offset = offset >>> 0; - if (!noAssert) - checkOOB(this, offset, 8); - - float64Array[0] = val; - this[offset++] = uInt8Float64Array[7]; - this[offset++] = uInt8Float64Array[6]; - this[offset++] = uInt8Float64Array[5]; - this[offset++] = uInt8Float64Array[4]; - this[offset++] = uInt8Float64Array[3]; - this[offset++] = uInt8Float64Array[2]; - this[offset++] = uInt8Float64Array[1]; - this[offset++] = uInt8Float64Array[0]; - return offset; -} - -function writeFloatForwards(val, offset, noAssert) { - val = +val; - offset = offset >>> 0; - if (!noAssert) - checkOOB(this, offset, 4); - - float32Array[0] = val; - this[offset++] = uInt8Float32Array[0]; - this[offset++] = uInt8Float32Array[1]; - this[offset++] = uInt8Float32Array[2]; - this[offset++] = uInt8Float32Array[3]; - return offset; -} - -function writeFloatBackwards(val, offset, noAssert) { - val = +val; - offset = offset >>> 0; - if (!noAssert) - checkOOB(this, offset, 4); - - float32Array[0] = val; - this[offset++] = uInt8Float32Array[3]; - this[offset++] = uInt8Float32Array[2]; - this[offset++] = uInt8Float32Array[1]; - this[offset++] = uInt8Float32Array[0]; - return offset; -} - -// Check endianness. -float32Array[0] = -1; -if (uInt8Float32Array[3] === 0) { // Big endian. - Buffer.prototype.writeFloatLE = writeFloatBackwards; - Buffer.prototype.writeFloatBE = writeFloatForwards; - Buffer.prototype.writeDoubleLE = writeDoubleBackwards; - Buffer.prototype.writeDoubleBE = writeDoubleForwards; -} else { // Small endian. - Buffer.prototype.writeFloatLE = writeFloatForwards; - Buffer.prototype.writeFloatBE = writeFloatBackwards; - Buffer.prototype.writeDoubleLE = writeDoubleForwards; - Buffer.prototype.writeDoubleBE = writeDoubleBackwards; -} - function swap(b, n, m) { const i = b[n]; b[n] = b[m]; diff --git a/lib/internal/buffer.js b/lib/internal/buffer.js index 105ff4132a9770..b5da69a5b3e27b 100644 --- a/lib/internal/buffer.js +++ b/lib/internal/buffer.js @@ -1,13 +1,797 @@ 'use strict'; const binding = process.binding('buffer'); +const { TypeError, RangeError } = require('internal/errors'); const { setupBufferJS } = binding; // Remove from the binding so that function is only available as exported here. // (That is, for internal use only.) delete binding.setupBufferJS; +// Temporary buffers to convert numbers. +const float32Array = new Float32Array(1); +const uInt8Float32Array = new Uint8Array(float32Array.buffer); +const float64Array = new Float64Array(1); +const uInt8Float64Array = new Uint8Array(float64Array.buffer); + +// Check endianness. +float32Array[0] = -1; +const bigEndian = uInt8Float32Array[3] === 0; + +function checkBounds(buf, offset, byteLength) { + checkNumberType(offset); + if (buf[offset] === undefined || buf[offset + byteLength] === undefined) + boundsError(offset, buf.length - (byteLength + 1)); +} + +function checkInt(value, min, max, buf, offset, byteLength) { + if (value > max || value < min) { + throw new RangeError('ERR_OUT_OF_RANGE', + 'value', `>= ${min} and <= ${max}`, value); + } + checkBounds(buf, offset, byteLength); +} + +function checkNumberType(value, type) { + if (typeof value !== 'number') { + throw new TypeError('ERR_INVALID_ARG_TYPE', + type || 'offset', 'number', value); + } +} + +function boundsError(value, length, type) { + if (Math.floor(value) !== value) { + checkNumberType(value, type); + throw new RangeError('ERR_OUT_OF_RANGE', + type || 'offset', 'an integer', value); + } + + if (length < 0) + throw new RangeError('ERR_BUFFER_OUT_OF_BOUNDS', null, true); + + throw new RangeError('ERR_OUT_OF_RANGE', + type || 'offset', + `>= ${type ? 1 : 0} and <= ${length}`, + value); +} + +// Read integers. +function readUIntLE(offset, byteLength) { + if (byteLength === 6) + return readUInt48LE(this, offset); + if (byteLength === 5) + return readUInt40LE(this, offset); + if (byteLength === 3) + return readUInt24LE(this, offset); + if (byteLength === 4) + return this.readUInt32LE(offset); + if (byteLength === 2) + return this.readUInt16LE(offset); + if (byteLength === 1) + return this.readUInt8(offset); + + boundsError(byteLength, 6, 'byteLength'); +} + +function readUInt48LE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 5]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 6); + + return first + + buf[++offset] * 2 ** 8 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 24 + + (buf[++offset] + last * 2 ** 8) * 2 ** 32; +} + +function readUInt40LE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 4]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 5); + + return first + + buf[++offset] * 2 ** 8 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 24 + + last * 2 ** 32; +} + +function readUInt32LE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 3]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 4); + + return first + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + last * 2 ** 24; +} + +function readUInt24LE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 2]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 3); + + return first + buf[++offset] * 2 ** 8 + last * 2 ** 16; +} + +function readUInt16LE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 1]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 2); + + return first + last * 2 ** 8; +} + +function readUInt8(offset) { + checkNumberType(offset); + const val = this[offset]; + if (val === undefined) + boundsError(offset, this.length - 1); + + return val; +} + +function readUIntBE(offset, byteLength) { + if (byteLength === 6) + return readUInt48BE(this, offset); + if (byteLength === 5) + return readUInt40BE(this, offset); + if (byteLength === 3) + return readUInt24BE(this, offset); + if (byteLength === 4) + return this.readUInt32BE(offset); + if (byteLength === 2) + return this.readUInt16BE(offset); + if (byteLength === 1) + return this.readUInt8(offset); + + boundsError(byteLength, 6, 'byteLength'); +} + +function readUInt48BE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 5]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 6); + + return (first * 2 ** 8 + buf[++offset]) * 2 ** 32 + + buf[++offset] * 2 ** 24 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 8 + + last; +} + +function readUInt40BE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 4]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 5); + + return first * 2 ** 32 + + buf[++offset] * 2 ** 24 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 8 + + last; +} + +function readUInt32BE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 3]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 4); + + return first * 2 ** 24 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + last; +} + +function readUInt24BE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 2]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 3); + + return first * 2 ** 16 + buf[++offset] * 2 ** 8 + last; +} + +function readUInt16BE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 1]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 2); + + return first * 2 ** 8 + last; +} + +function readIntLE(offset, byteLength) { + if (byteLength === 6) + return readInt48LE(this, offset); + if (byteLength === 5) + return readInt40LE(this, offset); + if (byteLength === 3) + return readInt24LE(this, offset); + if (byteLength === 4) + return this.readInt32LE(offset); + if (byteLength === 2) + return this.readInt16LE(offset); + if (byteLength === 1) + return this.readInt8(offset); + + boundsError(byteLength, 6, 'byteLength'); +} + +function readInt48LE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 5]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 6); + + const val = buf[offset + 4] + last * 2 ** 8; + return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + + first + + buf[++offset] * 2 ** 8 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 24; +} + +function readInt40LE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 4]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 5); + + return (last | (last & 2 ** 7) * 0x1fffffe) * 2 ** 32 + + first + + buf[++offset] * 2 ** 8 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 24; +} + +function readInt32LE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 3]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 4); + + return first + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + (last << 24); // Overflow +} + +function readInt24LE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 2]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 3); + + const val = first + buf[++offset] * 2 ** 8 + last * 2 ** 16; + return val | (val & 2 ** 23) * 0x1fe; +} + +function readInt16LE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 1]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 2); + + const val = first + last * 2 ** 8; + return val | (val & 2 ** 15) * 0x1fffe; +} + +function readInt8(offset) { + checkNumberType(offset); + const val = this[offset]; + if (val === undefined) + boundsError(offset, this.length - 1); + + return val | (val & 2 ** 7) * 0x1fffffe; +} + +function readIntBE(offset, byteLength) { + if (byteLength === 6) + return readInt48BE(this, offset); + if (byteLength === 5) + return readInt40BE(this, offset); + if (byteLength === 3) + return readInt24BE(this, offset); + if (byteLength === 4) + return this.readInt32BE(offset); + if (byteLength === 2) + return this.readInt16BE(offset); + if (byteLength === 1) + return this.readInt8(offset); + + boundsError(byteLength, 6, 'byteLength'); +} + +function readInt48BE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 5]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 6); + + const val = buf[++offset] + first * 2 ** 8; + return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + + buf[++offset] * 2 ** 24 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 8 + + last; +} + +function readInt40BE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 4]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 5); + + return (first | (first & 2 ** 7) * 0x1fffffe) * 2 ** 32 + + buf[++offset] * 2 ** 24 + + buf[++offset] * 2 ** 16 + + buf[++offset] * 2 ** 8 + + last; +} + +function readInt32BE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 3]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 4); + + return (first << 24) + // Overflow + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + last; +} + +function readInt24BE(buf, offset) { + checkNumberType(offset); + const first = buf[offset]; + const last = buf[offset + 2]; + if (first === undefined || last === undefined) + boundsError(offset, buf.length - 3); + + const val = first * 2 ** 16 + buf[++offset] * 2 ** 8 + last; + return val | (val & 2 ** 23) * 0x1fe; +} + +function readInt16BE(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 1]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 2); + + const val = first * 2 ** 8 + last; + return val | (val & 2 ** 15) * 0x1fffe; +} + +// Read floats +function readFloatBackwards(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 3]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 4); + + uInt8Float32Array[3] = first; + uInt8Float32Array[2] = this[++offset]; + uInt8Float32Array[1] = this[++offset]; + uInt8Float32Array[0] = last; + return float32Array[0]; +} + +function readFloatForwards(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 3]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 4); + + uInt8Float32Array[0] = first; + uInt8Float32Array[1] = this[++offset]; + uInt8Float32Array[2] = this[++offset]; + uInt8Float32Array[3] = last; + return float32Array[0]; +} + +function readDoubleBackwards(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 7]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 8); + + uInt8Float64Array[7] = first; + uInt8Float64Array[6] = this[++offset]; + uInt8Float64Array[5] = this[++offset]; + uInt8Float64Array[4] = this[++offset]; + uInt8Float64Array[3] = this[++offset]; + uInt8Float64Array[2] = this[++offset]; + uInt8Float64Array[1] = this[++offset]; + uInt8Float64Array[0] = last; + return float64Array[0]; +} + +function readDoubleForwards(offset) { + checkNumberType(offset); + const first = this[offset]; + const last = this[offset + 7]; + if (first === undefined || last === undefined) + boundsError(offset, this.length - 8); + + uInt8Float64Array[0] = first; + uInt8Float64Array[1] = this[++offset]; + uInt8Float64Array[2] = this[++offset]; + uInt8Float64Array[3] = this[++offset]; + uInt8Float64Array[4] = this[++offset]; + uInt8Float64Array[5] = this[++offset]; + uInt8Float64Array[6] = this[++offset]; + uInt8Float64Array[7] = last; + return float64Array[0]; +} + +// Write integers. +function writeUIntLE(value, offset, byteLength) { + if (byteLength === 6) + return writeU_Int48LE(this, value, offset, 0, 0xffffffffffff); + if (byteLength === 5) + return writeU_Int40LE(this, value, offset, 0, 0xffffffffff); + if (byteLength === 3) + return writeU_Int24LE(this, value, offset, 0, 0xffffff); + if (byteLength === 4) + return writeU_Int32LE(this, value, offset, 0, 0xffffffff); + if (byteLength === 2) + return writeU_Int16LE(this, value, offset, 0, 0xffff); + if (byteLength === 1) + return writeU_Int8(this, value, offset, 0, 0xff); + + boundsError(byteLength, 6, 'byteLength'); +} + +function writeU_Int48LE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 5); + + const newVal = Math.floor(value * 2 ** -32); + buf[offset++] = value; + buf[offset++] = (value >>> 8); + buf[offset++] = (value >>> 16); + buf[offset++] = (value >>> 24); + buf[offset++] = newVal; + buf[offset++] = (newVal >>> 8); + return offset; +} + +function writeU_Int40LE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 4); + + const newVal = value; + buf[offset++] = value; + buf[offset++] = (value >>> 8); + buf[offset++] = (value >>> 16); + buf[offset++] = (value >>> 24); + buf[offset++] = Math.floor(newVal * 2 ** -32); + return offset; +} + +function writeU_Int32LE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 3); + + buf[offset++] = value; + buf[offset++] = (value >>> 8); + buf[offset++] = (value >>> 16); + buf[offset++] = (value >>> 24); + return offset; +} + +function writeUInt32LE(value, offset) { + return writeU_Int32LE(this, value, offset, 0, 0xffffffff); +} + +function writeU_Int24LE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 2); + + buf[offset++] = value; + buf[offset++] = (value >>> 8); + buf[offset++] = (value >>> 16); + return offset; +} + +function writeU_Int16LE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 1); + + buf[offset++] = value; + buf[offset++] = (value >>> 8); + return offset; +} + +function writeUInt16LE(value, offset) { + return writeU_Int16LE(this, value, offset, 0, 0xffff); +} + +function writeU_Int8(buf, value, offset, min, max) { + value = +value; + // `checkInt()` can not be used here because it checks two entries. + checkNumberType(offset); + if (value > max || value < min) { + throw new RangeError('ERR_OUT_OF_RANGE', + 'value', + `>= ${min} and <= ${max}`, value); + } + if (buf[offset] === undefined) + boundsError(offset, buf.length - 1); + + buf[offset] = value; + return offset + 1; +} + +function writeUInt8(value, offset) { + return writeU_Int8(this, value, offset, 0, 0xff); +} + +function writeUIntBE(value, offset, byteLength) { + if (byteLength === 6) + return writeU_Int48BE(this, value, offset, 0, 0xffffffffffffff); + if (byteLength === 5) + return writeU_Int40BE(this, value, offset, 0, 0xffffffffff); + if (byteLength === 3) + return writeU_Int24BE(this, value, offset, 0, 0xffffff); + if (byteLength === 4) + return writeU_Int32BE(this, value, offset, 0, 0xffffffff); + if (byteLength === 2) + return writeU_Int16BE(this, value, offset, 0, 0xffff); + if (byteLength === 1) + return writeU_Int8(this, value, offset, 0, 0xff); + + boundsError(byteLength, 6, 'byteLength'); +} + +function writeU_Int48BE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 5); + + const newVal = Math.floor(value * 2 ** -32); + buf[offset++] = (newVal >>> 8); + buf[offset++] = newVal; + buf[offset++] = (value >>> 24); + buf[offset++] = (value >>> 16); + buf[offset++] = (value >>> 8); + buf[offset++] = value; + return offset; +} + +function writeU_Int40BE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 4); + + buf[offset++] = Math.floor(value * 2 ** -32); + buf[offset++] = (value >>> 24); + buf[offset++] = (value >>> 16); + buf[offset++] = (value >>> 8); + buf[offset++] = value; + return offset; +} + +function writeU_Int32BE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 3); + + buf[offset++] = (value >>> 24); + buf[offset++] = (value >>> 16); + buf[offset++] = (value >>> 8); + buf[offset++] = value; + return offset; +} + +function writeUInt32BE(value, offset) { + return writeU_Int32BE(this, value, offset, 0, 0xffffffff); +} + +function writeU_Int24BE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 2); + + buf[offset++] = (value >>> 16); + buf[offset++] = (value >>> 8); + buf[offset++] = value; + return offset; +} + +function writeU_Int16BE(buf, value, offset, min, max) { + value = +value; + checkInt(value, min, max, buf, offset, 1); + + buf[offset++] = (value >>> 8); + buf[offset++] = value; + return offset; +} + +function writeUInt16BE(value, offset) { + return writeU_Int16BE(this, value, offset, 0, 0xffffffff); +} + +function writeIntLE(value, offset, byteLength) { + if (byteLength === 6) + return writeU_Int48LE(this, value, offset, -0x800000000000, 0x7fffffffffff); + if (byteLength === 5) + return writeU_Int40LE(this, value, offset, -0x8000000000, 0x7fffffffff); + if (byteLength === 3) + return writeU_Int24LE(this, value, offset, -0x800000, 0x7fffff); + if (byteLength === 4) + return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff); + if (byteLength === 2) + return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff); + if (byteLength === 1) + return writeU_Int8(this, value, offset, -0x80, 0x7f); + + boundsError(byteLength, 6, 'byteLength'); +} + +function writeInt32LE(value, offset) { + return writeU_Int32LE(this, value, offset, -0x80000000, 0x7fffffff); +} + +function writeInt16LE(value, offset) { + return writeU_Int16LE(this, value, offset, -0x8000, 0x7fff); +} + +function writeInt8(value, offset) { + return writeU_Int8(this, value, offset, -0x80, 0x7f); +} + +function writeIntBE(value, offset, byteLength) { + if (byteLength === 6) + return writeU_Int48BE(this, value, offset, -0x800000000000, 0x7fffffffffff); + if (byteLength === 5) + return writeU_Int40BE(this, value, offset, -0x8000000000, 0x7fffffffff); + if (byteLength === 3) + return writeU_Int24BE(this, value, offset, -0x800000, 0x7fffff); + if (byteLength === 4) + return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff); + if (byteLength === 2) + return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff); + if (byteLength === 1) + return writeU_Int8(this, value, offset, -0x80, 0x7f); + + boundsError(byteLength, 6, 'byteLength'); +} + +function writeInt32BE(value, offset) { + return writeU_Int32BE(this, value, offset, -0x80000000, 0x7fffffff); +} + +function writeInt16BE(value, offset) { + return writeU_Int16BE(this, value, offset, -0x8000, 0x7fff); +} + +// Write floats. +function writeDoubleForwards(val, offset) { + val = +val; + checkBounds(this, offset, 7); + + float64Array[0] = val; + this[offset++] = uInt8Float64Array[0]; + this[offset++] = uInt8Float64Array[1]; + this[offset++] = uInt8Float64Array[2]; + this[offset++] = uInt8Float64Array[3]; + this[offset++] = uInt8Float64Array[4]; + this[offset++] = uInt8Float64Array[5]; + this[offset++] = uInt8Float64Array[6]; + this[offset++] = uInt8Float64Array[7]; + return offset; +} + +function writeDoubleBackwards(val, offset) { + val = +val; + checkBounds(this, offset, 7); + + float64Array[0] = val; + this[offset++] = uInt8Float64Array[7]; + this[offset++] = uInt8Float64Array[6]; + this[offset++] = uInt8Float64Array[5]; + this[offset++] = uInt8Float64Array[4]; + this[offset++] = uInt8Float64Array[3]; + this[offset++] = uInt8Float64Array[2]; + this[offset++] = uInt8Float64Array[1]; + this[offset++] = uInt8Float64Array[0]; + return offset; +} + +function writeFloatForwards(val, offset) { + val = +val; + checkBounds(this, offset, 3); + + float32Array[0] = val; + this[offset++] = uInt8Float32Array[0]; + this[offset++] = uInt8Float32Array[1]; + this[offset++] = uInt8Float32Array[2]; + this[offset++] = uInt8Float32Array[3]; + return offset; +} + +function writeFloatBackwards(val, offset) { + val = +val; + checkBounds(this, offset, 3); + + float32Array[0] = val; + this[offset++] = uInt8Float32Array[3]; + this[offset++] = uInt8Float32Array[2]; + this[offset++] = uInt8Float32Array[1]; + this[offset++] = uInt8Float32Array[0]; + return offset; +} + // FastBuffer wil be inserted here by lib/buffer.js module.exports = { - setupBufferJS + setupBufferJS, + // Container to export all read write functions. + readWrites: { + readUIntLE, + readUInt32LE, + readUInt16LE, + readUInt8, + readUIntBE, + readUInt32BE, + readUInt16BE, + readIntLE, + readInt32LE, + readInt16LE, + readInt8, + readIntBE, + readInt32BE, + readInt16BE, + writeUIntLE, + writeUInt32LE, + writeUInt16LE, + writeUInt8, + writeUIntBE, + writeUInt32BE, + writeUInt16BE, + writeIntLE, + writeInt32LE, + writeInt16LE, + writeInt8, + writeIntBE, + writeInt32BE, + writeInt16BE, + readFloatLE: bigEndian ? readFloatBackwards : readFloatForwards, + readFloatBE: bigEndian ? readFloatForwards : readFloatBackwards, + readDoubleLE: bigEndian ? readDoubleBackwards : readDoubleForwards, + readDoubleBE: bigEndian ? readDoubleForwards : readDoubleBackwards, + writeFloatLE: bigEndian ? writeFloatBackwards : writeFloatForwards, + writeFloatBE: bigEndian ? writeFloatForwards : writeFloatBackwards, + writeDoubleLE: bigEndian ? writeDoubleBackwards : writeDoubleForwards, + writeDoubleBE: bigEndian ? writeDoubleForwards : writeDoubleBackwards + } }; diff --git a/test/parallel/test-buffer-arraybuffer.js b/test/parallel/test-buffer-arraybuffer.js index 41af1eecbea4b2..b7f9359a00489c 100644 --- a/test/parallel/test-buffer-arraybuffer.js +++ b/test/parallel/test-buffer-arraybuffer.js @@ -42,13 +42,6 @@ assert.throws(function() { Buffer.from(new AB()); }, TypeError); -// write{Double,Float}{LE,BE} with noAssert should not crash, cf. #3766 -const b = Buffer.allocUnsafe(1); -b.writeFloatLE(11.11, 0, true); -b.writeFloatBE(11.11, 0, true); -b.writeDoubleLE(11.11, 0, true); -b.writeDoubleBE(11.11, 0, true); - // Test the byteOffset and length arguments { const ab = new Uint8Array(5); diff --git a/test/parallel/test-buffer-read.js b/test/parallel/test-buffer-read.js index ccde2cc3a2d762..e6a4f872b83260 100644 --- a/test/parallel/test-buffer-read.js +++ b/test/parallel/test-buffer-read.js @@ -6,16 +6,11 @@ const assert = require('assert'); const buf = Buffer.from([0xa4, 0xfd, 0x48, 0xea, 0xcf, 0xff, 0xd9, 0x01, 0xde]); function read(buff, funx, args, expected) { - assert.strictEqual(buff[funx](...args), expected); common.expectsError( () => buff[funx](-1, args[1]), - { - code: 'ERR_INDEX_OUT_OF_RANGE' - } + { code: 'ERR_OUT_OF_RANGE' } ); - - assert.strictEqual(buff[funx](...args, true), expected); } // testing basic functionality of readDoubleBE() and readDoubleLE() @@ -123,7 +118,7 @@ assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); (0xFFFFFFFF >> (32 - bits))); }); -// test for common read(U)IntLE/BE +// Test for common read(U)IntLE/BE { const buf = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); @@ -144,19 +139,3 @@ assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); assert.strictEqual(buf.readIntLE(0, 6), 0x060504030201); assert.strictEqual(buf.readIntBE(0, 6), 0x010203040506); } - -// test for byteLength parameter not between 1 and 6 (inclusive) -common.expectsError(() => { buf.readIntLE(1); }, { code: 'ERR_OUT_OF_RANGE' }); -common.expectsError(() => { buf.readIntLE(1, 'string'); }, - { code: 'ERR_OUT_OF_RANGE' }); -common.expectsError(() => { buf.readIntLE(1, 0); }, - { code: 'ERR_OUT_OF_RANGE' }); -common.expectsError(() => { buf.readIntLE(1, 7); }, - { code: 'ERR_OUT_OF_RANGE' }); -common.expectsError(() => { buf.readIntBE(1); }, { code: 'ERR_OUT_OF_RANGE' }); -common.expectsError(() => { buf.readIntBE(1, 'string'); }, - { code: 'ERR_OUT_OF_RANGE' }); -common.expectsError(() => { buf.readIntBE(1, 0); }, - { code: 'ERR_OUT_OF_RANGE' }); -common.expectsError(() => { buf.readIntBE(1, 7); }, - { code: 'ERR_OUT_OF_RANGE' }); diff --git a/test/parallel/test-buffer-readdouble.js b/test/parallel/test-buffer-readdouble.js new file mode 100644 index 00000000000000..2853142e3506ff --- /dev/null +++ b/test/parallel/test-buffer-readdouble.js @@ -0,0 +1,138 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test (64 bit) double +const buffer = Buffer.allocUnsafe(8); + +buffer[0] = 0x55; +buffer[1] = 0x55; +buffer[2] = 0x55; +buffer[3] = 0x55; +buffer[4] = 0x55; +buffer[5] = 0x55; +buffer[6] = 0xd5; +buffer[7] = 0x3f; +assert.strictEqual(buffer.readDoubleBE(0), 1.1945305291680097e+103); +assert.strictEqual(buffer.readDoubleLE(0), 0.3333333333333333); + +buffer[0] = 1; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0; +buffer[4] = 0; +buffer[5] = 0; +buffer[6] = 0xf0; +buffer[7] = 0x3f; +assert.strictEqual(buffer.readDoubleBE(0), 7.291122019655968e-304); +assert.strictEqual(buffer.readDoubleLE(0), 1.0000000000000002); + +buffer[0] = 2; +assert.strictEqual(buffer.readDoubleBE(0), 4.778309726801735e-299); +assert.strictEqual(buffer.readDoubleLE(0), 1.0000000000000004); + +buffer[0] = 1; +buffer[6] = 0; +buffer[7] = 0; +assert.strictEqual(buffer.readDoubleBE(0), 7.291122019556398e-304); +assert.strictEqual(buffer.readDoubleLE(0), 5e-324); + +buffer[0] = 0xff; +buffer[1] = 0xff; +buffer[2] = 0xff; +buffer[3] = 0xff; +buffer[4] = 0xff; +buffer[5] = 0xff; +buffer[6] = 0x0f; +buffer[7] = 0x00; +assert.ok(Number.isNaN(buffer.readDoubleBE(0))); +assert.strictEqual(buffer.readDoubleLE(0), 2.225073858507201e-308); + +buffer[6] = 0xef; +buffer[7] = 0x7f; +assert.ok(Number.isNaN(buffer.readDoubleBE(0))); +assert.strictEqual(buffer.readDoubleLE(0), 1.7976931348623157e+308); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0; +buffer[4] = 0; +buffer[5] = 0; +buffer[6] = 0xf0; +buffer[7] = 0x3f; +assert.strictEqual(buffer.readDoubleBE(0), 3.03865e-319); +assert.strictEqual(buffer.readDoubleLE(0), 1); + +buffer[6] = 0; +buffer[7] = 0x40; +assert.strictEqual(buffer.readDoubleBE(0), 3.16e-322); +assert.strictEqual(buffer.readDoubleLE(0), 2); + +buffer[7] = 0xc0; +assert.strictEqual(buffer.readDoubleBE(0), 9.5e-322); +assert.strictEqual(buffer.readDoubleLE(0), -2); + +buffer[6] = 0x10; +buffer[7] = 0; +assert.strictEqual(buffer.readDoubleBE(0), 2.0237e-320); +assert.strictEqual(buffer.readDoubleLE(0), 2.2250738585072014e-308); + +buffer[6] = 0; +assert.strictEqual(buffer.readDoubleBE(0), 0); +assert.strictEqual(buffer.readDoubleLE(0), 0); +assert.ok(1 / buffer.readDoubleLE(0) >= 0); + +buffer[7] = 0x80; +assert.strictEqual(buffer.readDoubleBE(0), 6.3e-322); +assert.strictEqual(buffer.readDoubleLE(0), -0); +assert.ok(1 / buffer.readDoubleLE(0) < 0); + +buffer[6] = 0xf0; +buffer[7] = 0x7f; +assert.strictEqual(buffer.readDoubleBE(0), 3.0418e-319); +assert.strictEqual(buffer.readDoubleLE(0), Infinity); + +buffer[7] = 0xff; +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) => { + assert.throws( + () => buffer[fn](off), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + }); + + [Infinity, -1, 1].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 0. Received ${offset}` + }); + }); + + assert.throws( + () => Buffer.alloc(1)[fn](1), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]', + message: 'Attempt to write outside buffer bounds' + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); +}); diff --git a/test/parallel/test-buffer-readfloat.js b/test/parallel/test-buffer-readfloat.js new file mode 100644 index 00000000000000..8e1e0ba5bb34b2 --- /dev/null +++ b/test/parallel/test-buffer-readfloat.js @@ -0,0 +1,101 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test 32 bit float +const buffer = Buffer.alloc(4); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0x80; +buffer[3] = 0x3f; +assert.strictEqual(buffer.readFloatBE(0), 4.600602988224807e-41); +assert.strictEqual(buffer.readFloatLE(0), 1); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0xc0; +assert.strictEqual(buffer.readFloatBE(0), 2.6904930515036488e-43); +assert.strictEqual(buffer.readFloatLE(0), -2); + +buffer[0] = 0xff; +buffer[1] = 0xff; +buffer[2] = 0x7f; +buffer[3] = 0x7f; +assert.ok(Number.isNaN(buffer.readFloatBE(0))); +assert.strictEqual(buffer.readFloatLE(0), 3.4028234663852886e+38); + +buffer[0] = 0xab; +buffer[1] = 0xaa; +buffer[2] = 0xaa; +buffer[3] = 0x3e; +assert.strictEqual(buffer.readFloatBE(0), -1.2126478207002966e-12); +assert.strictEqual(buffer.readFloatLE(0), 0.3333333432674408); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0; +assert.strictEqual(buffer.readFloatBE(0), 0); +assert.strictEqual(buffer.readFloatLE(0), 0); +assert.ok(1 / buffer.readFloatLE(0) >= 0); + +buffer[3] = 0x80; +assert.strictEqual(buffer.readFloatBE(0), 1.793662034335766e-43); +assert.strictEqual(buffer.readFloatLE(0), -0); +assert.ok(1 / buffer.readFloatLE(0) < 0); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0x80; +buffer[3] = 0x7f; +assert.strictEqual(buffer.readFloatBE(0), 4.609571298396486e-41); +assert.strictEqual(buffer.readFloatLE(0), Infinity); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0x80; +buffer[3] = 0xff; +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) => { + assert.throws( + () => buffer[fn](off), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + }); + + [Infinity, -1, 1].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 0. Received ${offset}` + }); + }); + + assert.throws( + () => Buffer.alloc(1)[fn](1), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]', + message: 'Attempt to write outside buffer bounds' + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); +}); diff --git a/test/parallel/test-buffer-readint.js b/test/parallel/test-buffer-readint.js new file mode 100644 index 00000000000000..6cb11ee5a03cce --- /dev/null +++ b/test/parallel/test-buffer-readint.js @@ -0,0 +1,195 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test OOB +{ + const buffer = Buffer.alloc(4); + + ['Int8', 'Int16BE', 'Int16LE', 'Int32BE', 'Int32LE'].forEach((fn) => { + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => buffer[`read${fn}`](o), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => buffer[`read${fn}`](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]' + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[`read${fn}`](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); +} + +// Test 8 bit signed integers +{ + const data = Buffer.alloc(4); + + data[0] = 0x23; + assert.strictEqual(data.readInt8(0), 0x23); + + data[0] = 0xff; + assert.strictEqual(data.readInt8(0), -1); + + data[0] = 0x87; + data[1] = 0xab; + data[2] = 0x7c; + data[3] = 0xef; + assert.strictEqual(data.readInt8(0), -121); + assert.strictEqual(data.readInt8(1), -85); + assert.strictEqual(data.readInt8(2), 124); + assert.strictEqual(data.readInt8(3), -17); +} + +// Test 16 bit integers +{ + const buffer = Buffer.alloc(6); + + buffer[0] = 0x16; + buffer[1] = 0x79; + assert.strictEqual(buffer.readInt16BE(0), 0x1679); + assert.strictEqual(buffer.readInt16LE(0), 0x7916); + + buffer[0] = 0xff; + buffer[1] = 0x80; + assert.strictEqual(buffer.readInt16BE(0), -128); + assert.strictEqual(buffer.readInt16LE(0), -32513); + + buffer[0] = 0x77; + buffer[1] = 0x65; + buffer[2] = 0x65; + buffer[3] = 0x6e; + buffer[4] = 0x69; + buffer[5] = 0x78; + assert.strictEqual(buffer.readInt16BE(0), 0x7765); + assert.strictEqual(buffer.readInt16BE(1), 0x6565); + assert.strictEqual(buffer.readInt16BE(2), 0x656e); + assert.strictEqual(buffer.readInt16BE(3), 0x6e69); + assert.strictEqual(buffer.readInt16BE(4), 0x6978); + assert.strictEqual(buffer.readInt16LE(0), 0x6577); + assert.strictEqual(buffer.readInt16LE(1), 0x6565); + assert.strictEqual(buffer.readInt16LE(2), 0x6e65); + assert.strictEqual(buffer.readInt16LE(3), 0x696e); + assert.strictEqual(buffer.readInt16LE(4), 0x7869); +} + +// Test 32 bit integers +{ + const buffer = Buffer.alloc(6); + + buffer[0] = 0x43; + buffer[1] = 0x53; + buffer[2] = 0x16; + buffer[3] = 0x79; + assert.strictEqual(buffer.readInt32BE(0), 0x43531679); + assert.strictEqual(buffer.readInt32LE(0), 0x79165343); + + buffer[0] = 0xff; + buffer[1] = 0xfe; + buffer[2] = 0xef; + buffer[3] = 0xfa; + assert.strictEqual(buffer.readInt32BE(0), -69638); + assert.strictEqual(buffer.readInt32LE(0), -84934913); + + buffer[0] = 0x42; + buffer[1] = 0xc3; + buffer[2] = 0x95; + buffer[3] = 0xa9; + buffer[4] = 0x36; + buffer[5] = 0x17; + assert.strictEqual(buffer.readInt32BE(0), 0x42c395a9); + assert.strictEqual(buffer.readInt32BE(1), -1013601994); + assert.strictEqual(buffer.readInt32BE(2), -1784072681); + assert.strictEqual(buffer.readInt32LE(0), -1449802942); + assert.strictEqual(buffer.readInt32LE(1), 917083587); + assert.strictEqual(buffer.readInt32LE(2), 389458325); +} + +// Test Int +{ + const buffer = Buffer.alloc(8); + + // Check byteLength. + ['readIntBE', 'readIntLE'].forEach((fn) => { + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((len) => { + assert.throws( + () => buffer[fn](0, len), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1].forEach((byteLength) => { + assert.throws( + () => buffer[fn](0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "byteLength" is out of range. ' + + `It must be >= 1 and <= 6. Received ${byteLength}` + }); + }); + + [NaN, 1.01].forEach((byteLength) => { + assert.throws( + () => buffer[fn](0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "byteLength" is out of range. ' + + `It must be an integer. Received ${byteLength}` + }); + }); + }); + + // Test 1 to 6 bytes. + for (let i = 1; i < 6; i++) { + ['readIntBE', 'readIntLE'].forEach((fn) => { + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => buffer[fn](o, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => buffer[fn](offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= ${8 - i}. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); + } +} diff --git a/test/parallel/test-buffer-write-noassert.js b/test/parallel/test-buffer-write-noassert.js deleted file mode 100644 index a521e01129a094..00000000000000 --- a/test/parallel/test-buffer-write-noassert.js +++ /dev/null @@ -1,95 +0,0 @@ -'use strict'; -require('../common'); -const assert = require('assert'); - -// testing buffer write functions - -const outOfRange = /^RangeError\b.*\bIndex out of range$/; - -function write(funx, args, result, res) { - { - const buf = Buffer.alloc(9); - assert.strictEqual(buf[funx](...args), result); - assert.deepStrictEqual(buf, res); - } - - writeInvalidOffset(-1); - writeInvalidOffset(9); - - { - const buf2 = Buffer.alloc(9); - assert.strictEqual(buf2[funx](...args, true), result); - assert.deepStrictEqual(buf2, res); - } - - function writeInvalidOffset(offset) { - const newArgs = Array.from(args); - newArgs[1] = offset; - assert.throws(() => Buffer.alloc(9)[funx](...newArgs), outOfRange); - - const buf = Buffer.alloc(9); - buf[funx](...newArgs, true); - assert.deepStrictEqual(buf, Buffer.alloc(9)); - } -} - -write('writeInt8', [1, 0], 1, Buffer.from([1, 0, 0, 0, 0, 0, 0, 0, 0])); -write('writeIntBE', [1, 1, 4], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); -write('writeIntLE', [1, 1, 4], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); -write('writeInt16LE', [1, 1], 3, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); -write('writeInt16BE', [1, 1], 3, Buffer.from([0, 0, 1, 0, 0, 0, 0, 0, 0])); -write('writeInt32LE', [1, 1], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); -write('writeInt32BE', [1, 1], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); -write('writeUInt8', [1, 0], 1, Buffer.from([1, 0, 0, 0, 0, 0, 0, 0, 0])); -write('writeUIntLE', [1, 1, 4], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); -write('writeUIntBE', [1, 1, 4], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); -write('writeUInt16LE', [1, 1], 3, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); -write('writeUInt16BE', [1, 1], 3, Buffer.from([0, 0, 1, 0, 0, 0, 0, 0, 0])); -write('writeUInt32LE', [1, 1], 5, Buffer.from([0, 1, 0, 0, 0, 0, 0, 0, 0])); -write('writeUInt32BE', [1, 1], 5, Buffer.from([0, 0, 0, 0, 1, 0, 0, 0, 0])); -write('writeDoubleBE', [1, 1], 9, Buffer.from([0, 63, 240, 0, 0, 0, 0, 0, 0])); -write('writeDoubleLE', [1, 1], 9, Buffer.from([0, 0, 0, 0, 0, 0, 0, 240, 63])); -write('writeFloatBE', [1, 1], 5, Buffer.from([0, 63, 128, 0, 0, 0, 0, 0, 0])); -write('writeFloatLE', [1, 1], 5, Buffer.from([0, 0, 0, 128, 63, 0, 0, 0, 0])); - -function writePartial(funx, args, result, res) { - assert.throws(() => Buffer.alloc(9)[funx](...args), outOfRange); - const buf = Buffer.alloc(9); - assert.strictEqual(buf[funx](...args, true), result); - assert.deepStrictEqual(buf, res); -} - -// Test partial writes (cases where the buffer isn't large enough to hold the -// entire value, but is large enough to hold parts of it). -writePartial('writeIntBE', [0x0eadbeef, 6, 4], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0x0e, 0xad, 0xbe])); -writePartial('writeIntLE', [0x0eadbeef, 6, 4], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); -writePartial('writeInt16BE', [0x1234, 8], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x12])); -writePartial('writeInt16LE', [0x1234, 8], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x34])); -writePartial('writeInt32BE', [0x0eadbeef, 6], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0x0e, 0xad, 0xbe])); -writePartial('writeInt32LE', [0x0eadbeef, 6], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); -writePartial('writeUIntBE', [0xdeadbeef, 6, 4], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0xde, 0xad, 0xbe])); -writePartial('writeUIntLE', [0xdeadbeef, 6, 4], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); -writePartial('writeUInt16BE', [0x1234, 8], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x12])); -writePartial('writeUInt16LE', [0x1234, 8], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x34])); -writePartial('writeUInt32BE', [0xdeadbeef, 6], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0xde, 0xad, 0xbe])); -writePartial('writeUInt32LE', [0xdeadbeef, 6], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); -writePartial('writeDoubleBE', [1, 2], 10, - Buffer.from([0, 0, 63, 240, 0, 0, 0, 0, 0])); -writePartial('writeDoubleLE', [1, 2], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 240])); -writePartial('writeFloatBE', [1, 6], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 63, 128, 0])); -writePartial('writeFloatLE', [1, 6], 10, - Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 128])); diff --git a/test/parallel/test-buffer-writedouble.js b/test/parallel/test-buffer-writedouble.js new file mode 100644 index 00000000000000..8f56e93f734dea --- /dev/null +++ b/test/parallel/test-buffer-writedouble.js @@ -0,0 +1,119 @@ +'use strict'; + +// Tests to verify doubles are correctly written + +require('../common'); +const assert = require('assert'); + +const buffer = Buffer.allocUnsafe(16); + +buffer.writeDoubleBE(2.225073858507201e-308, 0); +buffer.writeDoubleLE(2.225073858507201e-308, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00 +]))); + +buffer.writeDoubleBE(1.0000000000000004, 0); +buffer.writeDoubleLE(1.0000000000000004, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f +]))); + +buffer.writeDoubleBE(-2, 0); +buffer.writeDoubleLE(-2, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0 +]))); + +buffer.writeDoubleBE(1.7976931348623157e+308, 0); +buffer.writeDoubleLE(1.7976931348623157e+308, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x7f +]))); + +buffer.writeDoubleBE(0 * -1, 0); +buffer.writeDoubleLE(0 * -1, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 +]))); + +buffer.writeDoubleBE(Infinity, 0); +buffer.writeDoubleLE(Infinity, 8); + +assert.ok(buffer.equals(new Uint8Array([ + 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F +]))); + +assert.strictEqual(buffer.readDoubleBE(0), Infinity); +assert.strictEqual(buffer.readDoubleLE(8), Infinity); + +buffer.writeDoubleBE(-Infinity, 0); +buffer.writeDoubleLE(-Infinity, 8); + +assert.ok(buffer.equals(new Uint8Array([ + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF +]))); + +assert.strictEqual(buffer.readDoubleBE(0), -Infinity); +assert.strictEqual(buffer.readDoubleLE(8), -Infinity); + +buffer.writeDoubleBE(NaN, 0); +buffer.writeDoubleLE(NaN, 8); + +assert.ok(buffer.equals(new Uint8Array([ + 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F +]))); + +assert.ok(Number.isNaN(buffer.readDoubleBE(0))); +assert.ok(Number.isNaN(buffer.readDoubleLE(8))); + +// OOB in writeDouble{LE,BE} should throw. +{ + const small = Buffer.allocUnsafe(1); + + ['writeDoubleLE', 'writeDoubleBE'].forEach((fn) => { + assert.throws( + () => small[fn](11.11, 0), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]', + message: 'Attempt to write outside buffer bounds' + }); + + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => small[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1, 9].forEach((offset) => { + assert.throws( + () => buffer[fn](23, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 8. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](42, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); +} diff --git a/test/parallel/test-buffer-writefloat.js b/test/parallel/test-buffer-writefloat.js new file mode 100644 index 00000000000000..865b8838dae5dd --- /dev/null +++ b/test/parallel/test-buffer-writefloat.js @@ -0,0 +1,102 @@ +'use strict'; + +// Tests to verify floats are correctly written + +require('../common'); +const assert = require('assert'); + +const buffer = Buffer.allocUnsafe(8); + +buffer.writeFloatBE(1, 0); +buffer.writeFloatLE(1, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f ]))); + +buffer.writeFloatBE(1 / 3, 0); +buffer.writeFloatLE(1 / 3, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x3e, 0xaa, 0xaa, 0xab, 0xab, 0xaa, 0xaa, 0x3e ]))); + +buffer.writeFloatBE(3.4028234663852886e+38, 0); +buffer.writeFloatLE(3.4028234663852886e+38, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f ]))); + +buffer.writeFloatLE(1.1754943508222875e-38, 0); +buffer.writeFloatBE(1.1754943508222875e-38, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00 ]))); + +buffer.writeFloatBE(0 * -1, 0); +buffer.writeFloatLE(0 * -1, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 ]))); + +buffer.writeFloatBE(Infinity, 0); +buffer.writeFloatLE(Infinity, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7F ]))); + +assert.strictEqual(buffer.readFloatBE(0), Infinity); +assert.strictEqual(buffer.readFloatLE(4), Infinity); + +buffer.writeFloatBE(-Infinity, 0); +buffer.writeFloatLE(-Infinity, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF ]))); + +assert.strictEqual(buffer.readFloatBE(0), -Infinity); +assert.strictEqual(buffer.readFloatLE(4), -Infinity); + +buffer.writeFloatBE(NaN, 0); +buffer.writeFloatLE(NaN, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x7F ]))); + +assert.ok(Number.isNaN(buffer.readFloatBE(0))); +assert.ok(Number.isNaN(buffer.readFloatLE(4))); + +// OOB in writeFloat{LE,BE} should throw. +{ + const small = Buffer.allocUnsafe(1); + + ['writeFloatLE', 'writeFloatBE'].forEach((fn) => { + assert.throws( + () => small[fn](11.11, 0), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]', + message: 'Attempt to write outside buffer bounds' + }); + + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => small[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + }); + + [Infinity, -1, 5].forEach((offset) => { + assert.throws( + () => buffer[fn](23, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 4. Received ${offset}` + } + ); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](42, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); +} diff --git a/test/parallel/test-buffer-writeint.js b/test/parallel/test-buffer-writeint.js new file mode 100644 index 00000000000000..adddb35afee75e --- /dev/null +++ b/test/parallel/test-buffer-writeint.js @@ -0,0 +1,235 @@ +'use strict'; + +// Tests to verify signed integers are correctly written + +const common = require('../common'); +const assert = require('assert'); +const errorOutOfBounds = common.expectsError({ + code: 'ERR_OUT_OF_RANGE', + type: RangeError, + message: new RegExp('^The value of "value" is out of range\\. ' + + 'It must be >= -\\d+ and <= \\d+\\. Received .+$') +}, 10); + +// Test 8 bit +{ + const buffer = Buffer.alloc(2); + + buffer.writeInt8(0x23, 0); + buffer.writeInt8(-5, 1); + assert.ok(buffer.equals(new Uint8Array([ 0x23, 0xfb ]))); + + /* Make sure we handle min/max correctly */ + buffer.writeInt8(0x7f, 0); + buffer.writeInt8(-0x80, 1); + assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0x80 ]))); + + assert.throws(() => { + buffer.writeInt8(0x7f + 1, 0); + }, errorOutOfBounds); + assert.throws(() => { + buffer.writeInt8(-0x80 - 1, 0); + }, errorOutOfBounds); + + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer.writeInt8(23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((off) => { + assert.throws( + () => buffer.writeInt8(23, off), + { code: 'ERR_OUT_OF_RANGE' }); + }); +} + +// Test 16 bit +{ + const buffer = Buffer.alloc(4); + + buffer.writeInt16BE(0x0023, 0); + buffer.writeInt16LE(0x0023, 2); + assert.ok(buffer.equals(new Uint8Array([ 0x00, 0x23, 0x23, 0x00 ]))); + + buffer.writeInt16BE(-5, 0); + buffer.writeInt16LE(-5, 2); + assert.ok(buffer.equals(new Uint8Array([ 0xff, 0xfb, 0xfb, 0xff ]))); + + buffer.writeInt16BE(-1679, 0); + buffer.writeInt16LE(-1679, 2); + assert.ok(buffer.equals(new Uint8Array([ 0xf9, 0x71, 0x71, 0xf9 ]))); + + /* Make sure we handle min/max correctly */ + buffer.writeInt16BE(0x7fff, 0); + buffer.writeInt16BE(-0x8000, 2); + assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0xff, 0x80, 0x00 ]))); + + buffer.writeInt16LE(0x7fff, 0); + buffer.writeInt16LE(-0x8000, 2); + assert.ok(buffer.equals(new Uint8Array([ 0xff, 0x7f, 0x00, 0x80 ]))); + + ['writeInt16BE', 'writeInt16LE'].forEach((fn) => { + assert.throws(() => { + buffer[fn](0x7fff + 1, 0); + }, errorOutOfBounds); + assert.throws(() => { + buffer[fn](-0x8000 - 1, 0); + }, errorOutOfBounds); + + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_OUT_OF_RANGE' }); + }); + }); +} + +// Test 32 bit +{ + const buffer = Buffer.alloc(8); + + buffer.writeInt32BE(0x23, 0); + buffer.writeInt32LE(0x23, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00 + ]))); + + buffer.writeInt32BE(-5, 0); + buffer.writeInt32LE(-5, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0xff, 0xff, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xff + ]))); + + buffer.writeInt32BE(-805306713, 0); + buffer.writeInt32LE(-805306713, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0xcf, 0xff, 0xfe, 0xa7, 0xa7, 0xfe, 0xff, 0xcf + ]))); + + /* Make sure we handle min/max correctly */ + buffer.writeInt32BE(0x7fffffff, 0); + buffer.writeInt32BE(-0x80000000, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00 + ]))); + + buffer.writeInt32LE(0x7fffffff, 0); + buffer.writeInt32LE(-0x80000000, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80 + ]))); + + ['writeInt32BE', 'writeInt32LE'].forEach((fn) => { + assert.throws(() => { + buffer[fn](0x7fffffff + 1, 0); + }, errorOutOfBounds); + assert.throws(() => { + buffer[fn](-0x80000000 - 1, 0); + }, errorOutOfBounds); + + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_OUT_OF_RANGE' }); + }); + }); +} + +// Test Int +{ + const data = Buffer.alloc(8); + + // Check byteLength. + ['writeIntBE', 'writeIntLE'].forEach((fn) => { + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => data[fn](23, 0, o), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1].forEach((offset) => { + assert.throws( + () => data[fn](23, 0, offset), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "byteLength" is out of range. ' + + `It must be >= 1 and <= 6. Received ${offset}` + } + ); + }); + + [NaN, 1.01].forEach((byteLength) => { + assert.throws( + () => data[fn](42, 0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "byteLength" is out of range. ' + + `It must be an integer. Received ${byteLength}` + }); + }); + }); + + // Test 1 to 6 bytes. + for (let i = 1; i < 6; i++) { + ['writeIntBE', 'writeIntLE'].forEach((fn) => { + const min = -(2 ** (i * 8 - 1)); + const max = 2 ** (i * 8 - 1) - 1; + + [min - 1, max + 1].forEach((val) => { + assert.throws(() => { + data[fn](val, 0, i); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "value" is out of range. ' + + `It must be >= ${min} and <= ${max}. Received ${val}` + }); + }); + + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => data[fn](min, o, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => data[fn](min, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= ${8 - i}. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => data[fn](max, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); + } +} diff --git a/test/parallel/test-buffer-writeuint.js b/test/parallel/test-buffer-writeuint.js new file mode 100644 index 00000000000000..3d6f81264195a6 --- /dev/null +++ b/test/parallel/test-buffer-writeuint.js @@ -0,0 +1,190 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +/* + * We need to check the following things: + * - We are correctly resolving big endian (doesn't mean anything for 8 bit) + * - Correctly resolving little endian (doesn't mean anything for 8 bit) + * - Correctly using the offsets + * - Correctly interpreting values that are beyond the signed range as unsigned + */ + +{ // OOB + const data = Buffer.alloc(8); + ['UInt8', 'UInt16BE', 'UInt16LE', 'UInt32BE', 'UInt32LE'].forEach((fn) => { + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => data[`write${fn}`](23, o), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((o) => { + assert.throws( + () => data[`write${fn}`](23, o), + { code: 'ERR_OUT_OF_RANGE' }); + }); + }); +} + +{ // Test 8 bit + const data = Buffer.alloc(4); + + data.writeUInt8(23, 0); + data.writeUInt8(23, 1); + data.writeUInt8(23, 2); + data.writeUInt8(23, 3); + assert.ok(data.equals(new Uint8Array([23, 23, 23, 23]))); + + data.writeUInt8(23, 0); + data.writeUInt8(23, 1); + data.writeUInt8(23, 2); + data.writeUInt8(23, 3); + assert.ok(data.equals(new Uint8Array([23, 23, 23, 23]))); + + data.writeUInt8(255, 0); + assert.strictEqual(data[0], 255); + + data.writeUInt8(255, 0); + assert.strictEqual(data[0], 255); +} + +// Test 16 bit +{ + let value = 0x2343; + const data = Buffer.alloc(4); + + data.writeUInt16BE(value, 0); + assert.ok(data.equals(new Uint8Array([0x23, 0x43, 0, 0]))); + + data.writeUInt16BE(value, 1); + assert.ok(data.equals(new Uint8Array([0x23, 0x23, 0x43, 0]))); + + data.writeUInt16BE(value, 2); + assert.ok(data.equals(new Uint8Array([0x23, 0x23, 0x23, 0x43]))); + + data.writeUInt16LE(value, 0); + assert.ok(data.equals(new Uint8Array([0x43, 0x23, 0x23, 0x43]))); + + data.writeUInt16LE(value, 1); + assert.ok(data.equals(new Uint8Array([0x43, 0x43, 0x23, 0x43]))); + + data.writeUInt16LE(value, 2); + assert.ok(data.equals(new Uint8Array([0x43, 0x43, 0x43, 0x23]))); + + value = 0xff80; + data.writeUInt16LE(value, 0); + assert.ok(data.equals(new Uint8Array([0x80, 0xff, 0x43, 0x23]))); + + data.writeUInt16BE(value, 0); + assert.ok(data.equals(new Uint8Array([0xff, 0x80, 0x43, 0x23]))); +} + +// Test 32 bit +{ + const data = Buffer.alloc(6); + const value = 0xe7f90a6d; + + data.writeUInt32BE(value, 0); + assert.ok(data.equals(new Uint8Array([0xe7, 0xf9, 0x0a, 0x6d, 0, 0]))); + + data.writeUInt32BE(value, 1); + assert.ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xf9, 0x0a, 0x6d, 0]))); + + data.writeUInt32BE(value, 2); + assert.ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xe7, 0xf9, 0x0a, 0x6d]))); + + data.writeUInt32LE(value, 0); + assert.ok(data.equals(new Uint8Array([0x6d, 0x0a, 0xf9, 0xe7, 0x0a, 0x6d]))); + + data.writeUInt32LE(value, 1); + assert.ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x0a, 0xf9, 0xe7, 0x6d]))); + + data.writeUInt32LE(value, 2); + assert.ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x6d, 0x0a, 0xf9, 0xe7]))); +} + +// Test UInt +{ + const data = Buffer.alloc(8); + let val = 0x100; + + // Check byteLength. + ['writeUIntBE', 'writeUIntLE'].forEach((fn) => { + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => data[fn](23, 0, o), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1].forEach((offset) => { + assert.throws( + () => data[fn](23, 0, offset), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "byteLength" is out of range. ' + + `It must be >= 1 and <= 6. Received ${offset}` + } + ); + }); + + [NaN, 1.01].forEach((byteLength) => { + assert.throws( + () => data[fn](42, 0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "byteLength" is out of range. ' + + `It must be an integer. Received ${byteLength}` + }); + }); + }); + + // Test 1 to 6 bytes. + for (let i = 1; i < 6; i++) { + ['writeUIntBE', 'writeUIntLE'].forEach((fn) => { + assert.throws(() => { + data[fn](val, 0, i); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "value" is out of range. ' + + `It must be >= 0 and <= ${val - 1}. Received ${val}` + }); + + ['', '0', null, undefined, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => data[fn](23, o, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => data[fn](val - 1, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= ${8 - i}. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => data[fn](val - 1, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); + + val *= 0x100; + } +} diff --git a/test/parallel/test-zerolengthbufferbug.js b/test/parallel/test-http-zerolengthbuffer.js similarity index 100% rename from test/parallel/test-zerolengthbufferbug.js rename to test/parallel/test-http-zerolengthbuffer.js diff --git a/test/parallel/test-readdouble.js b/test/parallel/test-readdouble.js deleted file mode 100644 index f635edba9038d3..00000000000000 --- a/test/parallel/test-readdouble.js +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -/* - * Tests to verify we're reading in doubles correctly - */ -require('../common'); -const assert = require('assert'); - -/* - * Test (64 bit) double - */ -const buffer = Buffer.allocUnsafe(8); - -buffer[0] = 0x55; -buffer[1] = 0x55; -buffer[2] = 0x55; -buffer[3] = 0x55; -buffer[4] = 0x55; -buffer[5] = 0x55; -buffer[6] = 0xd5; -buffer[7] = 0x3f; -assert.strictEqual(1.1945305291680097e+103, buffer.readDoubleBE(0)); -assert.strictEqual(0.3333333333333333, buffer.readDoubleLE(0)); - -buffer[0] = 1; -buffer[1] = 0; -buffer[2] = 0; -buffer[3] = 0; -buffer[4] = 0; -buffer[5] = 0; -buffer[6] = 0xf0; -buffer[7] = 0x3f; -assert.strictEqual(7.291122019655968e-304, buffer.readDoubleBE(0)); -assert.strictEqual(1.0000000000000002, buffer.readDoubleLE(0)); - -buffer[0] = 2; -assert.strictEqual(4.778309726801735e-299, buffer.readDoubleBE(0)); -assert.strictEqual(1.0000000000000004, buffer.readDoubleLE(0)); - -buffer[0] = 1; -buffer[6] = 0; -buffer[7] = 0; -assert.strictEqual(7.291122019556398e-304, buffer.readDoubleBE(0)); -assert.strictEqual(5e-324, buffer.readDoubleLE(0)); - -buffer[0] = 0xff; -buffer[1] = 0xff; -buffer[2] = 0xff; -buffer[3] = 0xff; -buffer[4] = 0xff; -buffer[5] = 0xff; -buffer[6] = 0x0f; -buffer[7] = 0x00; -assert.ok(Number.isNaN(buffer.readDoubleBE(0))); -assert.strictEqual(2.225073858507201e-308, buffer.readDoubleLE(0)); - -buffer[6] = 0xef; -buffer[7] = 0x7f; -assert.ok(Number.isNaN(buffer.readDoubleBE(0))); -assert.strictEqual(1.7976931348623157e+308, buffer.readDoubleLE(0)); - -buffer[0] = 0; -buffer[1] = 0; -buffer[2] = 0; -buffer[3] = 0; -buffer[4] = 0; -buffer[5] = 0; -buffer[6] = 0xf0; -buffer[7] = 0x3f; -assert.strictEqual(3.03865e-319, buffer.readDoubleBE(0)); -assert.strictEqual(1, buffer.readDoubleLE(0)); - -buffer[6] = 0; -buffer[7] = 0x40; -assert.strictEqual(3.16e-322, buffer.readDoubleBE(0)); -assert.strictEqual(2, buffer.readDoubleLE(0)); - -buffer[7] = 0xc0; -assert.strictEqual(9.5e-322, buffer.readDoubleBE(0)); -assert.strictEqual(-2, buffer.readDoubleLE(0)); - -buffer[6] = 0x10; -buffer[7] = 0; -assert.strictEqual(2.0237e-320, buffer.readDoubleBE(0)); -assert.strictEqual(2.2250738585072014e-308, buffer.readDoubleLE(0)); - -buffer[6] = 0; -assert.strictEqual(0, buffer.readDoubleBE(0)); -assert.strictEqual(0, buffer.readDoubleLE(0)); -assert.strictEqual(false, 1 / buffer.readDoubleLE(0) < 0); - -buffer[7] = 0x80; -assert.strictEqual(6.3e-322, buffer.readDoubleBE(0)); -assert.strictEqual(-0, buffer.readDoubleLE(0)); -assert.strictEqual(true, 1 / buffer.readDoubleLE(0) < 0); - -buffer[6] = 0xf0; -buffer[7] = 0x7f; -assert.strictEqual(3.0418e-319, buffer.readDoubleBE(0)); -assert.strictEqual(Infinity, buffer.readDoubleLE(0)); - -buffer[7] = 0xff; -assert.strictEqual(3.04814e-319, buffer.readDoubleBE(0)); -assert.strictEqual(-Infinity, buffer.readDoubleLE(0)); - -buffer.writeDoubleBE(246800); -assert.strictEqual(buffer.readDoubleBE(), 246800); -assert.strictEqual(buffer.readDoubleBE(0.7), 246800); -assert.strictEqual(buffer.readDoubleBE(NaN), 246800); diff --git a/test/parallel/test-readfloat.js b/test/parallel/test-readfloat.js deleted file mode 100644 index ce7469977ead85..00000000000000 --- a/test/parallel/test-readfloat.js +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -/* - * Tests to verify we're reading in floats correctly - */ -require('../common'); -const assert = require('assert'); - -/* - * Test (32 bit) float - */ -function test(clazz) { - const buffer = new clazz(4); - - buffer[0] = 0; - buffer[1] = 0; - buffer[2] = 0x80; - buffer[3] = 0x3f; - assert.strictEqual(4.600602988224807e-41, buffer.readFloatBE(0)); - assert.strictEqual(1, buffer.readFloatLE(0)); - - buffer[0] = 0; - buffer[1] = 0; - buffer[2] = 0; - buffer[3] = 0xc0; - assert.strictEqual(2.6904930515036488e-43, buffer.readFloatBE(0)); - assert.strictEqual(-2, buffer.readFloatLE(0)); - - buffer[0] = 0xff; - buffer[1] = 0xff; - buffer[2] = 0x7f; - buffer[3] = 0x7f; - assert.ok(Number.isNaN(buffer.readFloatBE(0))); - assert.strictEqual(3.4028234663852886e+38, buffer.readFloatLE(0)); - - buffer[0] = 0xab; - buffer[1] = 0xaa; - buffer[2] = 0xaa; - buffer[3] = 0x3e; - assert.strictEqual(-1.2126478207002966e-12, buffer.readFloatBE(0)); - assert.strictEqual(0.3333333432674408, buffer.readFloatLE(0)); - - buffer[0] = 0; - buffer[1] = 0; - buffer[2] = 0; - buffer[3] = 0; - assert.strictEqual(0, buffer.readFloatBE(0)); - assert.strictEqual(0, buffer.readFloatLE(0)); - assert.strictEqual(false, 1 / buffer.readFloatLE(0) < 0); - - buffer[3] = 0x80; - assert.strictEqual(1.793662034335766e-43, buffer.readFloatBE(0)); - assert.strictEqual(-0, buffer.readFloatLE(0)); - assert.strictEqual(true, 1 / buffer.readFloatLE(0) < 0); - - buffer[0] = 0; - buffer[1] = 0; - buffer[2] = 0x80; - buffer[3] = 0x7f; - assert.strictEqual(4.609571298396486e-41, buffer.readFloatBE(0)); - assert.strictEqual(Infinity, buffer.readFloatLE(0)); - - buffer[0] = 0; - buffer[1] = 0; - buffer[2] = 0x80; - buffer[3] = 0xff; - assert.strictEqual(4.627507918739843e-41, buffer.readFloatBE(0)); - assert.strictEqual(-Infinity, buffer.readFloatLE(0)); -} - - -test(Buffer); diff --git a/test/parallel/test-readint.js b/test/parallel/test-readint.js deleted file mode 100644 index 42b9d1e61ebc43..00000000000000 --- a/test/parallel/test-readint.js +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -/* - * Tests to verify we're reading in signed integers correctly - */ -require('../common'); -const assert = require('assert'); - -/* - * Test 8 bit signed integers - */ -function test8(clazz) { - const data = new clazz(4); - - data[0] = 0x23; - assert.strictEqual(0x23, data.readInt8(0)); - - data[0] = 0xff; - assert.strictEqual(-1, data.readInt8(0)); - - data[0] = 0x87; - data[1] = 0xab; - data[2] = 0x7c; - data[3] = 0xef; - assert.strictEqual(-121, data.readInt8(0)); - assert.strictEqual(-85, data.readInt8(1)); - assert.strictEqual(124, data.readInt8(2)); - assert.strictEqual(-17, data.readInt8(3)); -} - - -function test16(clazz) { - const buffer = new clazz(6); - - buffer[0] = 0x16; - buffer[1] = 0x79; - assert.strictEqual(0x1679, buffer.readInt16BE(0)); - assert.strictEqual(0x7916, buffer.readInt16LE(0)); - - buffer[0] = 0xff; - buffer[1] = 0x80; - assert.strictEqual(-128, buffer.readInt16BE(0)); - assert.strictEqual(-32513, buffer.readInt16LE(0)); - - /* test offset with weenix */ - buffer[0] = 0x77; - buffer[1] = 0x65; - buffer[2] = 0x65; - buffer[3] = 0x6e; - buffer[4] = 0x69; - buffer[5] = 0x78; - assert.strictEqual(0x7765, buffer.readInt16BE(0)); - assert.strictEqual(0x6565, buffer.readInt16BE(1)); - assert.strictEqual(0x656e, buffer.readInt16BE(2)); - assert.strictEqual(0x6e69, buffer.readInt16BE(3)); - assert.strictEqual(0x6978, buffer.readInt16BE(4)); - assert.strictEqual(0x6577, buffer.readInt16LE(0)); - assert.strictEqual(0x6565, buffer.readInt16LE(1)); - assert.strictEqual(0x6e65, buffer.readInt16LE(2)); - assert.strictEqual(0x696e, buffer.readInt16LE(3)); - assert.strictEqual(0x7869, buffer.readInt16LE(4)); -} - - -function test32(clazz) { - const buffer = new clazz(6); - - buffer[0] = 0x43; - buffer[1] = 0x53; - buffer[2] = 0x16; - buffer[3] = 0x79; - assert.strictEqual(0x43531679, buffer.readInt32BE(0)); - assert.strictEqual(0x79165343, buffer.readInt32LE(0)); - - buffer[0] = 0xff; - buffer[1] = 0xfe; - buffer[2] = 0xef; - buffer[3] = 0xfa; - assert.strictEqual(-69638, buffer.readInt32BE(0)); - assert.strictEqual(-84934913, buffer.readInt32LE(0)); - - buffer[0] = 0x42; - buffer[1] = 0xc3; - buffer[2] = 0x95; - buffer[3] = 0xa9; - buffer[4] = 0x36; - buffer[5] = 0x17; - assert.strictEqual(0x42c395a9, buffer.readInt32BE(0)); - assert.strictEqual(-1013601994, buffer.readInt32BE(1)); - assert.strictEqual(-1784072681, buffer.readInt32BE(2)); - assert.strictEqual(-1449802942, buffer.readInt32LE(0)); - assert.strictEqual(917083587, buffer.readInt32LE(1)); - assert.strictEqual(389458325, buffer.readInt32LE(2)); -} - - -test8(Buffer); -test16(Buffer); -test32(Buffer); diff --git a/test/parallel/test-writedouble.js b/test/parallel/test-writedouble.js deleted file mode 100644 index cb1b0701531f06..00000000000000 --- a/test/parallel/test-writedouble.js +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -/* - * Tests to verify we're writing doubles correctly - */ -require('../common'); -const assert = require('assert'); - -function test(clazz) { - const buffer = new clazz(16); - - buffer.writeDoubleBE(2.225073858507201e-308, 0); - buffer.writeDoubleLE(2.225073858507201e-308, 8); - assert.strictEqual(0x00, buffer[0]); - assert.strictEqual(0x0f, buffer[1]); - assert.strictEqual(0xff, buffer[2]); - assert.strictEqual(0xff, buffer[3]); - assert.strictEqual(0xff, buffer[4]); - assert.strictEqual(0xff, buffer[5]); - assert.strictEqual(0xff, buffer[6]); - assert.strictEqual(0xff, buffer[7]); - assert.strictEqual(0xff, buffer[8]); - assert.strictEqual(0xff, buffer[9]); - assert.strictEqual(0xff, buffer[10]); - assert.strictEqual(0xff, buffer[11]); - assert.strictEqual(0xff, buffer[12]); - assert.strictEqual(0xff, buffer[13]); - assert.strictEqual(0x0f, buffer[14]); - assert.strictEqual(0x00, buffer[15]); - - buffer.writeDoubleBE(1.0000000000000004, 0); - buffer.writeDoubleLE(1.0000000000000004, 8); - assert.strictEqual(0x3f, buffer[0]); - assert.strictEqual(0xf0, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x02, buffer[7]); - assert.strictEqual(0x02, buffer[8]); - assert.strictEqual(0x00, buffer[9]); - assert.strictEqual(0x00, buffer[10]); - assert.strictEqual(0x00, buffer[11]); - assert.strictEqual(0x00, buffer[12]); - assert.strictEqual(0x00, buffer[13]); - assert.strictEqual(0xf0, buffer[14]); - assert.strictEqual(0x3f, buffer[15]); - - buffer.writeDoubleBE(-2, 0); - buffer.writeDoubleLE(-2, 8); - assert.strictEqual(0xc0, buffer[0]); - assert.strictEqual(0x00, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x00, buffer[7]); - assert.strictEqual(0x00, buffer[8]); - assert.strictEqual(0x00, buffer[9]); - assert.strictEqual(0x00, buffer[10]); - assert.strictEqual(0x00, buffer[11]); - assert.strictEqual(0x00, buffer[12]); - assert.strictEqual(0x00, buffer[13]); - assert.strictEqual(0x00, buffer[14]); - assert.strictEqual(0xc0, buffer[15]); - - buffer.writeDoubleBE(1.7976931348623157e+308, 0); - buffer.writeDoubleLE(1.7976931348623157e+308, 8); - assert.strictEqual(0x7f, buffer[0]); - assert.strictEqual(0xef, buffer[1]); - assert.strictEqual(0xff, buffer[2]); - assert.strictEqual(0xff, buffer[3]); - assert.strictEqual(0xff, buffer[4]); - assert.strictEqual(0xff, buffer[5]); - assert.strictEqual(0xff, buffer[6]); - assert.strictEqual(0xff, buffer[7]); - assert.strictEqual(0xff, buffer[8]); - assert.strictEqual(0xff, buffer[9]); - assert.strictEqual(0xff, buffer[10]); - assert.strictEqual(0xff, buffer[11]); - assert.strictEqual(0xff, buffer[12]); - assert.strictEqual(0xff, buffer[13]); - assert.strictEqual(0xef, buffer[14]); - assert.strictEqual(0x7f, buffer[15]); - - buffer.writeDoubleBE(0 * -1, 0); - buffer.writeDoubleLE(0 * -1, 8); - assert.strictEqual(0x80, buffer[0]); - assert.strictEqual(0x00, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x00, buffer[7]); - assert.strictEqual(0x00, buffer[8]); - assert.strictEqual(0x00, buffer[9]); - assert.strictEqual(0x00, buffer[10]); - assert.strictEqual(0x00, buffer[11]); - assert.strictEqual(0x00, buffer[12]); - assert.strictEqual(0x00, buffer[13]); - assert.strictEqual(0x00, buffer[14]); - assert.strictEqual(0x80, buffer[15]); - - buffer.writeDoubleBE(Infinity, 0); - buffer.writeDoubleLE(Infinity, 8); - assert.strictEqual(0x7F, buffer[0]); - assert.strictEqual(0xF0, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x00, buffer[7]); - assert.strictEqual(0x00, buffer[8]); - assert.strictEqual(0x00, buffer[9]); - assert.strictEqual(0x00, buffer[10]); - assert.strictEqual(0x00, buffer[11]); - assert.strictEqual(0x00, buffer[12]); - assert.strictEqual(0x00, buffer[13]); - assert.strictEqual(0xF0, buffer[14]); - assert.strictEqual(0x7F, buffer[15]); - assert.strictEqual(Infinity, buffer.readDoubleBE(0)); - assert.strictEqual(Infinity, buffer.readDoubleLE(8)); - - buffer.writeDoubleBE(-Infinity, 0); - buffer.writeDoubleLE(-Infinity, 8); - assert.strictEqual(0xFF, buffer[0]); - assert.strictEqual(0xF0, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x00, buffer[7]); - assert.strictEqual(0x00, buffer[8]); - assert.strictEqual(0x00, buffer[9]); - assert.strictEqual(0x00, buffer[10]); - assert.strictEqual(0x00, buffer[11]); - assert.strictEqual(0x00, buffer[12]); - assert.strictEqual(0x00, buffer[13]); - assert.strictEqual(0xF0, buffer[14]); - assert.strictEqual(0xFF, buffer[15]); - assert.strictEqual(-Infinity, buffer.readDoubleBE(0)); - assert.strictEqual(-Infinity, buffer.readDoubleLE(8)); - - buffer.writeDoubleBE(NaN, 0); - buffer.writeDoubleLE(NaN, 8); - // Darwin ia32 does the other kind of NaN. - // Compiler bug. No one really cares. - assert(0x7F === buffer[0] || 0xFF === buffer[0]); - // mips processors use a slightly different NaN - assert(0xF8 === buffer[1] || 0xF7 === buffer[1]); - assert(0x00 === buffer[2] || 0xFF === buffer[2]); - assert(0x00 === buffer[3] || 0xFF === buffer[3]); - assert(0x00 === buffer[4] || 0xFF === buffer[4]); - assert(0x00 === buffer[5] || 0xFF === buffer[5]); - assert(0x00 === buffer[6] || 0xFF === buffer[6]); - assert(0x00 === buffer[7] || 0xFF === buffer[7]); - assert(0x00 === buffer[8] || 0xFF === buffer[8]); - assert(0x00 === buffer[9] || 0xFF === buffer[9]); - assert(0x00 === buffer[10] || 0xFF === buffer[10]); - assert(0x00 === buffer[11] || 0xFF === buffer[11]); - assert(0x00 === buffer[12] || 0xFF === buffer[12]); - assert(0x00 === buffer[13] || 0xFF === buffer[13]); - assert(0xF8 === buffer[14] || 0xF7 === buffer[14]); - // Darwin ia32 does the other kind of NaN. - // Compiler bug. No one really cares. - assert(0x7F === buffer[15] || 0xFF === buffer[15]); - assert.ok(Number.isNaN(buffer.readDoubleBE(0))); - assert.ok(Number.isNaN(buffer.readDoubleLE(8))); -} - - -test(Buffer); diff --git a/test/parallel/test-writefloat.js b/test/parallel/test-writefloat.js deleted file mode 100644 index b22b9e8c924899..00000000000000 --- a/test/parallel/test-writefloat.js +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -/* - * Tests to verify we're writing floats correctly - */ -require('../common'); -const assert = require('assert'); - -function test(clazz) { - const buffer = new clazz(8); - - buffer.writeFloatBE(1, 0); - buffer.writeFloatLE(1, 4); - assert.strictEqual(0x3f, buffer[0]); - assert.strictEqual(0x80, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x80, buffer[6]); - assert.strictEqual(0x3f, buffer[7]); - - buffer.writeFloatBE(1 / 3, 0); - buffer.writeFloatLE(1 / 3, 4); - assert.strictEqual(0x3e, buffer[0]); - assert.strictEqual(0xaa, buffer[1]); - assert.strictEqual(0xaa, buffer[2]); - assert.strictEqual(0xab, buffer[3]); - assert.strictEqual(0xab, buffer[4]); - assert.strictEqual(0xaa, buffer[5]); - assert.strictEqual(0xaa, buffer[6]); - assert.strictEqual(0x3e, buffer[7]); - - buffer.writeFloatBE(3.4028234663852886e+38, 0); - buffer.writeFloatLE(3.4028234663852886e+38, 4); - assert.strictEqual(0x7f, buffer[0]); - assert.strictEqual(0x7f, buffer[1]); - assert.strictEqual(0xff, buffer[2]); - assert.strictEqual(0xff, buffer[3]); - assert.strictEqual(0xff, buffer[4]); - assert.strictEqual(0xff, buffer[5]); - assert.strictEqual(0x7f, buffer[6]); - assert.strictEqual(0x7f, buffer[7]); - - buffer.writeFloatLE(1.1754943508222875e-38, 0); - buffer.writeFloatBE(1.1754943508222875e-38, 4); - assert.strictEqual(0x00, buffer[0]); - assert.strictEqual(0x00, buffer[1]); - assert.strictEqual(0x80, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x80, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x00, buffer[7]); - - buffer.writeFloatBE(0 * -1, 0); - buffer.writeFloatLE(0 * -1, 4); - assert.strictEqual(0x80, buffer[0]); - assert.strictEqual(0x00, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x80, buffer[7]); - - buffer.writeFloatBE(Infinity, 0); - buffer.writeFloatLE(Infinity, 4); - assert.strictEqual(0x7F, buffer[0]); - assert.strictEqual(0x80, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x80, buffer[6]); - assert.strictEqual(0x7F, buffer[7]); - assert.strictEqual(Infinity, buffer.readFloatBE(0)); - assert.strictEqual(Infinity, buffer.readFloatLE(4)); - - buffer.writeFloatBE(-Infinity, 0); - buffer.writeFloatLE(-Infinity, 4); - // Darwin ia32 does the other kind of NaN. - // Compiler bug. No one really cares. - assert(0xFF === buffer[0] || 0x7F === buffer[0]); - assert.strictEqual(0x80, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x80, buffer[6]); - assert.strictEqual(0xFF, buffer[7]); - assert.strictEqual(-Infinity, buffer.readFloatBE(0)); - assert.strictEqual(-Infinity, buffer.readFloatLE(4)); - - buffer.writeFloatBE(NaN, 0); - buffer.writeFloatLE(NaN, 4); - // Darwin ia32 does the other kind of NaN. - // Compiler bug. No one really cares. - assert(0x7F === buffer[0] || 0xFF === buffer[0]); - // mips processors use a slightly different NaN - assert(0xC0 === buffer[1] || 0xBF === buffer[1]); - assert(0x00 === buffer[2] || 0xFF === buffer[2]); - assert(0x00 === buffer[3] || 0xFF === buffer[3]); - assert(0x00 === buffer[4] || 0xFF === buffer[4]); - assert(0x00 === buffer[5] || 0xFF === buffer[5]); - assert(0xC0 === buffer[6] || 0xBF === buffer[6]); - // Darwin ia32 does the other kind of NaN. - // Compiler bug. No one really cares. - assert(0x7F === buffer[7] || 0xFF === buffer[7]); - assert.ok(Number.isNaN(buffer.readFloatBE(0))); - assert.ok(Number.isNaN(buffer.readFloatLE(4))); -} - - -test(Buffer); diff --git a/test/parallel/test-writeint.js b/test/parallel/test-writeint.js deleted file mode 100644 index 1e0a8e8812ecb2..00000000000000 --- a/test/parallel/test-writeint.js +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -/* - * Tests to verify we're writing signed integers correctly - */ -const common = require('../common'); -const assert = require('assert'); -const errorOutOfBounds = common.expectsError({ - code: 'ERR_INVALID_OPT_VALUE', - type: RangeError, - message: /^The value "[^"]*" is invalid for option "value"$/ -}, 12); - -function test8(clazz) { - const buffer = new clazz(2); - - buffer.writeInt8(0x23, 0); - buffer.writeInt8(-5, 1); - - assert.strictEqual(0x23, buffer[0]); - assert.strictEqual(0xfb, buffer[1]); - - /* Make sure we handle truncation correctly */ - assert.throws(() => { - buffer.writeInt8(0xabc, 0); - }, errorOutOfBounds); - assert.throws(() => { - buffer.writeInt8(0xabc, 0); - }, errorOutOfBounds); - - /* Make sure we handle min/max correctly */ - buffer.writeInt8(0x7f, 0); - buffer.writeInt8(-0x80, 1); - - assert.strictEqual(0x7f, buffer[0]); - assert.strictEqual(0x80, buffer[1]); - assert.throws(() => { - buffer.writeInt8(0x7f + 1, 0); - }, errorOutOfBounds); - assert.throws(() => { - buffer.writeInt8(-0x80 - 1, 0); - }, errorOutOfBounds); -} - - -function test16(clazz) { - const buffer = new clazz(6); - - buffer.writeInt16BE(0x0023, 0); - buffer.writeInt16LE(0x0023, 2); - assert.strictEqual(0x00, buffer[0]); - assert.strictEqual(0x23, buffer[1]); - assert.strictEqual(0x23, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - - buffer.writeInt16BE(-5, 0); - buffer.writeInt16LE(-5, 2); - assert.strictEqual(0xff, buffer[0]); - assert.strictEqual(0xfb, buffer[1]); - assert.strictEqual(0xfb, buffer[2]); - assert.strictEqual(0xff, buffer[3]); - - buffer.writeInt16BE(-1679, 1); - buffer.writeInt16LE(-1679, 3); - assert.strictEqual(0xf9, buffer[1]); - assert.strictEqual(0x71, buffer[2]); - assert.strictEqual(0x71, buffer[3]); - assert.strictEqual(0xf9, buffer[4]); - - /* Make sure we handle min/max correctly */ - buffer.writeInt16BE(0x7fff, 0); - buffer.writeInt16BE(-0x8000, 2); - assert.strictEqual(0x7f, buffer[0]); - assert.strictEqual(0xff, buffer[1]); - assert.strictEqual(0x80, buffer[2]); - assert.strictEqual(0x00, buffer[3]); - assert.throws(() => { - buffer.writeInt16BE(0x7fff + 1, 0); - }, errorOutOfBounds); - assert.throws(() => { - buffer.writeInt16BE(-0x8000 - 1, 0); - }, errorOutOfBounds); - - buffer.writeInt16LE(0x7fff, 0); - buffer.writeInt16LE(-0x8000, 2); - assert.strictEqual(0xff, buffer[0]); - assert.strictEqual(0x7f, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x80, buffer[3]); - assert.throws(() => { - buffer.writeInt16LE(0x7fff + 1, 0); - }, errorOutOfBounds); - assert.throws(() => { - buffer.writeInt16LE(-0x8000 - 1, 0); - }, errorOutOfBounds); -} - - -function test32(clazz) { - const buffer = new clazz(8); - - buffer.writeInt32BE(0x23, 0); - buffer.writeInt32LE(0x23, 4); - assert.strictEqual(0x00, buffer[0]); - assert.strictEqual(0x00, buffer[1]); - assert.strictEqual(0x00, buffer[2]); - assert.strictEqual(0x23, buffer[3]); - assert.strictEqual(0x23, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x00, buffer[7]); - - buffer.writeInt32BE(-5, 0); - buffer.writeInt32LE(-5, 4); - assert.strictEqual(0xff, buffer[0]); - assert.strictEqual(0xff, buffer[1]); - assert.strictEqual(0xff, buffer[2]); - assert.strictEqual(0xfb, buffer[3]); - assert.strictEqual(0xfb, buffer[4]); - assert.strictEqual(0xff, buffer[5]); - assert.strictEqual(0xff, buffer[6]); - assert.strictEqual(0xff, buffer[7]); - - buffer.writeInt32BE(-805306713, 0); - buffer.writeInt32LE(-805306713, 4); - assert.strictEqual(0xcf, buffer[0]); - assert.strictEqual(0xff, buffer[1]); - assert.strictEqual(0xfe, buffer[2]); - assert.strictEqual(0xa7, buffer[3]); - assert.strictEqual(0xa7, buffer[4]); - assert.strictEqual(0xfe, buffer[5]); - assert.strictEqual(0xff, buffer[6]); - assert.strictEqual(0xcf, buffer[7]); - - /* Make sure we handle min/max correctly */ - buffer.writeInt32BE(0x7fffffff, 0); - buffer.writeInt32BE(-0x80000000, 4); - assert.strictEqual(0x7f, buffer[0]); - assert.strictEqual(0xff, buffer[1]); - assert.strictEqual(0xff, buffer[2]); - assert.strictEqual(0xff, buffer[3]); - assert.strictEqual(0x80, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x00, buffer[7]); - assert.throws(() => { - buffer.writeInt32BE(0x7fffffff + 1, 0); - }, errorOutOfBounds); - assert.throws(() => { - buffer.writeInt32BE(-0x80000000 - 1, 0); - }, errorOutOfBounds); - - buffer.writeInt32LE(0x7fffffff, 0); - buffer.writeInt32LE(-0x80000000, 4); - assert.strictEqual(0xff, buffer[0]); - assert.strictEqual(0xff, buffer[1]); - assert.strictEqual(0xff, buffer[2]); - assert.strictEqual(0x7f, buffer[3]); - assert.strictEqual(0x00, buffer[4]); - assert.strictEqual(0x00, buffer[5]); - assert.strictEqual(0x00, buffer[6]); - assert.strictEqual(0x80, buffer[7]); - assert.throws(() => { - buffer.writeInt32LE(0x7fffffff + 1, 0); - }, errorOutOfBounds); - assert.throws(() => { - buffer.writeInt32LE(-0x80000000 - 1, 0); - }, errorOutOfBounds); -} - - -test8(Buffer); -test16(Buffer); -test32(Buffer); diff --git a/test/parallel/test-writeuint.js b/test/parallel/test-writeuint.js deleted file mode 100644 index 0863135b2b8b05..00000000000000 --- a/test/parallel/test-writeuint.js +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -/* - * A battery of tests to help us read a series of uints - */ -const common = require('../common'); -const assert = require('assert'); - -/* - * We need to check the following things: - * - We are correctly resolving big endian (doesn't mean anything for 8 bit) - * - Correctly resolving little endian (doesn't mean anything for 8 bit) - * - Correctly using the offsets - * - Correctly interpreting values that are beyond the signed range as unsigned - */ -function test8(clazz) { - const data = new clazz(4); - - data.writeUInt8(23, 0); - data.writeUInt8(23, 1); - data.writeUInt8(23, 2); - data.writeUInt8(23, 3); - assert.strictEqual(23, data[0]); - assert.strictEqual(23, data[1]); - assert.strictEqual(23, data[2]); - assert.strictEqual(23, data[3]); - - data.writeUInt8(23, 0); - data.writeUInt8(23, 1); - data.writeUInt8(23, 2); - data.writeUInt8(23, 3); - assert.strictEqual(23, data[0]); - assert.strictEqual(23, data[1]); - assert.strictEqual(23, data[2]); - assert.strictEqual(23, data[3]); - - data.writeUInt8(255, 0); - assert.strictEqual(255, data[0]); - - data.writeUInt8(255, 0); - assert.strictEqual(255, data[0]); -} - - -function test16(clazz) { - let value = 0x2343; - const data = new clazz(4); - - data.writeUInt16BE(value, 0); - assert.strictEqual(0x23, data[0]); - assert.strictEqual(0x43, data[1]); - - data.writeUInt16BE(value, 1); - assert.strictEqual(0x23, data[1]); - assert.strictEqual(0x43, data[2]); - - data.writeUInt16BE(value, 2); - assert.strictEqual(0x23, data[2]); - assert.strictEqual(0x43, data[3]); - - data.writeUInt16LE(value, 0); - assert.strictEqual(0x23, data[1]); - assert.strictEqual(0x43, data[0]); - - data.writeUInt16LE(value, 1); - assert.strictEqual(0x23, data[2]); - assert.strictEqual(0x43, data[1]); - - data.writeUInt16LE(value, 2); - assert.strictEqual(0x23, data[3]); - assert.strictEqual(0x43, data[2]); - - value = 0xff80; - data.writeUInt16LE(value, 0); - assert.strictEqual(0xff, data[1]); - assert.strictEqual(0x80, data[0]); - - data.writeUInt16BE(value, 0); - assert.strictEqual(0xff, data[0]); - assert.strictEqual(0x80, data[1]); -} - - -function test32(clazz) { - const data = new clazz(6); - const value = 0xe7f90a6d; - - data.writeUInt32BE(value, 0); - assert.strictEqual(0xe7, data[0]); - assert.strictEqual(0xf9, data[1]); - assert.strictEqual(0x0a, data[2]); - assert.strictEqual(0x6d, data[3]); - - data.writeUInt32BE(value, 1); - assert.strictEqual(0xe7, data[1]); - assert.strictEqual(0xf9, data[2]); - assert.strictEqual(0x0a, data[3]); - assert.strictEqual(0x6d, data[4]); - - data.writeUInt32BE(value, 2); - assert.strictEqual(0xe7, data[2]); - assert.strictEqual(0xf9, data[3]); - assert.strictEqual(0x0a, data[4]); - assert.strictEqual(0x6d, data[5]); - - data.writeUInt32LE(value, 0); - assert.strictEqual(0xe7, data[3]); - assert.strictEqual(0xf9, data[2]); - assert.strictEqual(0x0a, data[1]); - assert.strictEqual(0x6d, data[0]); - - data.writeUInt32LE(value, 1); - assert.strictEqual(0xe7, data[4]); - assert.strictEqual(0xf9, data[3]); - assert.strictEqual(0x0a, data[2]); - assert.strictEqual(0x6d, data[1]); - - data.writeUInt32LE(value, 2); - assert.strictEqual(0xe7, data[5]); - assert.strictEqual(0xf9, data[4]); - assert.strictEqual(0x0a, data[3]); - assert.strictEqual(0x6d, data[2]); -} - - -function testUint(clazz) { - const data = new clazz(8); - let val = 1; - - // Test 0 to 5 bytes. - for (let i = 0; i <= 5; i++) { - const errMsg = common.expectsError({ - code: 'ERR_INVALID_OPT_VALUE', - type: RangeError, - message: /^The value "[^"]*" is invalid for option "value"$/ - }, 2); - assert.throws(() => { - data.writeUIntBE(val, 0, i); - }, errMsg); - assert.throws(() => { - data.writeUIntLE(val, 0, i); - }, errMsg); - val *= 0x100; - } -} - - -test8(Buffer); -test16(Buffer); -test32(Buffer); -testUint(Buffer); From 831dd76ef6b813732eb141caa8533231fd1d6abe Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 30 Jan 2018 21:06:59 +0100 Subject: [PATCH 5/6] benchmark: remove noAssert argument This removes the `noAssert` argument and also adds some more tests. --- benchmark/buffers/buffer-read-float.js | 8 ++- .../buffers/buffer-read-with-byteLength.js | 13 ++--- benchmark/buffers/buffer-read.js | 8 ++- benchmark/buffers/buffer-write.js | 54 ++++++++++++++----- test/sequential/test-benchmark-buffer.js | 1 - 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/benchmark/buffers/buffer-read-float.js b/benchmark/buffers/buffer-read-float.js index afd9edf5578308..e105642972d857 100644 --- a/benchmark/buffers/buffer-read-float.js +++ b/benchmark/buffers/buffer-read-float.js @@ -2,15 +2,13 @@ const common = require('../common.js'); const bench = common.createBenchmark(main, { - noAssert: ['false', 'true'], type: ['Double', 'Float'], endian: ['BE', 'LE'], value: ['zero', 'big', 'small', 'inf', 'nan'], millions: [1] }); -function main({ noAssert, millions, type, endian, value }) { - noAssert = noAssert === 'true'; +function main({ millions, type, endian, value }) { type = type || 'Double'; const buff = Buffer.alloc(8); const fn = `read${type}${endian}`; @@ -31,11 +29,11 @@ function main({ noAssert, millions, type, endian, value }) { }, }; - buff[`write${type}${endian}`](values[type][value], 0, noAssert); + buff[`write${type}${endian}`](values[type][value], 0); bench.start(); for (var i = 0; i !== millions * 1e6; i++) { - buff[fn](0, noAssert); + buff[fn](0); } bench.end(millions); } diff --git a/benchmark/buffers/buffer-read-with-byteLength.js b/benchmark/buffers/buffer-read-with-byteLength.js index 9fe5e6f4bf43ff..1858c4fd965e26 100644 --- a/benchmark/buffers/buffer-read-with-byteLength.js +++ b/benchmark/buffers/buffer-read-with-byteLength.js @@ -9,24 +9,21 @@ const types = [ ]; const bench = common.createBenchmark(main, { - noAssert: ['false', 'true'], buffer: ['fast', 'slow'], type: types, millions: [1], - byteLength: [1, 2, 4, 6] + byteLength: [1, 2, 3, 4, 5, 6] }); -function main({ millions, noAssert, buf, type, byteLength }) { - noAssert = noAssert === 'true'; - type = type || 'UInt8'; +function main({ millions, buf, type, byteLength }) { const clazz = buf === 'fast' ? Buffer : require('buffer').SlowBuffer; const buff = new clazz(8); - const fn = `read${type}`; + const fn = `read${type || 'IntBE'}`; - buff.writeDoubleLE(0, 0, noAssert); + buff.writeDoubleLE(0, 0); bench.start(); for (var i = 0; i !== millions * 1e6; i++) { - buff[fn](0, byteLength, noAssert); + buff[fn](0, byteLength); } bench.end(millions); } diff --git a/benchmark/buffers/buffer-read.js b/benchmark/buffers/buffer-read.js index 868f5cede8bd2d..88a46cb29079f6 100644 --- a/benchmark/buffers/buffer-read.js +++ b/benchmark/buffers/buffer-read.js @@ -19,22 +19,20 @@ const types = [ ]; const bench = common.createBenchmark(main, { - noAssert: ['false', 'true'], buffer: ['fast', 'slow'], type: types, millions: [1] }); -function main({ noAssert, millions, buf, type }) { - noAssert = noAssert === 'true'; +function main({ millions, buf, type }) { const clazz = buf === 'fast' ? Buffer : require('buffer').SlowBuffer; const buff = new clazz(8); const fn = `read${type || 'UInt8'}`; - buff.writeDoubleLE(0, 0, noAssert); + buff.writeDoubleLE(0, 0); bench.start(); for (var i = 0; i !== millions * 1e6; i++) { - buff[fn](0, noAssert); + buff[fn](0); } bench.end(millions); } diff --git a/benchmark/buffers/buffer-write.js b/benchmark/buffers/buffer-write.js index 823e95bf15d704..42ea9aa093cb88 100644 --- a/benchmark/buffers/buffer-write.js +++ b/benchmark/buffers/buffer-write.js @@ -7,11 +7,15 @@ const types = [ 'UInt16BE', 'UInt32LE', 'UInt32BE', + 'UIntLE', + 'UIntBE', 'Int8', 'Int16LE', 'Int16BE', 'Int32LE', 'Int32BE', + 'IntLE', + 'IntBE', 'FloatLE', 'FloatBE', 'DoubleLE', @@ -19,7 +23,6 @@ const types = [ ]; const bench = common.createBenchmark(main, { - noAssert: ['false', 'true'], buffer: ['fast', 'slow'], type: types, millions: [1] @@ -28,9 +31,9 @@ const bench = common.createBenchmark(main, { const INT8 = 0x7f; const INT16 = 0x7fff; const INT32 = 0x7fffffff; -const UINT8 = (INT8 * 2) + 1; -const UINT16 = (INT16 * 2) + 1; -const UINT32 = INT32; +const INT48 = 0x7fffffffffff; +const UINT8 = 0xff; +const UINT16 = 0xffff; const mod = { writeInt8: INT8, @@ -41,34 +44,57 @@ const mod = { writeUInt8: UINT8, writeUInt16BE: UINT16, writeUInt16LE: UINT16, - writeUInt32BE: UINT32, - writeUInt32LE: UINT32 + writeUInt32BE: INT32, + writeUInt32LE: INT32, + writeUIntLE: INT8, + writeUIntBE: INT16, + writeIntLE: INT32, + writeIntBE: INT48 }; -function main({ noAssert, millions, buf, type }) { +const byteLength = { + writeUIntLE: 1, + writeUIntBE: 2, + writeIntLE: 4, + writeIntBE: 6 +}; + +function main({ millions, buf, type }) { const clazz = buf === 'fast' ? Buffer : require('buffer').SlowBuffer; const buff = new clazz(8); const fn = `write${type || 'UInt8'}`; - if (/Int/.test(fn)) - benchInt(buff, fn, millions, noAssert); + if (!/\d/.test(fn)) + benchSpecialInt(buff, fn, millions); + else if (/Int/.test(fn)) + benchInt(buff, fn, millions); else - benchFloat(buff, fn, millions, noAssert); + benchFloat(buff, fn, millions); +} + +function benchInt(buff, fn, millions) { + const m = mod[fn]; + bench.start(); + for (var i = 0; i !== millions * 1e6; i++) { + buff[fn](i & m, 0); + } + bench.end(millions); } -function benchInt(buff, fn, millions, noAssert) { +function benchSpecialInt(buff, fn, millions) { const m = mod[fn]; + const byte = byteLength[fn]; bench.start(); for (var i = 0; i !== millions * 1e6; i++) { - buff[fn](i & m, 0, noAssert); + buff[fn](i & m, 0, byte); } bench.end(millions); } -function benchFloat(buff, fn, millions, noAssert) { +function benchFloat(buff, fn, millions) { bench.start(); for (var i = 0; i !== millions * 1e6; i++) { - buff[fn](i, 0, noAssert); + buff[fn](i, 0); } bench.end(millions); } diff --git a/test/sequential/test-benchmark-buffer.js b/test/sequential/test-benchmark-buffer.js index f5e0c692f367be..4eb4415a61dd7f 100644 --- a/test/sequential/test-benchmark-buffer.js +++ b/test/sequential/test-benchmark-buffer.js @@ -16,7 +16,6 @@ runBenchmark('buffers', 'millions=0.000001', 'method=', 'n=1', - 'noAssert=true', 'pieces=1', 'pieceSize=1', 'search=@', From f604a3354326424f2744526b3c4c55eb65805b2c Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Thu, 15 Feb 2018 14:22:57 +0100 Subject: [PATCH 6/6] doc: add deprecation notice --- doc/api/deprecations.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index b2eaa54254d64e..556c789fb48af2 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -923,6 +923,15 @@ Type: End-of-Life The `--with-lttng` compile time option is removed. + +### DEP0XXX: Using `noAssert` in Buffer#(read|write) operations. + +Type: End-of-Life + +Using the `noAssert` argument has no functionality anymore. All input is going +to be verified, no matter if it is set to true or not. Skipping the verification +could lead to hard to find errors and crashes. + [`--pending-deprecation`]: cli.html#cli_pending_deprecation [`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size [`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array