From 4a34c69cbf471f0c7f470a7fb2569f5ed06ee2cc Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Fri, 12 Jul 2013 16:29:54 -0700 Subject: [PATCH] buffer: return offset for end of last write --- lib/buffer.js | 10 ++++++++++ src/node_buffer.cc | 22 ++++++++++++++-------- test/simple/test-buffer.js | 8 ++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index 5592e316918..bab4a12c1ed 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -574,6 +574,7 @@ Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0); this[offset] = value; + return offset + 1; }; @@ -594,6 +595,7 @@ Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0); writeUInt16(this, value, offset, false); + return offset + 2; }; @@ -603,6 +605,7 @@ Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0); writeUInt16(this, value, offset, true); + return offset + 2; }; @@ -627,6 +630,7 @@ Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0); writeUInt32(this, value, offset, false); + return offset + 4; }; @@ -636,6 +640,7 @@ Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0); writeUInt32(this, value, offset, true); + return offset + 4; }; @@ -683,6 +688,7 @@ Buffer.prototype.writeInt8 = function(value, offset, noAssert) { checkInt(this, value, offset, 1, 0x7f, -0x80); if (value < 0) value = 0xff + value + 1; this[offset] = value; + return offset + 1; }; @@ -693,6 +699,7 @@ Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); if (value < 0) value = 0xffff + value + 1; writeUInt16(this, value, offset, false); + return offset + 2; }; @@ -703,6 +710,7 @@ Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { checkInt(this, value, offset, 2, 0x7fff, -0x8000); if (value < 0) value = 0xffff + value + 1; writeUInt16(this, value, offset, true); + return offset + 2; }; @@ -713,6 +721,7 @@ Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); if (value < 0) value = 0xffffffff + value + 1; writeUInt32(this, value, offset, false); + return offset + 4; }; @@ -723,4 +732,5 @@ Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); if (value < 0) value = 0xffffffff + value + 1; writeUInt32(this, value, offset, true); + return offset + 4; }; diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 53665bf8caa..08790a923c5 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -485,18 +485,23 @@ void ReadDoubleBE(const FunctionCallbackInfo& args) { template -void WriteFloatGeneric(const FunctionCallbackInfo& args) { +uint32_t WriteFloatGeneric(const FunctionCallbackInfo& args) { bool doAssert = !args[2]->BooleanValue(); T val = static_cast(args[0]->NumberValue()); size_t offset; - CHECK_NOT_OOB(ParseArrayIndex(args[1], 0, &offset)); + if (!ParseArrayIndex(args[1], 0, &offset)) { + ThrowRangeError("out of range index"); + return 0; + } if (doAssert) { size_t len = Length(args.This()); - if (offset + sizeof(T) > len || offset + sizeof(T) < offset) - return ThrowRangeError("Trying to write beyond buffer length"); + if (offset + sizeof(T) > len || offset + sizeof(T) < offset) { + ThrowRangeError("Trying to write beyond buffer length"); + return 0; + } } union NoAlias { @@ -509,26 +514,27 @@ void WriteFloatGeneric(const FunctionCallbackInfo& args) { char* ptr = static_cast(data) + offset; if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes)); memcpy(ptr, na.bytes, sizeof(na.bytes)); + return offset + sizeof(na.bytes); } void WriteFloatLE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); + args.GetReturnValue().Set(WriteFloatGeneric(args)); } void WriteFloatBE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); + args.GetReturnValue().Set(WriteFloatGeneric(args)); } void WriteDoubleLE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); + args.GetReturnValue().Set(WriteFloatGeneric(args)); } void WriteDoubleBE(const FunctionCallbackInfo& args) { - WriteFloatGeneric(args); + args.GetReturnValue().Set(WriteFloatGeneric(args)); } diff --git a/test/simple/test-buffer.js b/test/simple/test-buffer.js index 2baf0d2101d..40b8e7bebb3 100644 --- a/test/simple/test-buffer.js +++ b/test/simple/test-buffer.js @@ -778,6 +778,14 @@ assert.equal(buf[3], 0xFF); assert.equal(buf[3], 0xFF); }); +// test offset returns are correct +var b = new Buffer(16); +assert.equal(4, b.writeUInt32LE(0, 0)); +assert.equal(6, b.writeUInt16LE(0, 4)); +assert.equal(7, b.writeUInt8(0, 6)); +assert.equal(8, b.writeInt8(0, 7)); +assert.equal(16, b.writeDoubleLE(0, 8)); + // test for buffer overrun buf = new Buffer([0, 0, 0, 0, 0]); // length: 5 var sub = buf.slice(0, 4); // length: 4