mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Fix data loss in DataBufferUtils synchronous write
Prior to this commit, WritableByteChannelSubscriber.hookOnNext() called iterator.next() exactly once. If a DataBuffer consisted of multiple NIO ByteBuffers (e.g., NettyDataBuffer wrapping a CompositeByteBuf), only the first buffer was written to the channel, and the remaining buffers were silently ignored and lost. This commit adds the missing while (iterator.hasNext()) outer loop to ensure all fragmented buffers exposed by the iterator are completely and safely written to the synchronous channel. See gh-36714 Signed-off-by: KimDaehyeon <daehyeon3351@gmail.com>
This commit is contained in:
committed by
Brian Clozel
parent
6467fca05b
commit
d8bc54d2e7
@@ -1138,9 +1138,11 @@ public abstract class DataBufferUtils {
|
||||
protected void hookOnNext(DataBuffer dataBuffer) {
|
||||
try {
|
||||
try (DataBuffer.ByteBufferIterator iterator = dataBuffer.readableByteBuffers()) {
|
||||
ByteBuffer byteBuffer = iterator.next();
|
||||
while (byteBuffer.hasRemaining()) {
|
||||
this.channel.write(byteBuffer);
|
||||
while (iterator.hasNext()) {
|
||||
ByteBuffer byteBuffer = iterator.next();
|
||||
while (byteBuffer.hasRemaining()) {
|
||||
this.channel.write(byteBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.sink.next(dataBuffer);
|
||||
|
||||
+21
@@ -338,6 +338,27 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
channel.close();
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeWritableByteChannelWithJoinedBuffer(DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
DataBuffer bar = stringBuffer("bar");
|
||||
DataBuffer joined = bufferFactory.join(List.of(foo, bar));
|
||||
|
||||
WritableByteChannel channel = Files.newByteChannel(tempFile, StandardOpenOption.WRITE);
|
||||
|
||||
Flux<DataBuffer> writeResult = DataBufferUtils.write(Flux.just(joined), channel);
|
||||
StepVerifier.create(writeResult)
|
||||
.consumeNextWith(stringConsumer("foobar"))
|
||||
.verifyComplete();
|
||||
|
||||
String result = String.join("", Files.readAllLines(tempFile));
|
||||
|
||||
assertThat(result).isEqualTo("foobar");
|
||||
channel.close();
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeWritableByteChannelErrorInFlux(DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Reference in New Issue
Block a user