You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ck...@apache.org on 2020/08/28 12:05:49 UTC

[httpcomponents-core] branch master updated: HTTPCORE-648: Buffer array access respects the arrayOffset (#220)

This is an automated email from the ASF dual-hosted git repository.

ckozak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 784878d  HTTPCORE-648: Buffer array access respects the arrayOffset (#220)
784878d is described below

commit 784878de35003c414a620f27538614558d0398a4
Author: Carter Kozak <ck...@apache.org>
AuthorDate: Fri Aug 28 08:05:41 2020 -0400

    HTTPCORE-648: Buffer array access respects the arrayOffset (#220)
---
 .../apache/hc/core5/http2/hpack/HPackDecoder.java  |  2 +-
 .../apache/hc/core5/http2/hpack/HPackEncoder.java  |  2 +-
 .../hc/core5/http2/hpack/TestHPackCoding.java      | 31 ++++++++++++++--------
 .../http/impl/nio/SessionInputBufferImpl.java      |  6 ++---
 .../http/impl/nio/SessionOutputBufferImpl.java     |  3 ++-
 5 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackDecoder.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackDecoder.java
index 62ad3bb..dd9379c 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackDecoder.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackDecoder.java
@@ -133,7 +133,7 @@ public final class HPackDecoder {
         if (src.hasArray()) {
             final byte[] b = src.array();
             final int off = src.position();
-            buffer.append(b, off, strLen);
+            buffer.append(b, src.arrayOffset() + off, strLen);
             src.position(off + strLen);
         } else {
             for (int i = 0; i < strLen; i++) {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackEncoder.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackEncoder.java
index dc3179d..2824760 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackEncoder.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/HPackEncoder.java
@@ -113,7 +113,7 @@ public final class HPackEncoder {
             if (src.hasArray()) {
                 final byte[] b = src.array();
                 final int off = src.position();
-                dst.append(b, off, strLen);
+                dst.append(b, src.arrayOffset() + off, strLen);
                 src.position(off + strLen);
             } else {
                 while (src.hasRemaining()) {
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/hpack/TestHPackCoding.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/hpack/TestHPackCoding.java
index 7d1603a..8e71d5f 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/hpack/TestHPackCoding.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/hpack/TestHPackCoding.java
@@ -66,8 +66,17 @@ public class TestHPackCoding {
     }
 
     static ByteBuffer wrap(final ByteArrayBuffer src) {
+        // Use buffers with array offsets to verify correcness in additional cases
+        final byte[] originalArray = src.array();
+        final byte[] newArray = new byte[originalArray.length + 2];
+        System.arraycopy(originalArray, 0, newArray, 1, src.length());
+        return ByteBuffer.wrap(newArray, 1, src.length()).slice();
+    }
 
-        return ByteBuffer.wrap(src.array(), 0, src.length());
+    private static byte[] toArray(final ByteBuffer buffer) {
+        final byte[] result = new byte[buffer.remaining()];
+        buffer.get(result);
+        return result;
     }
 
     @Test
@@ -192,7 +201,7 @@ public class TestHPackCoding {
         HPackEncoder.encodeHuffman(buffer, createByteBuffer("www.example.com", StandardCharsets.US_ASCII));
         final ByteBuffer expected = createByteBuffer(
                 0xf1, 0xe3, 0xc2, 0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 0xff);
-        Assert.assertEquals(expected, wrap(buffer));
+        Assert.assertArrayEquals(toArray(expected), buffer.toByteArray());
     }
 
     @Test
@@ -205,13 +214,13 @@ public class TestHPackCoding {
         encoder.encodeString(buffer, "this and that", false);
 
         final StringBuilder strBuf = new StringBuilder();
-        decoder.decodeString(ByteBuffer.wrap(buffer.array(), 0, buffer.length()), strBuf);
+        decoder.decodeString(wrap(buffer), strBuf);
         Assert.assertEquals("this and that", strBuf.toString());
 
         buffer.clear();
         strBuf.setLength(0);
         encoder.encodeString(buffer, "this and that and Huffman", true);
-        decoder.decodeString(ByteBuffer.wrap(buffer.array(), 0, buffer.length()), strBuf);
+        decoder.decodeString(wrap(buffer), strBuf);
         Assert.assertEquals("this and that and Huffman", strBuf.toString());
     }
 
@@ -257,7 +266,7 @@ public class TestHPackCoding {
                     buffer.clear();
                     encoder.encodeString(buffer, hello, b);
                     strBuf.setLength(0);
-                    decoder.decodeString(ByteBuffer.wrap(buffer.array(), 0, buffer.length()), strBuf);
+                    decoder.decodeString(wrap(buffer), strBuf);
                     final String helloBack = strBuf.toString();
                     Assert.assertEquals("charset: " + charset + "; huffman: " + b, hello, helloBack);
                 }
@@ -285,7 +294,7 @@ public class TestHPackCoding {
                     buffer.clear();
                     strBuf.setLength(0);
                     encoder.encodeString(buffer, hello, b);
-                    decoder.decodeString(ByteBuffer.wrap(buffer.array(), 0, buffer.length()), strBuf);
+                    decoder.decodeString(wrap(buffer), strBuf);
                     final String helloBack = strBuf.toString();
                     Assert.assertEquals("charset: " + charset + "; huffman: " + b, hello, helloBack);
                 }
@@ -1004,7 +1013,7 @@ public class TestHPackCoding {
         decoder1.setMaxTableSize(48);
 
         encoder1.encodeHeader(buffer, header);
-        assertHeaderEquals(header, decoder1.decodeHeader(ByteBuffer.wrap(buffer.array(), 0, buffer.length())));
+        assertHeaderEquals(header, decoder1.decodeHeader(wrap(buffer)));
 
         Assert.assertEquals(1, outboundTable1.dynamicLength());
         Assert.assertEquals(1, inboundTable1.dynamicLength());
@@ -1023,7 +1032,7 @@ public class TestHPackCoding {
         decoder2.setMaxTableSize(48);
 
         encoder2.encodeHeader(buffer, header);
-        assertHeaderEquals(header, decoder2.decodeHeader(ByteBuffer.wrap(buffer.array(), 0, buffer.length())));
+        assertHeaderEquals(header, decoder2.decodeHeader(wrap(buffer)));
 
         Assert.assertEquals(0, outboundTable2.dynamicLength());
         Assert.assertEquals(0, inboundTable2.dynamicLength());
@@ -1044,13 +1053,13 @@ public class TestHPackCoding {
                                 "123456789012345678901234567890123456789012345678901234567890")),
                 false);
 
-        Assert.assertThat(decoder.decodeHeaders(ByteBuffer.wrap(buf.toByteArray())).size(), CoreMatchers.equalTo(2));
+        Assert.assertThat(decoder.decodeHeaders(wrap(buf)).size(), CoreMatchers.equalTo(2));
 
         decoder.setMaxListSize(1000000);
-        Assert.assertThat(decoder.decodeHeaders(ByteBuffer.wrap(buf.toByteArray())).size(), CoreMatchers.equalTo(2));
+        Assert.assertThat(decoder.decodeHeaders(wrap(buf)).size(), CoreMatchers.equalTo(2));
 
         decoder.setMaxListSize(200);
-        decoder.decodeHeaders(ByteBuffer.wrap(buf.toByteArray()));
+        decoder.decodeHeaders(wrap(buf));
     }
 
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionInputBufferImpl.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionInputBufferImpl.java
index 52f9b29..cab13b7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionInputBufferImpl.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionInputBufferImpl.java
@@ -250,7 +250,7 @@ class SessionInputBufferImpl extends ExpandableBuffer implements SessionInputBuf
                 final byte[] b = buffer().array();
                 final int off = buffer().position();
                 final int len = buffer().remaining();
-                lineBuffer.append(b, off, len);
+                lineBuffer.append(b, buffer().arrayOffset() + off, len);
                 buffer().position(off + len);
             } else {
                 while (buffer().hasRemaining()) {
@@ -275,7 +275,7 @@ class SessionInputBufferImpl extends ExpandableBuffer implements SessionInputBuf
                     this.charbuffer.flip();
                     lineBuffer.append(
                             this.charbuffer.array(),
-                            this.charbuffer.position(),
+                            this.charbuffer.arrayOffset() + this.charbuffer.position(),
                             this.charbuffer.remaining());
                     this.charbuffer.clear();
                 }
@@ -291,7 +291,7 @@ class SessionInputBufferImpl extends ExpandableBuffer implements SessionInputBuf
             if (this.charbuffer.hasRemaining()) {
                 lineBuffer.append(
                         this.charbuffer.array(),
-                        this.charbuffer.position(),
+                        this.charbuffer.arrayOffset() + this.charbuffer.position(),
                         this.charbuffer.remaining());
             }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionOutputBufferImpl.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionOutputBufferImpl.java
index bfc81df..23b8da2 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionOutputBufferImpl.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/SessionOutputBufferImpl.java
@@ -169,8 +169,9 @@ class SessionOutputBufferImpl extends ExpandableBuffer implements SessionOutputB
                     final byte[] b = buffer().array();
                     final int len = lineBuffer.length();
                     final int off = buffer().position();
+                    final int arrayOffset = buffer().arrayOffset();
                     for (int i = 0; i < len; i++) {
-                        b[off + i]  = (byte) lineBuffer.charAt(i);
+                        b[arrayOffset + off + i]  = (byte) lineBuffer.charAt(i);
                     }
                     buffer().position(off + len);
                 } else {