[#3896] Unpooled.copiedBuffer(ByteBuffer) and copiedBuffer(ByteBuffer...) is not thread-safe.

Motivation:

As we modify the position of the passed in ByteBuffer's this methods are not thread-safe.

Modifications:

Duplicate the input ByteBuffers before copy the content to  byte[].

Result:

Unpooled.copiedBuffer(ByteBuffer) and copiedBuffer(ByteBuffer...) is now thread-safe.
This commit is contained in:
Norman Maurer 2015-06-18 12:10:50 +02:00
parent 8c90d602d7
commit ae163d687d

View File

@ -392,13 +392,11 @@ public final class Unpooled {
return EMPTY_BUFFER; return EMPTY_BUFFER;
} }
byte[] copy = new byte[length]; byte[] copy = new byte[length];
int position = buffer.position(); // Duplicate the buffer so we not adjust the position during our get operation.
try { // See https://github.com/netty/netty/issues/3896
buffer.get(copy); ByteBuffer duplicate = buffer.duplicate();
} finally { duplicate.get(copy);
buffer.position(position); return wrappedBuffer(copy).order(duplicate.order());
}
return wrappedBuffer(copy).order(buffer.order());
} }
/** /**
@ -561,11 +559,11 @@ public final class Unpooled {
byte[] mergedArray = new byte[length]; byte[] mergedArray = new byte[length];
for (int i = 0, j = 0; i < buffers.length; i ++) { for (int i = 0, j = 0; i < buffers.length; i ++) {
ByteBuffer b = buffers[i]; // Duplicate the buffer so we not adjust the position during our get operation.
// See https://github.com/netty/netty/issues/3896
ByteBuffer b = buffers[i].duplicate();
int bLen = b.remaining(); int bLen = b.remaining();
int oldPos = b.position();
b.get(mergedArray, j, bLen); b.get(mergedArray, j, bLen);
b.position(oldPos);
j += bLen; j += bLen;
} }