From b7c0de81b836b9feeecba1c008ca422e4b09cb13 Mon Sep 17 00:00:00 2001 From: tzssangglass Date: Tue, 15 Jun 2021 20:34:47 +0800 Subject: [PATCH] fix: ensure correct encoding and decoding when data length is greater than 256 (#32) --- .../runner/codec/impl/FlatBuffersDecoder.java | 15 ++++++++++----- .../runner/codec/impl/FlatBuffersEncoder.java | 14 +++++++------- .../codec/impl/FlatBuffersDecoderTest.java | 17 +++++++++++++++++ .../codec/impl/FlatBuffersEncoderTest.java | 18 ++++++++++++++++++ 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoder.java b/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoder.java index acbfac7..0e1d221 100644 --- a/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoder.java +++ b/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoder.java @@ -77,7 +77,7 @@ private int getDataLength(ByteBuffer payload) { for (int i = 0; i < 3; i++) { bytes[i] = payload.get(); } - return byte3ToInt(bytes); + return bytes2Int(bytes, 0, 3); } private ByteBuffer getBody(ByteBuffer payload) throws BufferUnderflowException, IndexOutOfBoundsException { @@ -89,9 +89,14 @@ private ByteBuffer getBody(ByteBuffer payload) throws BufferUnderflowException, return buffer; } - private int byte3ToInt(byte[] bytes) { - return bytes[2] & 0xFF | - (bytes[1] & 0xFF << 8) | - (bytes[0] & 0xFF << 16); + int bytes2Int(byte[] b, int start, int len) { + int sum = 0; + int end = start + len; + for (int i = start; i < end; i++) { + int n = b[i] & 0xff; + n <<= (--len) * 8; + sum += n; + } + return sum; } } diff --git a/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoder.java b/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoder.java index 5abde30..caead07 100644 --- a/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoder.java +++ b/runner-core/src/main/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoder.java @@ -39,7 +39,7 @@ private ByteBuffer setBody(ByteBuffer payload, byte type) { ByteBuffer buffer = ByteBuffer.allocate(data.length + 4); buffer.put(type); // data length - byte[] length = intToByte3(data.length); + byte[] length = int2Bytes(data.length, 3); buffer.put(length); // data buffer.put(data); @@ -47,11 +47,11 @@ private ByteBuffer setBody(ByteBuffer payload, byte type) { return buffer; } - private byte[] intToByte3(int i) { - byte[] targets = new byte[3]; - targets[2] = (byte) (i & 0xFF); - targets[1] = (byte) (i >> 8 & 0xFF); - targets[0] = (byte) ((i >> 16 & 0xFF)); - return targets; + byte[] int2Bytes(int value, int len) { + byte[] b = new byte[len]; + for (int i = 0; i < len; i++) { + b[len - i - 1] = (byte) ((value >> 8 * i) & 0xff); + } + return b; } } diff --git a/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoderTest.java b/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoderTest.java index ba6708d..829845b 100644 --- a/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoderTest.java +++ b/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersDecoderTest.java @@ -20,6 +20,8 @@ import com.google.flatbuffers.FlatBufferBuilder; import io.github.api7.A6.Err.Code; import io.github.api7.A6.TextEntry; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.apache.apisix.plugin.runner.A6ConfigRequest; import org.apache.apisix.plugin.runner.A6ErrRequest; import org.apache.apisix.plugin.runner.A6Request; @@ -158,4 +160,19 @@ void testGetBody2() { A6ConfigRequest configReq = (A6ConfigRequest) flatBuffersDecoder.decode(buffer); assertThrows(IndexOutOfBoundsException.class, () -> configReq.getReq().conf(0)); } + + @Test + @DisplayName("test decode data length greater then 256") + void testDecodeDataGreaterLargeThen256() { + byte[] bytes = new byte[]{0, 1, 4}; + int length = flatBuffersDecoder.bytes2Int(bytes, 0, 3); + + // use Bytebuf getInt function (default 4 bytes) to verify + ByteBuf buf = Unpooled.buffer(4); + byte[] bufBytes = {0, 0, 1, 4}; + buf.writeBytes(bufBytes); + int bufLength = buf.getInt(0); + + Assertions.assertEquals(length, bufLength); + } } diff --git a/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoderTest.java b/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoderTest.java index ae07040..2d3ddbd 100644 --- a/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoderTest.java +++ b/runner-core/src/test/java/org/apache/apisix/plugin/runner/codec/impl/FlatBuffersEncoderTest.java @@ -21,6 +21,8 @@ import io.github.api7.A6.HTTPReqCall.Action; import io.github.api7.A6.HTTPReqCall.Rewrite; import io.github.api7.A6.HTTPReqCall.Stop; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.apache.apisix.plugin.runner.A6ConfigResponse; import org.apache.apisix.plugin.runner.A6ErrResponse; import org.apache.apisix.plugin.runner.HttpResponse; @@ -247,4 +249,20 @@ void testSetMoreStopHeaders() { } } } + + @Test + @DisplayName("test encode data length greater then 256") + void testEncodeDataGreaterLargeThen256() { + byte[] bytes = flatBuffersEncoder.int2Bytes(260, 3); + + // use Bytebuf getInt function (default 4 bytes) to verify + ByteBuf buf = Unpooled.buffer(4); + buf.setInt(0, 260); + byte[] array = buf.array(); + + Assertions.assertEquals(bytes[0], array[1]); + Assertions.assertEquals(bytes[1], array[2]); + Assertions.assertEquals(bytes[2], array[3]); + + } }