On Tue, Jul 21, 2020 at 05:33:39PM +0200, Theo Buehler wrote:
> > Hmm. I get neither a seg fault nor a loop on my amd64 Lenove E595. The
> > cursor moves to different spots in X/i3 xterm vs console and in either
> > case doesn't do any replacement.
> 
> I can reproduce both behaviors reliably as follows both on console and
> in xterm.
> 
> $ echo 'a\n\n\nb' > /tmp/test
> $ mg /tmp/test
> 
> Don't move the cursor, just do the following (what is between quotation
> marks is what you are supposed to type, the other bits are prompts):
> 
> "M-x query-replace-regexp<enter>"

Aha. I was just doing "M-%" which is query-replace and not
query-replace-regexp as I thought.

> RE Query replace: "^<enter>"
> Query replace ^ with: "a<enter>"
> Query replacing ^ with a: "<enter>"
> <SP> replace, [.] rep-end, <DEL> don't, [!] repl rest <ESC> quit "!"

And now I get this.

> 
> After hitting "!" here, it will enter a loop and eventually print
> 
> panic: Out of memory in undo code (record)
> 
> and exit.
> 
> If I do the exact same dance after moving the cursor to the second
> (empty) line, it will segfault.
> 
> With the diff below (which is what I understood to be Hiltjo's
> suggestion), I get more or less what I would expect. I think it should
> not replace the empty line after the last newline...
> 
> So I think both diffs are not quite right :)

Well, I think not quite right is much better than looping or
segfault. So I'd go ahead with either diff at your discretion.

.... Ken

> 
> Index: line.c
> ===================================================================
> RCS file: /var/cvs/src/usr.bin/mg/line.c,v
> retrieving revision 1.61
> diff -u -p -r1.61 line.c
> --- line.c    29 Aug 2018 07:50:16 -0000      1.61
> +++ line.c    21 Jul 2020 14:58:49 -0000
> @@ -556,6 +556,8 @@ lreplace(RSIZE plen, char *st)
>               goto done;
>  
>       lp = curwp->w_dotp;
> +     if (ltext(lp) == NULL)
> +             goto done;
>       doto = curwp->w_doto;
>       n = plen;
>  
> Index: re_search.c
> ===================================================================
> RCS file: /var/cvs/src/usr.bin/mg/re_search.c,v
> retrieving revision 1.34
> diff -u -p -r1.34 re_search.c
> --- re_search.c       9 Jul 2020 10:42:24 -0000       1.34
> +++ re_search.c       21 Jul 2020 15:00:08 -0000
> @@ -308,7 +308,7 @@ re_doreplace(RSIZE plen, char *st)
>  static int
>  re_forwsrch(void)
>  {
> -     int      tbo, tdotline, error;
> +     int              re_flags, tbo, tdotline, error;
>       struct line     *clp;
>  
>       clp = curwp->w_dotp;
> @@ -330,10 +330,13 @@ re_forwsrch(void)
>        * always makes the last line empty so this is good.
>        */
>       while (clp != (curbp->b_headp)) {
> +             re_flags = REG_STARTEND;
> +             if (tbo != 0)
> +                     re_flags |= REG_NOTBOL;
>               regex_match[0].rm_so = tbo;
>               regex_match[0].rm_eo = llength(clp);
>               error = regexec(&regex_buff, ltext(clp) ? ltext(clp) : "",
> -                 RE_NMATCH, regex_match, REG_STARTEND);
> +                 RE_NMATCH, regex_match, re_flags);
>               if (error != 0) {
>                       clp = lforw(clp);
>                       tdotline++;

Reply via email to