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 a3c3caaf5b..97045769ce 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 @@ -96,7 +96,7 @@ public class Snappy { in.readerIndex(in.readerIndex() + matched); insertTail = inIndex - 1; nextEmit = inIndex; - if (inIndex >= maxIndex) { + if (inIndex >= maxIndex - 4) { break outer; } diff --git a/codec/src/test/java/io/netty/handler/codec/compression/SnappyFramedEncoderTest.java b/codec/src/test/java/io/netty/handler/codec/compression/SnappyFramedEncoderTest.java index 0cfe810355..f8cd4c1225 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/SnappyFramedEncoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/SnappyFramedEncoderTest.java @@ -81,4 +81,51 @@ public class SnappyFramedEncoderTest { }; assertArrayEquals(expected, out.array()); } + + /** + * This test asserts that if we have a remainder after emitting a copy that + * is less than 4 bytes (ie. the minimum required for a copy), we should + * emit a literal rather than trying to see if we can emit another copy. + */ + @Test + public void testInputBufferOverseek() throws Exception { + ByteBuf in = Unpooled.wrappedBuffer(new byte[] { + 11, 0, // literal + 0, 0, 0, 0, // 1st copy + 16, 65, 96, 119, -22, 79, -43, 76, -75, -93, + 11, 104, 96, -99, 126, -98, 27, -36, 40, 117, + -65, -3, -57, -83, -58, 7, 114, -14, 68, -122, + 124, 88, 118, 54, 45, -26, 117, 13, -45, -9, + 60, -73, -53, -44, 53, 68, -77, -71, 109, 43, + -38, 59, 100, -12, -87, 44, -106, 123, -107, 38, + 13, -117, -23, -49, 29, 21, 26, 66, 1, -1, + -1, // literal + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, // 2nd copy + 66, 0, -104, -49, 16, -120, 22, 8, -52, -54, + -102, -52, -119, -124, -92, -71, 101, -120, -52, -48, + 45, -26, -24, 26, 41, -13, 36, 64, -47, 15, + -124, -7, -16, 91, 96, 0, -93, -42, 101, 20, + -74, 39, -124, 35, 43, -49, -21, -92, -20, -41, + 79, 41, 110, -105, 42, -96, 90, -9, -100, -22, + -62, 91, 2, 35, 113, 117, -71, 66, 1, // literal + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, // copy + -1, 1 // remainder + }); + + ByteBuf out = Unpooled.buffer(274); + + encoder.encode(null, in, out); + } }