fix snappy crc32c checksum (#10048)

Motivation:

The Snappy crc32c checksum produced by SnappyFrameEncoder maybe failed to be validated on other languages snappy decoder, such as golang/snappy.

Modification: 

- make the 4-byte cast later after the mask operation. Because whether retaining the higher 4-7 bytes in a long java type will make difference in (checksum >> 15 | checksum << 17) + 0xa282ead8 result.

Result:

Checksum correctly calculated
This commit is contained in:
Ning Xie 2020-02-27 16:03:50 +08:00 committed by GitHub
parent 9b7e091b8d
commit a304d61b26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 9 deletions

View File

@ -607,7 +607,7 @@ public final class Snappy {
Crc32c crc32 = new Crc32c();
try {
crc32.update(data, offset, length);
return maskChecksum((int) crc32.getValue());
return maskChecksum(crc32.getValue());
} finally {
crc32.reset();
}
@ -655,7 +655,7 @@ public final class Snappy {
* @param checksum The actual checksum of the data
* @return The masked checksum
*/
static int maskChecksum(int checksum) {
return (checksum >> 15 | checksum << 17) + 0xa282ead8;
static int maskChecksum(long checksum) {
return (int) ((checksum >> 15 | checksum << 17) + 0xa282ead8);
}
}

View File

@ -168,7 +168,7 @@ public class SnappyFrameDecoderTest {
// checksum here is presented as a282986f (little endian)
ByteBuf in = Unpooled.wrappedBuffer(new byte[]{
(byte) 0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59,
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, -0x7e, -0x5e, 'n', 'e', 't', 't', 'y'
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, 0x2e, -0x47, 'n', 'e', 't', 't', 'y'
});
assertTrue(channel.writeInbound(in));

View File

@ -40,10 +40,9 @@ public class SnappyFrameEncoderTest {
channel.writeOutbound(in);
assertTrue(channel.finish());
ByteBuf expected = Unpooled.wrappedBuffer(new byte[] {
(byte) 0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59,
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, -0x7e, -0x5e, 'n', 'e', 't', 't', 'y'
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, 0x2e, -0x47, 'n', 'e', 't', 't', 'y'
});
ByteBuf actual = channel.readOutbound();
assertEquals(expected, actual);
@ -89,8 +88,8 @@ public class SnappyFrameEncoderTest {
ByteBuf expected = Unpooled.wrappedBuffer(new byte[] {
(byte) 0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59,
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, -0x7e, -0x5e, 'n', 'e', 't', 't', 'y',
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, -0x7e, -0x5e, 'n', 'e', 't', 't', 'y',
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, 0x2e, -0x47, 'n', 'e', 't', 't', 'y',
0x01, 0x09, 0x00, 0x00, 0x6f, -0x68, 0x2e, -0x47, 'n', 'e', 't', 't', 'y',
});
CompositeByteBuf actual = Unpooled.compositeBuffer();

View File

@ -234,7 +234,19 @@ public class SnappyTest {
ByteBuf input = Unpooled.wrappedBuffer(new byte[] {
'n', 'e', 't', 't', 'y'
});
assertEquals(maskChecksum(0xd6cb8b55), calculateChecksum(input));
assertEquals(maskChecksum(0xd6cb8b55L), calculateChecksum(input));
input.release();
}
@Test
public void testMaskChecksum() {
ByteBuf input = Unpooled.wrappedBuffer(new byte[] {
0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65,
0x61, 0x74, 0x5f,
});
assertEquals(0x44a4301f, calculateChecksum(input));
input.release();
}