Skip to content
Prev Previous commit
Next Next commit
Address feedback
  • Loading branch information
jozkee authored and github-actions committed Sep 28, 2022
commit a255c73960e9411147a23b178d036dbae7d953a7
Original file line number Diff line number Diff line change
Expand Up @@ -378,45 +378,45 @@ private int WriteName(Span<byte> buffer)
}

// 'https://www.freebsd.org/cgi/man.cgi?tar(5)'
// If the pathname is too long to fit in the 100 bytes provided by the standard format,
// If the path name is too long to fit in the 100 bytes provided by the standard format,
// it can be split at any / character with the first portion going into the prefix field.
private int WriteUstarName(Span<byte> buffer)
{
// We can have a pathname as big as 256, prefix + '/' + name,
// We can have a path name as big as 256, prefix + '/' + name,
// the separator in between can be neglected as the reader will append it when it joins both fields.
const int MaxPathname = FieldLengths.Prefix + FieldLengths.Name + 1;
const int MaxPathName = FieldLengths.Prefix + 1 + FieldLengths.Name;

if (GetUtf8TextLength(_name) > MaxPathname)
if (GetUtf8TextLength(_name) > MaxPathName)
{
throw new ArgumentException(SR.TarEntryFieldExceedsMaxLength, ArgNameEntry);
throw new ArgumentException(SR.Format(SR.TarEntryFieldExceedsMaxLength, nameof(TarEntry.Name)), ArgNameEntry);
}

Span<byte> encodingBuffer = stackalloc byte[MaxPathname];
Span<byte> encodingBuffer = stackalloc byte[MaxPathName];
int encoded = Encoding.UTF8.GetBytes(_name, encodingBuffer);
ReadOnlySpan<byte> pathnameBytes = encodingBuffer.Slice(0, encoded);
ReadOnlySpan<byte> pathNameBytes = encodingBuffer.Slice(0, encoded);

// If the pathname is able to fit in Name, we can write it down there and avoid calculating Prefix.
if (pathnameBytes.Length <= FieldLengths.Name)
if (pathNameBytes.Length <= FieldLengths.Name)
{
return WriteLeftAlignedBytesAndGetChecksum(pathnameBytes, buffer.Slice(FieldLocations.Name, FieldLengths.Name));
return WriteLeftAlignedBytesAndGetChecksum(pathNameBytes, buffer.Slice(FieldLocations.Name, FieldLengths.Name));
}

int lastIdx = pathnameBytes.LastIndexOfAny(PathInternal.Utf8DirectorySeparators);
int lastIdx = pathNameBytes.LastIndexOfAny(PathInternal.Utf8DirectorySeparators);
scoped ReadOnlySpan<byte> name;
scoped ReadOnlySpan<byte> prefix;

if (lastIdx < 1) // splitting at the root is not allowed.
{
name = pathnameBytes;
name = pathNameBytes;
prefix = default;
}
else
{
name = pathnameBytes.Slice(lastIdx + 1);
prefix = pathnameBytes.Slice(0, lastIdx);
name = pathNameBytes.Slice(lastIdx + 1);
prefix = pathNameBytes.Slice(0, lastIdx);
}

// At this point pathnameBytes.Length > 100.
// At this point path name is > 100.
// Attempt to split it in a way it can use prefix.
while (prefix.Length - name.Length > FieldLengths.Prefix)
{
Expand All @@ -426,8 +426,8 @@ private int WriteUstarName(Span<byte> buffer)
break;
}

name = pathnameBytes.Slice(lastIdx + 1);
prefix = pathnameBytes.Slice(0, lastIdx);
name = pathNameBytes.Slice(lastIdx + 1);
prefix = pathNameBytes.Slice(0, lastIdx);
}

