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

Reply via email to