Always return a real slice even when the length is 0
Motivation: We need to always return a real slice even when the requested length is 0. This is needed as otherwise we not correctly share the reference count and so may leak a buffer if the user call release() on the returned slice and expect it to decrement the reference count of the "parent" buffer. Modifications: - Always return a real slice - Add unit test for the bug. Result: No more leak possible when a user requests a slice of length 0 of a SlicedByteBuf.
This commit is contained in:
parent
0528118669
commit
31ef237085
@ -153,9 +153,6 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
|||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
checkIndex(index, length);
|
checkIndex(index, length);
|
||||||
if (length == 0) {
|
|
||||||
return Unpooled.EMPTY_BUFFER;
|
|
||||||
}
|
|
||||||
return buffer.slice(idx(index), length);
|
return buffer.slice(idx(index), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import org.junit.Test;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests sliced channel buffers
|
* Tests sliced channel buffers
|
||||||
@ -137,4 +137,27 @@ public class SlicedByteBufTest extends AbstractByteBufTest {
|
|||||||
wrapped.release();
|
wrapped.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sliceEmptyNotLeak() {
|
||||||
|
ByteBuf buffer = Unpooled.buffer(8).retain();
|
||||||
|
assertEquals(2, buffer.refCnt());
|
||||||
|
|
||||||
|
ByteBuf slice1 = buffer.slice();
|
||||||
|
assertEquals(2, slice1.refCnt());
|
||||||
|
|
||||||
|
ByteBuf slice2 = slice1.slice();
|
||||||
|
assertEquals(2, slice2.refCnt());
|
||||||
|
|
||||||
|
assertFalse(slice2.release());
|
||||||
|
assertEquals(1, buffer.refCnt());
|
||||||
|
assertEquals(1, slice1.refCnt());
|
||||||
|
assertEquals(1, slice2.refCnt());
|
||||||
|
|
||||||
|
assertTrue(slice2.release());
|
||||||
|
|
||||||
|
assertEquals(0, buffer.refCnt());
|
||||||
|
assertEquals(0, slice1.refCnt());
|
||||||
|
assertEquals(0, slice2.refCnt());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user