From 11e569a4e8437910ca163fdceecc91a4789120f4 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 27 Aug 2023 10:16:42 +1000 Subject: [PATCH] emacs-search: be careful to avoid infinite loop. 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 --- DOC/TODO.md | 2 +- emacs-search.c | 8 +++++++- lib-search.c | 2 +- tests.d/00-basic | 29 ++++++++++++++++++++++++++--- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/DOC/TODO.md b/DOC/TODO.md index 54c19343..b78379f2 100644 --- a/DOC/TODO.md +++ b/DOC/TODO.md @@ -9,7 +9,7 @@ the file. ### Triage -- [ ] search hangs when seeking "^( *)" +- [X] search hangs when seeking "^( *)" ### Small diff --git a/emacs-search.c b/emacs-search.c index f702b389..8df41d14 100644 --- a/emacs-search.c +++ b/emacs-search.c @@ -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); } diff --git a/lib-search.c b/lib-search.c index fedfd0d2..feda3da8 100644 --- a/lib-search.c +++ b/lib-search.c @@ -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); diff --git a/tests.d/00-basic b/tests.d/00-basic index 27eeea41..0d0d0968 100644 --- a/tests.d/00-basic +++ b/tests.d/00-basic @@ -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 -- 2.39.5