mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-23 15:34:34 +00:00
Handle special case, empty file
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using ZstdSharp.Unsafe;
|
||||
|
||||
namespace SharpCompress.Common.Tar.Headers;
|
||||
|
||||
@@ -134,9 +135,8 @@ internal sealed class TarHeader
|
||||
hasLongValue = false;
|
||||
} while (hasLongValue);
|
||||
|
||||
var crc = ReadAsciiInt64Base8(buffer, 148, 7);
|
||||
|
||||
if (crc != RecalculateChecksum(buffer))
|
||||
// Check header checksum
|
||||
if (!checkChecksum(buffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -318,6 +318,42 @@ internal sealed class TarHeader
|
||||
(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.
|
||||
|
||||
@@ -217,7 +217,8 @@ public class TarArchiveTests : ArchiveTests
|
||||
{
|
||||
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]
|
||||
|
||||
Reference in New Issue
Block a user