Skip to content

Commit 5374110

Browse files
author
hauntsaninja
committed
Do not fail silently when unpacking large messages
Fixes #503 Raising ValueError matches the behaviour of the pure Python version. I'm not sure that this is the best place to raise this message; it might make more sense when reading headers or in `append_buffer` or something. It's also possible that we want to raise BufferFull instead of ValueError.
1 parent 849c806 commit 5374110

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

msgpack/_unpacker.pyx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,12 +441,17 @@ cdef class Unpacker(object):
441441
self.buf_tail = tail + _buf_len
442442

443443
cdef read_from_file(self):
444+
current_size = self.buf_tail - self.buf_head
444445
next_bytes = self.file_like_read(
445-
min(self.read_size,
446-
self.max_buffer_size - (self.buf_tail - self.buf_head)
447-
))
446+
min(self.read_size, self.max_buffer_size - current_size + 1)
447+
)
448448
if next_bytes:
449-
self.append_buffer(PyBytes_AsString(next_bytes), PyBytes_Size(next_bytes))
449+
next_bytes_size = PyBytes_Size(next_bytes)
450+
if next_bytes_size + current_size > self.max_buffer_size:
451+
raise ValueError(
452+
"object exceeds max_buffer_size(%s)" % self.max_buffer_size
453+
)
454+
self.append_buffer(PyBytes_AsString(next_bytes), next_bytes_size)
450455
else:
451456
self.file_like = None
452457

test/test_unpack.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from io import BytesIO
22
import sys
3-
from msgpack import Unpacker, packb, OutOfData, ExtType
3+
from msgpack import Unpacker, pack, packb, OutOfData, ExtType
44
from pytest import raises, mark
55

66
try:
@@ -90,3 +90,20 @@ def test_unpacker_tell_read_bytes():
9090
assert obj == unp
9191
assert pos == unpacker.tell()
9292
assert unpacker.read_bytes(n) == raw
93+
94+
95+
def test_unpacker_raise_max_buffer_size():
96+
max_buffer_size = 1024
97+
small_value = b"a" * max_buffer_size
98+
99+
f = BytesIO()
100+
pack(small_value, f)
101+
f.seek(0)
102+
assert list(Unpacker(f, max_buffer_size=max_buffer_size)) == [small_value]
103+
104+
large_value = b"a" * (max_buffer_size + 1)
105+
f = BytesIO()
106+
pack(large_value, f)
107+
f.seek(0)
108+
with raises(ValueError):
109+
list(Unpacker(f, max_buffer_size=max_buffer_size))

0 commit comments

Comments
 (0)