]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix buffer overflow in ns_compute_glyph_string_overhangs
authorDaniel Martín <mardani29@yahoo.es>
Sat, 9 Oct 2021 19:10:20 +0000 (21:10 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Fri, 5 Nov 2021 02:39:19 +0000 (03:39 +0100)
* 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

index ec4833b0ac8aa5e0470c5ab31a2391de5746195b..f3dd0d791ca2a8c037fbb3379eef37284017606d 100644 (file)
@@ -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
     {