duchien85 / kryo

Automatically exported from code.google.com/p/kryo
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

ByteArrayCompressor.compress() allocates byte array that is too short if input buffer length > 2048 #18

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
In Kryo 1.0, when ByteArrayCompressor.compress() is passed an inputBuffer 
that contains more than 2048 bytes to be compressed, it throws an 
IndexOutOfBoundsException.

Here's the code.

public void compress (ByteBuffer inputBuffer, Object object, ByteBuffer 
outputBuffer) {
    Context context = Kryo.getContext();                        // 1
    byte[] inputBytes = context.getBuffer(bufferSize).array();  // 2
    int inputLength = inputBuffer.remaining();                  // 3
    inputBuffer.get(inputBytes, 0, inputLength);                // 4
    compress(inputBytes, inputLength, outputBuffer);            // 5
}

The problem is that line 2 will normally return a byte array that is only 
2048 bytes long and line 4 will throw an exception if the 'inputBytes' 
array is shorter than 'inputLength'.

Original issue reported on code.google.com by paul.run...@gmail.com on 22 Apr 2010 at 7:45

GoogleCodeExporter commented 9 years ago
Line 2 will return a buffer size of "bufferSize" bytes. The bufferSize value 
comes
from the Compressor constructor, which is 2048 if not otherwise specified. 
Please
specify a larger buffer size for your compressor.

Compressor does not currently support automatically growing the buffer size. 
Let me
know if this is necessary and I will reopen this issue. If this were to be
implemented, it would work just like ObjectBuffer.

Original comment by nathan.s...@gmail.com on 22 Apr 2010 at 8:04

GoogleCodeExporter commented 9 years ago
The difficulty is that my code doesn't constuct or invoke the compressor 
directly.  
My code calls Kryo.writeClassAndObject(), which apparently constucts and 
invokes a 
ByteArrayCompressor within this call using the default 'bufferSize' of 2048.

Making it so that the buffer can grow like ObjectBuffer might be ultimately the 
most 
efficient option, I don't know how Kryo works well enough yet to say.  But it 
seems 
to me that since the problem with the above code is such a minor thing it would 
be 
worth fixing this in the mean time.  

Perhaps:

public void compress (ByteBuffer inputBuffer, Object object, ByteBuffer 
outputBuffer) {
  Context context = Kryo.getContext();                        
  int inputLength = inputBuffer.remaining();                   
  byte[] inputBytes = context.getBuffer(Math.max(bufferSize,inputLength)).array();
  inputBuffer.get(inputBytes, 0, inputLength);                
  compress(inputBytes, inputLength, outputBuffer);
}

Original comment by paul.run...@gmail.com on 22 Apr 2010 at 11:04

GoogleCodeExporter commented 9 years ago
Kryo will never use a compressor automatically, so someone has to be setting it 
up.

Ah, your proposed fix is a good improvement, thanks! In SVN r103.

Original comment by nathan.s...@gmail.com on 23 Apr 2010 at 6:57