Add tests for long USTAR names split at a directory separator

When an entry name is longer than the 100 byte USTAR name field,
TarHeader splits it into the 155 byte prefix field and the name field
at a directory separator. The existing tests only covered short paths
and long names without any separator.

Add sync and async tests that write a 186 byte path (with '/' and
'\' separators as input) using the USTAR format and read it back.

On Windows these tests fail with InvalidFormatException ("Directory
separator not found!"), which the next commit fixes. They pass on
Linux and macOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
drone1400
2026-10-30 11:48:10 +02:00
parent dedbf6ac57
commit fb0cd47bb0
2 changed files with 56 additions and 0 deletions

View File

@@ -124,6 +124,34 @@ public class TarWriterAsyncTests : WriterTests
);
}
[Theory]
[InlineData('/')]
[InlineData('\\')]
public async ValueTask Tar_Ustar_HeaderFormat_WritesLongPathUsingPrefix_Async(char separator)
{
// 186 bytes: too long for the 100 byte name field, but splittable into prefix + name
var longName =
new string('a', 60)
+ separator
+ new string('b', 60)
+ separator
+ new string('c', 60)
+ ".txt";
using var stream = new MemoryStream();
var options = new TarWriterOptions(CompressionType.None, true, TarHeaderWriteFormat.USTAR);
await using (var writer = new TarWriter(new AsyncOnlyStream(stream), options))
using (var content = new MemoryStream(Encoding.UTF8.GetBytes("hello")))
{
await writer.WriteAsync(longName, content, null);
}
stream.Position = 0;
using var archive = TarArchive.OpenArchive(stream);
Assert.Single(archive.Entries);
Assert.Equal(longName.Replace('\\', '/'), archive.Entries.Single().Key);
}
[Fact]
public async ValueTask Tar_GnuLongLink_HeaderFormat_WritesLongPath_Async()
{

View File

@@ -110,6 +110,34 @@ public class TarWriterTests : WriterTests
Assert.Throws<InvalidFormatException>(() => writer.Write(longName, content, null));
}
[Theory]
[InlineData('/')]
[InlineData('\\')]
public void Tar_Ustar_HeaderFormat_WritesLongPathUsingPrefix(char separator)
{
// 186 bytes: too long for the 100 byte name field, but splittable into prefix + name
var longName =
new string('a', 60)
+ separator
+ new string('b', 60)
+ separator
+ new string('c', 60)
+ ".txt";
using var stream = new MemoryStream();
var options = new TarWriterOptions(CompressionType.None, true, TarHeaderWriteFormat.USTAR);
using (var writer = new TarWriter(stream, options))
using (var content = new MemoryStream(Encoding.UTF8.GetBytes("hello")))
{
writer.Write(longName, content, null);
}
stream.Position = 0;
using var archive = TarArchive.OpenArchive(stream);
Assert.Single(archive.Entries);
Assert.Equal(longName.Replace('\\', '/'), archive.Entries.Single().Key);
}
[Fact]
public void Tar_GnuLongLink_HeaderFormat_WritesLongPath()
{