Skip to content

Commit 2b65d0e

Browse files
committed
Fix error when writing empty String to DataBuffer
Prior to this commit, `DataBuffer.write` would throw an `IllegalStateException` when called with an empty `String`, since the `CharsetEncoder` would be flushed on an incorrent state. This commit skips entirely the encoding phase for empty `String`. Fixes #22262
1 parent 86fb439 commit 2b65d0e

File tree

2 files changed

+35
-23
lines changed

2 files changed

+35
-23
lines changed

spring-core/src/main/java/org/springframework/core/io/buffer/DataBuffer.java

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -246,30 +246,32 @@ default DataBuffer ensureCapacity(int capacity) {
246246
default DataBuffer write(CharSequence charSequence, Charset charset) {
247247
Assert.notNull(charSequence, "CharSequence must not be null");
248248
Assert.notNull(charset, "Charset must not be null");
249-
CharsetEncoder charsetEncoder = charset.newEncoder()
250-
.onMalformedInput(CodingErrorAction.REPLACE)
251-
.onUnmappableCharacter(CodingErrorAction.REPLACE);
252-
CharBuffer inBuffer = CharBuffer.wrap(charSequence);
253-
int estimatedSize = (int) (inBuffer.remaining() * charsetEncoder.averageBytesPerChar());
254-
ByteBuffer outBuffer = ensureCapacity(estimatedSize)
255-
.asByteBuffer(writePosition(), writableByteCount());
256-
while (true) {
257-
CoderResult cr = (inBuffer.hasRemaining() ?
258-
charsetEncoder.encode(inBuffer, outBuffer, true) : CoderResult.UNDERFLOW);
259-
if (cr.isUnderflow()) {
260-
cr = charsetEncoder.flush(outBuffer);
261-
}
262-
if (cr.isUnderflow()) {
263-
break;
264-
}
265-
if (cr.isOverflow()) {
266-
writePosition(outBuffer.position());
267-
int maximumSize = (int) (inBuffer.remaining() * charsetEncoder.maxBytesPerChar());
268-
ensureCapacity(maximumSize);
269-
outBuffer = asByteBuffer(writePosition(), writableByteCount());
249+
if (charSequence.length() != 0) {
250+
CharsetEncoder charsetEncoder = charset.newEncoder()
251+
.onMalformedInput(CodingErrorAction.REPLACE)
252+
.onUnmappableCharacter(CodingErrorAction.REPLACE);
253+
CharBuffer inBuffer = CharBuffer.wrap(charSequence);
254+
int estimatedSize = (int) (inBuffer.remaining() * charsetEncoder.averageBytesPerChar());
255+
ByteBuffer outBuffer = ensureCapacity(estimatedSize)
256+
.asByteBuffer(writePosition(), writableByteCount());
257+
while (true) {
258+
CoderResult cr = (inBuffer.hasRemaining() ?
259+
charsetEncoder.encode(inBuffer, outBuffer, true) : CoderResult.UNDERFLOW);
260+
if (cr.isUnderflow()) {
261+
cr = charsetEncoder.flush(outBuffer);
262+
}
263+
if (cr.isUnderflow()) {
264+
break;
265+
}
266+
if (cr.isOverflow()) {
267+
writePosition(outBuffer.position());
268+
int maximumSize = (int) (inBuffer.remaining() * charsetEncoder.maxBytesPerChar());
269+
ensureCapacity(maximumSize);
270+
outBuffer = asByteBuffer(writePosition(), writableByteCount());
271+
}
270272
}
273+
writePosition(outBuffer.position());
271274
}
272-
writePosition(outBuffer.position());
273275
return this;
274276
}
275277

spring-core/src/test/java/org/springframework/core/io/buffer/DataBufferTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -179,6 +179,16 @@ public void writeNullCharset() {
179179
}
180180
}
181181

182+
@Test
183+
public void writeEmptyString() {
184+
DataBuffer buffer = createDataBuffer(1);
185+
buffer.write("", StandardCharsets.UTF_8);
186+
187+
assertEquals(0, buffer.readableByteCount());
188+
189+
release(buffer);
190+
}
191+
182192
@Test
183193
public void writeUtf8String() {
184194
DataBuffer buffer = createDataBuffer(6);

0 commit comments

Comments
 (0)