From fe42eb7a1a71aa0e1cfc225564bef063a6f3e84c Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Fri, 1 Apr 2022 16:52:45 +0200 Subject: [PATCH] painting: stop coloring an extremely long line after 2000 bytes Especially when softwrapping and when multiline regexes are involved, colorizing takes roughly exponential time relative to the line length. To avoid bogging down, stop colorizing a line beyond a certain point. This mitigates https://savannah.gnu.org/bugs/?61799. Reported-by: Devin Hussey --- src/winio.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/winio.c b/src/winio.c index 5e426726..fcec4919 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2475,6 +2475,9 @@ void place_the_cursor(void) openfile->current_y = row; } +/* The number of bytes after which to stop painting, to avoid major slowdowns. */ +#define PAINT_LIMIT 2000 + /* Draw the given text on the given row of the edit window. line is the * line to be drawn, and converted is the actual string to be written with * tabs and control characters replaced by strings of regular characters. @@ -2548,7 +2551,7 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col) /* First case: varnish is a single-line expression. */ if (varnish->end == NULL) { - while (index < till_x) { + while (index < PAINT_LIMIT && index < till_x) { /* If there is no match, go on to the next line. */ if (regexec(varnish->start, &line->data[index], 1, &match, (index == 0) ? 0 : REG_NOTBOL) != 0) @@ -2629,8 +2632,8 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col) * looking only after an end match, if there is one. */ index = (paintlen == 0) ? 0 : endmatch.rm_eo; - while (regexec(varnish->start, line->data + index, 1, &startmatch, - (index == 0) ? 0 : REG_NOTBOL) == 0) { + while (index < PAINT_LIMIT && regexec(varnish->start, line->data + index, + 1, &startmatch, (index == 0) ? 0 : REG_NOTBOL) == 0) { /* Make the match relative to the beginning of the line. */ startmatch.rm_so += index; startmatch.rm_eo += index;