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-07-02 04:02:25 +0300
committerJoão Matos <joao@tritao.eu>2016-07-02 04:02:25 +0300
commit77e2521d8cf359b47fd2e60286bdfa815b4fdba3 (patch)
tree3593e424e405a50a803311ec292ca60b86fbb4ad /mcs/class/System.IO.Compression
parent6b1b08cc60bab677a544944b0ddc1da1062c533a (diff)
[System.IO.Compression] Fixes ZipArchive to support non-seekable streams.
This is the same behavior as documented on MSDN. Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=30686.
Diffstat (limited to 'mcs/class/System.IO.Compression')
-rw-r--r--mcs/class/System.IO.Compression/Test/System.IO.Compression/ZipTest.cs19
-rw-r--r--mcs/class/System.IO.Compression/ZipArchive.cs22
2 files changed, 36 insertions, 5 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 b9bb8101185..2d03d559d4e 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
@@ -480,5 +480,24 @@ namespace MonoTests.System.IO.Compression
}
File.Delete ("empty.zip");
}
+
+ class MyFakeStream : FileStream
+ {
+ public MyFakeStream (string path, FileMode mode) : base(path, mode) {}
+
+ /// <summary>
+ /// Simulate "CanSeek" is false, which is the case when you are retreiving data from web.
+ /// </summary>
+ public override bool CanSeek => false;
+ }
+
+ [Test]
+ public void ZipReadNonSeekableStream()
+ {
+ var stream = new MyFakeStream("test.nupkg", FileMode.Open);
+ using (var archive = new ZipArchive (stream, ZipArchiveMode.Read))
+ {
+ }
+ }
}
}
diff --git a/mcs/class/System.IO.Compression/ZipArchive.cs b/mcs/class/System.IO.Compression/ZipArchive.cs
index 9dbf04cd339..c1a3df57566 100644
--- a/mcs/class/System.IO.Compression/ZipArchive.cs
+++ b/mcs/class/System.IO.Compression/ZipArchive.cs
@@ -49,7 +49,7 @@ namespace System.IO.Compression
this.stream = stream;
mode = ZipArchiveMode.Read;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
public ZipArchive (Stream stream, ZipArchiveMode mode)
@@ -59,7 +59,7 @@ namespace System.IO.Compression
this.stream = stream;
this.mode = mode;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
public ZipArchive (Stream stream, ZipArchiveMode mode, bool leaveOpen)
@@ -70,7 +70,7 @@ namespace System.IO.Compression
this.stream = stream;
this.mode = mode;
leaveStreamOpen = leaveOpen;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
public ZipArchive (Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding entryNameEncoding)
@@ -82,10 +82,10 @@ namespace System.IO.Compression
this.mode = mode;
leaveStreamOpen = leaveOpen;
this.entryNameEncoding = entryNameEncoding;
- CreateZip(stream, mode);
+ CreateZip(mode);
}
- private void CreateZip(Stream stream, ZipArchiveMode mode)
+ private void CreateZip(ZipArchiveMode mode)
{
try {
if (mode != ZipArchiveMode.Read && mode != ZipArchiveMode.Create && mode != ZipArchiveMode.Update)
@@ -103,6 +103,18 @@ namespace System.IO.Compression
if (mode == ZipArchiveMode.Update && (!stream.CanRead || !stream.CanWrite || !stream.CanSeek))
throw new ArgumentException("Stream must support reading, writing and seeking for Update archive mode");
+ // If the stream is not seekable, then buffer it into memory (same behavior as .NET).
+ if (mode == ZipArchiveMode.Read && !stream.CanSeek)
+ {
+ var memoryStream = new MemoryStream();
+ stream.CopyTo(memoryStream);
+
+ if (!leaveStreamOpen)
+ stream.Dispose();
+
+ this.stream = memoryStream;
+ }
+
try {
zipFile = mode != ZipArchiveMode.Create && stream.Length != 0
? SharpCompress.Archive.Zip.ZipArchive.Open(stream)