You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2021/12/07 15:55:26 UTC

[httpcomponents-core] branch master updated: HTTPCORE-704: HPackDecoder fails to correctly encode / decode an empty header if a non-ASCII charset is being used

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

olegk 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 b313afc  HTTPCORE-704: HPackDecoder fails to correctly encode / decode an empty header if a non-ASCII charset is being used
b313afc is described below

commit b313afc611c16936e8c69c6bc533864014b70f4d
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Dec 7 15:38:38 2021 +0100

    HTTPCORE-704: HPackDecoder fails to correctly encode / decode an empty header if a non-ASCII charset is being used
---
 .../apache/hc/core5/http2/hpack/HPackDecoder.java  |  3 +++
 .../apache/hc/core5/http2/hpack/HPackEncoder.java  | 20 +++++++++-------
 .../hc/core5/http2/hpack/TestHPackCoding.java      | 28 ++++++++++++++++++++++
 3 files changed, 42 insertions(+), 9 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 1df29a2..3f35676 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
@@ -193,6 +193,9 @@ public final class HPackDecoder {
         clearState();
         decodeString(this.contentBuf, src);
         final int binaryLen = this.contentBuf.length();
+        if (binaryLen == 0) {
+            return 0;
+        }
         if (this.charsetDecoder == null) {
             buf.ensureCapacity(binaryLen);
             for (int i = 0; i < binaryLen; 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 621bdf4..c582187 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
@@ -166,19 +166,21 @@ public final class HPackEncoder {
             }
             return len;
         }
-        final CharBuffer in = CharBuffer.wrap(charSequence, off, len);
-        while (in.hasRemaining()) {
-            ensureCapacity((int) (in.remaining() * this.charsetEncoder.averageBytesPerChar()) + 8);
-            final CoderResult result = this.charsetEncoder.encode(in, this.tmpBuf, true);
+        if (charSequence.length() > 0) {
+            final CharBuffer in = CharBuffer.wrap(charSequence, off, len);
+            while (in.hasRemaining()) {
+                ensureCapacity((int) (in.remaining() * this.charsetEncoder.averageBytesPerChar()) + 8);
+                final CoderResult result = this.charsetEncoder.encode(in, this.tmpBuf, true);
+                if (result.isError()) {
+                    result.throwException();
+                }
+            }
+            ensureCapacity(8);
+            final CoderResult result = this.charsetEncoder.flush(this.tmpBuf);
             if (result.isError()) {
                 result.throwException();
             }
         }
-        ensureCapacity(8);
-        final CoderResult result = this.charsetEncoder.flush(this.tmpBuf);
-        if (result.isError()) {
-            result.throwException();
-        }
         this.tmpBuf.flip();
         final int binaryLen = this.tmpBuf.remaining();
         encodeString(dst, this.tmpBuf, huffman);
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 7674b53..47dc1ce 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
@@ -1065,5 +1065,33 @@ public class TestHPackCoding {
                 decoder.decodeHeaders(wrap(buf)));
     }
 
+    @Test
+    public void testHeaderEmptyASCII() throws Exception {
+
+        final HPackEncoder encoder = new HPackEncoder(StandardCharsets.US_ASCII);
+        final HPackDecoder decoder = new HPackDecoder(StandardCharsets.US_ASCII);
+
+        final ByteArrayBuffer buf = new ByteArrayBuffer(128);
+
+        final Header header = new BasicHeader("empty-header", "");
+        encoder.encodeHeader(buf, header);
+
+        assertHeaderEquals(header, decoder.decodeHeader(wrap(buf)));
+    }
+
+    @Test
+    public void testHeaderEmptyUTF8() throws Exception {
+
+        final HPackEncoder encoder = new HPackEncoder(StandardCharsets.UTF_8);
+        final HPackDecoder decoder = new HPackDecoder(StandardCharsets.UTF_8);
+
+        final ByteArrayBuffer buf = new ByteArrayBuffer(128);
+
+        final Header header = new BasicHeader("empty-header", "");
+        encoder.encodeHeader(buf, header);
+
+        assertHeaderEquals(header, decoder.decodeHeader(wrap(buf)));
+    }
+
 }