Skip wrapped lines in top level search loop because they will be
authornicm <nicm@openbsd.org>
Mon, 4 Sep 2023 08:01:43 +0000 (08:01 +0000)
committernicm <nicm@openbsd.org>
Mon, 4 Sep 2023 08:01:43 +0000 (08:01 +0000)
combined in the inner loop (in window_copy_search_rl_regex and the
others), avoids searching the same text multiple times. Also add a line
length limit for regex searches. GitHub issue 3675.

usr.bin/tmux/window-copy.c

index 58454d5..741dfd3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-copy.c,v 1.343 2023/09/01 14:29:11 nicm Exp $ */
+/* $OpenBSD: window-copy.c,v 1.344 2023/09/04 08:01:43 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -295,6 +295,7 @@ struct window_copy_mode_data {
        int              timeout;       /* search has timed out */
 #define WINDOW_COPY_SEARCH_TIMEOUT 10000
 #define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200
+#define WINDOW_COPY_SEARCH_MAX_LINE 2000
 
        int                      jumptype;
        struct utf8_data        *jumpchar;
@@ -3205,7 +3206,9 @@ window_copy_search_lr_regex(struct grid *gd, u_int *ppx, u_int *psx, u_int py,
        len = gd->sx - first;
        endline = gd->hsize + gd->sy - 1;
        pywrap = py;
-       while (buf != NULL && pywrap <= endline) {
+       while (buf != NULL &&
+           pywrap <= endline &&
+           len < WINDOW_COPY_SEARCH_MAX_LINE) {
                gl = grid_get_line(gd, pywrap);
                if (~gl->flags & GRID_LINE_WRAPPED)
                        break;
@@ -3262,7 +3265,9 @@ window_copy_search_rl_regex(struct grid *gd, u_int *ppx, u_int *psx, u_int py,
        len = gd->sx - first;
        endline = gd->hsize + gd->sy - 1;
        pywrap = py;
-       while (buf != NULL && (pywrap <= endline)) {
+       while (buf != NULL &&
+           pywrap <= endline &&
+           len < WINDOW_COPY_SEARCH_MAX_LINE) {
                gl = grid_get_line(gd, pywrap);
                if (~gl->flags & GRID_LINE_WRAPPED)
                        break;
@@ -3601,10 +3606,11 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
     struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,
     int direction, int regex)
 {
-       u_int    i, px, sx, ssize = 1;
-       int      found = 0, cflags = REG_EXTENDED;
-       char    *sbuf;
-       regex_t  reg;
+       u_int                    i, px, sx, ssize = 1;
+       int                      found = 0, cflags = REG_EXTENDED;
+       char                    *sbuf;
+       regex_t                  reg;
+       struct grid_line        *gl;
 
        if (regex) {
                sbuf = xmalloc(ssize);
@@ -3621,6 +3627,9 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
 
        if (direction) {
                for (i = fy; i <= endline; i++) {
+                       gl = grid_get_line(gd, i);
+                       if (i != endline && gl->flags & GRID_LINE_WRAPPED)
+                               continue;
                        if (regex) {
                                found = window_copy_search_lr_regex(gd,
                                    &px, &sx, i, fx, gd->sx, &reg);
@@ -3634,6 +3643,9 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
                }
        } else {
                for (i = fy + 1; endline < i; i--) {
+                       gl = grid_get_line(gd, i - 1);
+                       if (i != endline && gl->flags & GRID_LINE_WRAPPED)
+                               continue;
                        if (regex) {
                                found = window_copy_search_rl_regex(gd,
                                    &px, &sx, i - 1, 0, fx + 1, &reg);