https://github.com/python/cpython/commit/87d7315ac57250046372b0d9ae4619ba619c8c87
commit: 87d7315ac57250046372b0d9ae4619ba619c8c87
branch: main
author: Sergey B Kirpichev <[email protected]>
committer: encukou <[email protected]>
date: 2024-10-10T14:42:03+02:00
summary:

gh-125118: don't copy arbitrary values to _Bool in the struct module (GH-125169)

memcopy'ing arbitrary values to _Bool variable triggers undefined
behaviour. Avoid this.
We assume that `false` is represented by all zero bytes.

Credits to Alex Gaynor.

Co-authored-by: Sam Gross <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>
Co-authored-by: Petr Viktorin <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst
M Lib/test/test_struct.py
M Modules/_struct.c

diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py
index e3193c7863fbae..04ec3ed0837c82 100644
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -540,6 +540,9 @@ def __bool__(self):
 
         for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
             self.assertTrue(struct.unpack('>?', c)[0])
+            self.assertTrue(struct.unpack('<?', c)[0])
+            self.assertTrue(struct.unpack('=?', c)[0])
+            self.assertTrue(struct.unpack('@?', c)[0])
 
     def test_count_overflow(self):
         hugecount = '{}b'.format(sys.maxsize+1)
diff --git 
a/Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst 
b/Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst
new file mode 100644
index 00000000000000..5d57cdbbbc2fe9
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-09-07-09-00.gh-issue-125118.J9rQ1S.rst
@@ -0,0 +1 @@
+Don't copy arbitrary values to :c:expr:`_Bool` in the :mod:`struct` module.
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 4387c55b7c8848..21582b945be23d 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -497,9 +497,8 @@ nu_ulonglong(_structmodulestate *state, const char *p, 
const formatdef *f)
 static PyObject *
 nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
 {
-    _Bool x;
-    memcpy(&x, p, sizeof x);
-    return PyBool_FromLong(x != 0);
+    const _Bool bool_false = 0;
+    return PyBool_FromLong(memcmp(p, &bool_false, sizeof(_Bool)));
 }
 
 

_______________________________________________
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