Repository: netty/netty
Issue: Snappy.java's  decodeLiteral method implemention

``` java
    private static int decodeLiteral(byte tag, ByteBuf in, ByteBuf out) {
        in.markReaderIndex();
        int length;
        switch(tag >> 2 & 0x3F) {
        case 60:
            if (!in.isReadable()) {
                return NOT_ENOUGH_INPUT;
            }
            length = in.readUnsignedByte();
            break;
        case 61:
            if (in.readableBytes() < 2) {
                return NOT_ENOUGH_INPUT;
            }
            length = ByteBufUtil.swapShort(in.readShort());
            break;
        case 62:
            if (in.readableBytes() < 3) {
                return NOT_ENOUGH_INPUT;
            }
            length = ByteBufUtil.swapMedium(in.readUnsignedMedium());
            break;
        case 64:
            if (in.readableBytes() < 4) {
                return NOT_ENOUGH_INPUT;
            }
            length = ByteBufUtil.swapInt(in.readInt());
            break;
        default:
            length = tag >> 2 & 0x3F;
        }
        length += 1;

        if (in.readableBytes() < length) {
            in.resetReaderIndex();
            return NOT_ENOUGH_INPUT;
        }

        out.writeBytes(in, length);
        return length;
    }
```

I was wondering to know why there's a 'case 64' here. Should 'tag >> 2 & 0x3F' never will be equal to '64'? 


Issue comments:
@lw346 could you please comment ? 

I guess he meant any number `&` with `0x3F` (63) must be less than 64.

Fixed in #4731


Pull request review comments:
Removed `private` to call it in test

Removed `private` to call it in test

`decoded` and `Unpooled.wrappedBuffer(...)` need to be released.

+1

Just call ByteBuf.release() ?

just call `in.release()`?

@normanmaurer - +1 :wink: 


Patch that resolved the issue:
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 39ec873dc8d..df4e88a0821 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
@@ -228,7 +228,7 @@ private static int bitsToEncode(int value) {
      * @param out The output buffer to copy to
      * @param length The length of the literal to copy
      */
-    private static void encodeLiteral(ByteBuf in, ByteBuf out, int length) {
+    static void encodeLiteral(ByteBuf in, ByteBuf out, int length) {
         if (length < 61) {
             out.writeByte(length - 1 << 2);
         } else {
@@ -395,7 +395,7 @@ private static int readPreamble(ByteBuf in) {
      * @param out The output buffer to write the literal to
      * @return The number of bytes appended to the output buffer, or -1 to indicate "try again later"
      */
-    private static int decodeLiteral(byte tag, ByteBuf in, ByteBuf out) {
+    static int decodeLiteral(byte tag, ByteBuf in, ByteBuf out) {
         in.markReaderIndex();
         int length;
         switch(tag >> 2 & 0x3F) {
@@ -417,7 +417,7 @@ private static int decodeLiteral(byte tag, ByteBuf in, ByteBuf out) {
             }
             length = in.readUnsignedMediumLE();
             break;
-        case 64:
+        case 63:
             if (in.readableBytes() < 4) {
                 return NOT_ENOUGH_INPUT;
             }


Test patch:
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 0ac3d6574c9..84b5e068362 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
@@ -195,4 +195,32 @@ public void testValidateChecksumFails() {
 
         validateChecksum(maskChecksum(0xd6cb8b55), input);
     }
+
+    @Test
+    public void testEncodeLiteralAndDecodeLiteral() {
+        int[] lengths = new int[] {
+            0x11, // default
+            0x100, // case 60
+            0x1000, // case 61
+            0x100000, // case 62
+            0x1000001 // case 63
+        };
+        for (int len : lengths) {
+            ByteBuf in = Unpooled.wrappedBuffer(new byte[len]);
+            ByteBuf encoded = Unpooled.buffer(10);
+            ByteBuf decoded = Unpooled.buffer(10);
+            ByteBuf expected = Unpooled.wrappedBuffer(new byte[len]);
+            try {
+                Snappy.encodeLiteral(in, encoded, len);
+                byte tag = encoded.readByte();
+                Snappy.decodeLiteral(tag, encoded, decoded);
+                assertEquals("Encoded or decoded literal was incorrect", expected, decoded);
+            } finally {
+                in.release();
+                encoded.release();
+                decoded.release();
+                expected.release();
+            }
+        }
+    }
 }