Skip to content

Commit

Permalink
Handle special case, empty file
Browse files Browse the repository at this point in the history
  • Loading branch information
Erior committed Jul 11, 2024
1 parent e42d953 commit 6b88f82
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
42 changes: 39 additions & 3 deletions src/SharpCompress/Common/Tar/Headers/TarHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Buffers.Binary;
using System.IO;
using System.Text;
using ZstdSharp.Unsafe;

namespace SharpCompress.Common.Tar.Headers;

Expand Down Expand Up @@ -134,9 +135,8 @@ internal bool Read(BinaryReader reader)
hasLongValue = false;
} while (hasLongValue);

var crc = ReadAsciiInt64Base8(buffer, 148, 7);

if (crc != RecalculateChecksum(buffer))
// Check header checksum
if (!checkChecksum(buffer))
{
return false;
}
Expand Down Expand Up @@ -318,6 +318,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
3 changes: 2 additions & 1 deletion tests/SharpCompress.Test/Tar/TarArchiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ public void Tar_Empty_Archive()
{
var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.Empty.tar");
using Stream stream = File.OpenRead(archiveFullPath);
Assert.Throws<InvalidOperationException>(() => ArchiveFactory.Open(stream));
using var archive = ArchiveFactory.Open(stream);
Assert.True(archive.Type == ArchiveType.Tar);
}

[Theory]
Expand Down

0 comments on commit 6b88f82

Please sign in to comment.