From 1fdd23d347d297b4ab7d36e46ac4d860c6a531c3 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Wed, 3 Feb 2021 16:27:51 +0100 Subject: [PATCH] display: for a large paste or insertion, recalculate the multiline cache When a large piece of text or code is pasted or inserted, it could contain matches for start= and end= regexes, and backtracking from the current screen could mistake an end for a start and could thus miscolor things. Avoid this by recalculating the multiline cache for pastes and insertions that cover more than a screenful. This fixes https://savannah.gnu.org/bugs/?59982. Bug existed since version 2.6.0, but existed also before 2.4.3. --- src/color.c | 3 +-- src/cut.c | 4 ++++ src/files.c | 7 ++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/color.c b/src/color.c index 4b016af1..2310f982 100644 --- a/src/color.c +++ b/src/color.c @@ -289,8 +289,7 @@ void precalc_multicolorinfo(void) regmatch_t startmatch, endmatch; linestruct *line, *tailline; - if (openfile->syntax == NULL || openfile->syntax->nmultis == 0 || - openfile->filetop->multidata || ISSET(NO_SYNTAX)) + if (!openfile->syntax || openfile->syntax->nmultis == 0 || ISSET(NO_SYNTAX)) return; //#define TIMEPRECALC 123 diff --git a/src/cut.c b/src/cut.c index 7d8794aa..722ba82e 100644 --- a/src/cut.c +++ b/src/cut.c @@ -734,6 +734,10 @@ void paste_text(void) /* If we pasted less than a screenful, don't center the cursor. */ if (less_than_a_screenful(was_lineno, was_leftedge)) focusing = FALSE; +#ifdef ENABLE_COLOR + else + precalc_multicolorinfo(); +#endif /* Set the desired x position to where the pasted text ends. */ openfile->placewewant = xplustabs(); diff --git a/src/files.c b/src/files.c index 68d20589..bc876cb1 100644 --- a/src/files.c +++ b/src/files.c @@ -498,7 +498,8 @@ void prepare_for_display(void) #ifdef ENABLE_COLOR /* Precalculate the data for any multiline coloring regexes. */ - precalc_multicolorinfo(); + if (!openfile->filetop->multidata) + precalc_multicolorinfo(); have_palette = FALSE; #endif refresh_needed = TRUE; @@ -818,6 +819,10 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable) /* If we inserted less than a screenful, don't center the cursor. */ if (undoable && less_than_a_screenful(was_lineno, was_leftedge)) focusing = FALSE; +#ifdef ENABLE_COLOR + else if (undoable) + precalc_multicolorinfo(); +#endif #ifndef NANO_TINY if (undoable)