https://github.com/python/cpython/commit/adebb68153346043c0671fa5725d269c32cc40e4
commit: adebb68153346043c0671fa5725d269c32cc40e4
branch: main
author: Stan Ulbrych <[email protected]>
committer: StanFromIreland <[email protected]>
date: 2026-07-13T09:02:02+02:00
summary:

gh-148286: Fix UB in `ZstdDecompressor.unused_data` when a frame is 
decompressed in one call (#153258)

Co-authored-by: Emma Smith <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-07-07-13-31-52.gh-issue-148286.-qu-em.rst
M Modules/_zstd/decompressor.c
M Tools/ubsan/suppressions.txt

diff --git 
a/Misc/NEWS.d/next/Library/2026-07-07-13-31-52.gh-issue-148286.-qu-em.rst 
b/Misc/NEWS.d/next/Library/2026-07-07-13-31-52.gh-issue-148286.-qu-em.rst
new file mode 100644
index 000000000000000..60cd49020c954a4
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-07-07-13-31-52.gh-issue-148286.-qu-em.rst
@@ -0,0 +1,3 @@
+Fix undefined behavior in
+:attr:`compression.zstd.ZstdDecompressor.unused_data` when a complete frame
+was decompressed in a single call.
diff --git a/Modules/_zstd/decompressor.c b/Modules/_zstd/decompressor.c
index cb95ba89eb650ae..ca9ea7e3b8f99bb 100644
--- a/Modules/_zstd/decompressor.c
+++ b/Modules/_zstd/decompressor.c
@@ -594,9 +594,14 @@ 
_zstd_ZstdDecompressor_unused_data_get_impl(ZstdDecompressor *self)
     }
     else {
         if (self->unused_data == NULL) {
-            self->unused_data = PyBytes_FromStringAndSize(
-                                    self->input_buffer + self->in_begin,
-                                    self->in_end - self->in_begin);
+            if (self->input_buffer == NULL) {
+                self->unused_data = Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
+            }
+            else {
+                self->unused_data = PyBytes_FromStringAndSize(
+                                        self->input_buffer + self->in_begin,
+                                        self->in_end - self->in_begin);
+            }
             ret = self->unused_data;
             Py_XINCREF(ret);
         }
diff --git a/Tools/ubsan/suppressions.txt b/Tools/ubsan/suppressions.txt
index e3679bc421f4205..2b9ad49ebf1eefb 100644
--- a/Tools/ubsan/suppressions.txt
+++ b/Tools/ubsan/suppressions.txt
@@ -15,8 +15,5 @@ shift-base:Modules/_ctypes/cfield.c
 # Modules/_ctypes/cfield.c:640:1: runtime error: signed integer overflow: 
-2147483648 - 1 cannot be represented in type 'int'
 signed-integer-overflow:Modules/_ctypes/cfield.c
 
-# Modules/_zstd/decompressor.c:598:56: runtime error: applying non-zero offset 
18446744073709551615 to null pointer
-pointer-overflow:Modules/_zstd/decompressor.c
-
 # Modules/_io/stringio.c:350:24: runtime error: addition of unsigned offset to 
0x7fd01ec25850 overflowed to 0x7fd01ec2584c
 pointer-overflow:Modules/_io/stringio.c

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to