Index | Thread | Search

From:
"Dante Catalfamo" <dante@lambda.cx>
Subject:
Re: mg: prevet crash with invalid compile buffer
To:
tech@openbsd.org
Date:
Wed, 31 Jul 2024 13:06:50 -0400

Download raw body.

Thread
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);
>>