@@ -102,62 +102,84 @@ def unpackb(packed, **kwargs):
102
102
103
103
104
104
class Unpacker (object ):
105
- """
106
- Streaming unpacker.
105
+ """Streaming unpacker.
106
+
107
+ arguments:
107
108
108
- `file_like` is a file-like object having a `.read(n)` method.
109
- When `Unpacker` is initialized with a `file_like`, `.feed( )` is not
110
- usable.
109
+ :param file_like:
110
+ File-like object having `.read(n )` method.
111
+ If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable.
111
112
112
- `read_size` is used for `file_like.read(read_size)`.
113
+ :param int read_size:
114
+ Used as `file_like.read(read_size)`. (default: `min(1024**2, max_buffer_size)`)
113
115
114
- If `use_list` is True (default), msgpack lists are deserialized to Python
115
- lists. Otherwise they are deserialized to tuples.
116
+ :param bool use_list:
117
+ If true, unpack msgpack array to Python list.
118
+ Otherwise, unpack to Python tuple. (default: True)
116
119
117
- `object_hook` is the same as in simplejson. If it is not None, it should
118
- be callable and Unpacker calls it with a dict argument after deserializing
119
- a map.
120
+ :param callable object_hook:
121
+ When specified, it should be callable.
122
+ Unpacker calls it with a dict argument after unpacking msgpack map.
123
+ (See also simplejson)
120
124
121
- `object_pairs_hook` is the same as in simplejson. If it is not None, it
122
- should be callable and Unpacker calls it with a list of key-value pairs
123
- after deserializing a map.
125
+ :param callable object_pairs_hook:
126
+ When specified, it should be callable.
127
+ Unpacker calls it with a list of key-value pairs after unpacking msgpack map.
128
+ (See also simplejson)
124
129
125
- `ext_hook` is callback for ext (User defined) type. It called with two
126
- arguments: (code, bytes). default: `msgpack.ExtType`
130
+ :param str encoding:
131
+ Encoding used for decoding msgpack raw.
132
+ If it is None (default), msgpack raw is deserialized to Python bytes.
127
133
128
- `encoding` is the encoding used for decoding msgpack bytes. If it is
129
- None (default), msgpack bytes are deserialized to Python bytes.
134
+ :param str unicode_errors:
135
+ Used for decoding msgpack raw with *encoding*.
136
+ (default: `'strict'`)
130
137
131
- `unicode_errors` is used for decoding bytes.
138
+ :param int max_buffer_size:
139
+ Limits size of data waiting unpacked. 0 means system's INT_MAX (default).
140
+ Raises `BufferFull` exception when it is insufficient.
141
+ You shoud set this parameter when unpacking data from untrasted source.
132
142
133
- `max_buffer_size` limits the buffer size. 0 means INT_MAX (default).
143
+ :param int max_str_len:
144
+ Limits max length of str. (default: 2**31-1)
134
145
135
- Raises `BufferFull` exception when it is unsufficient.
146
+ :param int max_bin_len:
147
+ Limits max length of bin. (default: 2**31-1)
136
148
137
- You should set this parameter when unpacking data from an untrustred source.
149
+ :param int max_array_len:
150
+ Limits max length of array. (default: 2**31-1)
138
151
139
- example of streaming deserialization from file-like object::
152
+ :param int max_map_len:
153
+ Limits max length of map. (default: 2**31-1)
154
+
155
+
156
+ example of streaming deserialize from file-like object::
140
157
141
158
unpacker = Unpacker(file_like)
142
159
for o in unpacker:
143
- do_something (o)
160
+ process (o)
144
161
145
- example of streaming deserialization from socket::
162
+ example of streaming deserialize from socket::
146
163
147
164
unpacker = Unpacker()
148
- while 1 :
149
- buf = sock.recv(1024*2)
165
+ while True :
166
+ buf = sock.recv(1024** 2)
150
167
if not buf:
151
168
break
152
169
unpacker.feed(buf)
153
170
for o in unpacker:
154
- do_something (o)
171
+ process (o)
155
172
"""
156
173
157
174
def __init__ (self , file_like = None , read_size = 0 , use_list = True ,
158
175
object_hook = None , object_pairs_hook = None , list_hook = None ,
159
176
encoding = None , unicode_errors = 'strict' , max_buffer_size = 0 ,
160
- ext_hook = ExtType ):
177
+ ext_hook = ExtType ,
178
+ max_str_len = 2147483647 , # 2**32-1
179
+ max_bin_len = 2147483647 ,
180
+ max_array_len = 2147483647 ,
181
+ max_map_len = 2147483647 ,
182
+ max_ext_len = 2147483647 ):
161
183
if file_like is None :
162
184
self ._fb_feeding = True
163
185
else :
@@ -185,6 +207,11 @@ def __init__(self, file_like=None, read_size=0, use_list=True,
185
207
self ._object_hook = object_hook
186
208
self ._object_pairs_hook = object_pairs_hook
187
209
self ._ext_hook = ext_hook
210
+ self ._max_str_len = max_str_len
211
+ self ._max_bin_len = max_bin_len
212
+ self ._max_array_len = max_array_len
213
+ self ._max_map_len = max_map_len
214
+ self ._max_ext_len = max_ext_len
188
215
189
216
if list_hook is not None and not callable (list_hook ):
190
217
raise TypeError ('`list_hook` is not callable' )
@@ -316,12 +343,18 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
316
343
n = b & 0b00011111
317
344
obj = self ._fb_read (n , write_bytes )
318
345
typ = TYPE_RAW
346
+ if n > self ._max_str_len :
347
+ raise ValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
319
348
elif b & 0b11110000 == 0b10010000 :
320
349
n = b & 0b00001111
321
350
typ = TYPE_ARRAY
351
+ if n > self ._max_array_len :
352
+ raise ValueError ("%s exceeds max_array_len(%s)" , n , self ._max_array_len )
322
353
elif b & 0b11110000 == 0b10000000 :
323
354
n = b & 0b00001111
324
355
typ = TYPE_MAP
356
+ if n > self ._max_map_len :
357
+ raise ValueError ("%s exceeds max_map_len(%s)" , n , self ._max_map_len )
325
358
elif b == 0xc0 :
326
359
obj = None
327
360
elif b == 0xc2 :
@@ -331,26 +364,38 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
331
364
elif b == 0xc4 :
332
365
typ = TYPE_BIN
333
366
n = struct .unpack ("B" , self ._fb_read (1 , write_bytes ))[0 ]
367
+ if n > self ._max_bin_len :
368
+ raise ValueError ("%s exceeds max_bin_len(%s)" % (n , self ._max_bin_len ))
334
369
obj = self ._fb_read (n , write_bytes )
335
370
elif b == 0xc5 :
336
371
typ = TYPE_BIN
337
372
n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
373
+ if n > self ._max_bin_len :
374
+ raise ValueError ("%s exceeds max_bin_len(%s)" % (n , self ._max_bin_len ))
338
375
obj = self ._fb_read (n , write_bytes )
339
376
elif b == 0xc6 :
340
377
typ = TYPE_BIN
341
378
n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
379
+ if n > self ._max_bin_len :
380
+ raise ValueError ("%s exceeds max_bin_len(%s)" % (n , self ._max_bin_len ))
342
381
obj = self ._fb_read (n , write_bytes )
343
382
elif b == 0xc7 : # ext 8
344
383
typ = TYPE_EXT
345
384
L , n = struct .unpack ('Bb' , self ._fb_read (2 , write_bytes ))
385
+ if L > self ._max_ext_len :
386
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (L , self ._max_ext_len ))
346
387
obj = self ._fb_read (L , write_bytes )
347
388
elif b == 0xc8 : # ext 16
348
389
typ = TYPE_EXT
349
390
L , n = struct .unpack ('>Hb' , self ._fb_read (3 , write_bytes ))
391
+ if L > self ._max_ext_len :
392
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (L , self ._max_ext_len ))
350
393
obj = self ._fb_read (L , write_bytes )
351
394
elif b == 0xc9 : # ext 32
352
395
typ = TYPE_EXT
353
396
L , n = struct .unpack ('>Ib' , self ._fb_read (5 , write_bytes ))
397
+ if L > self ._max_ext_len :
398
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (L , self ._max_ext_len ))
354
399
obj = self ._fb_read (L , write_bytes )
355
400
elif b == 0xca :
356
401
obj = struct .unpack (">f" , self ._fb_read (4 , write_bytes ))[0 ]
@@ -374,42 +419,66 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
374
419
obj = struct .unpack (">q" , self ._fb_read (8 , write_bytes ))[0 ]
375
420
elif b == 0xd4 : # fixext 1
376
421
typ = TYPE_EXT
422
+ if self ._max_ext_len < 1 :
423
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (1 , self ._max_ext_len ))
377
424
n , obj = struct .unpack ('b1s' , self ._fb_read (2 , write_bytes ))
378
425
elif b == 0xd5 : # fixext 2
379
426
typ = TYPE_EXT
427
+ if self ._max_ext_len < 2 :
428
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (2 , self ._max_ext_len ))
380
429
n , obj = struct .unpack ('b2s' , self ._fb_read (3 , write_bytes ))
381
430
elif b == 0xd6 : # fixext 4
382
431
typ = TYPE_EXT
432
+ if self ._max_ext_len < 4 :
433
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (4 , self ._max_ext_len ))
383
434
n , obj = struct .unpack ('b4s' , self ._fb_read (5 , write_bytes ))
384
435
elif b == 0xd7 : # fixext 8
385
436
typ = TYPE_EXT
437
+ if self ._max_ext_len < 8 :
438
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (8 , self ._max_ext_len ))
386
439
n , obj = struct .unpack ('b8s' , self ._fb_read (9 , write_bytes ))
387
440
elif b == 0xd8 : # fixext 16
388
441
typ = TYPE_EXT
442
+ if self ._max_ext_len < 16 :
443
+ raise ValueError ("%s exceeds max_ext_len(%s)" % (16 , self ._max_ext_len ))
389
444
n , obj = struct .unpack ('b16s' , self ._fb_read (17 , write_bytes ))
390
445
elif b == 0xd9 :
391
446
typ = TYPE_RAW
392
447
n = struct .unpack ("B" , self ._fb_read (1 , write_bytes ))[0 ]
448
+ if n > self ._max_str_len :
449
+ raise ValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
393
450
obj = self ._fb_read (n , write_bytes )
394
451
elif b == 0xda :
395
452
typ = TYPE_RAW
396
453
n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
454
+ if n > self ._max_str_len :
455
+ raise ValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
397
456
obj = self ._fb_read (n , write_bytes )
398
457
elif b == 0xdb :
399
458
typ = TYPE_RAW
400
459
n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
460
+ if n > self ._max_str_len :
461
+ raise ValueError ("%s exceeds max_str_len(%s)" , n , self ._max_str_len )
401
462
obj = self ._fb_read (n , write_bytes )
402
463
elif b == 0xdc :
403
464
n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
465
+ if n > self ._max_array_len :
466
+ raise ValueError ("%s exceeds max_array_len(%s)" , n , self ._max_array_len )
404
467
typ = TYPE_ARRAY
405
468
elif b == 0xdd :
406
469
n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
470
+ if n > self ._max_array_len :
471
+ raise ValueError ("%s exceeds max_array_len(%s)" , n , self ._max_array_len )
407
472
typ = TYPE_ARRAY
408
473
elif b == 0xde :
409
474
n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
475
+ if n > self ._max_map_len :
476
+ raise ValueError ("%s exceeds max_map_len(%s)" , n , self ._max_map_len )
410
477
typ = TYPE_MAP
411
478
elif b == 0xdf :
412
479
n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
480
+ if n > self ._max_map_len :
481
+ raise ValueError ("%s exceeds max_map_len(%s)" , n , self ._max_map_len )
413
482
typ = TYPE_MAP
414
483
else :
415
484
raise UnpackValueError ("Unknown header: 0x%x" % b )
0 commit comments