https://github.com/python/cpython/commit/08fd98b6bda30542f1e309389d072fcc9d393a05
commit: 08fd98b6bda30542f1e309389d072fcc9d393a05
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2026-10-22T08:27:11-07:00
summary:

[3.15] gh-159739: Handle overlapping buffers in struct.pack_into (GH-159985) 
(#160101)



`struct.pack_into()` can use the same bytearray as both the destination and an 
`s` or `p` value. The copy then passes overlapping regions to `memcpy`, which 
is undefined in C and can produce platform-dependent results or a sanitizer 
abort. `memmove` makes the overlapping copy defined.
(cherry picked from commit 31a7d994a559a421814ca9e8edfcab21ae4a5b36)

Co-authored-by: Jelle Zijlstra <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-10-20-00-00-00.gh-issue-159739.eb8987.rst
M Modules/_struct.c

diff --git 
a/Misc/NEWS.d/next/Library/2026-10-20-00-00-00.gh-issue-159739.eb8987.rst 
b/Misc/NEWS.d/next/Library/2026-10-20-00-00-00.gh-issue-159739.eb8987.rst
new file mode 100644
index 00000000000000..11c88411bb9125
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-10-20-00-00-00.gh-issue-159739.eb8987.rst
@@ -0,0 +1,2 @@
+Avoid undefined behavior when :func:`struct.pack_into` copies a bytearray into
+overlapping output.
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 7d88e7e662af4d..20955e9cc5563d 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -2366,7 +2366,7 @@ s_pack_internal(PyStructObject *soself, PyObject *const 
*args,
                 if (n > code->size)
                     n = code->size;
                 if (n > 0)
-                    memcpy(res, p, n);
+                    memmove(res, p, n);
             } else if (strcmp(e->format, "p") == 0) {
                 Py_ssize_t n;
                 int isstring;
@@ -2392,7 +2392,7 @@ s_pack_internal(PyStructObject *soself, PyObject *const 
*args,
                     n = code->size - 1;
                 }
                 if (n > 0)
-                    memcpy(res + 1, p, n);
+                    memmove(res + 1, p, n);
                 if (n > 255)
                     n = 255;
                 if (n > 0) {

_______________________________________________
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