From a304d61b26cb8041dd1fc8b88641226f3c32412b Mon Sep 17 00:00:00 2001 From: Ning Xie Date: Thu, 27 Feb 2020 16:03:50 +0800 Subject: [PATCH] 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 --- .../io/netty/handler/codec/compression/Snappy.java | 6 +++--- .../codec/compression/SnappyFrameDecoderTest.java | 2 +- .../codec/compression/SnappyFrameEncoderTest.java | 7 +++---- .../handler/codec/compression/SnappyTest.java | 14 +++++++++++++- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Snappy.java b/codec/src/main/java/io/netty/handler/codec/compression/Snappy.java index 9264244641..8e1825d5d2 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Snappy.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Snappy.java @@ -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); } } diff --git a/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameDecoderTest.java b/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameDecoderTest.java index 49323e9dde..6b31076fc0 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameDecoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameDecoderTest.java @@ -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)); diff --git a/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameEncoderTest.java b/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameEncoderTest.java index 7b61be151a..78a046a05a 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameEncoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/SnappyFrameEncoderTest.java @@ -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(); diff --git a/codec/src/test/java/io/netty/handler/codec/compression/SnappyTest.java b/codec/src/test/java/io/netty/handler/codec/compression/SnappyTest.java index 115deef158..1f2206a1a8 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/SnappyTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/SnappyTest.java @@ -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(); }