From 4137b55e251bad488df28c2d9817c713a376b850 Mon Sep 17 00:00:00 2001 From: Yanis Benson Date: Sun, 14 Apr 2019 15:48:56 +0300 Subject: [PATCH 1/3] fixes #76 --- fixture/fixture-v7.tar | Bin 0 -> 10240 bytes index.js | 30 +++++++++++++++++++++++++++++- test.js | 4 ++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 fixture/fixture-v7.tar diff --git a/fixture/fixture-v7.tar b/fixture/fixture-v7.tar new file mode 100644 index 0000000000000000000000000000000000000000..c590557e891197d4bbc9fe0fa30eca1c5bc6f1b7 GIT binary patch literal 10240 zcmeIuu?>JQ3 { // Does not check if checksum field was valid + if (buf.length < 512) { + return false; + } + + let sum = 256; + let signedBitCount = 0; + + for (let i = 0; i < 148; i++) { + const byte = buf[i]; + sum += byte; + signedBitCount += byte & 0x80; + } + + for (let i = 156; i < 512; i++) { + const byte = buf[i]; + sum += byte; + signedBitCount += byte & 0x80; + } + + const readSum = parseInt(buf.toString('utf8', 148, 154), 8); + + return sum === readSum || ((sum - (signedBitCount << 1)) === readSum); +}; + const fileType = input => { if (!(input instanceof Uint8Array || input instanceof ArrayBuffer || Buffer.isBuffer(input))) { throw new TypeError(`Expected the \`input\` argument to be of type \`Uint8Array\` or \`Buffer\` or \`ArrayBuffer\`, got \`${typeof input}\``); @@ -229,7 +254,10 @@ const fileType = input => { }; } - if (check([0x75, 0x73, 0x74, 0x61, 0x72], {offset: 257})) { + if ( + check([0x30, 0x30, 0x30, 0x30, 0x30, 0x30], {offset: 148, mask: [0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8]}) && // Valid tar checksum + tarHeaderChecksumMatches(buf) + ) { return { ext: 'tar', mime: 'application/x-tar' diff --git a/test.js b/test.js index 7efe5588..503ec13e 100644 --- a/test.js +++ b/test.js @@ -191,6 +191,10 @@ const names = { pcap: [ 'fixture-big-endian', 'fixture-little-endian' + ], + tar: [ + 'fixture', + 'fixture-v7' ] }; From dfc859c9554a0de46a35e8fdc4b84534a2ed97b2 Mon Sep 17 00:00:00 2001 From: Yanis Benson Date: Fri, 19 Apr 2019 09:00:10 +0300 Subject: [PATCH 2/3] made 0x80 constant, added comments --- index.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index 290752d4..279601fe 100644 --- a/index.js +++ b/index.js @@ -16,29 +16,33 @@ function readUInt64LE(buf, offset = 0) { return n; } -const tarHeaderChecksumMatches = buf => { // Does not check if checksum field was valid - if (buf.length < 512) { +const MASK_8TH_BIT = 0x80; + +const tarHeaderChecksumMatches = buf => { // Does not check if checksum field characters are valid + if (buf.length < 512) { // `tar` header size, can not compute checksum without it return false; } - let sum = 256; - let signedBitCount = 0; + let sum = 256; // Intitalize sum, with 256 as sum of 8 spaces + let signedBitSum = 0; // Initialize signed bit sum for (let i = 0; i < 148; i++) { const byte = buf[i]; - sum += byte; - signedBitCount += byte & 0x80; + sum += byte; // Add to sum + signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum } for (let i = 156; i < 512; i++) { const byte = buf[i]; - sum += byte; - signedBitCount += byte & 0x80; + sum += byte; // Add to sum + signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum } - const readSum = parseInt(buf.toString('utf8', 148, 154), 8); + const readSum = parseInt(buf.toString('utf8', 148, 154), 8); // Read sum in header - return sum === readSum || ((sum - (signedBitCount << 1)) === readSum); + // Some implementations compute sum incorrectly using signed bytes + return readSum === sum || // Sum in header equals the sum we calculated + readSum === (sum - (signedBitSum << 1)); // Sum in header equals sum we calculated plus signed-to-unsigned delta }; const fileType = input => { From f0e5af15263637721cadf083d722c4446dc768a8 Mon Sep 17 00:00:00 2001 From: Yanis Benson Date: Fri, 19 Apr 2019 09:03:44 +0300 Subject: [PATCH 3/3] better comments --- index.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 279601fe..903d0adc 100644 --- a/index.js +++ b/index.js @@ -23,7 +23,7 @@ const tarHeaderChecksumMatches = buf => { // Does not check if checksum field ch return false; } - let sum = 256; // Intitalize sum, with 256 as sum of 8 spaces + let sum = 256; // Intitalize sum, with 256 as sum of 8 spaces in checksum field let signedBitSum = 0; // Initialize signed bit sum for (let i = 0; i < 148; i++) { @@ -32,6 +32,8 @@ const tarHeaderChecksumMatches = buf => { // Does not check if checksum field ch signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum } + // Skip checksum field + for (let i = 156; i < 512; i++) { const byte = buf[i]; sum += byte; // Add to sum @@ -40,9 +42,9 @@ const tarHeaderChecksumMatches = buf => { // Does not check if checksum field ch const readSum = parseInt(buf.toString('utf8', 148, 154), 8); // Read sum in header - // Some implementations compute sum incorrectly using signed bytes - return readSum === sum || // Sum in header equals the sum we calculated - readSum === (sum - (signedBitSum << 1)); // Sum in header equals sum we calculated plus signed-to-unsigned delta + // Some implementations compute checksum incorrectly using signed bytes + return readSum === sum || // Checksum in header equals the sum we calculated + readSum === (sum - (signedBitSum << 1)); // Checksum in header equals sum we calculated plus signed-to-unsigned delta }; const fileType = input => {