ironfede / openmcdf

Microsoft Compound File .net component - pure C# - netstandard 2.0
Mozilla Public License 2.0
297 stars 73 forks source link

Reading from StreamDecorator with oversized buffer fails #88

Closed aunverdorben-dap closed 1 year ago

aunverdorben-dap commented 2 years ago

Assume you have a CFStream with a length of 670 bytes. When accessing the data from the CFStream via StreamDecorator and reading from it into an oversized buffer like so

Stream readStream = cf.RootStorage.GetStream("ANewStream").AsIOStream()
var buffer = new byte[81920];
var readBytes = readStream.Read(buffer, 0, buffer.Length)

a System.ArgumentOutOfRangeException will occur.

Now, one could argue the buffer size should not exceed the length of the stream but when using .NET funcionality like Stream.CopyTo or wrapping a CompressedStream around the StreamDecorator the exception will also occur, because Stream.CopyTo and DeflateStream both work with their default buffer sizes a) for performance/IO throughput reasons and b) because they need to be able to work with non-seekable streams and even with streams with unknown length.

The Stream.Read documentation states:

Returns Int32 The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.

So it's perfectly ok to request 81920 (see example code above) but only get 670 bytes of data when there's simply not more data available.