diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-08-26 11:52:55 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-08-26 11:52:55 +0000 |
commit | ff06305f945015c7a33b8f694168714c75e7bf84 (patch) | |
tree | f0df13e6e4fec79ea688cb1480647415846882e2 | |
parent | db32f795618df356c386aedf757d1d21055d96f9 (diff) |
Evaluate arguments of bitstring macros only once.
According to bit_alloc(3) man page the arguments to bitstring macros
are evaluated only once and may safely have side effects. Fix the
implementation with temporary variables to fulfill this requirement.
OK florian@ deraadt@
-rw-r--r-- | include/bitstring.h | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/include/bitstring.h b/include/bitstring.h index 13528746800..406a973581e 100644 --- a/include/bitstring.h +++ b/include/bitstring.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bitstring.h,v 1.6 2020/05/10 00:56:06 guenther Exp $ */ +/* $OpenBSD: bitstring.h,v 1.7 2024/08/26 11:52:54 bluhm Exp $ */ /* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */ /* @@ -70,16 +70,22 @@ typedef unsigned char bitstr_t; ((name)[bitstr_size(nbits)]) /* is bit N of bitstring name set? */ -#define bit_test(name, bit) \ - ((name)[_bit_byte(bit)] & _bit_mask(bit)) +#define bit_test(name, bit) ({ \ + register int __tbit = (bit); \ + ((name)[_bit_byte(__tbit)] & _bit_mask(__tbit)); \ +}) /* set bit N of bitstring name */ -#define bit_set(name, bit) \ - ((name)[_bit_byte(bit)] |= _bit_mask(bit)) +#define bit_set(name, bit) do { \ + register int __sbit = (bit); \ + ((name)[_bit_byte(__sbit)] |= _bit_mask(__sbit)); \ +} while(0) /* clear bit N of bitstring name */ -#define bit_clear(name, bit) \ - ((name)[_bit_byte(bit)] &= ~_bit_mask(bit)) +#define bit_clear(name, bit) do { \ + register int __cbit = (bit); \ + ((name)[_bit_byte(__cbit)] &= ~_bit_mask(__cbit)); \ +} while(0) /* clear bits start ... stop in bitstring */ #define bit_nclear(name, start, stop) do { \ |