Skip to content

Commit b84bb76

Browse files
mkittiMark Kittisopikul
andauthored
Fix Zstd decompression negative size issue on 32-bit platforms (Fixes #781) (#782)
* Update zstd.pyx with new content * Apply suggestion from @mkitti * Fix LLM issues .. * Add pass, comment for dest_size --------- Co-authored-by: Mark Kittisopikul <[email protected]>
1 parent f42a233 commit b84bb76

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

numcodecs/zstd.pyx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ from .abc import Codec
1515

1616
from libc.stdlib cimport malloc, realloc, free
1717

18+
cdef extern from "stdint.h":
19+
cdef size_t SIZE_MAX
20+
1821
cdef extern from "zstd.h":
1922

2023
unsigned ZSTD_versionNumber() nogil
@@ -202,8 +205,8 @@ def decompress(source, dest=None):
202205
Py_buffer* dest_pb
203206
char* dest_ptr
204207
size_t source_size, dest_size, decompressed_size
205-
size_t nbytes, cbytes, blocksize
206208
size_t dest_nbytes
209+
unsigned long long content_size
207210

208211
# obtain source memoryview
209212
source_mv = ensure_continguous_memoryview(source)
@@ -214,14 +217,20 @@ def decompress(source, dest=None):
214217
source_size = source_pb.len
215218

216219
try:
217-
218-
# determine uncompressed size
219-
dest_size = ZSTD_getFrameContentSize(source_ptr, source_size)
220-
if dest_size == 0 or dest_size == ZSTD_CONTENTSIZE_ERROR:
220+
# determine uncompressed size using unsigned long long for full range
221+
content_size = ZSTD_getFrameContentSize(source_ptr, source_size)
222+
if content_size == ZSTD_CONTENTSIZE_UNKNOWN and dest is None:
223+
return stream_decompress(source_pb)
224+
elif content_size == ZSTD_CONTENTSIZE_UNKNOWN:
225+
# dest is not None
226+
# set dest_size based on dest
227+
pass
228+
elif content_size == ZSTD_CONTENTSIZE_ERROR or content_size == 0:
221229
raise RuntimeError('Zstd decompression error: invalid input data')
230+
elif content_size > (<unsigned long long>SIZE_MAX):
231+
raise RuntimeError('Zstd decompression error: content size too large for platform')
222232

223-
if dest_size == ZSTD_CONTENTSIZE_UNKNOWN and dest is None:
224-
return stream_decompress(source_pb)
233+
dest_size = <size_t>content_size
225234

226235
# setup destination buffer
227236
if dest is None:
@@ -236,7 +245,7 @@ def decompress(source, dest=None):
236245
dest_ptr = <char*>dest_pb.buf
237246
dest_nbytes = dest_pb.len
238247

239-
if dest_size == ZSTD_CONTENTSIZE_UNKNOWN:
248+
if content_size == ZSTD_CONTENTSIZE_UNKNOWN:
240249
dest_size = dest_nbytes
241250

242251
# validate output buffer

0 commit comments

Comments
 (0)