diff options
author | Oleg Oshmyan <chortos@inbox.lv> | 2017-02-03 18:11:07 +0200 |
---|---|---|
committer | Oleg Oshmyan <chortos@inbox.lv> | 2020-10-18 05:01:31 +0300 |
commit | 815aae8308e177767ac9196bb60eb07fa588b392 (patch) | |
tree | 6aa0a53a90e250273dc766d1a7d41825473fcde9 | |
parent | 894e1d51cf252a3a38743b2828f190af17d0d31a (diff) | |
download | libass-815aae8308e177767ac9196bb60eb07fa588b392.tar.bz2 libass-815aae8308e177767ac9196bb60eb07fa588b392.tar.xz |
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.
-rw-r--r-- | libass/ass_parse.c | 5 |
1 files 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; } /** |