diff options
Diffstat (limited to 'deps/npm/node_modules/tar/lib/large-numbers.js')
-rw-r--r-- | deps/npm/node_modules/tar/lib/large-numbers.js | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/deps/npm/node_modules/tar/lib/large-numbers.js b/deps/npm/node_modules/tar/lib/large-numbers.js index ff49992630..3e5c99255a 100644 --- a/deps/npm/node_modules/tar/lib/large-numbers.js +++ b/deps/npm/node_modules/tar/lib/large-numbers.js @@ -1,12 +1,13 @@ 'use strict' // Tar can encode large and negative numbers using a leading byte of -// 0xff for negative, and 0x80 for positive. The trailing byte in the -// section will always be 0x20, or in some implementations 0x00. -// this module encodes and decodes these things. +// 0xff for negative, and 0x80 for positive. const encode = exports.encode = (num, buf) => { - buf[buf.length - 1] = 0x20 - if (num < 0) + if (!Number.isSafeInteger(num)) + // The number is so large that javascript cannot represent it with integer + // precision. + throw TypeError('cannot encode number outside of javascript safe integer range') + else if (num < 0) encodeNegative(num, buf) else encodePositive(num, buf) @@ -15,13 +16,10 @@ const encode = exports.encode = (num, buf) => { const encodePositive = (num, buf) => { buf[0] = 0x80 - for (var i = buf.length - 2; i > 0; i--) { - if (num === 0) - buf[i] = 0 - else { - buf[i] = num % 0x100 - num = Math.floor(num / 0x100) - } + + for (var i = buf.length; i > 1; i--) { + buf[i-1] = num & 0xff + num = Math.floor(num / 0x100) } } @@ -29,21 +27,16 @@ const encodeNegative = (num, buf) => { buf[0] = 0xff var flipped = false num = num * -1 - for (var i = buf.length - 2; i > 0; i--) { - var byte - if (num === 0) - byte = 0 - else { - byte = num % 0x100 - num = Math.floor(num / 0x100) - } + for (var i = buf.length; i > 1; i--) { + var byte = num & 0xff + num = Math.floor(num / 0x100) if (flipped) - buf[i] = onesComp(byte) + buf[i-1] = onesComp(byte) else if (byte === 0) - buf[i] = 0 + buf[i-1] = 0 else { flipped = true - buf[i] = twosComp(byte) + buf[i-1] = twosComp(byte) } } } @@ -51,8 +44,20 @@ const encodeNegative = (num, buf) => { const parse = exports.parse = (buf) => { var post = buf[buf.length - 1] var pre = buf[0] - return pre === 0x80 ? pos(buf.slice(1, buf.length - 1)) - : twos(buf.slice(1, buf.length - 1)) + var value; + if (pre === 0x80) + value = pos(buf.slice(1, buf.length)) + else if (pre === 0xff) + value = twos(buf) + else + throw TypeError('invalid base256 encoding') + + if (!Number.isSafeInteger(value)) + // The number is so large that javascript cannot represent it with integer + // precision. + throw TypeError('parsed number outside of javascript safe integer range') + + return value } const twos = (buf) => { @@ -71,9 +76,9 @@ const twos = (buf) => { f = twosComp(byte) } if (f !== 0) - sum += f * Math.pow(256, len - i - 1) + sum -= f * Math.pow(256, len - i - 1) } - return sum * -1 + return sum } const pos = (buf) => { |