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);
|
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)
|
public static SnappyCodec readHeader(InputStream in)
|
||||||
throws IOException
|
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
|
// 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");
|
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
|
// do the default uncompression
|
||||||
// (probably) compressed by Snappy.compress(byte[])
|
// (probably) compressed by Snappy.compress(byte[])
|
||||||
readFully(header, readBytes);
|
readFully(header, readBytes);
|
||||||
|
|
|
@ -204,4 +204,37 @@ public class SnappyInputStreamTest
|
||||||
|
|
||||||
assertArrayEquals(orig, uncompressed);
|
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