Skip to content

Commit 87d7315

Browse files
skirpichevcolesburyvstinnerencukou
authored
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]>
1 parent e4cab48 commit 87d7315

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
@@ -540,6 +540,9 @@ def __bool__(self):
540540

541541
for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
542542
self.assertTrue(struct.unpack('>?', c)[0])
543+
self.assertTrue(struct.unpack('<?', c)[0])
544+
self.assertTrue(struct.unpack('=?', c)[0])
545+
self.assertTrue(struct.unpack('@?', c)[0])
543546

544547
def test_count_overflow(self):
545548
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
@@ -497,9 +497,8 @@ nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
497497
static PyObject *
498498
nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
499499
{
500-
_Bool x;
501-
memcpy(&x, p, sizeof x);
502-
return PyBool_FromLong(x != 0);
500+
const _Bool bool_false = 0;
501+
return PyBool_FromLong(memcmp(p, &bool_false, sizeof(_Bool)));
503502
}
504503

505504

0 commit comments

Comments
 (0)