From 59f2290907e61038a7f07af536cb56981835b35e Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Thu, 29 May 2014 03:59:08 +0200 Subject: shaper: add FriBidi error handling It is unlikely, but FriBidi might not process a string correctly, and we should handle that. Tested by making it fail always. This should also fix some compiler warnings. --- libass/ass_render.c | 12 +++++++++++- libass/ass_shaper.c | 20 +++++++++++++++----- libass/ass_shaper.h | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/libass/ass_render.c b/libass/ass_render.c index 67d1b78..0d08dd9 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1985,7 +1985,11 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, resolve_base_direction(render_priv->state.font_encoding)); ass_shaper_find_runs(render_priv->shaper, render_priv, glyphs, text_info->length); - ass_shaper_shape(render_priv->shaper, text_info); + if (ass_shaper_shape(render_priv->shaper, text_info) < 0) { + ass_msg(render_priv->library, MSGL_ERR, "Failed to shape text"); + free_render_context(render_priv); + return 1; + } // Retrieve glyphs for (i = 0; i < text_info->length; i++) { @@ -2075,6 +2079,12 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, // Reorder text into visual order FriBidiStrIndex *cmap = ass_shaper_reorder(render_priv->shaper, text_info); + if (!cmap) { + ass_msg(render_priv->library, MSGL_ERR, "Failed to reorder text"); + ass_shaper_cleanup(render_priv->shaper, text_info); + free_render_context(render_priv); + return 1; + } // Reposition according to the map pen.x = 0; diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c index e9f2b53..d79d0f7 100644 --- a/libass/ass_shaper.c +++ b/libass/ass_shaper.c @@ -824,10 +824,11 @@ static void ass_shaper_skip_characters(TextInfo *text_info) /** * \brief Shape an event's text. Calculates directional runs and shapes them. * \param text_info event's text + * \return success, when 0 */ -void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) +int ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) { - int i, last_break; + int i, ret, last_break; FriBidiParType dir; GlyphInfo *glyphs = text_info->glyphs; @@ -842,8 +843,10 @@ void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) dir = shaper->base_direction; fribidi_get_bidi_types(shaper->event_text + last_break, i - last_break + 1, shaper->ctypes + last_break); - fribidi_get_par_embedding_levels(shaper->ctypes + last_break, + ret = fribidi_get_par_embedding_levels(shaper->ctypes + last_break, i - last_break + 1, &dir, shaper->emblevels + last_break); + if (ret == 0) + return -1; last_break = i + 1; } } @@ -867,6 +870,8 @@ void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) shape_fribidi(shaper, glyphs, text_info->length); ass_shaper_skip_characters(text_info); #endif + + return 0; } /** @@ -910,10 +915,13 @@ void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info) /** * \brief Calculate reorder map to render glyphs in visual order + * \param shaper shaper instance + * \param text_info text to be reordered + * \return map of reordered characters, or NULL */ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info) { - int i; + int i, ret; // Initialize reorder map for (i = 0; i < text_info->length; i++) @@ -924,10 +932,12 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info) LineInfo *line = text_info->lines + i; FriBidiParType dir = FRIBIDI_PAR_ON; - fribidi_reorder_line(0, + ret = fribidi_reorder_line(0, shaper->ctypes + line->offset, line->len, 0, dir, shaper->emblevels + line->offset, NULL, shaper->cmap + line->offset); + if (ret == 0) + return NULL; } return shaper->cmap; diff --git a/libass/ass_shaper.h b/libass/ass_shaper.h index 824bc22..e6121d1 100644 --- a/libass/ass_shaper.h +++ b/libass/ass_shaper.h @@ -33,7 +33,7 @@ void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv, void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir); void ass_shaper_set_language(ASS_Shaper *shaper, const char *code); void ass_shaper_set_level(ASS_Shaper *shaper, ASS_ShapingLevel level); -void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info); +int ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info); void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info); FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info); FriBidiParType resolve_base_direction(int font_encoding); -- cgit v1.2.3