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 <colesbury@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
Sergey B Kirpichev 2024-10-10 15:42:03 +03:00 committed by GitHub
parent e4cab488d4
commit 87d7315ac5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 6 additions and 3 deletions

View File

@ -540,6 +540,9 @@ class StructTest(ComplexesAreIdenticalMixin, unittest.TestCase):
for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']: 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])
self.assertTrue(struct.unpack('@?', c)[0])
def test_count_overflow(self): def test_count_overflow(self):
hugecount = '{}b'.format(sys.maxsize+1) hugecount = '{}b'.format(sys.maxsize+1)

View File

@ -0,0 +1 @@
Don't copy arbitrary values to :c:expr:`_Bool` in the :mod:`struct` module.

View File

@ -497,9 +497,8 @@ nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
static PyObject * static PyObject *
nu_bool(_structmodulestate *state, const char *p, const formatdef *f) nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
{ {
_Bool x; const _Bool bool_false = 0;
memcpy(&x, p, sizeof x); return PyBool_FromLong(memcmp(p, &bool_false, sizeof(_Bool)));
return PyBool_FromLong(x != 0);
} }