From: Mark Willson Subject: mg(1): regexp: infinite loop; over-eager anchor replacement [PATCH] To: Date: Wed, 27 Aug 2025 16:30:16 +0100 Hi Folks, The patch below fixes the following issues with the mg(1) editor: 1. An infinite loop with (replace-regexp "^" ""). replace-regexp does not advance to the next line. This also occurs when the search text is "^.*$". 2. replace-regexp replaces all occurances of ^pat on a line. For example, (replace-regexp "^#" "") will delete every occurance of "#" in the line "#############################". This is unexpected (at least to me) and is not the behaviour of emacs. I'd be very grateful if someone could apply this patch (or a more acceptable version) to the source tree. Best Regards, Mark --- re_search.c.orig Wed Aug 27 14:42:51 2025 +++ re_search.c Wed Aug 27 14:42:49 2025 @@ -191,6 +191,12 @@ ewprintf(" replace, [.] rep-end, don't, [!] repl rest quit"); goto retry; } + /* Prevent: + * infinite loop when replacing ^ with "" + * multiple replacements of ^pat on same line + */ + if (re_pat[0] == '^' && news[0] == '\0') + curwp->w_doto = curwp->w_dotp->l_used; } stopsearch: @@ -224,6 +230,12 @@ plen = regex_match[0].rm_eo - regex_match[0].rm_so; if (re_doreplace((RSIZE)plen, news) == FALSE) return (FALSE); + /* Prevent: + * infinite loop when replacing ^ with "" + * multiple replacements of ^pat on same line + */ + if (re_pat[0] == '^' && news[0] == '\0') + curwp->w_doto = curwp->w_dotp->l_used; rcnt++; } @@ -342,10 +354,9 @@ if (tbo == clp->l_used) /* * Don't start matching past end of line -- must move to - * beginning of next line, unless line is empty or at - * end of file. + * beginning of next line, unless at end of file. */ - if (clp != curbp->b_headp && llength(clp) != 0) { + if (clp != curbp->b_headp) { clp = lforw(clp); tdotline++; tbo = 0; -- Mark Willson mark.willson@hydrus.org.uk