This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository e16.
View the commit online.
commit 46691a336bf69ffb9fb1ab6dcef9313124462dd6
Author: Kim Woelders <k...@woelders.dk>
AuthorDate: Wed Jul 23 20:16:13 2025 +0200
text: Avoid lockup (endless loop) in TextFit functions
Commit 4f617c77bfed9221b8ccab527839ae3742746054 "text: Converge faster
in TextFit functions" introduced the possibility of triggering an
endless loop when dealing with strings containing glyphs with very
different widths.
The new algoritm may be a bit slower or faster or less accurate
depending on the particlar string, but should never lock up.
Reported by Thanatermesis.
---
src/text.c | 46 ++++++++++++++--------------------------------
1 file changed, 14 insertions(+), 32 deletions(-)
diff --git a/src/text.c b/src/text.c
index da1e4d35..6522d1ca 100644
--- a/src/text.c
+++ b/src/text.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
- * Copyright (C) 2004-2023 Kim Woelders
+ * Copyright (C) 2004-2025 Kim Woelders
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -237,9 +237,9 @@ static void
TextstateTextFit1(TextState *ts, char **ptext, int *pw, int textwidth_limit)
{
char *text = *ptext;
- int width, hh, ascent;
+ int width, hh, ascent, dw;
char *new_line;
- int nuke_count, nc2, len_n, cw;
+ int i, nuke_count, nc2;
int len;
len = strlen(text);
@@ -251,11 +251,9 @@ TextstateTextFit1(TextState *ts, char **ptext, int *pw, int textwidth_limit)
return;
width = *pw;
- nuke_count = ((width - textwidth_limit) * len) / width;
- if (nuke_count < 2)
- nuke_count = 2;
+ nuke_count = ((width - textwidth_limit) * len) / width + 3;
- for (;;)
+ for (i = 0; i < 10; i++, nuke_count++)
{
if (nuke_count >= len - 1)
{
@@ -269,20 +267,13 @@ TextstateTextFit1(TextState *ts, char **ptext, int *pw, int textwidth_limit)
memcpy(new_line, text, nc2);
memcpy(new_line + nc2, "...", 3);
strcpy(new_line + nc2 + 3, text + nc2 + nuke_count);
- len_n = len - nuke_count + 3;
ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
width = *pw;
- nc2 = textwidth_limit - width;
- cw = width / len_n;
-
- if (nc2 >= 0 && nc2 < 3 * cw)
+ dw = textwidth_limit - width;
+ if (dw >= 0)
break;
- if (nc2 > 0)
- nuke_count -= (nc2 <= 2 * cw) ? 1 : (nc2 + cw / 2) / cw;
- else
- nuke_count += (-nc2 <= 2 * cw) ? 1 : (-nc2 + cw / 2) / cw;
}
Efree(text);
@@ -293,12 +284,12 @@ static void
TextstateTextFitMB(TextState *ts, char **ptext, int *pw, int textwidth_limit)
{
char *text = *ptext;
- int width, hh, ascent, cw;
+ int width, hh, ascent, dw;
char *new_line;
- int nuke_count, nc2;
+ int i, nuke_count, nc2;
int len, len_mb;
wchar_t *wc_line = NULL;
- int wc_len, len_n;
+ int wc_len;
if (EwcOpen(ts->need_utf8 || Mode.locale.utf8_int))
return;
@@ -320,11 +311,9 @@ TextstateTextFitMB(TextState *ts, char **ptext, int *pw, int textwidth_limit)
goto done;
width = *pw;
- nuke_count = ((width - textwidth_limit) * wc_len) / width;
- if (nuke_count < 2)
- nuke_count = 2;
+ nuke_count = ((width - textwidth_limit) * wc_len) / width + 3;
- for (;;)
+ for (i = 0; i < 10; i++, nuke_count++)
{
if (nuke_count >= wc_len - 1)
{
@@ -345,20 +334,13 @@ TextstateTextFitMB(TextState *ts, char **ptext, int *pw, int textwidth_limit)
wc_len - nc2 - nuke_count,
new_line + len_mb, len + 10 - len_mb);
new_line[len_mb] = '\0';
- len_n = wc_len - nuke_count + 3;
ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent);
width = *pw;
- nc2 = textwidth_limit - width;
- cw = width / len_n;
-
- if (nc2 >= 0 && nc2 < 3 * cw)
+ dw = textwidth_limit - width;
+ if (dw >= 0)
break;
- if (nc2 > 0)
- nuke_count -= (nc2 <= 2 * cw) ? 1 : (nc2 + cw / 2) / cw;
- else
- nuke_count += (-nc2 <= 2 * cw) ? 1 : (-nc2 + cw / 2) / cw;
}
Efree(text);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.