Skip to content

Commit

Permalink
Simplify tar checksum calculation (#386)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
Borewit and sindresorhus committed Aug 9, 2020
1 parent 683b770 commit 4a4d39c
Showing 1 changed file with 13 additions and 26 deletions.
39 changes: 13 additions & 26 deletions util.js
Expand Up @@ -2,43 +2,30 @@

exports.stringToBytes = string => [...string].map(character => character.charCodeAt(0));

exports.tarHeaderChecksumMatches = buffer => { // Does not check if checksum field characters are valid
if (buffer.length < 512) { // `tar` header size, cannot compute checksum without it
return false;
}
/**
Checks whether the TAR checksum is valid.
@param {Buffer} buffer - The TAR header `[offset ... offset + 512]`.
@param {number} offset - TAR header offset.
@returns {boolean} `true` if the TAR checksum is valid, otherwise `false`.
*/
exports.tarHeaderChecksumMatches = (buffer, offset = 0) => {
const readSum = parseInt(buffer.toString('utf8', 148, 154).replace(/\0.*$/, '').trim(), 8); // Read sum in header
if (isNaN(readSum)) {
return false;
}

const MASK_8TH_BIT = 0x80;
let sum = 8 * 0x20; // Initialize signed bit sum

let sum = 256; // Initialize 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++) {
const byte = buffer[i];
sum += byte;
signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum
for (let i = offset; i < offset + 148; i++) {
sum += buffer[i];
}

// Skip checksum field

for (let i = 156; i < 512; i++) {
const byte = buffer[i];
sum += byte;
signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum
for (let i = offset + 156; i < offset + 512; i++) {
sum += buffer[i];
}

// Some implementations compute checksum incorrectly using signed bytes
return (
// Checksum in header equals the sum we calculated
readSum === sum ||

// Checksum in header equals sum we calculated plus signed-to-unsigned delta
readSum === (sum - (signedBitSum << 1))
);
return readSum === sum;
};

/**
Expand Down

0 comments on commit 4a4d39c

Please sign in to comment.