]> git.neil.brown.name Git - edlib.git/commitdiff
emacs-search: be careful to avoid infinite loop.
authorNeilBrown <neil@brown.name>
Sun, 27 Aug 2023 00:16:42 +0000 (10:16 +1000)
committerNeilBrown <neil@brown.name>
Sun, 27 Aug 2023 03:33:13 +0000 (13:33 +1000)
Assuming that 'm' moved if length > 1 isn't entirely safe.
It *should* be the case, but protecting against infinite loops
deserves belt *and* braces.

So add some extra checks, and test for a case that currently causes an
infinite loop

Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
emacs-search.c
lib-search.c
tests.d/00-basic

index 54c19343798b4dbf9d8e98663939311175dc2d52..b78379f2c8e6610d9a58b54dbcb6410e2c5c41f1 100644 (file)
@@ -9,7 +9,7 @@ the file.
 
 ### Triage
 
-- [ ] search hangs when seeking "^( *)"
+- [X] search hangs when seeking "^( *)"
 
 ### Small
 
index f702b389d6fcd79acb7d1bb55ac94b426296e4ac..8df41d1453e67efcd7d175dfc13dca0172a05b9c 100644 (file)
@@ -746,10 +746,12 @@ static void do_searches(struct pane *p safe,
 {
        int ret;
        struct highlight_info *hi = owner->data;
+       struct mark *start;
 
        if (!m)
                return;
        m = mark_dup(m);
+       start = mark_dup(m);
        while ((ret = call("text-search", p, ci, m, patn, 0, end)) >= 1) {
                struct mark *m2, *m3;
                int len = ret - 1;
@@ -779,10 +781,14 @@ static void do_searches(struct pane *p safe,
                                             0);
                        }
                }
-               if (len == 0)
+
+               if (len == 0 || mark_ordered_or_same(m, start))
                        /* Need to move forward, or we'll just match here again*/
                        doc_next(p, m);
+               mark_free(start);
+               start = mark_dup(m);
        }
+       mark_free(start);
        mark_free(m);
 }
 
index fedfd0d2dd746b44c10550aca955d03b4de63791..feda3da8a69eb25c8dfc4bbae39378c96ab41411 100644 (file)
@@ -125,7 +125,7 @@ DEF_CB(search_test)
                    mark_ordered_not_same(ss->end, ci->mark)) {
                        /* Mark is *after* the char, so if end and mark
                         * are the same, we haven't passed the 'end' yet,
-                        * we it is too early to abort.  Hence 'not' above
+                        * and it is too early to abort.  Hence 'not' above
                         */
                        if (ss->anchor_at_end) {
                                found = rxl_advance(ss->st, RXL_ANCHOR);
index 27eeea4196e7e537186cf484a36feb6aac6ce719..0d0d09682e02689b881390ec57165471633cceed 100644 (file)
@@ -701,8 +701,31 @@ Key ":C-F"
 Display 80,30 3C812011C331AE6C522C00B0145F9E4D 7,7
 Key ":C-F"
 Display 80,30 68CC3869602D7CE09C8CB343CB22E8D9 2,7
+Key ":A-<"
+Display 80,30 D5B3049D8076DB789C8E2E4F8618269B 1,0
+Key ":C-S"
+Display 80,30 33F87FCE49B9C6BF4D1D721CD250A5E2 30,0
+Key ":A-^"
+Display 80,30 84B076F05226EFB8B9A123251C977176 31,0
+Display 80,30 A2B40688118C3E637B75716028DF9799 31,0
+Key ":A-("
+Display 80,30 B5F28C1C31BBFDE836CC569AA8A079D4 37,0
+Key "- "
+Display 80,30 E0FABBE3663A7A3D9E60096256D52AEA 33,0
+Display 80,30 89BB7EAE4B3B326B7D9639B385945A7B 33,0
+Key ":A-*"
+Display 80,30 C0DA1BD87EBD2F695750F5C476DF30FD 34,0
+Display 80,30 73141BC1B00150904D453A43CC32F667 34,0
+Key ":C-S"
+Display 80,30 CF36D321FC2E8BBF753727F50A4462D5 34,0
+Display 80,30 73141BC1B00150904D453A43CC32F667 34,0
+Key ":C-S"
+Display 80,30 F4380BB2A1A540A385B373BB04B0DE14 34,0
+Display 80,30 DC891DB9A031F49837FC8F35941B52F6 34,0
+Key ":Enter"
+Display 80,30 29F3151EB6D0ED1BF8BC637E0E8F41CB 1,3
 Key ":C-X"
-Display 80,30 CF77174CFC77ECAC2102213E88F4BF50 2,7
+Display 80,30 6C71927B10030D3ABC828BF38CF37799 1,3
 Key ":C-C"
-Display 80,30 7EB025B1893D47CC56F241B3FAB0090A 21,8
-Close 1809
+Display 80,30 39B814F1E8577AAD3DF0FAE0D5E0B412 21,8
+Close 1965