@@ -408,16 +408,17 @@ cdef class Decompress:
408
408
self .stream.avail_in = total_length
409
409
self .stream.avail_out = 0
410
410
cdef unsigned long prev_avail_out
411
+ cdef unsigned long bytes_written
411
412
cdef int err
412
413
# This loop reads all the input bytes. If there are no input bytes
413
414
# anymore the output is written.
414
415
while (self .stream.avail_out == 0
415
416
or self .stream.avail_in != 0
416
417
or self .stream.block_state != ISAL_BLOCK_FINISH):
417
418
self .stream.next_out = self .obuf # Reset output buffer.
418
- if total_bytes > max_length:
419
+ if total_bytes >= max_length:
419
420
break
420
- elif total_bytes + self .obuflen > max_length:
421
+ elif total_bytes + self .obuflen >= max_length:
421
422
self .stream.avail_out = max_length - total_bytes
422
423
else :
423
424
self .stream.avail_out = self .obuflen
@@ -428,8 +429,9 @@ cdef class Decompress:
428
429
# Are raised. So we remain in pure C code if we check for
429
430
# COMP_OK first.
430
431
check_isal_inflate_rc(err)
431
- total_bytes += self .stream.avail_out
432
- out.append(self .obuf[:prev_avail_out - self .stream.avail_out])
432
+ bytes_written = prev_avail_out - self .stream.avail_out
433
+ total_bytes += bytes_written
434
+ out.append(self .obuf[:bytes_written])
433
435
if self .stream.block_state == ISAL_BLOCK_FINISH:
434
436
break
435
437
# Save unconsumed input implementation from zlibmodule.c
@@ -438,7 +440,7 @@ cdef class Decompress:
438
440
# leftover input data in self->unused_data.
439
441
self .eof = 1
440
442
if self .stream.avail_in > 0 :
441
- self .unused_data = self .stream.next_in[ :]
443
+ self .unused_data = data[total_bytes :]
442
444
self .stream.avail_in = 0
443
445
if self .stream.avail_in > 0 or self .unconsumed_tail:
444
446
# This code handles two distinct cases:
@@ -452,14 +454,16 @@ cdef class Decompress:
452
454
raise ValueError (" Length must be greater than 0" )
453
455
if length > UINT32_MAX:
454
456
raise ValueError (" Length should not be larger than 4GB." )
455
- cdef Py_ssize_t ibuflen = len (self .unconsumed_tail)
457
+ data = self .unconsumed_tail
458
+ cdef Py_ssize_t ibuflen = len (data)
456
459
if ibuflen > UINT32_MAX:
457
460
# This should never happen, because we check the input size in
458
461
# the decompress function as well.
459
462
raise IsalError(" Unconsumed tail too large. Can not flush." )
460
- self .stream.next_in = self .unconsumed_tail
463
+ self .stream.next_in = data
461
464
self .stream.avail_in = ibuflen
462
-
465
+ cdef unsigned long total_bytes = 0
466
+ cdef unsigned long bytes_written
463
467
out = []
464
468
cdef unsigned long obuflen = length
465
469
cdef unsigned char * obuf = < unsigned char * > PyMem_Malloc(obuflen * sizeof(char ))
@@ -478,20 +482,22 @@ cdef class Decompress:
478
482
# Instead of output buffer resizing as the zlibmodule.c example
479
483
# the data is appended to a list.
480
484
# TODO: Improve this with the buffer protocol.
481
- out.append(obuf[:obuflen - self .stream.avail_out])
485
+ bytes_written = obuflen - self .stream.avail_out
486
+ total_bytes += bytes_written
487
+ out.append(obuf[:bytes_written])
482
488
if self .stream.block_state == ISAL_BLOCK_FINISH:
483
489
# The end of the compressed data has been reached. Store the
484
490
# leftover input data in self->unused_data.
485
491
self .eof = 1
486
492
self .is_initialised = 0
487
493
if self .stream.avail_in > 0 :
488
- self .unused_data = self .stream.next_in[ :]
494
+ self .unused_data = data[total_bytes :]
489
495
self .stream.avail_in = 0
490
496
if self .stream.avail_in > 0 or self .unconsumed_tail:
491
497
# This code handles two distinct cases:
492
498
# 1. Output limit was reached. Save leftover input in unconsumed_tail.
493
499
# 2. All input data was consumed. Clear unconsumed_tail.
494
- self .unconsumed_tail = self .stream.next_in[ :]
500
+ self .unconsumed_tail = data[total_bytes :]
495
501
return b" " .join(out)
496
502
finally :
497
503
PyMem_Free(obuf)
0 commit comments