Skip to content

Commit 1440435

Browse files
authored
Fix bug in forEachByte on nested composite bytebuf with leak detection (#12790)
Motivation: An NPE could occur when forEachByte was called on nested leak-aware composite byte buffers. Modification: WrappedCompositeByteBuf extends CompositeByteBuf but must delegate all calls to the wrapped instance. Add delegation calls for forEachByteAsc0 and forEachByteDesc0. Without delegation, those calls would, from an outer composite buffer, go to the composite structure of the wrapper buffer, which have no components. Result: No more NPE when calling forEachByte on nested composite leak-aware buffers. Fixes #12787
1 parent ef4a9df commit 1440435

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

buffer/src/main/java/io/netty/buffer/WrappedCompositeByteBuf.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,16 @@ public int forEachByteDesc(int index, int length, ByteProcessor processor) {
408408
return wrapped.forEachByteDesc(index, length, processor);
409409
}
410410

411+
@Override
412+
protected int forEachByteAsc0(int start, int end, ByteProcessor processor) throws Exception {
413+
return wrapped.forEachByteAsc0(start, end, processor);
414+
}
415+
416+
@Override
417+
protected int forEachByteDesc0(int rStart, int rEnd, ByteProcessor processor) throws Exception {
418+
return wrapped.forEachByteDesc0(rStart, rEnd, processor);
419+
}
420+
411421
@Override
412422
public final int hashCode() {
413423
return wrapped.hashCode();

buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package io.netty.buffer;
1717

18+
import io.netty.util.ByteProcessor;
1819
import io.netty.util.ReferenceCountUtil;
1920
import io.netty.util.internal.ObjectUtil;
2021
import io.netty.util.internal.PlatformDependent;
@@ -1774,4 +1775,36 @@ public void sliceOfCompositeBufferMustThrowISEAfterDiscardBytes() {
17741775
composite.release();
17751776
}
17761777
}
1778+
1779+
@Test
1780+
public void forEachByteOnNestedCompositeByteBufMustSeeEntireFlattenedContents() {
1781+
CompositeByteBuf buf = newCompositeBuffer();
1782+
buf.addComponent(true, newCompositeBuffer().addComponents(
1783+
true,
1784+
wrappedBuffer(new byte[] {1, 2, 3}),
1785+
wrappedBuffer(new byte[] {4, 5, 6})));
1786+
final byte[] arrayAsc = new byte[6];
1787+
final byte[] arrayDesc = new byte[6];
1788+
buf.forEachByte(new ByteProcessor() {
1789+
int index;
1790+
1791+
@Override
1792+
public boolean process(byte value) throws Exception {
1793+
arrayAsc[index++] = value;
1794+
return true;
1795+
}
1796+
});
1797+
buf.forEachByteDesc(new ByteProcessor() {
1798+
int index;
1799+
1800+
@Override
1801+
public boolean process(byte value) throws Exception {
1802+
arrayDesc[index++] = value;
1803+
return true;
1804+
}
1805+
});
1806+
assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6}, arrayAsc);
1807+
assertArrayEquals(new byte[] {6, 5, 4, 3, 2, 1}, arrayDesc);
1808+
buf.release();
1809+
}
17771810
}

0 commit comments

Comments
 (0)