Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,7 @@
<data name="Zip64EOCDNotWhereExpected" xml:space="preserve">
<value>Zip 64 End of Central Directory Record not where indicated.</value>
</data>
<data name="EntryNameAlreadyExists" xml:space="preserve">
<value>The entry name '{0}' already exists in the archive.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,11 @@ private ZipArchiveEntry DoCreateEntry(string entryName, CompressionLevel? compre
if (_mode == ZipArchiveMode.Read)
throw new NotSupportedException(SR.CreateInReadMode);

if (_entriesDictionary.ContainsKey(entryName))
{
throw new InvalidOperationException(string.Format(SR.EntryNameAlreadyExists, entryName));
}
Comment on lines +391 to +394
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm working on getting various MAUI workloads running on .NET 7. One of our tests hit an issue due to this change.

An MSBuild task inside a NuGet package has the following call:

https://github.com/xamarin/XamarinComponents/blob/895182cc16d88b0e092578d8a6d27bb68d0d459a/Util/Xamarin.Build.Download/source/Xamarin.Build.Download/AndroidAarFixups.cs#L60

Previously the code was creating a new entry then removing the old one afterward. (Code is old, it may indeed be incorrect)

Is the new exception intentional? Is it something that needs to be on a "breaking changes" list somewhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed an issue; it seems I can reproduce in a smaller example: #68734


ThrowIfDisposed();


Expand Down Expand Up @@ -421,12 +426,7 @@ internal void AcquireArchiveStream(ZipArchiveEntry entry)
private void AddEntry(ZipArchiveEntry entry)
{
_entries.Add(entry);

string entryName = entry.FullName;
if (!_entriesDictionary.ContainsKey(entryName))
{
_entriesDictionary.Add(entryName, entry);
}
_entriesDictionary.Add(entry.FullName, entry);
}

[Conditional("DEBUG")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ public static void CreateNormal_VerifyDataDescriptor()
AssertDataDescriptor(memoryStream, false);
}

[Fact]
public static void CreateNormal_With2SameEntries_ThrowException()
{
using var memoryStream = new MemoryStream();
// We need an non-seekable stream so the data descriptor bit is turned on when saving
var wrappedStream = new WrappedStream(memoryStream);

// Creation will go through the path that sets the data descriptor bit when the stream is unseekable
using (var archive = new ZipArchive(wrappedStream, ZipArchiveMode.Create))
{
CreateEntry(archive, "A", "xxx");
AssertExtensions.ThrowsContains<InvalidOperationException>(() => CreateEntry(archive, "A", "yyy"),
"The entry name 'A' already exists in the archive.");
}
}

private static string ReadStringFromSpan(Span<byte> input)
{
return Text.Encoding.UTF8.GetString(input.ToArray());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,36 @@ public static void EmptyEntryTest(ZipArchiveMode mode)
baseline = baseline.Clone();
using (ZipArchive archive = new ZipArchive(baseline, mode))
{
AddEntry(archive, "data1.txt", data1, lastWrite);
if (mode == ZipArchiveMode.Create)
{
AddEntry(archive, "data1.txt", data1, lastWrite);

ZipArchiveEntry e = archive.CreateEntry("empty.txt");
e.LastWriteTime = lastWrite;
using (Stream s = e.Open()) { }
ZipArchiveEntry e = archive.CreateEntry("empty.txt");
e.LastWriteTime = lastWrite;
using (Stream s = e.Open()) { }
}
else
{
ZipArchiveEntry e = archive.GetEntry("data2.txt");
e.Delete();
}
}

test = test.Clone();
using (ZipArchive archive = new ZipArchive(test, mode))
{
AddEntry(archive, "data1.txt", data1, lastWrite);
if (mode == ZipArchiveMode.Create)
{
AddEntry(archive, "data1.txt", data1, lastWrite);

ZipArchiveEntry e = archive.CreateEntry("empty.txt");
e.LastWriteTime = lastWrite;
ZipArchiveEntry e = archive.CreateEntry("empty.txt");
e.LastWriteTime = lastWrite;
}
else
{
ZipArchiveEntry e = archive.GetEntry("data2.txt");
e.Delete();
}
}
//compare
Assert.True(ArraysEqual(baseline.ToArray(), test.ToArray()), "Arrays didn't match after update");
Expand Down