Firefox · Graphics
CVE-2026-4699
Logic Error in Graphics
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
gfx/harfbuzz/src/hb-algs.hhgfx/harfbuzz/src/hb-ot-shaper-arabic.cc
Patch
diff --git a/gfx/harfbuzz/src/hb-algs.hh b/gfx/harfbuzz/src/hb-algs.hh
index c58049621af..b28a587d475 100644
--- a/gfx/harfbuzz/src/hb-algs.hh
+++ b/gfx/harfbuzz/src/hb-algs.hh
@@ -1200,6 +1200,21 @@ hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *resu
return (size > 0) && (count >= ((unsigned int) -1) / size);
}
+static inline bool
+hb_unsigned_add_overflows (unsigned int a, unsigned int b, unsigned *result = nullptr)
+{
+#if hb_has_builtin(__builtin_add_overflow)
+ unsigned stack_result;
+ if (!result)
+ result = &stack_result;
+ return __builtin_add_overflow (a, b, result);
+#endif
+
+ if (result)
+ *result = a + b;
+ return b > (unsigned int) -1 - a;
+}
+
/*
* Sort and search.
diff --git a/gfx/harfbuzz/src/hb-ot-shaper-arabic.cc b/gfx/harfbuzz/src/hb-ot-shaper-arabic.cc
index 69320eb9544..2a05af1462e 100644
--- a/gfx/harfbuzz/src/hb-ot-shaper-arabic.cc
+++ b/gfx/harfbuzz/src/hb-ot-shaper-arabic.cc
@@ -561,20 +561,29 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%" PRId32, n_fixed, w_fixed);
DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%" PRId32, n_repeating, w_repeating);
+ static constexpr unsigned STCH_MAX_GLYPHS = 256;
+
/* Number of additional times to repeat each repeating tile. */
- int n_copies = 0;
+ unsigned int n_copies = 0;
- hb_position_t w_remaining = w_total - w_fixed;
- if (sign * w_remaining > sign * w_repeating && sign * w_repeating > 0)
- n_copies = (sign * w_remaining) / (sign * w_repeating) - 1;
+ int64_t w_remaining_signed = (int64_t) w_total - w_fixed;
+ int64_t w_repeating_signed = w_repeating;
+ if (sign < 0)
+ {
+ w_remaining_signed = -w_remaining_signed;
+ w_repeating_signed = -w_repeating_signed;
+ }
+ hb_position_t w_remaining = (hb_position_t) (w_total - w_fixed);
+ if (w_remaining_signed > w_repeating_signed && w_repeating_signed > 0)
+ n_copies = w_remaining_signed / w_repeating_signed - 1;
/* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */
hb_position_t extra_repeat_overlap = 0;
- hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1);
+ int64_t shortfall = w_remaining_signed - w_repeating_signed * (n_copies + 1);
if (shortfall > 0 && n_repeating > 0)
{
++n_copies;
- hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
+ int64_t excess = (n_copies + 1) * w_repeating_signed - w_remaining_signed;
if (excess > 0)
{
extra_repeat_overlap = excess / (n_copies * n_repeating);
@@ -582,10 +591,22 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
}
+ unsigned int max_copies = 0;
+ if (n_repeating > 0)
+ {
+ unsigned int base_glyphs = n_fixed + n_repeating;
+ if (base_glyphs < STCH_MAX_GLYPHS)
+ max_copies = (STCH_MAX_GLYPHS - base_glyphs) / n_repeating;
+ }
+ n_copies = hb_min (n_copies, max_copies);
+
if (step == MEASURE)
{
- extra_glyphs_needed += n_copies * n_repeating;
- DEBUG_MSG (ARABIC, nullptr, "will add extra %d copies of repeating tiles", n_copies);
+ unsigned int added_glyphs = 0;
+ if (unlikely (hb_unsigned_mul_overflows (n_copies, n_repeating, &added_glyphs) ||
+ hb_unsigned_add_overflows (extra_glyphs_needed, added_glyphs, &extra_glyphs_needed)))
+ break;
+ DEBUG_MSG (ARABIC, nullptr, "will add extra %u copies of repeating tiles", n_copies);
}
else
{
@@ -629,7 +650,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (step == MEASURE)
{
- if (unlikely (!buffer->ensure (count + extra_glyphs_needed)))
+ unsigned int total_glyphs = 0;
+ if (unlikely (hb_unsigned_add_overflows (count, extra_glyphs_needed, &total_glyphs) ||
+ !buffer->ensure (total_glyphs)))
break;
}
else
Loading diff…
References
On This Page