Skip to content

Commit 0e18e68

Browse files
pabigotrvagg
authored andcommitted
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 4302648 commit 0e18e68

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
@@ -939,10 +939,13 @@ Buffer.prototype.writeIntLE = function(value, offset, byteLength, noAssert) {
939939

940940
var i = 0;
941941
var mul = 1;
942-
var sub = value < 0 ? 1 : 0;
942+
var sub = 0;
943943
this[offset] = value;
944-
while (++i < byteLength && (mul *= 0x100))
944+
while (++i < byteLength && (mul *= 0x100)) {
945+
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0)
946+
sub = 1;
945947
this[offset + i] = ((value / mul) >> 0) - sub;
948+
}
946949

947950
return offset + byteLength;
948951
};
@@ -962,10 +965,13 @@ Buffer.prototype.writeIntBE = function(value, offset, byteLength, noAssert) {
962965

963966
var i = byteLength - 1;
964967
var mul = 1;
965-
var sub = value < 0 ? 1 : 0;
968+
var sub = 0;
966969
this[offset + i] = value;
967-
while (--i >= 0 && (mul *= 0x100))
970+
while (--i >= 0 && (mul *= 0x100)) {
971+
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0)
972+
sub = 1;
968973
this[offset + i] = ((value / mul) >> 0) - sub;
974+
}
969975

970976
return offset + byteLength;
971977
};

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)