Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Matos <joao@tritao.eu>2016-06-29 13:18:16 +0300
committerJoão Matos <joao@tritao.eu>2016-06-29 13:28:16 +0300
commit7a9a7b2373d92fd12007e6640a0c21db1bd40e0a (patch)
tree9effdef200f944029d663f6779841ba6e078d128 /mcs/class/System.IO.Compression
parent0d5ea337a687021643750cfee771080fc50cab4d (diff)
[System.IO.Compression] Fixed handling of Zip archives with duplicate entries with same name.
.NET supports this, from MSDN: "If an entry with the specified path and name already exists in the archive, a second entry is created with the same path and name.". Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=42219.
Diffstat (limited to 'mcs/class/System.IO.Compression')
-rw-r--r--mcs/class/System.IO.Compression/SharpCompress/Archive/AbstractWritableArchive.cs7
-rw-r--r--mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs17
-rw-r--r--mcs/class/System.IO.Compression/ZipArchive.cs12
3 files changed, 29 insertions, 7 deletions
diff --git a/mcs/class/System.IO.Compression/SharpCompress/Archive/AbstractWritableArchive.cs b/mcs/class/System.IO.Compression/SharpCompress/Archive/AbstractWritableArchive.cs
index 96af8c4131d..f844e5cb471 100644
--- a/mcs/class/System.IO.Compression/SharpCompress/Archive/AbstractWritableArchive.cs
+++ b/mcs/class/System.IO.Compression/SharpCompress/Archive/AbstractWritableArchive.cs
@@ -82,10 +82,14 @@ namespace SharpCompress.Archive
{
key = key.Substring(1);
}
+ // .NET allows duplicate entries when saving and loading Zip files.
+ // The following lines are disabled from upstream SharpCompress to allow this.
+#if ZIP_ALLOW_DUPLICATE_KEYS
if (DoesKeyMatchExisting(key))
{
throw new ArchiveException("Cannot add entry with duplicate key: " + key);
}
+#endif
var entry = CreateEntry(key, source, size, modified, closeStream);
newEntries.Add(entry);
RebuildModifiedCollection();
@@ -101,7 +105,8 @@ namespace SharpCompress.Archive
{
p = p.Substring(1);
}
- return string.Equals(p, key, StringComparison.OrdinalIgnoreCase);
+ if (string.Equals(p, key, StringComparison.OrdinalIgnoreCase))
+ return true;
}
return false;
}
diff --git a/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs b/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs
index 64b102c2d3d..99692163002 100644
--- a/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs
+++ b/mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs
@@ -358,6 +358,23 @@ namespace MonoTests.System.IO.Compression
}
[Test]
+ public void ZipCreateDuplicateEntriesUpdateMode()
+ {
+ var stream = new MemoryStream();
+ using (var zipArchive = new ZipArchive(stream, ZipArchiveMode.Update, true))
+ {
+ var e2 = zipArchive.CreateEntry("BBB");
+ var e3 = zipArchive.CreateEntry("BBB");
+ }
+
+ stream.Position = 0;
+ using (var zipArchive = new ZipArchive(stream, ZipArchiveMode.Read))
+ {
+ Assert.AreEqual(2, zipArchive.Entries.Count);
+ }
+ }
+
+ [Test]
public void ZipWriteEntriesUpdateModeNonZeroPosition()
{
File.Copy("archive.zip", "test.zip", overwrite: true);
diff --git a/mcs/class/System.IO.Compression/ZipArchive.cs b/mcs/class/System.IO.Compression/ZipArchive.cs
index 4f0c7bb70b9..9dbf04cd339 100644
--- a/mcs/class/System.IO.Compression/ZipArchive.cs
+++ b/mcs/class/System.IO.Compression/ZipArchive.cs
@@ -39,7 +39,7 @@ namespace System.IO.Compression
internal readonly ZipArchiveMode mode;
internal Encoding entryNameEncoding;
internal bool disposed;
- internal Dictionary<string, ZipArchiveEntry> entries;
+ internal List<ZipArchiveEntry> entries;
internal SharpCompress.Archive.Zip.ZipArchive zipFile;
public ZipArchive (Stream stream)
@@ -111,11 +111,11 @@ namespace System.IO.Compression
throw new InvalidDataException("The contents of the stream are not in the zip archive format.", e);
}
- entries = new Dictionary<string, ZipArchiveEntry>();
+ entries = new List<ZipArchiveEntry>();
if (Mode != ZipArchiveMode.Create) {
foreach (var entry in zipFile.Entries) {
var zipEntry = new ZipArchiveEntry(this, entry);
- entries[entry.Key] = zipEntry;
+ entries.Add(zipEntry);
}
}
}
@@ -140,7 +140,7 @@ namespace System.IO.Compression
if (entries == null)
return new ReadOnlyCollection<ZipArchiveEntry>(new List<ZipArchiveEntry>());
- return new ReadOnlyCollection<ZipArchiveEntry>(entries.Values.ToList());
+ return new ReadOnlyCollection<ZipArchiveEntry>(entries);
}
}
@@ -188,7 +188,7 @@ namespace System.IO.Compression
var internalEntry = CreateEntryInternal(entryName);
var archiveEntry = new ZipArchiveEntry(this, internalEntry);
- entries[entryName] = archiveEntry;
+ entries.Add(archiveEntry);
return archiveEntry;
}
@@ -210,7 +210,7 @@ namespace System.IO.Compression
if (zipFile == null)
throw new InvalidDataException("The zip archive is corrupt, and its entries cannot be retrieved.");
- return entries.ContainsKey(entryName) ? entries[entryName] : null;
+ return entries.FirstOrDefault(e => e.FullName == entryName);
}
private void Save()