This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-4.22.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.22.x by this push:
new d171e3d79cb0 CAMEL-24936: camel-netty - NettyConverter.toByteArray
copies only the readable bytes of the ByteBuf (#26973)
d171e3d79cb0 is described below
commit d171e3d79cb0f4977deec63325eaac49027ca473
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Sep 28 14:32:35 2026 +0200
CAMEL-24936: camel-netty - NettyConverter.toByteArray copies only the
readable bytes of the ByteBuf (#26973)
buffer.array() returned the whole backing array, ignoring
arrayOffset()/readerIndex()/readableBytes();
for a shared or pooled backing array that can include bytes outside this
buffer's own slice, and it also
handed back a reference to a buffer that may later be reused. Always copy
exactly the readable region
instead, consistent with the non-array branch, regardless of the underlying
allocator.
Backport of #26781 to camel-4.22.x. The upgrade-guide note stays on main
only.
Co-authored-by: Claude Opus 4.8 <[email protected]>
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../camel/component/netty/NettyConverter.java | 19 +++++--------
.../camel/component/netty/NettyConverterTest.java | 31 ++++++++++++++++++++++
2 files changed, 38 insertions(+), 12 deletions(-)
diff --git
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
index 36920d1034df..98a4c2ffd3bc 100644
---
a/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
+++
b/components/camel-netty/src/main/java/org/apache/camel/component/netty/NettyConverter.java
@@ -32,6 +32,7 @@ import org.w3c.dom.Document;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.ByteBufUtil;
import org.apache.camel.Converter;
import org.apache.camel.Exchange;
import org.apache.camel.support.DeserializationFilterHelper;
@@ -48,18 +49,12 @@ public final class NettyConverter {
@Converter
public static byte[] toByteArray(ByteBuf buffer, Exchange exchange) {
- if (buffer.hasArray()) {
- return buffer.array();
- }
- byte[] bytes = new byte[buffer.readableBytes()];
- int readerIndex = buffer.readerIndex();
- buffer.retain();
- try {
- buffer.getBytes(readerIndex, bytes);
- } finally {
- buffer.release();
- }
- return bytes;
+ // Copy only the readable region of the buffer. Returning
buffer.array() directly would hand back the
+ // whole backing array, ignoring
arrayOffset()/readerIndex()/readableBytes(): for a shared or pooled
+ // backing array that can include bytes outside this buffer's own
slice, and it also exposes a reference
+ // to a buffer that may later be reused. ByteBufUtil.getBytes() copies
exactly the readable bytes for
+ // every buffer kind (heap or direct, pooled or unpooled).
+ return ByteBufUtil.getBytes(buffer);
}
@Converter
diff --git
a/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyConverterTest.java
b/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyConverterTest.java
index b68f146efd75..bff50bb17686 100644
---
a/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyConverterTest.java
+++
b/components/camel-netty/src/test/java/org/apache/camel/component/netty/NettyConverterTest.java
@@ -16,8 +16,11 @@
*/
package org.apache.camel.component.netty;
+import java.nio.charset.StandardCharsets;
+
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
+import io.netty.buffer.Unpooled;
import org.apache.camel.support.DefaultExchange;
import org.apache.camel.test.junit6.CamelTestSupport;
import org.junit.jupiter.api.BeforeEach;
@@ -25,6 +28,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Utility test to verify netty type converter.
@@ -64,4 +68,31 @@ public class NettyConverterTest extends CamelTestSupport {
assertEquals(PAYLOAD, result);
}
+ /**
+ * A heap (array-backed) buffer whose backing array is larger than the
readable region, and whose reader index has
+ * been advanced past a prefix, must convert to exactly the readable bytes
- not the whole backing array. Converting
+ * via buffer.array() used to return the full backing array (prefix +
payload + spare capacity).
+ */
+ @Test
+ public void testConversionHeapBufferReturnsOnlyReadableBytes() {
+ byte[] payload = PAYLOAD.getBytes(StandardCharsets.UTF_8);
+ byte[] prefix = "SKIP".getBytes(StandardCharsets.UTF_8);
+ // Heap buffer with spare capacity so its backing array is larger than
the readable region
+ ByteBuf heap = Unpooled.buffer(prefix.length + payload.length + 32);
+ try {
+ heap.writeBytes(prefix);
+ heap.writeBytes(payload);
+ // Skip the prefix: only "payload" is readable now
+ heap.readerIndex(prefix.length);
+
+ assertTrue(heap.hasArray(), "expected an array-backed heap buffer
for this test");
+
+ byte[] result = NettyConverter.toByteArray(heap, null);
+ assertEquals(payload.length, result.length);
+ assertEquals(PAYLOAD, new String(result, StandardCharsets.UTF_8));
+ } finally {
+ heap.release();
+ }
+ }
+
}