Issue Details (XML | Word | Printable)

Key: DNET-944
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Jiri Cincura
Reporter: tonim
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
.NET Data provider

Resize compression buffer as needed in decompression

Created: 30/Jul/20 01:24 PM   Updated: 19/Aug/20 09:10 AM
Component/s: ADO.NET Provider
Affects Version/s: 7.5.0.0
Fix Version/s: vNext

Environment: Firebird.net provider selecting rows, more frequent selecting data containing blobs, for example SELECT * FROM RDB$PROCEDURES on a database width some procedures. You can reproduce the bug easily setting the CompressionBufferSize to 8192 for example

Sub-Tasks  All   Open   

 Description  « Hide
Any environment, when selecting Compression=true in Connection string, more common selecting packetsize=32000

A big constant decompression buffer size is defined in FirebirdNetwordStream.
const int CompressionBufferSize = 1 * 1024 * 1024;

Any decompression bigger than this size throws an exception in HandleDecompression function.

I provide a tested fix, the buffer will grow dynamically, depending on the uncompressed size.

                // There is no need to define a big buffer size, it will grow as needed
const int CompressionBufferSize = 32000;



int HandleDecompression(byte[] buffer, int count)
{
_decompressor.OutputBuffer = _compressionBuffer;
_decompressor.InputBuffer = buffer;
_decompressor.NextOut = 0;
_decompressor.NextIn = 0;
_decompressor.AvailableBytesIn = count;
do
{
// Double the buffer size until the decompression fits in the output buffer
_decompressor.OutputBuffer = _compressionBuffer;
_decompressor.AvailableBytesOut = _compressionBuffer.Length - _decompressor.NextOut;
var rc = _decompressor.Inflate(Ionic.Zlib.FlushType.None);
if (rc != Ionic.Zlib.ZlibConstants.Z_OK)
throw new IOException($"Error '{rc}' while decompressing the data.");
if (_decompressor.AvailableBytesIn != 0)
{
byte[] newCompressionBuffer = new byte[_compressionBuffer.Length * 2];
Array.Copy(_compressionBuffer, newCompressionBuffer, _decompressor.NextOut);
_compressionBuffer = newCompressionBuffer;
}
} while (_decompressor.AvailableBytesIn != 0);
return _decompressor.NextOut;
}




 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
There are no subversion log entries for this issue yet.