[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
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);
}

View File

@ -172,12 +172,13 @@ hb_buffer_t::enlarge (unsigned int size)
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 @@ hb_buffer_t::enter ()
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

View File

@ -198,10 +198,11 @@ struct hb_sanitize_context_t :
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 @@ struct hb_sanitize_context_t :
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 @@ struct hb_sanitize_context_t :
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>