@@ -68,10 +68,12 @@ cdef extern from "zstd.h":
6868 size_t ZSTD_freeDStream(ZSTD_DStream* zds) nogil
6969 size_t ZSTD_initDStream(ZSTD_DStream* zds) nogil
7070
71- cdef long ZSTD_CONTENTSIZE_UNKNOWN
72- cdef long ZSTD_CONTENTSIZE_ERROR
71+ cdef unsigned long long ZSTD_CONTENTSIZE_UNKNOWN
72+ cdef unsigned long long ZSTD_CONTENTSIZE_ERROR
73+
7374 unsigned long long ZSTD_getFrameContentSize(const void * src,
7475 size_t srcSize) nogil
76+ size_t ZSTD_findFrameCompressedSize(const void * src, size_t srcSize) nogil
7577
7678 int ZSTD_minCLevel() nogil
7779 int ZSTD_maxCLevel() nogil
@@ -216,7 +218,11 @@ def decompress(source, dest=None):
216218 try :
217219
218220 # determine uncompressed size
219- dest_size = ZSTD_getFrameContentSize(source_ptr, source_size)
221+ try :
222+ dest_size = findTotalContentSize(source_ptr, source_size)
223+ except RuntimeError :
224+ raise RuntimeError (' Zstd decompression error: invalid input data' )
225+
220226 if dest_size == 0 or dest_size == ZSTD_CONTENTSIZE_ERROR:
221227 raise RuntimeError (' Zstd decompression error: invalid input data' )
222228
@@ -353,6 +359,33 @@ cdef stream_decompress(const Py_buffer* source_pb):
353359
354360 return dest
355361
362+ cdef findTotalContentSize(const void * source_ptr, size_t source_size):
363+ cdef:
364+ unsigned long long frame_content_size = 0
365+ unsigned long long total_content_size = 0
366+ size_t frame_compressed_size = 0
367+ size_t offset = 0
368+
369+ while offset < source_size:
370+ frame_compressed_size = ZSTD_findFrameCompressedSize(source_ptr + offset, source_size - offset);
371+
372+ if ZSTD_isError(frame_compressed_size):
373+ error = ZSTD_getErrorName(frame_compressed_size)
374+ raise RuntimeError (' Could not set determine zstd frame size: %s ' % error)
375+
376+ frame_content_size = ZSTD_getFrameContentSize(source_ptr + offset, frame_compressed_size);
377+
378+ if frame_content_size == ZSTD_CONTENTSIZE_ERROR:
379+ return ZSTD_CONTENTSIZE_ERROR
380+
381+ if frame_content_size == ZSTD_CONTENTSIZE_UNKNOWN:
382+ return ZSTD_CONTENTSIZE_UNKNOWN
383+
384+ total_content_size += frame_content_size
385+ offset += frame_compressed_size
386+
387+ return total_content_size
388+
356389class Zstd (Codec ):
357390 """ Codec providing compression using Zstandard.
358391
0 commit comments