From: "Dante Catalfamo" Subject: Re: mg: prevet crash with invalid compile buffer To: tech@openbsd.org Date: Wed, 31 Jul 2024 13:06:50 -0400 Realized I could open the compile buffer in a new window if it's not associated with one currently. diff --git a/usr.bin/mg/grep.c b/usr.bin/mg/grep.c index aa7f9dfd8..6f15f2405 100644 --- a/usr.bin/mg/grep.c +++ b/usr.bin/mg/grep.c @@ -21,6 +21,7 @@ int globalwd = FALSE; static int compile_goto_error(int, int); +int valid_compile_buffer(void); int next_error(int, int); static int grep(int, int); static int gid(int, int); @@ -318,9 +319,46 @@ fail: } int -next_error(int f, int n) +valid_compile_buffer(void) { + struct mgwin *wp; + struct buffer *bp; + if (compile_win == NULL || compile_buffer == NULL) { + return (FALSE); + } + + for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { + if (compile_win == wp && compile_win->w_bufp == compile_buffer) { + return (TRUE); + } + } + + for (bp = bheadp; bp != NULL; bp = bp->b_bufp) { + if (bp == compile_buffer) + break; + } + + /* compile buffer found, but not associated with a window */ + if (bp) { + splitwind(0, 1); + if (showbuffer(bp, curwp, 0) != TRUE) + return (FALSE); + compile_win = curwp; + return (TRUE); + } + + compile_win = NULL; + compile_buffer = NULL; + + return (FALSE); +} + + +int +next_error(int f, int n) +{ + if (!valid_compile_buffer()) { dobeep(); ewprintf("No compilation active"); return (FALSE); On Wed, Jul 31, 2024, at 12:24 AM, Dante Catalfamo wrote: > I just realized this could be greatly simplified > > diff --git a/usr.bin/mg/grep.c b/usr.bin/mg/grep.c > index aa7f9dfd8..cf5337f8d 100644 > --- a/usr.bin/mg/grep.c > +++ b/usr.bin/mg/grep.c > @@ -21,6 +21,7 @@ > > int globalwd = FALSE; > static int compile_goto_error(int, int); > +int valid_compile_buffer(void); > int next_error(int, int); > static int grep(int, int); > static int gid(int, int); > @@ -318,9 +319,31 @@ fail: > } > > int > -next_error(int f, int n) > +valid_compile_buffer(void) > { > + struct mgwin *wp; > + > if (compile_win == NULL || compile_buffer == NULL) { > + return (FALSE); > + } > + > + for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { > + if (compile_win == wp && compile_win->w_bufp == > compile_buffer) { > + return (TRUE); > + } > + } > + > + compile_win = NULL; > + compile_buffer = NULL; > + > + return (FALSE); > +} > + > + > +int > +next_error(int f, int n) > +{ > + if (!valid_compile_buffer()) { > dobeep(); > ewprintf("No compilation active"); > return (FALSE); > > On Sat, 2024-07-27 at 17:10 -0400, Dante Catalfamo wrote: >> Hello tech@, >> >> There is a bug in mg that will cause a crash if you call `next-error` >> after deleting the compile window or compile buffer. You can easily >> replicate the issue by calling `grep`, changing the buffer in the >> completion window, and calling `next-error`. >> >> This patch will check if the completion buffer and window are still >> valid before attempting to read from them. >> >> Thanks >> >> diff --git a/usr.bin/mg/grep.c b/usr.bin/mg/grep.c >> index aa7f9dfd8..b6db138d3 100644 >> --- a/usr.bin/mg/grep.c >> +++ b/usr.bin/mg/grep.c >> @@ -21,6 +21,7 @@ >>   >>  int globalwd = FALSE; >>  static int compile_goto_error(int, int); >> +int valid_compile_buffer(void); >>  int next_error(int, int); >>  static int grep(int, int); >>  static int gid(int, int); >> @@ -318,9 +319,47 @@ fail: >>  } >>   >>  int >> -next_error(int f, int n) >> +valid_compile_buffer(void) >>  { >> + struct mgwin *wp; >> + struct buffer *bp; >> + int win_found, buffer_found; >> + >>   if (compile_win == NULL || compile_buffer == NULL) { >> + return (FALSE); >> + } >> + >> + win_found = buffer_found = 0; >> + >> + for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { >> + if (compile_win == wp) >> + win_found = 1; >> + } >> + if (!win_found) { >> + compile_win = NULL; >> + return (FALSE); >> + } >> + >> + for (bp = bheadp; bp != NULL; bp = bp->b_bufp) { >> + if (compile_buffer == bp) >> + buffer_found = 1; >> + } >> + if (!buffer_found) { >> + compile_buffer = NULL; >> + return (FALSE); >> + } >> + >> + if (compile_win->w_bufp != compile_buffer) >> + return (FALSE); >> + >> + return (TRUE); >> +} >> + >> + >> +int >> +next_error(int f, int n) >> +{ >> +    if (!valid_compile_buffer()) { >>   dobeep(); >>   ewprintf("No compilation active"); >>   return (FALSE); >>