summaryrefslogtreecommitdiff
path: root/msgpack/fallback.py
diff options
context:
space:
mode:
Diffstat (limited to 'msgpack/fallback.py')
-rw-r--r--msgpack/fallback.py43
1 files changed, 38 insertions, 5 deletions
diff --git a/msgpack/fallback.py b/msgpack/fallback.py
index 04fb5b9..9c767a7 100644
--- a/msgpack/fallback.py
+++ b/msgpack/fallback.py
@@ -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