Skip to content

Commit 67f8302

Browse files
skirpichevcolesburyvstinnerencukou
authored
[3.12] gh-125118: don't copy arbitrary values to _Bool in the struct module (GH-125169) (#125265)
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. (cherry picked from commit 87d7315) Co-authored-by: Sam Gross <[email protected]> Co-authored-by: Victor Stinner <[email protected]> Co-authored-by: Petr Viktorin <[email protected]>
1 parent 74df3a7 commit 67f8302

File tree

3 files changed

+6
-3
lines changed

3 files changed

+6
-3
lines changed

Lib/test/test_struct.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,9 @@ def __bool__(self):
529529

530530
for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
531531
self.assertTrue(struct.unpack('>?', c)[0])
532+
self.assertTrue(struct.unpack('<?', c)[0])
533+
self.assertTrue(struct.unpack('=?', c)[0])
534+
self.assertTrue(struct.unpack('@?', c)[0])
532535

533536
def test_count_overflow(self):
534537
hugecount = '{}b'.format(sys.maxsize+1)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Don't copy arbitrary values to :c:expr:`_Bool` in the :mod:`struct` module.

Modules/_struct.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,8 @@ nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
483483
static PyObject *
484484
nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
485485
{
486-
_Bool x;
487-
memcpy((char *)&x, p, sizeof x);
488-
return PyBool_FromLong(x != 0);
486+
const _Bool bool_false = 0;
487+
return PyBool_FromLong(memcmp(p, &bool_false, sizeof(_Bool)));
489488
}
490489

491490

0 commit comments

Comments
 (0)