Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 500a238

Browse filesBrowse files
authored
Fix Unpacker max_buffer_length handling (#506)
1 parent b75e341 commit 500a238
Copy full SHA for 500a238

File tree

3 files changed

+24
-17
lines changed
Filter options

3 files changed

+24
-17
lines changed

‎msgpack/_unpacker.pyx

Copy file name to clipboardExpand all lines: msgpack/_unpacker.pyx
+12-16Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -440,34 +440,30 @@ cdef class Unpacker(object):
440440
self.buf_size = buf_size
441441
self.buf_tail = tail + _buf_len
442442

443-
cdef read_from_file(self):
444-
next_bytes = self.file_like_read(
445-
min(self.read_size,
446-
self.max_buffer_size - (self.buf_tail - self.buf_head)
447-
))
443+
cdef int read_from_file(self) except -1:
444+
cdef Py_ssize_t remains = self.max_buffer_size - (self.buf_tail - self.buf_head)
445+
if remains <= 0:
446+
raise BufferFull
447+
448+
next_bytes = self.file_like_read(min(self.read_size, remains))
448449
if next_bytes:
449450
self.append_buffer(PyBytes_AsString(next_bytes), PyBytes_Size(next_bytes))
450451
else:
451452
self.file_like = None
453+
return 0
452454

453455
cdef object _unpack(self, execute_fn execute, bint iter=0):
454456
cdef int ret
455457
cdef object obj
456458
cdef Py_ssize_t prev_head
457459

458-
if self.buf_head >= self.buf_tail and self.file_like is not None:
459-
self.read_from_file()
460-
461460
while 1:
462461
prev_head = self.buf_head
463-
if prev_head >= self.buf_tail:
464-
if iter:
465-
raise StopIteration("No more data to unpack.")
466-
else:
467-
raise OutOfData("No more data to unpack.")
468-
469-
ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head)
470-
self.stream_offset += self.buf_head - prev_head
462+
if prev_head < self.buf_tail:
463+
ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head)
464+
self.stream_offset += self.buf_head - prev_head
465+
else:
466+
ret = 0
471467

472468
if ret == 1:
473469
obj = unpack_data(&self.ctx)

‎msgpack/fallback.py

Copy file name to clipboardExpand all lines: msgpack/fallback.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ def _reserve(self, n, raise_outofdata=True):
423423

424424
# Read from file
425425
remain_bytes = -remain_bytes
426+
if remain_bytes + len(self._buffer) > self._max_buffer_size:
427+
raise BufferFull
426428
while remain_bytes > 0:
427429
to_read_bytes = max(self._read_size, remain_bytes)
428430
read_data = self.file_like.read(to_read_bytes)

‎test/test_sequnpack.py

Copy file name to clipboardExpand all lines: test/test_sequnpack.py
+10-1Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# coding: utf-8
33
import io
44
from msgpack import Unpacker, BufferFull
5-
from msgpack import pack
5+
from msgpack import pack, packb
66
from msgpack.exceptions import OutOfData
77
from pytest import raises
88

@@ -78,6 +78,15 @@ def test_maxbuffersize():
7878
assert ord("b") == next(unpacker)
7979

8080

81+
def test_maxbuffersize_file():
82+
buff = io.BytesIO(packb(b"a" * 10) + packb([b"a" * 20] * 2))
83+
unpacker = Unpacker(buff, read_size=1, max_buffer_size=19, max_bin_len=20)
84+
assert unpacker.unpack() == b"a" * 10
85+
# assert unpacker.unpack() == [b"a" * 20]*2
86+
with raises(BufferFull):
87+
print(unpacker.unpack())
88+
89+
8190
def test_readbytes():
8291
unpacker = Unpacker(read_size=3)
8392
unpacker.feed(b"foobar")

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.