diff --git a/common/common.h b/common/common.h index 5f56c60cdc154..27f0e92a65b83 100644 --- a/common/common.h +++ b/common/common.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "config.h" @@ -65,6 +66,27 @@ // Return a+b, unless a is NOPTS. b must not be NOPTS. #define MP_ADD_PTS(a, b) ((a) == MP_NOPTS_VALUE ? (a) : ((a) + (b))) +// Return the maximum value representable by integer type of a. +#define MP_MAX_VAL(a) _Generic((a), \ + char: SCHAR_MAX, \ + unsigned char: UCHAR_MAX, \ + short: SHRT_MAX, \ + unsigned short: USHRT_MAX, \ + int: INT_MAX, \ + unsigned int: UINT_MAX, \ + long: LONG_MAX, \ + unsigned long: ULONG_MAX, \ + long long: LLONG_MAX, \ + unsigned long long: ULLONG_MAX) + +// Multiply a * b and store in result. If result would overflow, saturate at +// its maximum value instead, and return true. Otherwise, return false. +#define MP_SATURATE_MUL(result, a, b) ( \ + MP_CKD_MUL(result, a, b) ? \ + *result = MP_MAX_VAL(*result), true : \ + false \ +) + #define CONTROL_OK 1 #define CONTROL_TRUE 1 #define CONTROL_FALSE 0 diff --git a/demux/demux_edl.c b/demux/demux_edl.c index 8e043e6983ad5..71351b8b15323 100644 --- a/demux/demux_edl.c +++ b/demux/demux_edl.c @@ -243,7 +243,7 @@ static struct tl_root *parse_edl(bstr str, struct mp_log *log) : get_meta(tl, index); sh->lang = get_param0(&ctx, sh, "lang"); sh->title = get_param0(&ctx, sh, "title"); - sh->hls_bitrate = get_param_int(&ctx, "byterate", 0) * 8; + MP_SATURATE_MUL(&sh->hls_bitrate, get_param_int(&ctx, "byterate", 0), 8); int pid = get_param_int(&ctx, "program_id", -1); if (pid >= 0) MP_TARRAY_APPEND(sh, sh->program_ids, sh->num_program_ids, pid); diff --git a/osdep/compiler.h b/osdep/compiler.h index d3edecdb200c5..7639805f59337 100644 --- a/osdep/compiler.h +++ b/osdep/compiler.h @@ -7,6 +7,7 @@ #define MP_EXPAND_ARGS(...) __VA_ARGS__ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +#include #define MP_NORETURN [[noreturn]] #define MP_FALLTHROUGH [[fallthrough]] #define MP_WARN_UNUSED_RESULT [[nodiscard]] @@ -78,4 +79,10 @@ #define MP_SCANF_ATTRIBUTE(a1, a2) #endif +#if defined(__STDC_VERSION_STDCKDINT_H__) && __STDC_VERSION_STDCKDINT_H__ >= 202311L +#define MP_CKD_MUL(result, a, b) ckd_mul(result, a, b) +#elif __has_builtin(__builtin_mul_overflow) +#define MP_CKD_MUL(result, a, b) __builtin_mul_overflow(a, b, result) +#endif + #endif