Skip to content

Commit

Permalink
Added a new ZeroLengthHeaderNameError
Browse files Browse the repository at this point in the history
This that indicates that an invalid header has been received. This
places the HPACK decoder into a broken state: it must not be used
after this exception is thrown.
  • Loading branch information
pgjones committed Aug 27, 2019
1 parent ec8c671 commit 5b47c05
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
4 changes: 4 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Release History

**API Changes (Backward Compatible)**

- Added a new ``ZeroLengthHeaderNameError`` that indicates that an
invalid header has been received. This places the HPACK decoder into
a broken state: it must not be used after this exception is thrown.

**Bugfixes**

- Performance improvement of static header search. Use dict search instead
Expand Down
5 changes: 3 additions & 2 deletions hpack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
from .hpack import Encoder, Decoder
from .struct import HeaderTuple, NeverIndexedHeaderTuple
from .exceptions import (
HPACKError, HPACKDecodingError, InvalidTableIndex, OversizedHeaderListError
HPACKError, HPACKDecodingError, InvalidTableIndex,
OversizedHeaderListError, ZeroLengthHeaderNameError,
)

__all__ = [
'Encoder', 'Decoder', 'HPACKError', 'HPACKDecodingError',
'InvalidTableIndex', 'HeaderTuple', 'NeverIndexedHeaderTuple',
'OversizedHeaderListError'
'OversizedHeaderListError', 'ZeroLengthHeaderNameError',
]

__version__ = '3.1.0dev0'
9 changes: 9 additions & 0 deletions hpack/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,12 @@ class InvalidTableSizeError(HPACKDecodingError):
.. versionadded:: 3.0.0
"""
pass


class ZeroLengthHeaderNameError(HPACKDecodingError):
"""
An invalid header with a zero length name has been received.
.. versionadded:: 3.1.0
"""
pass
11 changes: 10 additions & 1 deletion hpack/hpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
from .table import HeaderTable, table_entry_size
from .compat import to_byte, to_bytes
from .exceptions import (
HPACKDecodingError, OversizedHeaderListError, InvalidTableSizeError
HPACKDecodingError, OversizedHeaderListError, InvalidTableSizeError,
ZeroLengthHeaderNameError,
)
from .huffman import HuffmanEncoder
from .huffman_constants import (
Expand Down Expand Up @@ -496,6 +497,7 @@ def decode(self, data, raw=False):

if header:
headers.append(header)
self._assert_valid_header_name_size(header)
inflated_size += table_entry_size(*header)

if inflated_size > self.max_header_list_size:
Expand All @@ -516,6 +518,13 @@ def decode(self, data, raw=False):
except UnicodeDecodeError:
raise HPACKDecodingError("Unable to decode headers as UTF-8.")

def _assert_valid_header_name_size(self, header):
"""
Check that the header name size is valid, i.e. non-zero.
"""
if len(header[0]) == 0:
raise ZeroLengthHeaderNameError()

def _assert_valid_table_size(self):
"""
Check that the table size set by the encoder is lower than the maximum
Expand Down
12 changes: 11 additions & 1 deletion test/test_hpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from hpack.hpack import Encoder, Decoder, _dict_to_iterable, _to_bytes
from hpack.exceptions import (
HPACKDecodingError, InvalidTableIndex, OversizedHeaderListError,
InvalidTableSizeError
InvalidTableSizeError, ZeroLengthHeaderNameError,
)
from hpack.struct import HeaderTuple, NeverIndexedHeaderTuple
import itertools
Expand Down Expand Up @@ -638,6 +638,16 @@ def test_max_header_list_size(self):
with pytest.raises(OversizedHeaderListError):
d.decode(data)

def test_zero_length_header(self):
"""
If a header has a name of zero length it is invalid and the HPACK
decoder raises a ZeroLengthHeaderNameError.
"""
d = Decoder(max_header_list_size=44)
data = b"@\x80\x80"
with pytest.raises(ZeroLengthHeaderNameError):
d.decode(data)

def test_can_decode_multiple_header_table_size_changes(self):
"""
If multiple header table size changes are sent in at once, they are
Expand Down

0 comments on commit 5b47c05

Please sign in to comment.