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