Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix gzip decoding when FLG.FHCRC is set #11805

Merged
merged 2 commits into from Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -388,7 +388,7 @@ private boolean readGZIPHeader(ByteBuf in) {
// fall through
case PROCESS_FHCRC:
if ((flags & FHCRC) != 0) {
if (!verifyCrc(in)) {
if (!verifyCrc16(in)) {
return false;
}
}
Expand Down Expand Up @@ -478,6 +478,25 @@ private boolean verifyCrc(ByteBuf in) {
return true;
}

private boolean verifyCrc16(ByteBuf in) {
normanmaurer marked this conversation as resolved.
Show resolved Hide resolved
if (in.readableBytes() < 2) {
return false;
}
long readCrc32 = crc.getValue();
long crc16Value = 0;
long readCrc16 = 0; // the two least significant bytes from the CRC32
for (int i = 0; i < 2; ++i) {
crc16Value |= (long) in.readUnsignedByte() << (i * 8);
readCrc16 |= ((readCrc32 >> (i * 8)) & 0xff) << (i * 8);
}

if (crc16Value != readCrc16) {
throw new DecompressionException(
"CRC16 value mismatch. Expected: " + crc16Value + ", Got: " + readCrc16);
}
return true;
}

/*
* Returns true if the cmf_flg parameter (think: first two bytes of a zlib stream)
* indicates that this is a zlib stream.
Expand Down
Expand Up @@ -133,6 +133,50 @@ public void testGZIP2() throws Exception {
}
}

@Test
public void testGZIP3() throws Exception {
byte[] bytes = "Foo".getBytes(CharsetUtil.UTF_8);
ByteBuf data = Unpooled.wrappedBuffer(bytes);
ByteBuf deflatedData = Unpooled.wrappedBuffer(
new byte[]{
31, -117, // magic number
8, // CM
2, // FLG.FHCRC
0, 0, 0, 0, // MTIME
0, // XFL
7, // OS
-66, -77, // CRC16
115, -53, -49, 7, 0, // compressed blocks
-63, 35, 62, -76, // CRC32
3, 0, 0, 0 // ISIZE
}
);

EmbeddedChannel chDecoderGZip = new EmbeddedChannel(createDecoder(ZlibWrapper.GZIP));
try {
while (deflatedData.isReadable()) {
chDecoderGZip.writeInbound(deflatedData.readRetainedSlice(1));
}
deflatedData.release();
assertTrue(chDecoderGZip.finish());
ByteBuf buf = Unpooled.buffer();
for (;;) {
ByteBuf b = chDecoderGZip.readInbound();
if (b == null) {
break;
}
buf.writeBytes(b);
b.release();
}
assertEquals(buf, data);
assertNull(chDecoderGZip.readInbound());
data.release();
buf.release();
} finally {
dispose(chDecoderGZip);
}
}

private void testCompress0(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper, ByteBuf data) throws Exception {
EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));
EmbeddedChannel chDecoderZlib = new EmbeddedChannel(createDecoder(decoderWrapper));
Expand Down