diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-05-23 22:44:57 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-05-23 22:44:57 +0700 |
commit | 98b3ce6512812cd1d91c60ca0e69d69c32838d8e (patch) | |
tree | 8af69c097b389fe494e97401f7808590314a5b6b /crypto/src/util | |
parent | Add ValidateBufferArguments (diff) | |
download | BouncyCastle.NET-ed25519-98b3ce6512812cd1d91c60ca0e69d69c32838d8e.tar.xz |
Work on Stream classes
- consistent naming, ordering - CanRead/Seek/Write fixes - argument validation - some cases of blocking zero-byte Read calls
Diffstat (limited to 'crypto/src/util')
-rw-r--r-- | crypto/src/util/io/BaseInputStream.cs | 43 | ||||
-rw-r--r-- | crypto/src/util/io/BaseOutputStream.cs | 53 | ||||
-rw-r--r-- | crypto/src/util/io/NullOutputStream.cs | 7 | ||||
-rw-r--r-- | crypto/src/util/io/PushbackStream.cs | 24 | ||||
-rw-r--r-- | crypto/src/util/io/TeeInputStream.cs | 6 | ||||
-rw-r--r-- | crypto/src/util/io/TeeOutputStream.cs | 6 | ||||
-rw-r--r-- | crypto/src/util/zlib/ZInputStream.cs | 246 | ||||
-rw-r--r-- | crypto/src/util/zlib/ZOutputStream.cs | 272 |
8 files changed, 297 insertions, 360 deletions
diff --git a/crypto/src/util/io/BaseInputStream.cs b/crypto/src/util/io/BaseInputStream.cs index a5613d801..ebe256632 100644 --- a/crypto/src/util/io/BaseInputStream.cs +++ b/crypto/src/util/io/BaseInputStream.cs @@ -1,34 +1,15 @@ using System; -using System.Diagnostics; using System.IO; namespace Org.BouncyCastle.Utilities.IO { - public abstract class BaseInputStream : Stream + public abstract class BaseInputStream + : Stream { - private bool closed; - - public sealed override bool CanRead { get { return !closed; } } + public sealed override bool CanRead { get { return true; } } public sealed override bool CanSeek { get { return false; } } public sealed override bool CanWrite { get { return false; } } -#if PORTABLE - protected override void Dispose(bool disposing) - { - if (disposing) - { - closed = true; - } - base.Dispose(disposing); - } -#else - public override void Close() - { - closed = true; - base.Close(); - } -#endif - public sealed override void Flush() {} public sealed override long Length { get { throw new NotSupportedException(); } } public sealed override long Position @@ -39,22 +20,26 @@ namespace Org.BouncyCastle.Utilities.IO public override int Read(byte[] buffer, int offset, int count) { - int pos = offset; + Streams.ValidateBufferArguments(buffer, offset, count); + + int pos = 0; try { - int end = offset + count; - while (pos < end) + while (pos < count) { int b = ReadByte(); - if (b == -1) break; - buffer[pos++] = (byte) b; + if (b < 0) + break; + + buffer[offset + pos++] = (byte)b; } } catch (IOException) { - if (pos == offset) throw; + if (pos == 0) + throw; } - return pos - offset; + return pos; } public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } diff --git a/crypto/src/util/io/BaseOutputStream.cs b/crypto/src/util/io/BaseOutputStream.cs index 0dbe821de..d9a5b92d6 100644 --- a/crypto/src/util/io/BaseOutputStream.cs +++ b/crypto/src/util/io/BaseOutputStream.cs @@ -1,35 +1,16 @@ using System; -using System.Diagnostics; using System.IO; namespace Org.BouncyCastle.Utilities.IO { - public abstract class BaseOutputStream : Stream + public abstract class BaseOutputStream + : Stream { - private bool closed; - - public sealed override bool CanRead { get { return false; } } + public sealed override bool CanRead { get { return false; } } public sealed override bool CanSeek { get { return false; } } - public sealed override bool CanWrite { get { return !closed; } } - -#if PORTABLE - protected override void Dispose(bool disposing) - { - if (disposing) - { - closed = true; - } - base.Dispose(disposing); - } -#else - public override void Close() - { - closed = true; - base.Close(); - } -#endif + public sealed override bool CanWrite { get { return true; } } - public override void Flush() { } + public override void Flush() {} public sealed override long Length { get { throw new NotSupportedException(); } } public sealed override long Position { @@ -42,28 +23,22 @@ namespace Org.BouncyCastle.Utilities.IO public override void Write(byte[] buffer, int offset, int count) { - Debug.Assert(buffer != null); - Debug.Assert(0 <= offset && offset <= buffer.Length); - Debug.Assert(count >= 0); - - int end = offset + count; + Streams.ValidateBufferArguments(buffer, offset, count); - Debug.Assert(0 <= end && end <= buffer.Length); - - for (int i = offset; i < end; ++i) + for (int i = 0; i < count; ++i) { - this.WriteByte(buffer[i]); + WriteByte(buffer[offset + i]); } } - public virtual void Write(params byte[] buffer) - { - Write(buffer, 0, buffer.Length); - } + public virtual void Write(params byte[] buffer) + { + Write(buffer, 0, buffer.Length); + } - public override void WriteByte(byte b) + public override void WriteByte(byte value) { - Write(new byte[]{ b }, 0, 1); + Write(new byte[]{ value }, 0, 1); } } } diff --git a/crypto/src/util/io/NullOutputStream.cs b/crypto/src/util/io/NullOutputStream.cs index 13877fa13..c435549d2 100644 --- a/crypto/src/util/io/NullOutputStream.cs +++ b/crypto/src/util/io/NullOutputStream.cs @@ -5,14 +5,13 @@ namespace Org.BouncyCastle.Utilities.IO internal class NullOutputStream : BaseOutputStream { - public override void WriteByte(byte b) + public override void Write(byte[] buffer, int offset, int count) { - // do nothing + Streams.ValidateBufferArguments(buffer, offset, count); } - public override void Write(byte[] buffer, int offset, int count) + public override void WriteByte(byte value) { - // do nothing } } } diff --git a/crypto/src/util/io/PushbackStream.cs b/crypto/src/util/io/PushbackStream.cs index d51e195ca..2ceb64361 100644 --- a/crypto/src/util/io/PushbackStream.cs +++ b/crypto/src/util/io/PushbackStream.cs @@ -13,31 +13,33 @@ namespace Org.BouncyCastle.Utilities.IO { } - public override int ReadByte() + public override int Read(byte[] buffer, int offset, int count) { + Streams.ValidateBufferArguments(buffer, offset, count); + if (m_buf != -1) { - int tmp = m_buf; + if (count < 1) + return 0; + + buffer[offset] = (byte)m_buf; m_buf = -1; - return tmp; + return 1; } - return base.ReadByte(); + return base.Read(buffer, offset, count); } - public override int Read(byte[] buffer, int offset, int count) + public override int ReadByte() { - if (count < 1) - return 0; - if (m_buf != -1) { - buffer[offset] = (byte)m_buf; + int tmp = m_buf; m_buf = -1; - return 1; + return tmp; } - return base.Read(buffer, offset, count); + return base.ReadByte(); } public virtual void Unread(int b) diff --git a/crypto/src/util/io/TeeInputStream.cs b/crypto/src/util/io/TeeInputStream.cs index 6996f3fbb..73ea8fed0 100644 --- a/crypto/src/util/io/TeeInputStream.cs +++ b/crypto/src/util/io/TeeInputStream.cs @@ -37,13 +37,13 @@ namespace Org.BouncyCastle.Utilities.IO } #endif - public override int Read(byte[] buf, int off, int len) + public override int Read(byte[] buffer, int offset, int count) { - int i = input.Read(buf, off, len); + int i = input.Read(buffer, offset, count); if (i > 0) { - tee.Write(buf, off, i); + tee.Write(buffer, offset, i); } return i; diff --git a/crypto/src/util/io/TeeOutputStream.cs b/crypto/src/util/io/TeeOutputStream.cs index a6c7fd5b5..5f447b18b 100644 --- a/crypto/src/util/io/TeeOutputStream.cs +++ b/crypto/src/util/io/TeeOutputStream.cs @@ -43,10 +43,10 @@ namespace Org.BouncyCastle.Utilities.IO tee.Write(buffer, offset, count); } - public override void WriteByte(byte b) + public override void WriteByte(byte value) { - output.WriteByte(b); - tee.WriteByte(b); + output.WriteByte(value); + tee.WriteByte(value); } } } diff --git a/crypto/src/util/zlib/ZInputStream.cs b/crypto/src/util/zlib/ZInputStream.cs index ea803fa4f..3e6fcc1be 100644 --- a/crypto/src/util/zlib/ZInputStream.cs +++ b/crypto/src/util/zlib/ZInputStream.cs @@ -37,11 +37,13 @@ using System; using System.Diagnostics; using System.IO; +using Org.BouncyCastle.Utilities.IO; + namespace Org.BouncyCastle.Utilities.Zlib { - public class ZInputStream - : Stream - { + public class ZInputStream + : BaseInputStream + { private static ZStream GetDefaultZStream(bool nowrap) { ZStream z = new ZStream(); @@ -51,32 +53,32 @@ namespace Org.BouncyCastle.Utilities.Zlib private const int BufferSize = 4096; - protected ZStream z; - protected int flushLevel = JZlib.Z_NO_FLUSH; - // TODO Allow custom buf - protected byte[] buf = new byte[BufferSize]; - protected byte[] buf1 = new byte[1]; - protected bool compress; + protected ZStream z; + protected int flushLevel = JZlib.Z_NO_FLUSH; + // TODO Allow custom buf + protected byte[] buf = new byte[BufferSize]; + protected byte[] buf1 = new byte[1]; + protected bool compress; - protected Stream input; - protected bool closed; + protected Stream input; + protected bool closed; - private bool nomoreinput = false; + private bool nomoreinput = false; - public ZInputStream(Stream input) - : this(input, false) - { - } + public ZInputStream(Stream input) + : this(input, false) + { + } - public ZInputStream(Stream input, bool nowrap) + public ZInputStream(Stream input, bool nowrap) : this(input, GetDefaultZStream(nowrap)) - { - } + { + } public ZInputStream(Stream input, ZStream z) - : base() - { - Debug.Assert(input.CanRead); + : base() + { + Debug.Assert(input.CanRead); if (z == null) { @@ -92,36 +94,32 @@ namespace Org.BouncyCastle.Utilities.Zlib this.compress = (z.istate == null); this.z = z; this.z.next_in = buf; - this.z.next_in_index = 0; - this.z.avail_in = 0; - } + this.z.next_in_index = 0; + this.z.avail_in = 0; + } public ZInputStream(Stream input, int level) : this(input, level, false) - { + { } public ZInputStream(Stream input, int level, bool nowrap) - { - Debug.Assert(input.CanRead); - - this.input = input; + { + Debug.Assert(input.CanRead); + + this.input = input; this.compress = true; this.z = new ZStream(); - this.z.deflateInit(level, nowrap); - this.z.next_in = buf; - this.z.next_in_index = 0; - this.z.avail_in = 0; - } + this.z.deflateInit(level, nowrap); + this.z.next_in = buf; + this.z.next_in_index = 0; + this.z.avail_in = 0; + } - /*public int available() throws IOException { + /*public int available() throws IOException { return inf.finished() ? 0 : 1; }*/ - public sealed override bool CanRead { get { return !closed; } } - public sealed override bool CanSeek { get { return false; } } - public sealed override bool CanWrite { get { return false; } } - #if PORTABLE protected override void Dispose(bool disposing) { @@ -137,102 +135,90 @@ namespace Org.BouncyCastle.Utilities.Zlib } #else public override void Close() - { + { if (closed) return; closed = true; Platform.Dispose(input); base.Close(); - } + } #endif - public sealed override void Flush() {} - - public virtual int FlushMode - { - get { return flushLevel; } - set { this.flushLevel = value; } - } - - public sealed override long Length { get { throw new NotSupportedException(); } } - public sealed override long Position - { - get { throw new NotSupportedException(); } - set { throw new NotSupportedException(); } - } - - public override int Read(byte[] b, int off, int len) - { - if (len==0) - return 0; - - z.next_out = b; - z.next_out_index = off; - z.avail_out = len; - - int err; - do - { - if (z.avail_in == 0 && !nomoreinput) - { - // if buffer is empty and more input is available, refill it - z.next_in_index = 0; - z.avail_in = input.Read(buf, 0, buf.Length); //(bufsize<z.avail_out ? bufsize : z.avail_out)); - - if (z.avail_in <= 0) - { - z.avail_in = 0; - nomoreinput = true; - } - } - - err = compress - ? z.deflate(flushLevel) - : z.inflate(flushLevel); - - if (nomoreinput && err == JZlib.Z_BUF_ERROR) - return 0; - if (err != JZlib.Z_OK && err != JZlib.Z_STREAM_END) - // TODO -// throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); - throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); - if ((nomoreinput || err == JZlib.Z_STREAM_END) && z.avail_out == len) - return 0; - } - while(z.avail_out == len && err == JZlib.Z_OK); - //Console.Error.WriteLine("("+(len-z.avail_out)+")"); - return len - z.avail_out; - } - - public override int ReadByte() - { - if (Read(buf1, 0, 1) <= 0) - return -1; - return buf1[0]; - } - -// public long skip(long n) throws IOException { -// int len=512; -// if(n<len) -// len=(int)n; -// byte[] tmp=new byte[len]; -// return((long)read(tmp)); -// } - - public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } - public sealed override void SetLength(long value) { throw new NotSupportedException(); } - - public virtual long TotalIn - { - get { return z.total_in; } - } - - public virtual long TotalOut - { - get { return z.total_out; } - } - - public sealed override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } - } + public virtual int FlushMode + { + get { return flushLevel; } + set { this.flushLevel = value; } + } + + public override int Read(byte[] buffer, int offset, int count) + { + Streams.ValidateBufferArguments(buffer, offset, count); + + if (count == 0) + return 0; + + z.next_out = buffer; + z.next_out_index = offset; + z.avail_out = count; + + int err; + do + { + if (z.avail_in == 0 && !nomoreinput) + { + // if buffer is empty and more input is available, refill it + z.next_in_index = 0; + z.avail_in = input.Read(buf, 0, buf.Length); //(bufsize<z.avail_out ? bufsize : z.avail_out)); + + if (z.avail_in <= 0) + { + z.avail_in = 0; + nomoreinput = true; + } + } + + err = compress + ? z.deflate(flushLevel) + : z.inflate(flushLevel); + + if (nomoreinput && err == JZlib.Z_BUF_ERROR) + return 0; + if (err != JZlib.Z_OK && err != JZlib.Z_STREAM_END) + // TODO + //throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); + throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); + if ((nomoreinput || err == JZlib.Z_STREAM_END) && z.avail_out == count) + return 0; + } + while (z.avail_out == count && err == JZlib.Z_OK); + //Console.Error.WriteLine("("+(len-z.avail_out)+")"); + return count - z.avail_out; + } + + public override int ReadByte() + { + if (Read(buf1, 0, 1) <= 0) + return -1; + return buf1[0]; + } + + // public long skip(long n) throws IOException { + // int len=512; + // if(n<len) + // len=(int)n; + // byte[] tmp=new byte[len]; + // return((long)read(tmp)); + // } + + public virtual long TotalIn + { + get { return z.total_in; } + } + + public virtual long TotalOut + { + get { return z.total_out; } + } + } } diff --git a/crypto/src/util/zlib/ZOutputStream.cs b/crypto/src/util/zlib/ZOutputStream.cs index a1482a07f..dcb93f97b 100644 --- a/crypto/src/util/zlib/ZOutputStream.cs +++ b/crypto/src/util/zlib/ZOutputStream.cs @@ -37,11 +37,13 @@ using System; using System.Diagnostics; using System.IO; +using Org.BouncyCastle.Utilities.IO; + namespace Org.BouncyCastle.Utilities.Zlib { - public class ZOutputStream - : Stream - { + public class ZOutputStream + : BaseOutputStream + { private static ZStream GetDefaultZStream(bool nowrap) { ZStream z = new ZStream(); @@ -51,30 +53,30 @@ namespace Org.BouncyCastle.Utilities.Zlib private const int BufferSize = 4096; - protected ZStream z; - protected int flushLevel = JZlib.Z_NO_FLUSH; - // TODO Allow custom buf - protected byte[] buf = new byte[BufferSize]; - protected byte[] buf1 = new byte[1]; - protected bool compress; + protected ZStream z; + protected int flushLevel = JZlib.Z_NO_FLUSH; + // TODO Allow custom buf + protected byte[] buf = new byte[BufferSize]; + protected byte[] buf1 = new byte[1]; + protected bool compress; - protected Stream output; - protected bool closed; + protected Stream output; + protected bool closed; public ZOutputStream(Stream output) : this(output, false) - { - } + { + } public ZOutputStream(Stream output, bool nowrap) : this(output, GetDefaultZStream(nowrap)) - { - } + { + } public ZOutputStream(Stream output, ZStream z) - : base() - { - Debug.Assert(output.CanWrite); + : base() + { + Debug.Assert(output.CanWrite); if (z == null) { @@ -89,27 +91,23 @@ namespace Org.BouncyCastle.Utilities.Zlib this.output = output; this.compress = (z.istate == null); this.z = z; - } + } public ZOutputStream(Stream output, int level) - : this(output, level, false) - { - } + : this(output, level, false) + { + } - public ZOutputStream(Stream output, int level, bool nowrap) - : base() - { - Debug.Assert(output.CanWrite); + public ZOutputStream(Stream output, int level, bool nowrap) + : base() + { + Debug.Assert(output.CanWrite); - this.output = output; + this.output = output; this.compress = true; this.z = new ZStream(); - this.z.deflateInit(level, nowrap); - } - - public sealed override bool CanRead { get { return false; } } - public sealed override bool CanSeek { get { return false; } } - public sealed override bool CanWrite { get { return !closed; } } + this.z.deflateInit(level, nowrap); + } #if PORTABLE protected override void Dispose(bool disposing) @@ -124,14 +122,14 @@ namespace Org.BouncyCastle.Utilities.Zlib base.Dispose(disposing); } #else - public override void Close() - { - if (closed) - return; + public override void Close() + { + if (closed) + return; DoClose(); base.Close(); - } + } #endif private void DoClose() @@ -157,109 +155,101 @@ namespace Org.BouncyCastle.Utilities.Zlib } public virtual void End() - { - if (z == null) - return; - if (compress) - z.deflateEnd(); - else - z.inflateEnd(); - z.free(); - z = null; - } - - public virtual void Finish() - { - do - { - z.next_out = buf; - z.next_out_index = 0; - z.avail_out = buf.Length; - - int err = compress - ? z.deflate(JZlib.Z_FINISH) - : z.inflate(JZlib.Z_FINISH); - - if (err != JZlib.Z_STREAM_END && err != JZlib.Z_OK) - // TODO -// throw new ZStreamException((compress?"de":"in")+"flating: "+z.msg); - throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); - - int count = buf.Length - z.avail_out; - if (count > 0) - { - output.Write(buf, 0, count); - } - } - while (z.avail_in > 0 || z.avail_out == 0); - - Flush(); - } - - public override void Flush() - { - output.Flush(); - } - - public virtual int FlushMode - { - get { return flushLevel; } - set { this.flushLevel = value; } - } - - public sealed override long Length { get { throw new NotSupportedException(); } } - public sealed override long Position { - get { throw new NotSupportedException(); } - set { throw new NotSupportedException(); } + if (z == null) + return; + if (compress) + z.deflateEnd(); + else + z.inflateEnd(); + z.free(); + z = null; + } + + public virtual void Finish() + { + do + { + z.next_out = buf; + z.next_out_index = 0; + z.avail_out = buf.Length; + + int err = compress + ? z.deflate(JZlib.Z_FINISH) + : z.inflate(JZlib.Z_FINISH); + + if (err != JZlib.Z_STREAM_END && err != JZlib.Z_OK) + // TODO + //throw new ZStreamException((compress?"de":"in")+"flating: "+z.msg); + throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); + + int count = buf.Length - z.avail_out; + if (count > 0) + { + output.Write(buf, 0, count); + } + } + while (z.avail_in > 0 || z.avail_out == 0); + + Flush(); + } + + public override void Flush() + { + output.Flush(); + } + + public virtual int FlushMode + { + get { return flushLevel; } + set { this.flushLevel = value; } + } + + public virtual long TotalIn + { + get { return z.total_in; } + } + + public virtual long TotalOut + { + get { return z.total_out; } + } + + public override void Write(byte[] buffer, int offset, int count) + { + Streams.ValidateBufferArguments(buffer, offset, count); + + if (count == 0) + return; + + z.next_in = buffer; + z.next_in_index = offset; + z.avail_in = count; + + do + { + z.next_out = buf; + z.next_out_index = 0; + z.avail_out = buf.Length; + + int err = compress + ? z.deflate(flushLevel) + : z.inflate(flushLevel); + + if (err != JZlib.Z_OK) + // TODO + //throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); + throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); + + output.Write(buf, 0, buf.Length - z.avail_out); + } + while (z.avail_in > 0 || z.avail_out == 0); + } + + public override void WriteByte(byte value) + { + buf1[0] = value; + Write(buf1, 0, 1); } - public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } - public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } - public sealed override void SetLength(long value) { throw new NotSupportedException(); } - - public virtual long TotalIn - { - get { return z.total_in; } - } - - public virtual long TotalOut - { - get { return z.total_out; } - } - - public override void Write(byte[] b, int off, int len) - { - if (len == 0) - return; - - z.next_in = b; - z.next_in_index = off; - z.avail_in = len; - - do - { - z.next_out = buf; - z.next_out_index = 0; - z.avail_out = buf.Length; - - int err = compress - ? z.deflate(flushLevel) - : z.inflate(flushLevel); - - if (err != JZlib.Z_OK) - // TODO -// throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); - throw new IOException((compress ? "de" : "in") + "flating: " + z.msg); - - output.Write(buf, 0, buf.Length - z.avail_out); - } - while (z.avail_in > 0 || z.avail_out == 0); - } - - public override void WriteByte(byte b) - { - buf1[0] = b; - Write(buf1, 0, 1); - } - } + } } |