From 48af19c1f06c2f3b20e4056bedf137a5e3c0e05e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Mart=C3=ADn?= Date: Sat, 9 Oct 2021 21:10:20 +0200 Subject: [PATCH] Fix buffer overflow in ns_compute_glyph_string_overhangs * src/nsterm.m (ns_compute_glyph_string_overhangs): When the first glyph of a glyph string is a composite glyph, `s->nchars' is 0, so "s->char2b + s->nchars - 1" dereferenced a position before buffer `s->char2b'. Instead, rewrite part of the function to distinguish between character glyphs and composite glyphs. For character glyphs, calculate the font metrics using the `text_extents' function, passing it the entire glyph string; for composite glyphs, call `composition_gstring_width'. (Bug#51105) --- src/nsterm.m | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index ec4833b0ac8..f3dd0d791ca 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2849,20 +2849,27 @@ ns_compute_glyph_string_overhangs (struct glyph_string *s) External (RIF); compute left/right overhang of whole string and set in s -------------------------------------------------------------------------- */ { - struct font *font = s->font; - if (s->char2b) { struct font_metrics metrics; - unsigned int codes[2]; - codes[0] = *(s->char2b); - codes[1] = *(s->char2b + s->nchars - 1); - - font->driver->text_extents (font, codes, 2, &metrics); - s->left_overhang = -metrics.lbearing; - s->right_overhang - = metrics.rbearing > metrics.width - ? metrics.rbearing - metrics.width : 0; + if (s->first_glyph->type == CHAR_GLYPH && !s->font_not_found_p) + { + struct font *font = s->font; + font->driver->text_extents (font, s->char2b, s->nchars, &metrics); + s->left_overhang = -metrics.lbearing; + s->right_overhang + = metrics.rbearing > metrics.width + ? metrics.rbearing - metrics.width : 0; + } + else if (s->first_glyph->type == COMPOSITE_GLYPH) + { + Lisp_Object gstring = composition_gstring_from_id (s->cmp_id); + + composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics); + s->right_overhang = (metrics.rbearing > metrics.width + ? metrics.rbearing - metrics.width : 0); + s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0; + } } else { -- 2.39.2