Skip to content

Commit 2bb9c1c

Browse files
pabigotMyles Borins
authored and
Myles Borins
committed
buffer: fix writeInt{B,L}E for some neg values
The algorithm used to convert negative values to hex generates incorrect values when the low byte(s) of the value are zero because a carried subtraction is applied prematurely. Fixes: #3992 PR-URL: #3994 Reviewed-By: Trevor Norris <[email protected]> Signed-off-by: Peter A. Bigot <[email protected]>
1 parent 66d6990 commit 2bb9c1c

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

lib/buffer.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -942,10 +942,13 @@ Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
942942

943943
var i = 0;
944944
var mul = 1;
945-
var sub = value < 0 ? 1 : 0;
945+
var sub = 0;
946946
this[offset] = value;
947-
while (++i < byteLength && (mul *= 0x100))
947+
while (++i < byteLength && (mul *= 0x100)) {
948+
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0)
949+
sub = 1;
948950
this[offset + i] = ((value / mul) >> 0) - sub;
951+
}
949952

950953
return offset + byteLength;
951954
};
@@ -965,10 +968,13 @@ Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
965968

966969
var i = byteLength - 1;
967970
var mul = 1;
968-
var sub = value < 0 ? 1 : 0;
971+
var sub = 0;
969972
this[offset + i] = value;
970-
while (--i >= 0 && (mul *= 0x100))
973+
while (--i >= 0 && (mul *= 0x100)) {
974+
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0)
975+
sub = 1;
971976
this[offset + i] = ((value / mul) >> 0) - sub;
977+
}
972978

973979
return offset + byteLength;
974980
};

test/parallel/test-buffer.js

+30
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,26 @@ assert.equal(buf.readInt8(0), -1);
10271027
assert.deepEqual(buf.toJSON().data, [0xed, 0xcb, 0xaa]);
10281028
assert.equal(buf.readIntBE(0, 3), -0x123456);
10291029

1030+
buf = new Buffer(3);
1031+
buf.writeIntLE(-0x123400, 0, 3);
1032+
assert.deepEqual(buf.toJSON().data, [0x00, 0xcc, 0xed]);
1033+
assert.equal(buf.readIntLE(0, 3), -0x123400);
1034+
1035+
buf = new Buffer(3);
1036+
buf.writeIntBE(-0x123400, 0, 3);
1037+
assert.deepEqual(buf.toJSON().data, [0xed, 0xcc, 0x00]);
1038+
assert.equal(buf.readIntBE(0, 3), -0x123400);
1039+
1040+
buf = new Buffer(3);
1041+
buf.writeIntLE(-0x120000, 0, 3);
1042+
assert.deepEqual(buf.toJSON().data, [0x00, 0x00, 0xee]);
1043+
assert.equal(buf.readIntLE(0, 3), -0x120000);
1044+
1045+
buf = new Buffer(3);
1046+
buf.writeIntBE(-0x120000, 0, 3);
1047+
assert.deepEqual(buf.toJSON().data, [0xee, 0x00, 0x00]);
1048+
assert.equal(buf.readIntBE(0, 3), -0x120000);
1049+
10301050
buf = new Buffer(5);
10311051
buf.writeUIntLE(0x1234567890, 0, 5);
10321052
assert.deepEqual(buf.toJSON().data, [0x90, 0x78, 0x56, 0x34, 0x12]);
@@ -1056,6 +1076,16 @@ assert.equal(buf.readInt8(0), -1);
10561076
buf.writeIntBE(-0x1234567890, 0, 5);
10571077
assert.deepEqual(buf.toJSON().data, [0xed, 0xcb, 0xa9, 0x87, 0x70]);
10581078
assert.equal(buf.readIntBE(0, 5), -0x1234567890);
1079+
1080+
buf = new Buffer(5);
1081+
buf.writeIntLE(-0x0012000000, 0, 5);
1082+
assert.deepEqual(buf.toJSON().data, [0x00, 0x00, 0x00, 0xee, 0xff]);
1083+
assert.equal(buf.readIntLE(0, 5), -0x0012000000);
1084+
1085+
buf = new Buffer(5);
1086+
buf.writeIntBE(-0x0012000000, 0, 5);
1087+
assert.deepEqual(buf.toJSON().data, [0xff, 0xee, 0x00, 0x00, 0x00]);
1088+
assert.equal(buf.readIntBE(0, 5), -0x0012000000);
10591089
})();
10601090

10611091
// test Buffer slice

0 commit comments

Comments
 (0)