[algs] Add output argument to hb_unsigned_mul_overflows()
diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 9659d63..64e9142 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh
@@ -854,13 +854,17 @@ */ static inline bool -hb_unsigned_mul_overflows (unsigned int count, unsigned int size) +hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr) { #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) - unsigned result; - return __builtin_mul_overflow (count, size, &result); + unsigned stack_result; + if (!result) + result = &stack_result; + return __builtin_mul_overflow (count, size, result); #endif + if (result) + *result = count * size; return (size > 0) && (count >= ((unsigned int) -1) / size); }
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 2fe2eea..44b5dcb 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc
@@ -172,12 +172,13 @@ while (size >= new_allocated) new_allocated += (new_allocated >> 1) + 32; - static_assert ((sizeof (info[0]) == sizeof (pos[0])), ""); - if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0])))) + unsigned new_bytes; + if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes))) goto done; - new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0])); - new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0])); + static_assert (sizeof (info[0]) == sizeof (pos[0]), ""); + new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes); + new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes); done: if (unlikely (!new_pos || !new_info)) @@ -313,15 +314,14 @@ serial = 0; shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; - if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR))) + unsigned mul; + if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul))) { - max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR, - (unsigned) HB_BUFFER_MAX_LEN_MIN); + max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN); } - if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR))) + if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR, &mul))) { - max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR, - (unsigned) HB_BUFFER_MAX_OPS_MIN); + max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN); } } void
diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index 65c2772..bd3250e 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh
@@ -198,10 +198,11 @@ void start_processing () { reset_object (); - if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR))) + unsigned m; + if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m))) this->max_ops = HB_SANITIZE_MAX_OPS_MAX; else - this->max_ops = hb_clamp ((unsigned) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, + this->max_ops = hb_clamp (m, (unsigned) HB_SANITIZE_MAX_OPS_MIN, (unsigned) HB_SANITIZE_MAX_OPS_MAX); this->edit_count = 0; @@ -252,8 +253,9 @@ unsigned int a, unsigned int b) const { - return !hb_unsigned_mul_overflows (a, b) && - this->check_range (base, a * b); + unsigned m; + return !hb_unsigned_mul_overflows (a, b, &m) && + this->check_range (base, m); } template <typename T> @@ -262,8 +264,9 @@ unsigned int b, unsigned int c) const { - return !hb_unsigned_mul_overflows (a, b) && - this->check_range (base, a * b, c); + unsigned m; + return !hb_unsigned_mul_overflows (a, b, &m) && + this->check_range (base, m, c); } template <typename T>