mirror of
https://github.com/msgpack/msgpack-python.git
synced 2025-10-24 14:23:19 +00:00
Auto limit configuration (#342)
This commit is contained in:
parent
f46523b1af
commit
28b5f46a34
3 changed files with 92 additions and 28 deletions
|
|
@ -145,11 +145,11 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
|
||||||
bint use_list=True, bint raw=True, bint strict_map_key=False,
|
bint use_list=True, bint raw=True, bint strict_map_key=False,
|
||||||
encoding=None, unicode_errors=None,
|
encoding=None, unicode_errors=None,
|
||||||
object_pairs_hook=None, ext_hook=ExtType,
|
object_pairs_hook=None, ext_hook=ExtType,
|
||||||
Py_ssize_t max_str_len=1024*1024,
|
Py_ssize_t max_str_len=-1,
|
||||||
Py_ssize_t max_bin_len=1024*1024,
|
Py_ssize_t max_bin_len=-1,
|
||||||
Py_ssize_t max_array_len=128*1024,
|
Py_ssize_t max_array_len=-1,
|
||||||
Py_ssize_t max_map_len=32*1024,
|
Py_ssize_t max_map_len=-1,
|
||||||
Py_ssize_t max_ext_len=1024*1024):
|
Py_ssize_t max_ext_len=-1):
|
||||||
"""
|
"""
|
||||||
Unpack packed_bytes to object. Returns an unpacked object.
|
Unpack packed_bytes to object. Returns an unpacked object.
|
||||||
|
|
||||||
|
|
@ -160,6 +160,8 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
|
||||||
Other exceptions can be raised during unpacking.
|
Other exceptions can be raised during unpacking.
|
||||||
|
|
||||||
See :class:`Unpacker` for options.
|
See :class:`Unpacker` for options.
|
||||||
|
|
||||||
|
*max_xxx_len* options are configured automatically from ``len(packed)``.
|
||||||
"""
|
"""
|
||||||
cdef unpack_context ctx
|
cdef unpack_context ctx
|
||||||
cdef Py_ssize_t off = 0
|
cdef Py_ssize_t off = 0
|
||||||
|
|
@ -180,6 +182,18 @@ def unpackb(object packed, object object_hook=None, object list_hook=None,
|
||||||
cerr = unicode_errors
|
cerr = unicode_errors
|
||||||
|
|
||||||
get_data_from_buffer(packed, &view, &buf, &buf_len, &new_protocol)
|
get_data_from_buffer(packed, &view, &buf, &buf_len, &new_protocol)
|
||||||
|
|
||||||
|
if max_str_len == -1:
|
||||||
|
max_str_len = buf_len
|
||||||
|
if max_bin_len == -1:
|
||||||
|
max_bin_len = buf_len
|
||||||
|
if max_array_len == -1:
|
||||||
|
max_array_len = buf_len
|
||||||
|
if max_map_len == -1:
|
||||||
|
max_map_len = buf_len//2
|
||||||
|
if max_ext_len == -1:
|
||||||
|
max_ext_len = buf_len
|
||||||
|
|
||||||
try:
|
try:
|
||||||
init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, ext_hook,
|
init_ctx(&ctx, object_hook, object_pairs_hook, list_hook, ext_hook,
|
||||||
use_list, raw, strict_map_key, cenc, cerr,
|
use_list, raw, strict_map_key, cenc, cerr,
|
||||||
|
|
@ -259,19 +273,19 @@ cdef class Unpacker(object):
|
||||||
You should set this parameter when unpacking data from untrusted source.
|
You should set this parameter when unpacking data from untrusted source.
|
||||||
|
|
||||||
:param int max_str_len:
|
:param int max_str_len:
|
||||||
Limits max length of str. (default: 1024*1024)
|
Limits max length of str. (default: max_buffer_size or 1024*1024)
|
||||||
|
|
||||||
:param int max_bin_len:
|
:param int max_bin_len:
|
||||||
Limits max length of bin. (default: 1024*1024)
|
Limits max length of bin. (default: max_buffer_size or 1024*1024)
|
||||||
|
|
||||||
:param int max_array_len:
|
:param int max_array_len:
|
||||||
Limits max length of array. (default: 128*1024)
|
Limits max length of array. (default: max_buffer_size or 128*1024)
|
||||||
|
|
||||||
:param int max_map_len:
|
:param int max_map_len:
|
||||||
Limits max length of map. (default: 32*1024)
|
Limits max length of map. (default: max_buffer_size//2 or 32*1024)
|
||||||
|
|
||||||
:param int max_ext_len:
|
:param int max_ext_len:
|
||||||
Limits max size of ext type. (default: 1024*1024)
|
Limits max size of ext type. (default: max_buffer_size or 1024*1024)
|
||||||
|
|
||||||
:param str encoding:
|
:param str encoding:
|
||||||
Deprecated, use raw instead.
|
Deprecated, use raw instead.
|
||||||
|
|
@ -329,11 +343,11 @@ cdef class Unpacker(object):
|
||||||
object object_hook=None, object object_pairs_hook=None, object list_hook=None,
|
object object_hook=None, object object_pairs_hook=None, object list_hook=None,
|
||||||
encoding=None, unicode_errors=None, Py_ssize_t max_buffer_size=0,
|
encoding=None, unicode_errors=None, Py_ssize_t max_buffer_size=0,
|
||||||
object ext_hook=ExtType,
|
object ext_hook=ExtType,
|
||||||
Py_ssize_t max_str_len=1024*1024,
|
Py_ssize_t max_str_len=-1,
|
||||||
Py_ssize_t max_bin_len=1024*1024,
|
Py_ssize_t max_bin_len=-1,
|
||||||
Py_ssize_t max_array_len=128*1024,
|
Py_ssize_t max_array_len=-1,
|
||||||
Py_ssize_t max_map_len=32*1024,
|
Py_ssize_t max_map_len=-1,
|
||||||
Py_ssize_t max_ext_len=1024*1024):
|
Py_ssize_t max_ext_len=-1):
|
||||||
cdef const char *cenc=NULL,
|
cdef const char *cenc=NULL,
|
||||||
cdef const char *cerr=NULL
|
cdef const char *cerr=NULL
|
||||||
|
|
||||||
|
|
@ -347,6 +361,18 @@ cdef class Unpacker(object):
|
||||||
self.file_like_read = file_like.read
|
self.file_like_read = file_like.read
|
||||||
if not PyCallable_Check(self.file_like_read):
|
if not PyCallable_Check(self.file_like_read):
|
||||||
raise TypeError("`file_like.read` must be a callable.")
|
raise TypeError("`file_like.read` must be a callable.")
|
||||||
|
|
||||||
|
if max_str_len == -1:
|
||||||
|
max_str_len = max_buffer_size or 1024*1024
|
||||||
|
if max_bin_len == -1:
|
||||||
|
max_bin_len = max_buffer_size or 1024*1024
|
||||||
|
if max_array_len == -1:
|
||||||
|
max_array_len = max_buffer_size or 128*1024
|
||||||
|
if max_map_len == -1:
|
||||||
|
max_map_len = max_buffer_size//2 or 32*1024
|
||||||
|
if max_ext_len == -1:
|
||||||
|
max_ext_len = max_buffer_size or 1024*1024
|
||||||
|
|
||||||
if not max_buffer_size:
|
if not max_buffer_size:
|
||||||
max_buffer_size = INT_MAX
|
max_buffer_size = INT_MAX
|
||||||
if read_size > max_buffer_size:
|
if read_size > max_buffer_size:
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ def unpackb(packed, **kwargs):
|
||||||
|
|
||||||
See :class:`Unpacker` for options.
|
See :class:`Unpacker` for options.
|
||||||
"""
|
"""
|
||||||
unpacker = Unpacker(None, **kwargs)
|
unpacker = Unpacker(None, max_buffer_size=len(packed), **kwargs)
|
||||||
unpacker.feed(packed)
|
unpacker.feed(packed)
|
||||||
try:
|
try:
|
||||||
ret = unpacker._unpack()
|
ret = unpacker._unpack()
|
||||||
|
|
@ -208,19 +208,24 @@ class Unpacker(object):
|
||||||
You should set this parameter when unpacking data from untrusted source.
|
You should set this parameter when unpacking data from untrusted source.
|
||||||
|
|
||||||
:param int max_str_len:
|
:param int max_str_len:
|
||||||
Limits max length of str. (default: 1024*1024)
|
(deprecated) Limits max length of str.
|
||||||
|
(default: max_buffer_size or 1024*1024)
|
||||||
|
|
||||||
:param int max_bin_len:
|
:param int max_bin_len:
|
||||||
Limits max length of bin. (default: 1024*1024)
|
(deprecated) Limits max length of bin.
|
||||||
|
(default: max_buffer_size or 1024*1024)
|
||||||
|
|
||||||
:param int max_array_len:
|
:param int max_array_len:
|
||||||
Limits max length of array. (default: 128*1024)
|
Limits max length of array.
|
||||||
|
(default: max_buffer_size or 128*1024)
|
||||||
|
|
||||||
:param int max_map_len:
|
:param int max_map_len:
|
||||||
Limits max length of map. (default: 32*1024)
|
Limits max length of map.
|
||||||
|
(default: max_buffer_size//2 or 32*1024)
|
||||||
|
|
||||||
:param int max_ext_len:
|
:param int max_ext_len:
|
||||||
Limits max size of ext type. (default: 1024*1024)
|
(deprecated) Limits max size of ext type.
|
||||||
|
(default: max_buffer_size or 1024*1024)
|
||||||
|
|
||||||
example of streaming deserialize from file-like object::
|
example of streaming deserialize from file-like object::
|
||||||
|
|
||||||
|
|
@ -250,12 +255,11 @@ class Unpacker(object):
|
||||||
object_hook=None, object_pairs_hook=None, list_hook=None,
|
object_hook=None, object_pairs_hook=None, list_hook=None,
|
||||||
encoding=None, unicode_errors=None, max_buffer_size=0,
|
encoding=None, unicode_errors=None, max_buffer_size=0,
|
||||||
ext_hook=ExtType,
|
ext_hook=ExtType,
|
||||||
max_str_len=1024*1024,
|
max_str_len=-1,
|
||||||
max_bin_len=1024*1024,
|
max_bin_len=-1,
|
||||||
max_array_len=128*1024,
|
max_array_len=-1,
|
||||||
max_map_len=32*1024,
|
max_map_len=-1,
|
||||||
max_ext_len=1024*1024):
|
max_ext_len=-1):
|
||||||
|
|
||||||
if encoding is not None:
|
if encoding is not None:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"encoding is deprecated, Use raw=False instead.",
|
"encoding is deprecated, Use raw=False instead.",
|
||||||
|
|
@ -286,6 +290,17 @@ class Unpacker(object):
|
||||||
# state, which _buf_checkpoint records.
|
# state, which _buf_checkpoint records.
|
||||||
self._buf_checkpoint = 0
|
self._buf_checkpoint = 0
|
||||||
|
|
||||||
|
if max_str_len == -1:
|
||||||
|
max_str_len = max_buffer_size or 1024*1024
|
||||||
|
if max_bin_len == -1:
|
||||||
|
max_bin_len = max_buffer_size or 1024*1024
|
||||||
|
if max_array_len == -1:
|
||||||
|
max_array_len = max_buffer_size or 128*1024
|
||||||
|
if max_map_len == -1:
|
||||||
|
max_map_len = max_buffer_size//2 or 32*1024
|
||||||
|
if max_ext_len == -1:
|
||||||
|
max_ext_len = max_buffer_size or 1024*1024
|
||||||
|
|
||||||
self._max_buffer_size = max_buffer_size or 2**31-1
|
self._max_buffer_size = max_buffer_size or 2**31-1
|
||||||
if read_size > self._max_buffer_size:
|
if read_size > self._max_buffer_size:
|
||||||
raise ValueError("read_size must be smaller than max_buffer_size")
|
raise ValueError("read_size must be smaller than max_buffer_size")
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@ def test_max_ext_len():
|
||||||
unpacker.unpack()
|
unpacker.unpack()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# PyPy fails following tests because of constant folding?
|
# PyPy fails following tests because of constant folding?
|
||||||
# https://bugs.pypy.org/issue1721
|
# https://bugs.pypy.org/issue1721
|
||||||
#@pytest.mark.skipif(True, reason="Requires very large memory.")
|
#@pytest.mark.skipif(True, reason="Requires very large memory.")
|
||||||
|
|
@ -134,3 +133,27 @@ def test_max_ext_len():
|
||||||
# x.append(0)
|
# x.append(0)
|
||||||
# with pytest.raises(ValueError):
|
# with pytest.raises(ValueError):
|
||||||
# packb(x)
|
# packb(x)
|
||||||
|
|
||||||
|
|
||||||
|
# auto max len
|
||||||
|
|
||||||
|
def test_auto_max_array_len():
|
||||||
|
packed = b'\xde\x00\x06zz'
|
||||||
|
with pytest.raises(UnpackValueError):
|
||||||
|
unpackb(packed, raw=False)
|
||||||
|
|
||||||
|
unpacker = Unpacker(max_buffer_size=5, raw=False)
|
||||||
|
unpacker.feed(packed)
|
||||||
|
with pytest.raises(UnpackValueError):
|
||||||
|
unpacker.unpack()
|
||||||
|
|
||||||
|
def test_auto_max_map_len():
|
||||||
|
# len(packed) == 6 -> max_map_len == 3
|
||||||
|
packed = b'\xde\x00\x04zzz'
|
||||||
|
with pytest.raises(UnpackValueError):
|
||||||
|
unpackb(packed, raw=False)
|
||||||
|
|
||||||
|
unpacker = Unpacker(max_buffer_size=6, raw=False)
|
||||||
|
unpacker.feed(packed)
|
||||||
|
with pytest.raises(UnpackValueError):
|
||||||
|
unpacker.unpack()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue