Merge pull request #1066 from esdrubal/bug19313
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 4 Aug 2014 16:29:43 +0000 (12:29 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 4 Aug 2014 16:29:43 +0000 (12:29 -0400)
Changed DeflateStream to stop reading base_stream sooner. Fixes #19313.

mcs/class/System/System.IO.Compression/DeflateStream.cs
mcs/class/System/Test/System.IO.Compression/DeflateStreamTest.cs

index 02c0c9f6b02dc00345ba844de459196299aae41d..1a67e39e0c7eaa4134085efecfdaaaf1fcbead7a 100644 (file)
@@ -395,24 +395,15 @@ namespace System.IO.Compression
 
                int UnmanagedRead (IntPtr buffer, int length)
                {
-                       int total = 0;
-                       int n = 1;
-                       while (length > 0 && n > 0) {
-                               if (io_buffer == null)
-                                       io_buffer = new byte [BufferSize];
+                       if (io_buffer == null)
+                               io_buffer = new byte [BufferSize];
 
-                               int count = Math.Min (length, io_buffer.Length);
-                               n = base_stream.Read (io_buffer, 0, count);
-                               if (n > 0) {
-                                       Marshal.Copy (io_buffer, 0, buffer, n);
-                                       unsafe {
-                                               buffer = new IntPtr ((byte *) buffer.ToPointer () + n);
-                                       }
-                                       length -= n;
-                                       total += n;
-                               }
-                       }
-                       return total;
+                       int count = Math.Min (length, io_buffer.Length);
+                       int n = base_stream.Read (io_buffer, 0, count);
+                       if (n > 0)
+                               Marshal.Copy (io_buffer, 0, buffer, n);
+
+                       return n;
                }
 
 #if MONOTOUCH
index 61eda5b803005e56480528082438e0396f555563..84cc1c419ae3565eb10b3b2231f0101730c811e6 100644 (file)
@@ -297,6 +297,35 @@ namespace MonoTests.System.IO.Compression
                                }
                        }
                }
+               
+               class Bug19313Stream : MemoryStream
+               {
+                       public Bug19313Stream (byte [] buffer)
+                               : base (buffer)
+                       {
+                       }
+
+                       public override int Read (byte [] buffer, int offset, int count)
+                       {
+                               // Thread was blocking when DeflateStream uses a NetworkStream.
+                               // Because the NetworkStream.Read calls Socket.Receive that
+                               // blocks the thread waiting for at least a byte to return.
+                               // This assert guarantees that Read is called only when there 
+                               // is something to be read.
+                               Assert.IsTrue (Position < Length, "Trying to read empty stream.");
+
+                               return base.Read (buffer, offset, count);
+                       }
+               }
+
+               [Test]
+               public void Bug19313 ()
+               {
+                       byte [] buffer  = new byte [512];
+                       using (var backing = new Bug19313Stream (compressed_data))
+                       using (var decompressing = new DeflateStream (backing, CompressionMode.Decompress))
+                               decompressing.Read (buffer, 0, buffer.Length);
+               }
        }
 }