platform: make FOR_EACH_DELAYED_ACTION() robust against integer overflow

Currently there is no problem. However, DelayedActionType is a packed
enum, and if we add a few more enum values, it might happen that
DELAYED_ACTION_TYPE_MAX is 0x8000 and DelayedActionType effectively
uint16_t.

When that happens, the code would become an infinite loop, because
0x8000 is not larger than DELAYED_ACTION_TYPE_MAX, but `<<= 1`
shifts out the bit, making it zero.

Avoid that.
This commit is contained in:
Thomas Haller 2022-07-12 18:18:30 +02:00
parent d83bd8c6a0
commit 355331b779
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728

View file

@ -365,21 +365,21 @@ typedef enum _nm_packed {
DELAYED_ACTION_TYPE_MAX = __DELAYED_ACTION_TYPE_MAX - 1,
} DelayedActionType;
#define FOR_EACH_DELAYED_ACTION(iflags, flags_all) \
for ((iflags) = (DelayedActionType) 0x1LL; ({ \
gboolean _good = FALSE; \
\
nm_assert(nm_utils_is_power_of_two(iflags)); \
\
while ((iflags) <= DELAYED_ACTION_TYPE_MAX) { \
if (NM_FLAGS_ANY((flags_all), (iflags))) { \
_good = TRUE; \
break; \
} \
(iflags) <<= 1; \
} \
_good; \
}); \
#define FOR_EACH_DELAYED_ACTION(iflags, flags_all) \
for ((iflags) = (DelayedActionType) 0x1LL; ({ \
gboolean _good = FALSE; \
\
nm_assert((iflags) == 0 || nm_utils_is_power_of_two(iflags)); \
\
while ((iflags) != 0 && (iflags) <= DELAYED_ACTION_TYPE_MAX) { \
if (NM_FLAGS_ANY((flags_all), (iflags))) { \
_good = TRUE; \
break; \
} \
(iflags) <<= 1; \
} \
_good; \
}); \
(iflags) <<= 1)
typedef enum _nm_packed {