8000 gh-96821: Fix undefined behaviour in cfield.c · matthiasgoergens/cpython@0572043 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0572043

Browse files
pythongh-96821: Fix undefined behaviour in cfield.c
1 parent bbc24b2 commit 0572043

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

Modules/_ctypes/cfield.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,21 +412,23 @@ get_ulonglong(PyObject *v, unsigned long long *p)
412412
#define NUM_BITS(x) ((x) >> 16)
413413

414414
/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */
415-
#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1)
415+
#define BIT_MASK(type, size) \
416+
(assert(NUM_BITS(size) > 0), \
417+
(((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1))
416418

417419
/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
418420
we must first shift left, then right.
419421
*/
420422
#define GET_BITFIELD(v, size) \
421423
if (NUM_BITS(size)) { \
422-
v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
424+
v *= 1ULL << (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
423425
v >>= (sizeof(v)*8 - NUM_BITS(size)); \
424426
}
425427

426428
/* This macro RETURNS the first parameter with the bit field CHANGED. */
427429
#define SET(type, x, v, size) \
428430
(NUM_BITS(size) ? \
429-
( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \
431+
( ( (type)x & ~(BIT_MASK(type, size) * (1ULL << LOW_BIT(size))) ) | ( ((type)v & BIT_MASK(type, size)) * (1ULL << LOW_BIT(size) )) ) \
430432
: (type)v)
431433

432434
#if SIZEOF_SHORT == 2

0 commit comments

Comments
 (0)
0