if (prefix.Length <= FieldLengths.Prefix && name.Length <= FieldLengths.Name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ public async Task NameRoundtripsAsync(TarEntryFormat entryFormat, TarEntryType e
MemoryStream ms = new();
Stream s = unseekableStream ? new WrappedStream(ms, ms.CanRead, ms.CanWrite, canSeek: false) : ms;

using (TarWriter writer = new(s, leaveOpen: true))
await using (TarWriter writer = new(s, leaveOpen: true))
{
await writer.WriteEntryAsync(entry);
}

ms.Position = 0;
using TarReader reader = new(s);
await using TarReader reader = new(s);

entry = await reader.GetNextEntryAsync();
Assert.Null(await reader.GetNextEntryAsync());
Expand All @@ -41,7 +41,7 @@ public static IEnumerable<object[]> LinkNameRoundtripsAsyncTheoryData()

[Theory]
[MemberData(nameof(LinkNameRoundtripsAsyncTheoryData))]
public async Task LinkNameRoundtrips(TarEntryFormat entryFormat, TarEntryType entryType, bool unseekableStream, string linkName)
public async Task LinkNameRoundtripsAsync(TarEntryFormat entryFormat, TarEntryType entryType, bool unseekableStream, string linkName)
{
string name = "foo";
TarEntry entry = InvokeTarEntryCreationConstructor(entryFormat, entryType, name);
Expand All @@ -50,13 +50,13 @@ public async Task LinkNameRoundtrips(TarEntryFormat entryFormat, TarEntryType en
MemoryStream ms = new();
Stream s = unseekableStream ? new WrappedStream(ms, ms.CanRead, ms.CanWrite, canSeek: false) : ms;

using (TarWriter writer = new(s, leaveOpen: true))
await using (TarWriter writer = new(s, leaveOpen: true))
{
await writer.WriteEntryAsync(entry);
}

ms.Position = 0;
using TarReader reader = new(s);
await using TarReader reader = new(s);

entry = await reader.GetNextEntryAsync();
Assert.Null(await reader.GetNextEntryAsync());
Expand All @@ -69,7 +69,7 @@ public static IEnumerable<object[]> UserNameGroupNameRoundtripsAsyncTheoryData()

[Theory]
[MemberData(nameof(UserNameGroupNameRoundtripsAsyncTheoryData))]
public async Task UserNameGroupNameRoundtrips(TarEntryFormat entryFormat, bool unseekableStream, string userGroupName)
public async Task UserNameGroupNameRoundtripsAsync(TarEntryFormat entryFormat, bool unseekableStream, string userGroupName)
{
string name = "foo";
TarEntry entry = InvokeTarEntryCreationConstructor(entryFormat, TarEntryType.RegularFile, name);
Expand All @@ -80,13 +80,13 @@ public async Task UserNameGroupNameRoundtrips(TarEntryFormat entryFormat, bool u
MemoryStream ms = new();
Stream s = unseekableStream ? new WrappedStream(ms, ms.CanRead, ms.CanWrite, canSeek: false) : ms;

using (TarWriter writer = new(s, leaveOpen: true))
await using (TarWriter writer = new(s, leaveOpen: true))
{
await writer.WriteEntryAsync(posixEntry);
}

ms.Position = 0;
using TarReader reader = new(s);
await using TarReader reader = new(s);

entry = await reader.GetNextEntryAsync();
posixEntry = Assert.IsAssignableFrom<PosixTarEntry>(entry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ public static IEnumerable<object[]> WriteEntry_TooLongName_Throws_Async_TheoryDa
[MemberData(nameof(WriteEntry_TooLongName_Throws_Async_TheoryData))]
public async Task WriteEntry_TooLongName_Throws_Async(TarEntryFormat entryFormat, TarEntryType entryType, string name)
{
using TarWriter writer = new(new MemoryStream());
await using TarWriter writer = new(new MemoryStream());

TarEntry entry = InvokeTarEntryCreationConstructor(entryFormat, entryType, name);
await Assert.ThrowsAsync<ArgumentException>("entry", () => writer.WriteEntryAsync(entry));
Expand All @@ -343,7 +343,7 @@ public static IEnumerable<object[]> WriteEntry_TooLongLinkName_Throws_Async_Theo
[MemberData(nameof(WriteEntry_TooLongLinkName_Throws_Async_TheoryData))]
public async Task WriteEntry_TooLongLinkName_Throws_Async(TarEntryFormat entryFormat, TarEntryType entryType, string linkName)
{
using TarWriter writer = new(new MemoryStream());
await using TarWriter writer = new(new MemoryStream());

TarEntry entry = InvokeTarEntryCreationConstructor(entryFormat, entryType, "foo");
entry.LinkName = linkName;
Expand All @@ -356,9 +356,9 @@ public static IEnumerable<object[]> WriteEntry_TooLongUserGroupName_Throws_Async

[Theory]
[MemberData(nameof(WriteEntry_TooLongUserGroupName_Throws_Async_TheoryData))]
public async Task WriteEntry_TooLongUserName_Throws(TarEntryFormat entryFormat, string userName)
public async Task WriteEntry_TooLongUserName_Throws_Async(TarEntryFormat entryFormat, string userName)
{
using TarWriter writer = new(new MemoryStream());
await using TarWriter writer = new(new MemoryStream());

TarEntry entry = InvokeTarEntryCreationConstructor(entryFormat, TarEntryType.RegularFile, "foo");
PosixTarEntry posixEntry = Assert.IsAssignableFrom<PosixTarEntry>(entry);
Expand All @@ -369,9 +369,9 @@ public async Task WriteEntry_TooLongUserName_Throws(TarEntryFormat entryFormat,

[Theory]
[MemberData(nameof(WriteEntry_TooLongUserGroupName_Throws_Async_TheoryData))]
public async Task WriteEntry_TooLongGroupName_Throws(TarEntryFormat entryFormat, string groupName)
public async Task WriteEntry_TooLongGroupName_Throws_Async(TarEntryFormat entryFormat, string groupName)
{
using TarWriter writer = new(new MemoryStream());
await using TarWriter writer = new(new MemoryStream());

TarEntry entry = InvokeTarEntryCreationConstructor(entryFormat, TarEntryType.RegularFile, "foo");
PosixTarEntry posixEntry = Assert.IsAssignableFrom<PosixTarEntry>(entry);
Expand Down