From 815aae8308e177767ac9196bb60eb07fa588b392 Mon Sep 17 00:00:00 2001 From: Oleg Oshmyan Date: Fri, 3 Feb 2017 18:11:07 +0200 Subject: Fix mult_alpha of large argument This function is passed alpha values from \fade, which are restricted to nonnegative values but have no upper limit. Given a large value, the subtraction and the multiply-divide could wrap around or even overflow (in case of integer promotion to signed int). Overflow is undesirable due to undefined behavior, and wraparound is also undesirable due to VSFilter compatibility. Rewrite the expression as a simpler equivalent that does not need to deal with negative numbers and works correctly regardless of integer promotion. --- libass/ass_parse.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 3e4264d..3456410 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -176,11 +176,12 @@ inline void change_alpha(uint32_t *var, int32_t new, double pwr) * \param a first value * \param b second value * \return result of multiplication - * Parameters and result are limited by 0xFF. + * At least one of the parameters must be less than or equal to 0xFF. + * The result is less than or equal to max(a, b, 0xFF). */ inline uint32_t mult_alpha(uint32_t a, uint32_t b) { - return 0xFF - (0xFF - a) * (0xFF - b) / 0xFF; + return a - (uint64_t) a * b / 0xFF + b; } /** -- cgit v1.2.3