Leak detection combined with composite buffers results in incorrectly handled writerIndex when calling ByteBufUtil.writeAscii/writeUtf8 (#8153)
Motivation: We need to add special handling for WrappedCompositeByteBuf as these also extend AbstractByteBuf, otherwise we will not correctly adjust / read the writerIndex during processing. Modifications: - Add instanceof checks for WrappedCompositeByteBuf as well. - Add testcases Result: Fixes https://github.com/netty/netty/issues/8152.
This commit is contained in:
parent
0dc71cee3a
commit
9b08dbca00
@ -498,7 +498,10 @@ public final class ByteBufUtil {
|
||||
*/
|
||||
public static int reserveAndWriteUtf8(ByteBuf buf, CharSequence seq, int reserveBytes) {
|
||||
for (;;) {
|
||||
if (buf instanceof AbstractByteBuf) {
|
||||
if (buf instanceof WrappedCompositeByteBuf) {
|
||||
// WrappedCompositeByteBuf is a sub-class of AbstractByteBuf so it needs special handling.
|
||||
buf = buf.unwrap();
|
||||
} else if (buf instanceof AbstractByteBuf) {
|
||||
AbstractByteBuf byteBuf = (AbstractByteBuf) buf;
|
||||
byteBuf.ensureWritable0(reserveBytes);
|
||||
int written = writeUtf8(byteBuf, byteBuf.writerIndex, seq, seq.length());
|
||||
@ -665,7 +668,10 @@ public final class ByteBufUtil {
|
||||
buf.writeBytes(asciiString.array(), asciiString.arrayOffset(), len);
|
||||
} else {
|
||||
for (;;) {
|
||||
if (buf instanceof AbstractByteBuf) {
|
||||
if (buf instanceof WrappedCompositeByteBuf) {
|
||||
// WrappedCompositeByteBuf is a sub-class of AbstractByteBuf so it needs special handling.
|
||||
buf = buf.unwrap();
|
||||
} else if (buf instanceof AbstractByteBuf) {
|
||||
AbstractByteBuf byteBuf = (AbstractByteBuf) buf;
|
||||
byteBuf.ensureWritable0(len);
|
||||
int written = writeAscii(byteBuf, byteBuf.writerIndex, seq, len);
|
||||
|
@ -238,6 +238,42 @@ public class ByteBufUtilTest {
|
||||
buf2.unwrap().release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteUsAsciiComposite() {
|
||||
String usAscii = "NettyRocks";
|
||||
ByteBuf buf = Unpooled.buffer(16);
|
||||
buf.writeBytes(usAscii.getBytes(CharsetUtil.US_ASCII));
|
||||
ByteBuf buf2 = Unpooled.compositeBuffer().addComponent(
|
||||
Unpooled.buffer(8)).addComponent(Unpooled.buffer(24));
|
||||
// write some byte so we start writing with an offset.
|
||||
buf2.writeByte(1);
|
||||
ByteBufUtil.writeAscii(buf2, usAscii);
|
||||
|
||||
// Skip the previously written byte.
|
||||
assertEquals(buf, buf2.skipBytes(1));
|
||||
|
||||
buf.release();
|
||||
buf2.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteUsAsciiCompositeWrapped() {
|
||||
String usAscii = "NettyRocks";
|
||||
ByteBuf buf = Unpooled.buffer(16);
|
||||
buf.writeBytes(usAscii.getBytes(CharsetUtil.US_ASCII));
|
||||
ByteBuf buf2 = new WrappedCompositeByteBuf(Unpooled.compositeBuffer().addComponent(
|
||||
Unpooled.buffer(8)).addComponent(Unpooled.buffer(24)));
|
||||
// write some byte so we start writing with an offset.
|
||||
buf2.writeByte(1);
|
||||
ByteBufUtil.writeAscii(buf2, usAscii);
|
||||
|
||||
// Skip the previously written byte.
|
||||
assertEquals(buf, buf2.skipBytes(1));
|
||||
|
||||
buf.release();
|
||||
buf2.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteUtf8() {
|
||||
String usAscii = "Some UTF-8 like äÄ∏ŒŒ";
|
||||
@ -252,6 +288,42 @@ public class ByteBufUtilTest {
|
||||
buf2.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteUtf8Composite() {
|
||||
String utf8 = "Some UTF-8 like äÄ∏ŒŒ";
|
||||
ByteBuf buf = Unpooled.buffer(16);
|
||||
buf.writeBytes(utf8.getBytes(CharsetUtil.UTF_8));
|
||||
ByteBuf buf2 = Unpooled.compositeBuffer().addComponent(
|
||||
Unpooled.buffer(8)).addComponent(Unpooled.buffer(24));
|
||||
// write some byte so we start writing with an offset.
|
||||
buf2.writeByte(1);
|
||||
ByteBufUtil.writeUtf8(buf2, utf8);
|
||||
|
||||
// Skip the previously written byte.
|
||||
assertEquals(buf, buf2.skipBytes(1));
|
||||
|
||||
buf.release();
|
||||
buf2.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteUtf8CompositeWrapped() {
|
||||
String utf8 = "Some UTF-8 like äÄ∏ŒŒ";
|
||||
ByteBuf buf = Unpooled.buffer(16);
|
||||
buf.writeBytes(utf8.getBytes(CharsetUtil.UTF_8));
|
||||
ByteBuf buf2 = new WrappedCompositeByteBuf(Unpooled.compositeBuffer().addComponent(
|
||||
Unpooled.buffer(8)).addComponent(Unpooled.buffer(24)));
|
||||
// write some byte so we start writing with an offset.
|
||||
buf2.writeByte(1);
|
||||
ByteBufUtil.writeUtf8(buf2, utf8);
|
||||
|
||||
// Skip the previously written byte.
|
||||
assertEquals(buf, buf2.skipBytes(1));
|
||||
|
||||
buf.release();
|
||||
buf2.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteUtf8Surrogates() {
|
||||
// leading surrogate + trailing surrogate
|
||||
|
Loading…
Reference in New Issue
Block a user