Merge pull request #143 from xerial/fix-header-check
#142: Fix reading stream that happens to have MAGIC_HEADER[0]
This commit is contained in:
commit
1f54055894
|
@ -120,6 +120,18 @@ public class SnappyCodec
|
|||
return Arrays.equals(MAGIC_HEADER, magic);
|
||||
}
|
||||
|
||||
public static boolean hasMagicHeaderPrefix(byte[] b) {
|
||||
int limit = Math.min(MAGIC_LEN, b.length);
|
||||
int i = 0;
|
||||
while(i < limit) {
|
||||
if(b[i] != MAGIC_HEADER[i]) {
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static SnappyCodec readHeader(InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
|
|
|
@ -93,7 +93,7 @@ public class SnappyInputStream
|
|||
// Snappy produces at least 1-byte result. So the empty input is not a valid input
|
||||
throw new SnappyIOException(SnappyErrorCode.EMPTY_INPUT, "Cannot decompress empty stream");
|
||||
}
|
||||
if (readBytes < header.length || header[0] != SnappyCodec.MAGIC_HEADER[0]) {
|
||||
if (readBytes < header.length || !SnappyCodec.hasMagicHeaderPrefix(header)) {
|
||||
// do the default uncompression
|
||||
// (probably) compressed by Snappy.compress(byte[])
|
||||
readFully(header, readBytes);
|
||||
|
|
|
@ -204,4 +204,37 @@ public class SnappyInputStreamTest
|
|||
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkMagicHeader()
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
// Write uncompressed length beginning with -126 (the same with magicheader[0])
|
||||
b.write(SnappyCodec.MAGIC_HEADER[0]);
|
||||
b.write(0x01);
|
||||
// uncompressed data length = 130
|
||||
|
||||
ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||
for(int i=0; i<130; ++i) {
|
||||
data.write('A');
|
||||
}
|
||||
byte[] dataMoreThan8Len = data.toByteArray();
|
||||
|
||||
// write literal (lower 2-bit of the first tag byte is 00, upper 6-bits represents data size)
|
||||
b.write(60<<2); // 1-byte data length follows
|
||||
b.write(dataMoreThan8Len.length-1); // subsequent data length
|
||||
b.write(dataMoreThan8Len);
|
||||
|
||||
byte[] compressed = b.toByteArray();
|
||||
|
||||
// This should succeed
|
||||
assertArrayEquals(dataMoreThan8Len, Snappy.uncompress(compressed));
|
||||
|
||||
// Reproduce error in #142
|
||||
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
byte[] uncompressed = readFully(in);
|
||||
|
||||
assertArrayEquals(dataMoreThan8Len, uncompressed);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue