Skip to content

Commit

Permalink
Merge pull request #855 from Erior/feature/Check-tar-crc-on-header
Browse files Browse the repository at this point in the history
Check crc on tar header
  • Loading branch information
adamhathcock authored Jul 12, 2024
2 parents d18cad6 + 9515350 commit 6fcfae8
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/SharpCompress/Common/Tar/Headers/TarHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ internal bool Read(BinaryReader reader)
hasLongValue = false;
} while (hasLongValue);

// Check header checksum
if (!checkChecksum(buffer))
{
return false;
}

Name = longName ?? ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
EntryType = entryType;
Size = ReadSize(buffer);
Expand Down Expand Up @@ -311,6 +317,42 @@ private static long ReadAsciiInt64(byte[] buffer, int offset, int count)
(byte)' '
};

internal static bool checkChecksum(byte[] buf)
{
const int eightSpacesChksum = 256;
var buffer = new Span<byte>(buf).Slice(0, 512);
int posix_sum = eightSpacesChksum;
int sun_sum = eightSpacesChksum;

foreach (byte b in buffer)
{
posix_sum += b;
sun_sum += unchecked((sbyte)b);
}

// Special case, empty file header
if (posix_sum == eightSpacesChksum)
{
return true;
}

// Remove current checksum from calculation
foreach (byte b in buffer.Slice(148, 8))
{
posix_sum -= b;
sun_sum -= unchecked((sbyte)b);
}

// Read and compare checksum for header
var crc = ReadAsciiInt64Base8(buf, 148, 7);
if (crc != posix_sum && crc != sun_sum)
{
return false;
}

return true;
}

internal static int RecalculateChecksum(byte[] buf)
{
// Set default value for checksum. That is 8 spaces.
Expand Down
8 changes: 8 additions & 0 deletions tests/SharpCompress.Test/Tar/TarArchiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,12 @@ public void Tar_Read_One_At_A_Time()

Assert.Equal(2, numberOfEntries);
}

[Fact]
public void Tar_Detect_Test()
{
var isTar = TarArchive.IsTarFile(Path.Combine(TEST_ARCHIVES_PATH, "false.positive.tar"));

Assert.False(isTar);
}
}
Binary file not shown.

0 comments on commit 6fcfae8

Please sign in to comment.