summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-03-06 22:44:32 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-03-06 22:44:32 +0700
commit44844b4c0e0df30a72f1659b9904749f456f2545 (patch)
treed727163d1ff7d8126c640b4263aed0f041de1e8e
parentUse Id instead of ToString (diff)
downloadBouncyCastle.NET-ed25519-44844b4c0e0df30a72f1659b9904749f456f2545.tar.xz
Support leaveOpen in decompressors
-rw-r--r--crypto/src/util/bzip2/CBZip2InputStream.cs46
-rw-r--r--crypto/src/util/bzip2/CBZip2OutputStream.cs22
-rw-r--r--crypto/src/util/io/compression/Bzip2.cs6
-rw-r--r--crypto/src/util/io/compression/ZLib.cs8
-rw-r--r--crypto/src/util/io/compression/Zip.cs8
-rw-r--r--crypto/src/util/zlib/ZInputStream.cs57
-rw-r--r--crypto/src/util/zlib/ZOutputStream.cs57
7 files changed, 141 insertions, 63 deletions
diff --git a/crypto/src/util/bzip2/CBZip2InputStream.cs b/crypto/src/util/bzip2/CBZip2InputStream.cs
index 08760f547..be085c517 100644
--- a/crypto/src/util/bzip2/CBZip2InputStream.cs
+++ b/crypto/src/util/bzip2/CBZip2InputStream.cs
@@ -193,7 +193,7 @@ namespace Org.BouncyCastle.Utilities.Bzip2
                 if (m_expectedStreamCrc != m_streamCrc)
                     throw new IOException("Stream CRC error");
 
-                BsFinishedWithStream();
+                // TODO If not a LeaveOpen stream, should we check that we are at the end of stream here?
                 streamEnd = true;
                 return;
             }
@@ -252,19 +252,33 @@ namespace Org.BouncyCastle.Utilities.Bzip2
             m_streamCrc = Integers.RotateLeft(m_streamCrc, 1) ^ blockFinalCrc;
         }
 
-        private void BsFinishedWithStream()
+        protected void Detach(bool disposing)
         {
-            try
+            if (disposing)
             {
-                if (this.bsStream != null)
+                ImplDisposing(disposeInput: false);
+            }
+            base.Dispose(disposing);
+        }
+
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                ImplDisposing(disposeInput: true);
+            }
+            base.Dispose(disposing);
+        }
+
+        private void ImplDisposing(bool disposeInput)
+        {
+            if (this.bsStream != null)
+            {
+                if (disposeInput)
                 {
                     this.bsStream.Dispose();
-                    this.bsStream = null;
                 }
-            }
-            catch
-            {
-                //ignore
+                this.bsStream = null;
             }
         }
 
@@ -806,4 +820,18 @@ namespace Org.BouncyCastle.Utilities.Bzip2
             return a;
         }
     }
+
+    public class CBZip2InputStreamLeaveOpen
+        : CBZip2InputStream
+    {
+        public CBZip2InputStreamLeaveOpen(Stream outStream)
+            : base(outStream)
+        {
+        }
+
+        protected override void Dispose(bool disposing)
+        {
+            Detach(disposing);
+        }
+    }
 }
diff --git a/crypto/src/util/bzip2/CBZip2OutputStream.cs b/crypto/src/util/bzip2/CBZip2OutputStream.cs
index d1400c7c4..10b76c677 100644
--- a/crypto/src/util/bzip2/CBZip2OutputStream.cs
+++ b/crypto/src/util/bzip2/CBZip2OutputStream.cs
@@ -424,11 +424,7 @@ namespace Org.BouncyCastle.Utilities.Bzip2
         {
             if (disposing)
             {
-                if (!closed)
-                {
-                    Finish();
-                    closed = true;
-                }
+                ImplDisposing(disposeOutput: false);
             }
             base.Dispose(disposing);
         }
@@ -437,14 +433,22 @@ namespace Org.BouncyCastle.Utilities.Bzip2
         {
             if (disposing)
             {
-                if (!closed)
+                ImplDisposing(disposeOutput: true);
+            }
+            base.Dispose(disposing);
+        }
+
+        private void ImplDisposing(bool disposeOutput)
+        {
+            if (!closed)
+            {
+                Finish();
+                closed = true;
+                if (disposeOutput)
                 {
-                    Finish();
-                    closed = true;
                     this.bsStream.Dispose();
                 }
             }
-            base.Dispose(disposing);
         }
 
         public void Finish()
diff --git a/crypto/src/util/io/compression/Bzip2.cs b/crypto/src/util/io/compression/Bzip2.cs
index 72b006dc9..cf84923a2 100644
--- a/crypto/src/util/io/compression/Bzip2.cs
+++ b/crypto/src/util/io/compression/Bzip2.cs
@@ -13,9 +13,11 @@ namespace Org.BouncyCastle.Utilities.IO.Compression
                 :   new Impl.CBZip2OutputStream(stream);
         }
 
-        internal static Stream DecompressInput(Stream stream)
+        internal static Stream DecompressInput(Stream stream, bool leaveOpen = false)
         {
-            return new Impl.CBZip2InputStream(stream);
+            return leaveOpen
+                ?   new Impl.CBZip2InputStreamLeaveOpen(stream)
+                :   new Impl.CBZip2InputStream(stream);
         }
     }
 }
diff --git a/crypto/src/util/io/compression/ZLib.cs b/crypto/src/util/io/compression/ZLib.cs
index 1254da012..b44d1106f 100644
--- a/crypto/src/util/io/compression/ZLib.cs
+++ b/crypto/src/util/io/compression/ZLib.cs
@@ -21,12 +21,14 @@ namespace Org.BouncyCastle.Utilities.IO.Compression
 #endif
         }
 
