Skip to content

Commit

Permalink
Fix bug in forEachByte on nested composite bytebuf with leak detection (
Browse files Browse the repository at this point in the history
#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
  • Loading branch information
chrisvest committed Sep 9, 2022
1 parent ef4a9df commit 1440435
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
10 changes: 10 additions & 0 deletions buffer/src/main/java/io/netty/buffer/WrappedCompositeByteBuf.java
Expand Up @@ -408,6 +408,16 @@ public int forEachByteDesc(int index, int length, ByteProcessor processor) {
return wrapped.forEachByteDesc(index, length, processor);
}

@Override
protected int forEachByteAsc0(int start, int end, ByteProcessor processor) throws Exception {
return wrapped.forEachByteAsc0(start, end, processor);
}

@Override
protected int forEachByteDesc0(int rStart, int rEnd, ByteProcessor processor) throws Exception {
return wrapped.forEachByteDesc0(rStart, rEnd, processor);
}

@Override
public final int hashCode() {
return wrapped.hashCode();
Expand Down
Expand Up @@ -15,6 +15,7 @@
*/
package io.netty.buffer;

import io.netty.util.ByteProcessor;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.ObjectUtil;
import io.netty.util.internal.PlatformDependent;
Expand Down Expand Up @@ -1774,4 +1775,36 @@ public void sliceOfCompositeBufferMustThrowISEAfterDiscardBytes() {
composite.release();
}
}

@Test
public void forEachByteOnNestedCompositeByteBufMustSeeEntireFlattenedContents() {
CompositeByteBuf buf = newCompositeBuffer();
buf.addComponent(true, newCompositeBuffer().addComponents(
true,
wrappedBuffer(new byte[] {1, 2, 3}),
wrappedBuffer(new byte[] {4, 5, 6})));
final byte[] arrayAsc = new byte[6];
final byte[] arrayDesc = new byte[6];
buf.forEachByte(new ByteProcessor() {
int index;

@Override
public boolean process(byte value) throws Exception {
arrayAsc[index++] = value;
return true;
}
});
buf.forEachByteDesc(new ByteProcessor() {
int index;

@Override
public boolean process(byte value) throws Exception {
arrayDesc[index++] = value;
return true;
}
});
assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6}, arrayAsc);
assertArrayEquals(new byte[] {6, 5, 4, 3, 2, 1}, arrayDesc);
buf.release();
}
}

0 comments on commit 1440435

Please sign in to comment.