Ensure StringDecoder supports multiline delimiters

This commit makes sure the StringDecoder supports stripping off
multi-line delimiters, such as \r\n. Specifically, we ensure that the
delimiter is stripped from the joined buffer.

Closes gh-26511
This commit is contained in:
Arjen Poutsma
2021-02-08 15:40:47 +01:00
parent 6c22f7ef5e
commit c09b2513e0
2 changed files with 25 additions and 6 deletions

View File

@@ -157,16 +157,20 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
int startIndex = buffer.readPosition(); int startIndex = buffer.readPosition();
int length = (endIndex - startIndex + 1); int length = (endIndex - startIndex + 1);
DataBuffer slice = buffer.retainedSlice(startIndex, length); DataBuffer slice = buffer.retainedSlice(startIndex, length);
if (this.stripDelimiter) {
slice.writePosition(slice.writePosition() - matcher.delimiter().length);
}
result = (result != null ? result : new ArrayList<>()); result = (result != null ? result : new ArrayList<>());
if (chunks.isEmpty()) { if (chunks.isEmpty()) {
if (this.stripDelimiter) {
slice.writePosition(slice.writePosition() - matcher.delimiter().length);
}
result.add(slice); result.add(slice);
} }
else { else {
chunks.add(slice); chunks.add(slice);
result.add(buffer.factory().join(chunks)); DataBuffer joined = buffer.factory().join(chunks);
if (this.stripDelimiter) {
joined.writePosition(joined.writePosition() - matcher.delimiter().length);
}
result.add(joined);
chunks.clear(); chunks.clear();
} }
buffer.readPosition(endIndex + 1); buffer.readPosition(endIndex + 1);

View File

@@ -125,10 +125,10 @@ class StringDecoderTests extends AbstractDecoderTests<StringDecoder> {
); );
testDecode(input, String.class, step -> step testDecode(input, String.class, step -> step
.expectNext("") .expectNext("").as("1st")
.expectNext("abc") .expectNext("abc")
.expectNext("defghi") .expectNext("defghi")
.expectNext("") .expectNext("").as("2nd")
.expectNext("jklmno") .expectNext("jklmno")
.expectNext("pqr") .expectNext("pqr")
.expectNext("stuvwxyz") .expectNext("stuvwxyz")
@@ -136,6 +136,21 @@ class StringDecoderTests extends AbstractDecoderTests<StringDecoder> {
.verify()); .verify());
} }
@Test
void decodeNewlinesAcrossBuffers() {
Flux<DataBuffer> input = Flux.just(
stringBuffer("\r"),
stringBuffer("\n"),
stringBuffer("xyz")
);
testDecode(input, String.class, step -> step
.expectNext("")
.expectNext("xyz")
.expectComplete()
.verify());
}
@Test @Test
void maxInMemoryLimit() { void maxInMemoryLimit() {
Flux<DataBuffer> input = Flux.just( Flux<DataBuffer> input = Flux.just(