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-30 15:58:27 +0300
committerJoão Matos <joao@tritao.eu>2016-06-30 16:15:52 +0300
commit4fc860ec217b121bda019de9b182a48ad9642f8d (patch)
tree246d6b829e38f89de8587aa757ee0b8cc054164c /mcs/class/System.IO.Compression
parentc167f3abe391923656db51f7d5db4c6d0eaef951 (diff)
[System.IO.Compression] Fixed Zip entry stream length/position getters in Update mode.
This does away with the lazy writeable entry scheme in Update mode and converts the stream to be writeable when its opened in Update mode. From local testing, .NET does the same in this case. Fixes another issue reported by @Numpsy in https://github.com/OfficeDev/Open-XML-SDK/issues/64. Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=42274.
Diffstat (limited to 'mcs/class/System.IO.Compression')
-rw-r--r--mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs31
-rw-r--r--mcs/class/System.IO.Compression/ZipArchiveEntry.cs24
2 files changed, 38 insertions, 17 deletions
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 99692163002..b9bb8101185 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
@@ -275,11 +275,10 @@ namespace MonoTests.System.IO.Compression
}
}
- [Test]
- public void ZipGetArchiveEntryStreamLengthPositionReadMode()
+ public void ZipGetArchiveEntryStreamLengthPosition(ZipArchiveMode mode)
{
- using (var archive = new ZipArchive(File.Open("test.nupkg", FileMode.Open),
- ZipArchiveMode.Read))
+ File.Copy("test.nupkg", "test2.nupkg", overwrite: true);
+ using (var archive = new ZipArchive(File.Open("test2.nupkg", FileMode.Open), mode))
{
var entry = archive.GetEntry("_rels/.rels");
using (var stream = entry.Open())
@@ -287,10 +286,34 @@ namespace MonoTests.System.IO.Compression
Assert.AreEqual(0, stream.Position);
Assert.AreEqual(425, stream.Length);
}
+
+ // .NET does not support these in Read mode but we do.
+ var entry2 = archive.GetEntry("modernhttpclient.nuspec");
+ using (var stream = entry2.Open())
+ {
+ Assert.AreEqual(857, stream.Length);
+ if (mode == ZipArchiveMode.Update)
+ {
+ Assert.AreEqual(0, stream.Position);
+ }
+ }
}
+ File.Delete ("test2.nupkg");
}
[Test]
+ public void ZipGetArchiveEntryStreamLengthPositionReadMode()
+ {
+ ZipGetArchiveEntryStreamLengthPosition(ZipArchiveMode.Read);
+ }
+
+ [Test]
+ public void ZipGetArchiveEntryStreamLengthPositionUpdateMode()
+ {
+ ZipGetArchiveEntryStreamLengthPosition(ZipArchiveMode.Update);
+ }
+
+ [Test]
public void ZipEnumerateEntriesReadMode()
{
File.Copy("archive.zip", "test.zip", overwrite: true);
diff --git a/mcs/class/System.IO.Compression/ZipArchiveEntry.cs b/mcs/class/System.IO.Compression/ZipArchiveEntry.cs
index 002b6f14ceb..9b415fbe6fd 100644
--- a/mcs/class/System.IO.Compression/ZipArchiveEntry.cs
+++ b/mcs/class/System.IO.Compression/ZipArchiveEntry.cs
@@ -54,7 +54,7 @@ namespace System.IO.Compression
public override long Length {
get {
- return stream.Length;
+ return stream.CanWrite ? stream.Length : entry.Length;
}
}
@@ -95,15 +95,16 @@ namespace System.IO.Compression
public override void Write (byte[] buffer, int offset, int count)
{
- if (entry.Archive.Mode == ZipArchiveMode.Update && !entry.wasWritten)
+ stream.Write(buffer, offset, count);
+ }
+
+ internal void EnsureWriteable()
+ {
+ if (entry.Archive.Mode == ZipArchiveMode.Update && !stream.CanWrite)
{
// Replace the read-only stream with a writeable memory stream.
- if (!stream.CanWrite)
- SetWriteable();
- entry.wasWritten = true;
+ SetWriteable();
}
-
- stream.Write(buffer, offset, count);
}
internal void SetWriteable()
@@ -115,15 +116,11 @@ namespace System.IO.Compression
var newStream = newEntry.OpenEntryStream();
var openStream = stream;
- var position = openStream.Position;
-
- entry.openStream = null;
- entry.Open();
-
openStream.CopyTo(newStream);
- newStream.Position = position;
openStream.Dispose();
+ newStream.Position = 0;
+
archive.zipFile.RemoveEntry(internalEntry);
entry.entry = newEntry;
stream = newStream;
@@ -232,6 +229,7 @@ namespace System.IO.Compression
var entryStream = entry.OpenEntryStream();
openStream = new ZipArchiveEntryStream(this, entryStream);
+ openStream.EnsureWriteable();
return openStream;
}