[vlc-commits] [Git][videolan/vlc][master] contrib: ass: fix crash when combined with recent freetype
Steve Lhomme (@robUx4)
gitlab at videolan.org
Thu Apr 28 15:28:23 UTC 2022
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
e516a8f2 by Steve Lhomme at 2022-04-28T14:16:46+00:00
contrib: ass: fix crash when combined with recent freetype
Using upstream patch until a new release comes.
https://github.com/libass/libass/commit/0915955733bd236ecc44645ee968fb7a55ad5079
Fixes #26865
- - - - -
2 changed files:
- + contrib/src/ass/libass-freetype-fix.patch
- contrib/src/ass/rules.mak
Changes:
=====================================
contrib/src/ass/libass-freetype-fix.patch
=====================================
@@ -0,0 +1,182 @@
+From 0915955733bd236ecc44645ee968fb7a55ad5079 Mon Sep 17 00:00:00 2001
+From: Oleg Oshmyan <chortos at inbox.lv>
+Date: Mon, 20 Sep 2021 23:37:23 +0300
+Subject: [PATCH] Add strikeout/underline to ASS_Outline, not FreeType-owned
+ memory
+
+ass_strike_outline_glyph was realloc()ing memory that was
+allocated by FreeType, not us. This isn't generally safe.
+Indeed, FreeType recently switched to a different allocator
+on Windows, so this code started crashing.
+
+To avoid this, move the ass_strike_outline_glyph call
+after the FT_Outline -> ASS_Outline conversion.
+
+It's safer (less chance to exceed outline size limits)
+and easier to work with ASS_Outline, anyway.
+
+Fixes the crash in https://github.com/mpv-player/mpv/issues/9227.
+---
+ libass/ass_font.c | 55 +++++++++++++++++++--------------------------
+ libass/ass_font.h | 5 +++++
+ libass/ass_render.c | 4 ++++
+ 3 files changed, 32 insertions(+), 32 deletions(-)
+
+diff --git a/libass/ass_font.c b/libass/ass_font.c
+index 221a7b4a7..46b797598 100644
+--- a/libass/ass_font.c
++++ b/libass/ass_font.c
+@@ -357,29 +357,25 @@ void ass_font_get_asc_desc(ASS_Font *font, int face_index,
+ *desc = FT_MulFix(-face->descender, y_scale);
+ }
+
+-static void add_line(FT_Outline *ol, int bear, int advance, int dir, int pos, int size) {
+- FT_Vector points[4] = {
+- {.x = bear, .y = pos + size},
+- {.x = advance, .y = pos + size},
+- {.x = advance, .y = pos - size},
++static void add_line(ASS_Outline *ol, int bear, int advance, int dir, int pos, int size) {
++ ASS_Vector points[4] = {
+ {.x = bear, .y = pos - size},
++ {.x = advance, .y = pos - size},
++ {.x = advance, .y = pos + size},
++ {.x = bear, .y = pos + size},
+ };
+
+ if (dir == FT_ORIENTATION_TRUETYPE) {
+- int i;
+- for (i = 0; i < 4; i++) {
+- ol->points[ol->n_points] = points[i];
+- ol->tags[ol->n_points++] = 1;
+- }
++ for (int i = 0; i < 4; i++)
++ ol->points[ol->n_points++] = points[i];
+ } else {
+- int i;
+- for (i = 3; i >= 0; i--) {
+- ol->points[ol->n_points] = points[i];
+- ol->tags[ol->n_points++] = 1;
+- }
++ for (int i = 3; i >= 0; i--)
++ ol->points[ol->n_points++] = points[i];
+ }
+
+- ol->contours[ol->n_contours++] = ol->n_points - 1;
++ for (int i = 0; i < 4; i++)
++ ol->segments[ol->n_segments++] = OUTLINE_LINE_SEGMENT;
++ ol->segments[ol->n_segments - 1] |= OUTLINE_CONTOUR_END;
+ }
+
+ /*
+@@ -389,12 +385,13 @@ static void add_line(FT_Outline *ol, int bear, int advance, int dir, int pos, in
+ * being accurate.
+ *
+ */
+-static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font,
+- FT_Glyph glyph, int under, int through)
++int ass_strike_outline_glyph(ASS_Font *font, int face_index,
++ FT_Glyph glyph, ASS_Outline *ol,
++ int under, int through)
+ {
++ FT_Face face = font->faces[face_index];
+ TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ TT_Postscript *ps = FT_Get_Sfnt_Table(face, ft_sfnt_post);
+- FT_Outline *ol = &((FT_OutlineGlyph) glyph)->outline;
+ int advance, y_scale, i, dir;
+
+ if (!under && !through)
+@@ -402,23 +399,20 @@ static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font,
+
+ // Grow outline
+ i = (under ? 4 : 0) + (through ? 4 : 0);
+- if (ol->n_points > SHRT_MAX - i)
+- return 0;
+- if (!ASS_REALLOC_ARRAY(ol->points, ol->n_points + i))
++ if (ol->n_points > SIZE_MAX - i)
+ return 0;
+- if (!ASS_REALLOC_ARRAY(ol->tags, ol->n_points + i))
++ if (ol->n_segments > SIZE_MAX - i)
+ return 0;
+- i = !!under + !!through;
+- if (ol->n_contours > SHRT_MAX - i)
++ if (!ASS_REALLOC_ARRAY(ol->points, ol->n_points + i))
+ return 0;
+- if (!ASS_REALLOC_ARRAY(ol->contours, ol->n_contours + i))
++ if (!ASS_REALLOC_ARRAY(ol->segments, ol->n_segments + i))
+ return 0;
+
+ advance = d16_to_d6(glyph->advance.x);
+ y_scale = face->size->metrics.y_scale;
+
+ // Reverse drawing direction for non-truetype fonts
+- dir = FT_Outline_Get_Orientation(ol);
++ dir = FT_Outline_Get_Orientation(&((FT_OutlineGlyph) glyph)->outline);
+
+ // Add points to the outline
+ if (under && ps) {
+@@ -428,7 +422,7 @@ static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font,
+ if (pos > 0 || size <= 0)
+ return 1;
+
+- add_line(ol, 0, advance, dir, pos, size);
++ add_line(ol, 0, advance, dir, -pos, size);
+ }
+
+ if (through && os2) {
+@@ -438,7 +432,7 @@ static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font,
+ if (pos < 0 || size <= 0)
+ return 1;
+
+- add_line(ol, 0, advance, dir, pos, size);
++ add_line(ol, 0, advance, dir, -pos, size);
+ }
+
+ return 0;
+@@ -593,9 +587,6 @@ FT_Glyph ass_font_get_glyph(ASS_Font *font, int face_index, int index,
+ glyph->advance.x = face->glyph->linearVertAdvance;
+ }
+
+- ass_strike_outline_glyph(face, font, glyph, deco & DECO_UNDERLINE,
+- deco & DECO_STRIKETHROUGH);
+-
+ return glyph;
+ }
+
+diff --git a/libass/ass_font.h b/libass/ass_font.h
+index 98ac1c85b..57f832d67 100644
+--- a/libass/ass_font.h
++++ b/libass/ass_font.h
+@@ -30,6 +30,7 @@ typedef struct ass_font ASS_Font;
+ #include "ass_types.h"
+ #include "ass_fontselect.h"
+ #include "ass_cache.h"
++#include "ass_outline.h"
+
+ #define VERTICAL_LOWER_BOUND 0x02f1
+
+@@ -63,6 +64,10 @@ FT_Glyph ass_font_get_glyph(ASS_Font *font, int face_index, int index,
+ ASS_Hinting hinting, int deco);
+ void ass_font_clear(ASS_Font *font);
+
++int ass_strike_outline_glyph(ASS_Font *font, int face_index,
++ FT_Glyph glyph, ASS_Outline *ol,
++ int under, int through);
++
+ FT_Face ass_face_open(ASS_Library *lib, FT_Library ftlib, const char *path,
+ const char *postscript_name, int index);
+ FT_Face ass_face_stream(ASS_Library *lib, FT_Library ftlib, const char *name,
+diff --git a/libass/ass_render.c b/libass/ass_render.c
+index 59c54b923..5fcbe968b 100644
+--- a/libass/ass_render.c
++++ b/libass/ass_render.c
+@@ -1173,6 +1173,10 @@ size_t ass_outline_construct(void *key, void *value, void *priv)
+ if (!outline_convert(&v->outline[0], src))
+ return 1;
+ v->advance = d16_to_d6(glyph->advance.x);
++ ass_strike_outline_glyph(k->font, k->face_index,
++ glyph, &v->outline[0],
++ k->flags & DECO_UNDERLINE,
++ k->flags & DECO_STRIKETHROUGH);
+ FT_Done_Glyph(glyph);
+ ass_font_get_asc_desc(k->font, k->face_index,
+ &v->asc, &v->desc);
=====================================
contrib/src/ass/rules.mak
=====================================
@@ -36,6 +36,7 @@ $(TARBALLS)/libass-$(ASS_VERSION).tar.gz:
libass: libass-$(ASS_VERSION).tar.gz .sum-ass
$(UNPACK)
+ $(APPLY) $(SRC)/ass/libass-freetype-fix.patch
$(APPLY) $(SRC)/ass/ass-macosx.patch
$(APPLY) $(SRC)/ass/0001-configure-add-Core-Text-and-DirectWrite-to-Libs.priv.patch
ifdef HAVE_WIN32
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/e516a8f24b48d0ca4ad14f57115d35c1f0b71a47
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/e516a8f24b48d0ca4ad14f57115d35c1f0b71a47
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list