From 18cde9042c9a1b8d13efd9e53cffef2520bd2356 Mon Sep 17 00:00:00 2001 From: Oneric Date: Sun, 14 Mar 2021 02:51:25 +0100 Subject: wrap_lines: do not merge linebreaks Merging linebreaks will always result in text overflowing its designated bounds, but integer overflows or other bugs may erroneously make it seems like it would be beneficial. If this is not prevented it can also lead to out-of-bound reads as in CVE-2016-7969. This replaces and reverts f4f48950788b91c6a30029cc28a240b834713ea7 which did not prevent linebreak-merges and turned hard linebreaks into soft ones on merge. --- libass/ass_render.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libass/ass_render.c b/libass/ass_render.c index 7f31f2b..f846f33 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1703,7 +1703,7 @@ wrap_lines_naive(ASS_Renderer *render_priv, double max_text_width, char *unibrks /* * Shift soft linebreaks to balance out line lengths - * May remove but never add linebreaks + * Does not change the linebreak count * FIXME: implement style 0 and 3 correctly */ static void @@ -1742,6 +1742,8 @@ wrap_lines_rebalance(ASS_Renderer *render_priv, double max_text_width, char *uni } if (w->symbol == ' ') ++w; + if (w == s1) + continue; // Merging linebreaks is never beneficial l1 = d6_to_double(((s2 - 1)->bbox.x_max + (s2 - 1)->pos.x) - (s1->bbox.x_min + s1->pos.x)); @@ -1755,10 +1757,7 @@ wrap_lines_rebalance(ASS_Renderer *render_priv, double max_text_width, char *uni (w->bbox.x_min + w->pos.x)); if (DIFF(l1_new, l2_new) < DIFF(l1, l2)) { - if (w->linebreak || w == text_info->glyphs) - text_info->n_lines--; - if (w != text_info->glyphs) - w->linebreak = 1; + w->linebreak = 1; s2->linebreak = 0; exit = 0; } -- cgit v1.2.3