Author: markt
Date: Fri Mar 24 15:32:45 2017
New Revision: 1788473

URL: http://svn.apache.org/viewvc?rev=1788473&view=rev
Log:
Huffman encoded string literals must not have more than 7 bits of padding.
Identified by Moto Ishizawa's h2spec tool.

Modified:
    tomcat/trunk/java/org/apache/coyote/http2/HPackHuffman.java
    tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties
    tomcat/trunk/test/org/apache/coyote/http2/TestHpack.java

Modified: tomcat/trunk/java/org/apache/coyote/http2/HPackHuffman.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/HPackHuffman.java?rev=1788473&r1=1788472&r2=1788473&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/HPackHuffman.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/HPackHuffman.java Fri Mar 24 
15:32:45 2017
@@ -379,22 +379,27 @@ public class HPackHuffman {
         assert data.remaining() >= length;
         int treePos = 0;
         boolean eosBits = true;
+        int eosBitCount = 0;
         for (int i = 0; i < length; ++i) {
             byte b = data.get();
             int bitPos = 7;
             while (bitPos >= 0) {
                 int val = DECODING_TABLE[treePos];
                 if (((1 << bitPos) & b) == 0) {
-                    eosBits = false;
                     //bit not set, we want the lower part of the tree
                     if ((val & LOW_TERMINAL_BIT) == 0) {
                         treePos = val & LOW_MASK;
+                        eosBits = false;
+                        eosBitCount = 0;
                     } else {
                         target.append((char) (val & LOW_MASK));
                         treePos = 0;
                         eosBits = true;
                     }
                 } else {
+                    if (eosBits) {
+                        eosBitCount++;
+                    }
                     //bit not set, we want the lower part of the tree
                     if ((val & HIGH_TERMINAL_BIT) == 0) {
                         treePos = (val >> 16) & LOW_MASK;
@@ -407,6 +412,10 @@ public class HPackHuffman {
                 bitPos--;
             }
         }
+        if (eosBitCount > 7) {
+            throw new HpackException(sm.getString(
+                    "hpackhuffman.stringLiteralTooMuchPadding"));
+        }
         if (!eosBits) {
             throw new HpackException(sm.getString(
                     "hpackhuffman.huffmanEncodedHpackValueDidNotEndWithEOS"));

Modified: tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties?rev=1788473&r1=1788472&r2=1788473&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Fri Mar 
24 15:32:45 2017
@@ -40,6 +40,7 @@ hpackdecoder.tableSizeUpdateNotAtStart=A
 hpackEncoder.encodeHeader=Encoding header [{0}] with value [{1}]
 
 hpackhuffman.huffmanEncodedHpackValueDidNotEndWithEOS=Huffman encoded value in 
HPACK headers did not end with EOS padding
+hpackhuffman.stringLiteralTooMuchPadding=More than 7 bits of EOS padding were 
provided at the end of an Huffman encoded string literal
 
 http2Parser.headerLimitCount=Connection [{0}], Stream [{1}], Too many headers
 http2Parser.headerLimitSize=Connection [{0}], Stream [{1}], Total header size 
too big

Modified: tomcat/trunk/test/org/apache/coyote/http2/TestHpack.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHpack.java?rev=1788473&r1=1788472&r2=1788473&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/TestHpack.java (original)
+++ tomcat/trunk/test/org/apache/coyote/http2/TestHpack.java Fri Mar 24 
15:32:45 2017
@@ -105,6 +105,25 @@ public class TestHpack {
         }
     }
 
+    @Test(expected=HpackException.class)
+    public void testExcessiveStringLiteralPadding() throws Exception {
+        MimeHeaders headers = new MimeHeaders();
+        headers.setValue("X-test").setString("foobar");
+        ByteBuffer output = ByteBuffer.allocate(512);
+        HpackEncoder encoder = new HpackEncoder();
+        encoder.encode(headers, output);
+        // Hack the output buffer to extend the EOS marker for the header value
+        // by another byte
+        output.array()[7] = (byte) -122;
+        output.put((byte) -1);
+        output.flip();
+        MimeHeaders headers2 = new MimeHeaders();
+        HpackDecoder decoder = new HpackDecoder();
+        decoder.setHeaderEmitter(new HeadersListener(headers2));
+        decoder.decode(output);
+    }
+
+
     private void doTestHeaderValueBug60451(String filename) throws 
HpackException {
         String headerName = "Content-Disposition";
         String headerValue = "attachment;filename=\"" + filename + "\"";



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to