HPackDecoder incorrectly calculates required buffer length causing G1 Humongous Allocation and OOM (#465)
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 3f35676..880d0cc 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
@@ -158,6 +158,10 @@
}
}
+ int getTmpBufSize() {
+ return tmpBuf == null ? 0 : tmpBuf.capacity();
+ }
+
private void clearState() {
if (this.tmpBuf != null) {
@@ -182,7 +186,7 @@
if (this.tmpBuf == null) {
this.tmpBuf = CharBuffer.allocate(Math.max(256, extra));
}
- final int requiredCapacity = this.tmpBuf.remaining() + extra;
+ final int requiredCapacity = this.tmpBuf.position() + extra;
if (requiredCapacity > this.tmpBuf.capacity()) {
expandCapacity(requiredCapacity);
}
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 47dc1ce..ed1f4d1 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
@@ -226,6 +226,23 @@
Assertions.assertEquals("this and that and Huffman", strBuf.toString());
}
+ @Test
+ public void testEnsureCapacity() throws Exception {
+
+ final HPackEncoder encoder = new HPackEncoder(StandardCharsets.US_ASCII);
+ final HPackDecoder decoder = new HPackDecoder(StandardCharsets.UTF_8);
+
+ final ByteArrayBuffer buffer = new ByteArrayBuffer(16);
+ encoder.encodeString(buffer, "this and that", false);
+
+ final StringBuilder strBuf = new StringBuilder();
+ for (int i = 0; i < 1000; i++) {
+ decoder.decodeString(wrap(buffer), strBuf);
+ strBuf.delete(0,strBuf.length());
+ }
+ Assertions.assertEquals(decoder.getTmpBufSize(), 256);
+ }
+
static final int SWISS_GERMAN_HELLO[] = {
0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
};