Add StackError and FormatError (#331)

This commit is contained in:
INADA Naoki 2018-11-20 13:12:49 +09:00 committed by GitHub
parent 8b6ce53cce
commit 44254dd35e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 48 deletions

View file

@ -18,6 +18,16 @@ else:
def dict_iteritems(d):
return d.iteritems()
if sys.version_info < (3, 5):
# Ugly hack...
RecursionError = RuntimeError
def _is_recursionerror(e):
return len(e.args) == 1 and isinstance(e.args[0], str) and \
e.args[0].startswith('maximum recursion depth exceeded')
else:
def _is_recursionerror(e):
return True
if hasattr(sys, 'pypy_version_info'):
# cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own
@ -52,7 +62,10 @@ else:
from msgpack.exceptions import (
BufferFull,
OutOfData,
ExtraData)
ExtraData,
FormatError,
StackError,
)
from msgpack import ExtType
@ -109,7 +122,12 @@ def unpackb(packed, **kwargs):
"""
Unpack an object from `packed`.
Raises `ExtraData` when `packed` contains extra bytes.
Raises ``ExtraData`` when *packed* contains extra bytes.
Raises ``ValueError`` when *packed* is incomplete.
Raises ``FormatError`` when *packed* is not valid msgpack.
Raises ``StackError`` when *packed* contains too nested.
Other exceptions can be raised during unpacking.
See :class:`Unpacker` for options.
"""
unpacker = Unpacker(None, **kwargs)
@ -117,7 +135,11 @@ def unpackb(packed, **kwargs):
try:
ret = unpacker._unpack()
except OutOfData:
raise ValueError("Data is not enough.")
raise ValueError("Unpack failed: incomplete input")
except RecursionError as e:
if _is_recursionerror(e):
raise StackError
raise
if unpacker._got_extradata():
raise ExtraData(ret, unpacker._get_extradata())
return ret
@ -211,6 +233,12 @@ class Unpacker(object):
unpacker.feed(buf)
for o in unpacker:
process(o)
Raises ``ExtraData`` when *packed* contains extra bytes.
Raises ``OutOfData`` when *packed* is incomplete.
Raises ``FormatError`` when *packed* is not valid msgpack.
Raises ``StackError`` when *packed* contains too nested.
Other exceptions can be raised during unpacking.
"""
def __init__(self, file_like=None, read_size=0, use_list=True, raw=True,
@ -561,7 +589,7 @@ class Unpacker(object):
raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
typ = TYPE_MAP
else:
raise ValueError("Unknown header: 0x%x" % b)
raise FormatError("Unknown header: 0x%x" % b)
return typ, n, obj
def _unpack(self, execute=EX_CONSTRUCT):
@ -637,6 +665,8 @@ class Unpacker(object):
except OutOfData:
self._consume()
raise StopIteration
except RecursionError:
raise StackError
next = __next__
@ -645,7 +675,10 @@ class Unpacker(object):
self._consume()
def unpack(self):
ret = self._unpack(EX_CONSTRUCT)
try:
ret = self._unpack(EX_CONSTRUCT)
except RecursionError:
raise StackError
self._consume()
return ret