@@ -68,10 +68,12 @@ cdef extern from "zstd.h":
68
68
size_t ZSTD_freeDStream(ZSTD_DStream* zds) nogil
69
69
size_t ZSTD_initDStream(ZSTD_DStream* zds) nogil
70
70
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
+
73
74
unsigned long long ZSTD_getFrameContentSize(const void * src,
74
75
size_t srcSize) nogil
76
+ size_t ZSTD_findFrameCompressedSize(const void * src, size_t srcSize) nogil
75
77
76
78
int ZSTD_minCLevel() nogil
77
79
int ZSTD_maxCLevel() nogil
@@ -216,7 +218,11 @@ def decompress(source, dest=None):
216
218
try :
217
219
218
220
# 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
+
220
226
if dest_size == 0 or dest_size == ZSTD_CONTENTSIZE_ERROR:
221
227
raise RuntimeError (' Zstd decompression error: invalid input data' )
222
228
@@ -353,6 +359,33 @@ cdef stream_decompress(const Py_buffer* source_pb):
353
359
354
360
return dest
355
361
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
+
356
389
class Zstd (Codec ):
357
390
""" Codec providing compression using Zstandard.
358
391
0 commit comments