Add tests to ensure an IllegalReferenceCountException is thrown if set/writeCharSequence is called on a released buffer

Motivation:

We need to ensure we not allow calling set/writeCharsequence on an released ByteBuf.

Modifications:

Add test-cases

Result:

Proves fix of [#6951].
This commit is contained in:
Norman Maurer 2017-07-07 16:34:08 +01:00
parent f897507b09
commit 06f64948d5
4 changed files with 129 additions and 27 deletions

View File

@ -261,7 +261,7 @@ abstract class AbstractUnpooledSlicedByteBuf extends AbstractDerivedByteBuf {
@Override
public CharSequence getCharSequence(int index, int length, Charset charset) {
checkIndex0(index, length);
return buffer.getCharSequence(idx(index), length, charset);
return unwrap().getCharSequence(idx(index), length, charset);
}
@Override
@ -386,11 +386,6 @@ abstract class AbstractUnpooledSlicedByteBuf extends AbstractDerivedByteBuf {
return this;
}
@Override
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
return super.setCharSequence(idx(index), sequence, charset);
}
@Override
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
checkIndex0(index, length);

View File

@ -2502,6 +2502,10 @@ public abstract class AbstractByteBufTest {
private ByteBuf releasedBuffer() {
ByteBuf buffer = newBuffer(8);
// Clear the buffer so we are sure the reader and writer indices are 0.
// This is important as we may return a slice from newBuffer(...).
buffer.clear();
assertTrue(buffer.release());
return buffer;
}
@ -2766,6 +2770,30 @@ public abstract class AbstractByteBufTest {
}
}
@Test(expected = IllegalReferenceCountException.class)
public void testSetUsAsciiCharSequenceAfterRelease() {
testSetCharSequenceAfterRelease0(CharsetUtil.US_ASCII);
}
@Test(expected = IllegalReferenceCountException.class)
public void testSetIso88591CharSequenceAfterRelease() {
testSetCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1);
}
@Test(expected = IllegalReferenceCountException.class)
public void testSetUtf8CharSequenceAfterRelease() {
testSetCharSequenceAfterRelease0(CharsetUtil.UTF_8);
}
@Test(expected = IllegalReferenceCountException.class)
public void testSetUtf16CharSequenceAfterRelease() {
testSetCharSequenceAfterRelease0(CharsetUtil.UTF_16);
}
private void testSetCharSequenceAfterRelease0(Charset charset) {
releasedBuffer().setCharSequence(0, "x", charset);
}
@Test(expected = IllegalReferenceCountException.class)
public void testSetBytesAfterRelease4() {
releasedBuffer().setBytes(0, new byte[8]);
@ -3086,6 +3114,30 @@ public abstract class AbstractByteBufTest {
releasedBuffer().writeZero(1);
}
@Test(expected = IllegalReferenceCountException.class)
public void testWriteUsAsciiCharSequenceAfterRelease() {
testWriteCharSequenceAfterRelease0(CharsetUtil.US_ASCII);
}
@Test(expected = IllegalReferenceCountException.class)
public void testWriteIso88591CharSequenceAfterRelease() {
testWriteCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1);
}
@Test(expected = IllegalReferenceCountException.class)
public void testWriteUtf8CharSequenceAfterRelease() {
testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_8);
}
@Test(expected = IllegalReferenceCountException.class)
public void testWriteUtf16CharSequenceAfterRelease() {
testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_16);
}
private void testWriteCharSequenceAfterRelease0(Charset charset) {
releasedBuffer().writeCharSequence("x", charset);
}
@Test(expected = IllegalReferenceCountException.class)
public void testForEachByteAfterRelease() {
releasedBuffer().forEachByte(new TestByteProcessor());
@ -3236,6 +3288,64 @@ public abstract class AbstractByteBufTest {
}
}
@Test
public void testSetUsAsciiCharSequence() {
testSetGetCharSequence(CharsetUtil.US_ASCII);
}
@Test
public void testSetUtf8CharSequence() {
testSetGetCharSequence(CharsetUtil.UTF_8);
}
@Test
public void testSetIso88591CharSequence() {
testSetGetCharSequence(CharsetUtil.ISO_8859_1);
}
@Test
public void testSetUtf16CharSequence() {
testSetGetCharSequence(CharsetUtil.UTF_16);
}
private void testSetGetCharSequence(Charset charset) {
ByteBuf buf = newBuffer(16);
String sequence = "AB";
int bytes = buf.setCharSequence(1, sequence, charset);
assertEquals(sequence, buf.getCharSequence(1, bytes, charset));
buf.release();
}
@Test
public void testWriteReadUsAsciiCharSequence() {
testWriteReadCharSequence(CharsetUtil.US_ASCII);
}
@Test
public void testWriteReadUtf8CharSequence() {
testWriteReadCharSequence(CharsetUtil.UTF_8);
}
@Test
public void testWriteReadIso88591CharSequence() {
testWriteReadCharSequence(CharsetUtil.ISO_8859_1);
}
@Test
public void testWriteReadUtf16CharSequence() {
testWriteReadCharSequence(CharsetUtil.UTF_16);
}
private void testWriteReadCharSequence(Charset charset) {
ByteBuf buf = newBuffer(16);
String sequence = "AB";
buf.writerIndex(1);
int bytes = buf.writeCharSequence(sequence, charset);
buf.readerIndex(1);
assertEquals(sequence, buf.readCharSequence(bytes, charset));
buf.release();
}
@Test(expected = IndexOutOfBoundsException.class)
public void testRetainedSliceIndexOutOfBounds() {
testSliceOutOfBounds(true, true, true);

View File

@ -16,22 +16,16 @@
package io.netty.buffer;
import io.netty.util.internal.PlatformDependent;
import org.junit.Assume;
import static org.junit.Assert.assertEquals;
import org.junit.Assert;
public class RetainedSlicedByteBufTest extends SlicedByteBufTest {
@Override
protected ByteBuf newBuffer(int length, int maxCapacity) {
Assume.assumeTrue(maxCapacity == Integer.MAX_VALUE);
ByteBuf wrapped = Unpooled.wrappedBuffer(new byte[length * 2]);
ByteBuf buffer = wrapped.retainedSlice(length > 1 ?
PlatformDependent.threadLocalRandom().nextInt(length - 1) + 1 : 0, length);
wrapped.release();
assertEquals(0, buffer.readerIndex());
assertEquals(length, buffer.writerIndex());
return buffer;
@Override
protected ByteBuf newSlice(ByteBuf buffer, int offset, int length) {
ByteBuf slice = buffer.retainedSlice(offset, length);
buffer.release();
Assert.assertEquals(buffer.refCnt(), slice.refCnt());
return slice;
}
}

View File

@ -20,7 +20,6 @@ import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Test;
import java.io.IOException;
import java.nio.ByteBuffer;
import static org.junit.Assert.*;
@ -31,14 +30,18 @@ import static org.junit.Assert.*;
public class SlicedByteBufTest extends AbstractByteBufTest {
@Override
protected ByteBuf newBuffer(int length, int maxCapacity) {
protected final ByteBuf newBuffer(int length, int maxCapacity) {
Assume.assumeTrue(maxCapacity == Integer.MAX_VALUE);
ByteBuf buffer = Unpooled.wrappedBuffer(
new byte[length * 2], length > 1 ?
PlatformDependent.threadLocalRandom().nextInt(length - 1) + 1 : 0, length);
assertEquals(0, buffer.readerIndex());
assertEquals(length, buffer.writerIndex());
return buffer;
int offset = length == 0 ? 0 : PlatformDependent.threadLocalRandom().nextInt(length);
ByteBuf buffer = Unpooled.buffer(length * 2);
ByteBuf slice = newSlice(buffer, offset, length);
assertEquals(0, slice.readerIndex());
assertEquals(length, slice.writerIndex());
return slice;
}
protected ByteBuf newSlice(ByteBuf buffer, int offset, int length) {
return buffer.slice(offset, length);
}
@Test(expected = NullPointerException.class)