@@ -18,6 +18,16 @@ def dict_iteritems(d):
1818 def dict_iteritems (d ):
1919 return d .iteritems ()
2020
21+ if sys .version_info < (3 , 5 ):
22+ # Ugly hack...
23+ RecursionError = RuntimeError
24+
25+ def _is_recursionerror (e ):
26+ return len (e .args ) == 1 and isinstance (e .args [0 ], str ) and \
27+ e .args [0 ].startswith ('maximum recursion depth exceeded' )
28+ else :
29+ def _is_recursionerror (e ):
30+ return True
2131
2232if hasattr (sys , 'pypy_version_info' ):
2333 # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own
@@ -52,7 +62,10 @@ def getvalue(self):
5262from msgpack .exceptions import (
5363 BufferFull ,
5464 OutOfData ,
55- ExtraData )
65+ ExtraData ,
66+ FormatError ,
67+ StackError ,
68+ )
5669
5770from msgpack import ExtType
5871
@@ -109,15 +122,24 @@ def unpackb(packed, **kwargs):
109122 """
110123 Unpack an object from `packed`.
111124
112- Raises `ExtraData` when `packed` contains extra bytes.
125+ Raises ``ExtraData`` when *packed* contains extra bytes.
126+ Raises ``ValueError`` when *packed* is incomplete.
127+ Raises ``FormatError`` when *packed* is not valid msgpack.
128+ Raises ``StackError`` when *packed* contains too nested.
129+ Other exceptions can be raised during unpacking.
130+
113131 See :class:`Unpacker` for options.
114132 """
115133 unpacker = Unpacker (None , ** kwargs )
116134 unpacker .feed (packed )
117135 try :
118136 ret = unpacker ._unpack ()
119137 except OutOfData :
120- raise ValueError ("Data is not enough." )
138+ raise ValueError ("Unpack failed: incomplete input" )
139+ except RecursionError as e :
140+ if _is_recursionerror (e ):
141+ raise StackError
142+ raise
121143 if unpacker ._got_extradata ():
122144 raise ExtraData (ret , unpacker ._get_extradata ())
123145 return ret
@@ -211,6 +233,12 @@ class Unpacker(object):
211233 unpacker.feed(buf)
212234 for o in unpacker:
213235 process(o)
236+
237+ Raises ``ExtraData`` when *packed* contains extra bytes.
238+ Raises ``OutOfData`` when *packed* is incomplete.
239+ Raises ``FormatError`` when *packed* is not valid msgpack.
240+ Raises ``StackError`` when *packed* contains too nested.
241+ Other exceptions can be raised during unpacking.
214242 """
215243
216244 def __init__ (self , file_like = None , read_size = 0 , use_list = True , raw = True ,
@@ -561,7 +589,7 @@ def _read_header(self, execute=EX_CONSTRUCT):
561589 raise ValueError ("%s exceeds max_map_len(%s)" , n , self ._max_map_len )
562590 typ = TYPE_MAP
563591 else :
564- raise ValueError ("Unknown header: 0x%x" % b )
592+ raise FormatError ("Unknown header: 0x%x" % b )
565593 return typ , n , obj
566594
567595 def _unpack (self , execute = EX_CONSTRUCT ):
@@ -637,6 +665,8 @@ def __next__(self):
637665 except OutOfData :
638666 self ._consume ()
639667 raise StopIteration
668+ except RecursionError :
669+ raise StackError
640670
641671 next = __next__
642672
@@ -645,7 +675,10 @@ def skip(self):
645675 self ._consume ()
646676
647677 def unpack (self ):
648- ret = self ._unpack (EX_CONSTRUCT )
678+ try :
679+ ret = self ._unpack (EX_CONSTRUCT )
680+ except RecursionError :
681+ raise StackError
649682 self ._consume ()
650683 return ret
651684
0 commit comments