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
This commit is contained in:
Brian Clozel
2019-01-17 11:09:48 -05:00
parent 86fb43900e
commit 2b65d0e51f
2 changed files with 35 additions and 23 deletions

View File

@@ -246,30 +246,32 @@ public interface DataBuffer {
default DataBuffer write(CharSequence charSequence, Charset charset) {
Assert.notNull(charSequence, "CharSequence must not be null");
Assert.notNull(charset, "Charset must not be null");
CharsetEncoder charsetEncoder = charset.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
CharBuffer inBuffer = CharBuffer.wrap(charSequence);
int estimatedSize = (int) (inBuffer.remaining() * charsetEncoder.averageBytesPerChar());
ByteBuffer outBuffer = ensureCapacity(estimatedSize)
.asByteBuffer(writePosition(), writableByteCount());
while (true) {
CoderResult cr = (inBuffer.hasRemaining() ?
charsetEncoder.encode(inBuffer, outBuffer, true) : CoderResult.UNDERFLOW);
if (cr.isUnderflow()) {
cr = charsetEncoder.flush(outBuffer);
}
if (cr.isUnderflow()) {
break;
}
if (cr.isOverflow()) {
writePosition(outBuffer.position());
int maximumSize = (int) (inBuffer.remaining() * charsetEncoder.maxBytesPerChar());
ensureCapacity(maximumSize);
outBuffer = asByteBuffer(writePosition(), writableByteCount());
if (charSequence.length() != 0) {
CharsetEncoder charsetEncoder = charset.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
CharBuffer inBuffer = CharBuffer.wrap(charSequence);
int estimatedSize = (int) (inBuffer.remaining() * charsetEncoder.averageBytesPerChar());
ByteBuffer outBuffer = ensureCapacity(estimatedSize)
.asByteBuffer(writePosition(), writableByteCount());
while (true) {
CoderResult cr = (inBuffer.hasRemaining() ?
charsetEncoder.encode(inBuffer, outBuffer, true) : CoderResult.UNDERFLOW);
if (cr.isUnderflow()) {
cr = charsetEncoder.flush(outBuffer);
}
if (cr.isUnderflow()) {
break;
}
if (cr.isOverflow()) {
writePosition(outBuffer.position());
int maximumSize = (int) (inBuffer.remaining() * charsetEncoder.maxBytesPerChar());
ensureCapacity(maximumSize);
outBuffer = asByteBuffer(writePosition(), writableByteCount());
}
}
writePosition(outBuffer.position());
}
writePosition(outBuffer.position());
return this;
}