This is an automated email from the ASF dual-hosted git repository. robbie pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/qpid-proton-j.git
The following commit(s) were added to refs/heads/master by this push: new 462027b PROTON-2297: fix handling where the string doesnt consume all of its last containing array 462027b is described below commit 462027b23506392d8a8f982c7aa6599d8c0e3baf Author: Robbie Gemmell <rob...@apache.org> AuthorDate: Thu Nov 12 19:39:24 2020 +0000 PROTON-2297: fix handling where the string doesnt consume all of its last containing array --- .../qpid/proton/codec/CompositeReadableBuffer.java | 9 ++-- .../proton/codec/CompositeReadableBufferTest.java | 60 ++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java b/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java index a4c6de9..cd6f673 100644 --- a/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java +++ b/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java @@ -587,10 +587,13 @@ public class CompositeReadableBuffer implements ReadableBuffer { final int unprocessed = wrapper.remaining(); final byte[] next = contents.get(++arrayIndex); final ByteBuffer previous = wrapper; - wrapper = ByteBuffer.allocate(unprocessed + next.length); + final int nextAmount = Math.min(next.length, viewSpan - processed); + wrapper = ByteBuffer.allocate(unprocessed + nextAmount); + wrapper.put(previous); - wrapper.put(next); - processed += wrapper.position() - unprocessed; + wrapper.put(next, 0, nextAmount); + processed += nextAmount; + wrapper.flip(); } else { final byte[] next = contents.get(++arrayIndex); diff --git a/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java b/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java index 6ae4592..e0f3792 100644 --- a/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java +++ b/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java @@ -32,8 +32,13 @@ import java.nio.ByteBuffer; import java.nio.InvalidMarkException; import java.nio.charset.CharacterCodingException; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.apache.qpid.proton.amqp.Symbol; +import org.apache.qpid.proton.amqp.messaging.AmqpValue; +import org.apache.qpid.proton.amqp.messaging.Footer; import org.junit.Test; /** @@ -3417,6 +3422,61 @@ public class CompositeReadableBufferTest { assertEquals("Failed to round trip String correctly: ", expected, result); } + @Test + public void testRoundtripUnicodeStringThatSpansArraySlicesButDoesntFillLastContainingArray() throws IOException { + StringBuilder unicodeStringBuilder = new StringBuilder(); + + unicodeStringBuilder.append((char) 1000); + unicodeStringBuilder.append((char) 1001); + unicodeStringBuilder.append((char) 1002); + unicodeStringBuilder.append((char) 1003); + + final DecoderImpl decoder = new DecoderImpl(); + final EncoderImpl encoder = new EncoderImpl(decoder); + AMQPDefinedTypes.registerAllTypes(decoder, encoder); + final ByteBuffer bb = ByteBuffer.allocate(1024); + + final AmqpValue inputValue = new AmqpValue(unicodeStringBuilder.toString()); + encoder.setByteBuffer(bb); + encoder.writeObject(inputValue); + + assertTrue(bb.position() > 1); + + // Now write some trailing content, which will fill the + // remainder of the last array after the end of the string + Map<Symbol, Object> footerValues = new HashMap<>(); + footerValues.put(Symbol.valueOf("some-key"), "some-value"); + + int startOfFooter = bb.position(); + encoder.writeObject(new Footer(footerValues)); + assertTrue("position did not move as required", bb.position() > startOfFooter); + + // Prepare the array slices + int firstSliceLength = startOfFooter - 1; + + final byte[] slice1 = new byte[firstSliceLength]; + int remainder = bb.position() - firstSliceLength; + final byte[] slice2 = new byte[remainder]; + + bb.flip(); + bb.get(slice1); + bb.get(slice2); + + // Create the buffer with them, then read the string and footer back + CompositeReadableBuffer composite = new CompositeReadableBuffer(); + composite.append(slice1); + composite.append(slice2); + + decoder.setBuffer(composite); + + final AmqpValue outputValue = (AmqpValue) decoder.readObject(); + assertEquals("Failed to round trip String correctly: ", unicodeStringBuilder.toString(), outputValue.getValue()); + + final Footer footer = (Footer) decoder.readObject(); + assertNotNull(footer); + assertEquals("Failed to round trip Footer correctly: ", footerValues, footer.getValue()); + } + //----- Tests for hashCode -----------------------------------------------// @Test --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org