-        internal static Stream DecompressInput(Stream stream)
+        internal static Stream DecompressInput(Stream stream, bool leaveOpen = false)
         {
 #if NET6_0_OR_GREATER
-            return new ZLibStream(stream, CompressionMode.Decompress, leaveOpen: false);
+            return new ZLibStream(stream, CompressionMode.Decompress, leaveOpen);
 #else
-            return new ZInputStream(stream);
+            return leaveOpen
+                ?   new ZInputStreamLeaveOpen(stream)
+                :   new ZInputStream(stream);
 #endif
         }
 
diff --git a/crypto/src/util/io/compression/Zip.cs b/crypto/src/util/io/compression/Zip.cs
index f2773d63b..e5907c60d 100644
--- a/crypto/src/util/io/compression/Zip.cs
+++ b/crypto/src/util/io/compression/Zip.cs
@@ -21,12 +21,14 @@ namespace Org.BouncyCastle.Utilities.IO.Compression
 #endif
         }
 
-        internal static Stream DecompressInput(Stream stream)
+        internal static Stream DecompressInput(Stream stream, bool leaveOpen = false)
         {
 #if NET6_0_OR_GREATER
-            return new DeflateStream(stream, CompressionMode.Decompress, leaveOpen: false);
+            return new DeflateStream(stream, CompressionMode.Decompress, leaveOpen);
 #else
-            return new ZInputStream(stream, true);
+            return leaveOpen
+                ? new ZInputStreamLeaveOpen(stream, true)
+                : new ZInputStream(stream, true);
 #endif
         }
     }
diff --git a/crypto/src/util/zlib/ZInputStream.cs b/crypto/src/util/zlib/ZInputStream.cs
index de1c27202..67b30a3ec 100644
--- a/crypto/src/util/zlib/ZInputStream.cs
+++ b/crypto/src/util/zlib/ZInputStream.cs
@@ -116,17 +116,34 @@ namespace Org.BouncyCastle.Utilities.Zlib
             this.z.avail_in = 0;
         }
 
+        protected void Detach(bool disposing)
+        {
+            if (disposing)
+            {
+                ImplDisposing(disposeInput: false);
+            }
+            base.Dispose(disposing);
+        }
+
         protected override void Dispose(bool disposing)
         {
             if (disposing)
             {
-			    if (!closed)
+                ImplDisposing(disposeInput: true);
+            }
+            base.Dispose(disposing);
+        }
+
+        private void ImplDisposing(bool disposeInput)
+        {
+            if (!closed)
+            {
+                closed = true;
+                if (disposeInput)
                 {
-                    closed = true;
                     input.Dispose();
                 }
             }
-            base.Dispose(disposing);
         }
 
         public virtual int FlushMode
@@ -205,4 +222,38 @@ namespace Org.BouncyCastle.Utilities.Zlib
             get { return z.total_out; }
         }
     }
+
+    public class ZInputStreamLeaveOpen
+        : ZInputStream
+    {
+        public ZInputStreamLeaveOpen(Stream input)
+            : base(input)
+        {
+        }
+
+        public ZInputStreamLeaveOpen(Stream input, bool nowrap)
+            : base(input, nowrap)
+        {
+        }
+
+        public ZInputStreamLeaveOpen(Stream input, ZStream z)
+            : base(input, z)
+        {
+        }
+
+        public ZInputStreamLeaveOpen(Stream input, int level)
+            : base(input, level)
+        {
+        }
+
+        public ZInputStreamLeaveOpen(Stream input, int level, bool nowrap)
+            : base(input, level, nowrap)
+        {
+        }
+
+        protected override void Dispose(bool disposing)
+        {
+            Detach(disposing);
+        }
+    }
 }
diff --git a/crypto/src/util/zlib/ZOutputStream.cs b/crypto/src/util/zlib/ZOutputStream.cs
index ecf33cddf..04b7bb8e5 100644
--- a/crypto/src/util/zlib/ZOutputStream.cs
+++ b/crypto/src/util/zlib/ZOutputStream.cs
@@ -113,26 +113,7 @@ namespace Org.BouncyCastle.Utilities.Zlib
         {
             if (disposing)
             {
-                if (!closed)
-                {
-                    try
-                    {
-                        try
-                        {
-                            Finish();
-                        }
-                        catch (IOException)
-                        {
-                            // Ignore
-                        }
-                    }
-                    finally
-                    {
-                        this.closed = true;
-                        End();
-                        output = null;
-                    }
-                }
+                ImplDisposing(disposeOutput: false);
             }
             base.Dispose(disposing);
         }
@@ -141,29 +122,37 @@ namespace Org.BouncyCastle.Utilities.Zlib
         {
             if (disposing)
             {
-			    if (!closed)
+                ImplDisposing(disposeOutput: true);
+            }
+            base.Dispose(disposing);
+        }
+
+        private void ImplDisposing(bool disposeOutput)
+        {
+            if (!closed)
+            {
+                try
                 {
                     try
                     {
-                        try
-                        {
-                            Finish();
-                        }
-                        catch (IOException)
-                        {
-                            // Ignore
-                        }
+                        Finish();
                     }
-                    finally
+                    catch (IOException)
+                    {
+                        // Ignore
+                    }
+                }
+                finally
+                {
+                    this.closed = true;
+                    End();
+                    if (disposeOutput)
                     {
-                        this.closed = true;
-                        End();
                         output.Dispose();
-                        output = null;
                     }
+                    output = null;
                 }
             }
-            base.Dispose(disposing);
         }
 
         public virtual void End()