From edc3dadc82f25ce975fcb84648bc775304832557 Mon Sep 17 00:00:00 2001 From: cherue <40793059+cherue@users.noreply.github.com> Date: Sun, 15 Mar 2020 22:50:39 +0100 Subject: [PATCH 1/2] Fix overflow when reading negative s8 When doing bitwise operations in JS the values are always converted to a signed 32-bit integer and the result is also always a signed 32-bit integer. The calculation that converts two `u4`s to one `s8` assumes only positive inputs, this change makes sure of that. --- KaitaiStream.js | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/KaitaiStream.js b/KaitaiStream.js index 579a117..4b4e49b 100644 --- a/KaitaiStream.js +++ b/KaitaiStream.js @@ -214,15 +214,9 @@ KaitaiStream.prototype.readS4be = function(e) { */ KaitaiStream.prototype.readS8be = function(e) { this.ensureBytesLeft(8); - var v1 = this.readU4be(); - var v2 = this.readU4be(); - - if ((v1 & 0x80000000) != 0) { - // negative number - return -(0x100000000 * (v1 ^ 0xffffffff) + (v2 ^ 0xffffffff)) - 1; - } else { - return 0x100000000 * v1 + v2; - } + var high = this.readU4be(); + var low = this.readU4be(); + return KaitaiStream.twoU4sToS8(high, low); }; // ........................................................................ @@ -260,15 +254,9 @@ KaitaiStream.prototype.readS4le = function(e) { */ KaitaiStream.prototype.readS8le = function(e) { this.ensureBytesLeft(8); - var v1 = this.readU4le(); - var v2 = this.readU4le(); - - if ((v2 & 0x80000000) != 0) { - // negative number - return -(0x100000000 * (v2 ^ 0xffffffff) + (v1 ^ 0xffffffff)) - 1; - } else { - return 0x100000000 * v2 + v1; - } + var low = this.readU4le(); + var high = this.readU4le(); + return KaitaiStream.twoU4sToS8(high, low); }; // ------------------------------------------------------------------------ @@ -802,6 +790,19 @@ KaitaiStream.createStringFromArray = function(array) { return chunks.join(""); }; +KaitaiStream.twoU4sToS8 = function(high, low) { + if ((high & 0x80000000) != 0) { + // negative number + high = high ^ 0xffffffff; + high = high < 0 ? 2**32 + high : high; + low = low ^ 0xffffffff; + low = low < 0 ? 2**32 + low : low; + return -(0x100000000 * high + low) - 1; + } else { + return 0x100000000 * high + low; + } +} + return KaitaiStream; })); From 7c0de722bce4b8c3d00fd3cc3e43fc285c9dd1b2 Mon Sep 17 00:00:00 2001 From: cherue <40793059+cherue@users.noreply.github.com> Date: Mon, 16 Mar 2020 08:07:28 +0100 Subject: [PATCH 2/2] Remove overflow check for high bytes in s8 Because the high bytes always have the sign bit set XORing them can never result in a negative number. --- KaitaiStream.js | 1 - 1 file changed, 1 deletion(-) diff --git a/KaitaiStream.js b/KaitaiStream.js index 4b4e49b..eb27839 100644 --- a/KaitaiStream.js +++ b/KaitaiStream.js @@ -794,7 +794,6 @@ KaitaiStream.twoU4sToS8 = function(high, low) { if ((high & 0x80000000) != 0) { // negative number high = high ^ 0xffffffff; - high = high < 0 ? 2**32 + high : high; low = low ^ 0xffffffff; low = low < 0 ? 2**32 + low : low; return -(0x100000000 * high + low) - 1;