Skip to content

Commit 3d32968

Browse files
committed
Use save unconsumed input function
1 parent fbddb48 commit 3d32968

File tree

1 file changed

+27
-32
lines changed

1 file changed

+27
-32
lines changed

src/isal/isal_zlib.pyx

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ from .igzip_lib cimport *
2929
from libc.stdint cimport UINT64_MAX, UINT32_MAX, uint32_t
3030
from cpython.mem cimport PyMem_Malloc, PyMem_Free
3131

32+
cdef extern from "<Python.h>":
33+
const Py_ssize_t PY_SSIZE_T_MAX
34+
3235
ISAL_BEST_SPEED = ISAL_DEF_MIN_LEVEL
3336
ISAL_BEST_COMPRESSION = ISAL_DEF_MAX_LEVEL
3437
ISAL_DEFAULT_COMPRESSION = 2
@@ -382,6 +385,28 @@ cdef class Decompress:
382385
self.eof = 0
383386
self.is_initialised = 1
384387

388+
cdef save_unconsumed_input(self, object data):
389+
cdef Py_ssize_t old_size, new_size, left_size, offset
390+
cdef unsigned char * data_ptr
391+
if self.stream.block_state == ISAL_BLOCK_FINISH:
392+
if self.stream.avail_in > 0:
393+
old_size = len(self.unused_data)
394+
data_ptr = data
395+
left_size = data_ptr + len(data) - self.stream.next_in
396+
offset = self.stream.next_in - data_ptr
397+
if offset < 0:
398+
raise Exception()
399+
if left_size > (PY_SSIZE_T_MAX - old_size):
400+
raise MemoryError()
401+
self.unused_data += data[offset:]
402+
if self.stream.avail_in > 0 or self.unconsumed_tail:
403+
data_ptr = data
404+
left_size = data_ptr + len(data) - self.stream.next_in
405+
offset = self.stream.next_in - data_ptr
406+
if offset < 0:
407+
raise Exception()
408+
self.unconsumed_tail = data[offset:]
409+
385410
def decompress(self, data, Py_ssize_t max_length = 0):
386411

387412
cdef Py_ssize_t total_bytes = 0
@@ -441,24 +466,7 @@ cdef class Decompress:
441466
out.append(obuf[:bytes_written])
442467
if self.stream.block_state == ISAL_BLOCK_FINISH or last_round:
443468
break
444-
# Save unconsumed input implementation from zlibmodule.c
445-
if self.stream.block_state == ISAL_BLOCK_FINISH:
446-
# The end of the compressed data has been reached. Store the
447-
# leftover input data in self->unused_data.
448-
self.eof = 1
449-
if self.stream.avail_in > 0:
450-
unused_bytes = self.stream.avail_in
451-
self.unused_data = data[-unused_bytes:]
452-
self.stream.avail_in = 0
453-
if self.stream.avail_in > 0 or self.unconsumed_tail:
454-
# This code handles two distinct cases:
455-
# 1. Output limit was reached. Save leftover input in unconsumed_tail.
456-
# 2. All input data was consumed. Clear unconsumed_tail.
457-
unused_bytes = self.stream.avail_in
458-
if unused_bytes == 0:
459-
self.unconsumed_tail = b""
460-
else:
461-
self.unconsumed_tail = data[-unused_bytes:]
469+
self.save_unconsumed_input(data)
462470
return b"".join(out)
463471
finally:
464472
PyMem_Free(obuf)
@@ -500,20 +508,7 @@ cdef class Decompress:
500508
bytes_written = obuflen - self.stream.avail_out
501509
total_bytes += bytes_written
502510
out.append(obuf[:bytes_written])
503-
if self.stream.block_state == ISAL_BLOCK_FINISH:
504-
# The end of the compressed data has been reached. Store the
505-
# leftover input data in self->unused_data.
506-
self.eof = 1
507-
self.is_initialised = 0
508-
if self.stream.avail_in > 0:
509-
unused_bytes = self.stream.avail_in
510-
self.unused_data = data[-unused_bytes:]
511-
if self.stream.avail_in > 0 or self.unconsumed_tail:
512-
# This code handles two distinct cases:
513-
# 1. Output limit was reached. Save leftover input in unconsumed_tail.
514-
# 2. All input data was consumed. Clear unconsumed_tail.
515-
unused_bytes = self.stream.avail_in
516-
self.unconsumed_tail = data[-unused_bytes:]
511+
self.save_unconsumed_input(data)
517512
return b"".join(out)
518513
finally:
519514
PyMem_Free(obuf)

0 commit comments

Comments
 (0)