[algs] Add output argument to hb_unsigned_mul_overflows()

This commit is contained in:
Behdad Esfahbod 2022-11-21 12:56:33 -07:00
parent 25adbb3825
commit 4c14043b06
3 changed files with 26 additions and 19 deletions

View File

@ -854,13 +854,17 @@ hb_in_ranges (T u, T lo1, T hi1, Ts... ds)
*/ */
static inline bool 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__) #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
unsigned result; unsigned stack_result;
return __builtin_mul_overflow (count, size, &result); if (!result)
result = &stack_result;
return __builtin_mul_overflow (count, size, result);
#endif #endif
if (result)
*result = count * size;
return (size > 0) && (count >= ((unsigned int) -1) / size); return (size > 0) && (count >= ((unsigned int) -1) / size);
} }

View File

@ -172,12 +172,13 @@ hb_buffer_t::enlarge (unsigned int size)
while (size >= new_allocated) while (size >= new_allocated)
new_allocated += (new_allocated >> 1) + 32; new_allocated += (new_allocated >> 1) + 32;
static_assert ((sizeof (info[0]) == sizeof (pos[0])), ""); unsigned new_bytes;
if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0])))) if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0]), &new_bytes)))
goto done; goto done;
new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0])); static_assert (sizeof (info[0]) == sizeof (pos[0]), "");
new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0])); new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_bytes);
new_info = (hb_glyph_info_t *) hb_realloc (info, new_bytes);
done: done:
if (unlikely (!new_pos || !new_info)) if (unlikely (!new_pos || !new_info))
@ -313,15 +314,14 @@ hb_buffer_t::enter ()
serial = 0; serial = 0;
shaping_failed = false; shaping_failed = false;
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; 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, max_len = hb_max (mul, (unsigned) HB_BUFFER_MAX_LEN_MIN);
(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, max_ops = hb_max (mul, (unsigned) HB_BUFFER_MAX_OPS_MIN);
(unsigned) HB_BUFFER_MAX_OPS_MIN);
} }
} }
void void

View File

@ -198,10 +198,11 @@ struct hb_sanitize_context_t :
void start_processing () void start_processing ()
{ {
reset_object (); 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; this->max_ops = HB_SANITIZE_MAX_OPS_MAX;
else 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_MIN,
(unsigned) HB_SANITIZE_MAX_OPS_MAX); (unsigned) HB_SANITIZE_MAX_OPS_MAX);
this->edit_count = 0; this->edit_count = 0;
@ -252,8 +253,9 @@ struct hb_sanitize_context_t :
unsigned int a, unsigned int a,
unsigned int b) const unsigned int b) const
{ {
return !hb_unsigned_mul_overflows (a, b) && unsigned m;
this->check_range (base, a * b); return !hb_unsigned_mul_overflows (a, b, &m) &&
this->check_range (base, m);
} }
template <typename T> template <typename T>
@ -262,8 +264,9 @@ struct hb_sanitize_context_t :
unsigned int b, unsigned int b,
unsigned int c) const unsigned int c) const
{ {
return !hb_unsigned_mul_overflows (a, b) && unsigned m;
this->check_range (base, a * b, c); return !hb_unsigned_mul_overflows (a, b, &m) &&
this->check_range (base, m, c);
} }
template <typename T> template <typename T>