From 80525751c5ce9ed82c41d83faf9ef38667bf61b1 Mon Sep 17 00:00:00 2001
From: Bram Moolenaar <Bram@vim.org>
Date: Wed, 24 Aug 2022 19:27:45 +0100
Subject: [PATCH] patch 9.0.0259: crash with mouse click when not initialized

Problem:    Crash with mouse click when not initialized.
Solution:   Check TabPageIdxs[] is not NULL.
---
 src/mouse.c                  | 107 ++++++++++++++++++++++---------------------
 src/testdir/test_tabline.vim |  14 ++++++
 2 files changed, 69 insertions(+), 52 deletions(-)

diff --git a/src/mouse.c b/src/mouse.c
index c39f614..12895f8 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -471,74 +471,77 @@ do_mouse(
 
     start_visual.lnum = 0;
 
-    // Check for clicking in the tab page line.
-    if (mouse_row == 0 && firstwin->w_winrow > 0)
+    if (TabPageIdxs != NULL)  // only when initialized
     {
-	if (is_drag)
+	// Check for clicking in the tab page line.
+	if (mouse_row == 0 && firstwin->w_winrow > 0)
 	{
-	    if (in_tab_line)
+	    if (is_drag)
 	    {
-		c1 = TabPageIdxs[mouse_col];
-		tabpage_move(c1 <= 0 ? 9999 : c1 < tabpage_index(curtab)
-								? c1 - 1 : c1);
+		if (in_tab_line)
+		{
+		    c1 = TabPageIdxs[mouse_col];
+		    tabpage_move(c1 <= 0 ? 9999 : c1 < tabpage_index(curtab)
+								    ? c1 - 1 : c1);
+		}
+		return FALSE;
 	    }
-	    return FALSE;
-	}
 
-	// click in a tab selects that tab page
-	if (is_click
+	    // click in a tab selects that tab page
+	    if (is_click
 # ifdef FEAT_CMDWIN
-		&& cmdwin_type == 0
+		    && cmdwin_type == 0
 # endif
-		&& mouse_col < Columns)
-	{
-	    in_tab_line = TRUE;
-	    c1 = TabPageIdxs[mouse_col];
-	    if (c1 >= 0)
+		    && mouse_col < Columns)
 	    {
-		if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
-		{
-		    // double click opens new page
-		    end_visual_mode_keep_button();
-		    tabpage_new();
-		    tabpage_move(c1 == 0 ? 9999 : c1 - 1);
-		}
-		else
+		in_tab_line = TRUE;
+		c1 = TabPageIdxs[mouse_col];
+		if (c1 >= 0)
 		{
-		    // Go to specified tab page, or next one if not clicking
-		    // on a label.
-		    goto_tabpage(c1);
-
-		    // It's like clicking on the status line of a window.
-		    if (curwin != old_curwin)
+		    if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
+		    {
+			// double click opens new page
 			end_visual_mode_keep_button();
-		}
-	    }
-	    else
-	    {
-		tabpage_T	*tp;
+			tabpage_new();
+			tabpage_move(c1 == 0 ? 9999 : c1 - 1);
+		    }
+		    else
+		    {
+			// Go to specified tab page, or next one if not clicking
+			// on a label.
+			goto_tabpage(c1);
 
-		// Close the current or specified tab page.
-		if (c1 == -999)
-		    tp = curtab;
+			// It's like clicking on the status line of a window.
+			if (curwin != old_curwin)
+			    end_visual_mode_keep_button();
+		    }
+		}
 		else
-		    tp = find_tabpage(-c1);
-		if (tp == curtab)
 		{
-		    if (first_tabpage->tp_next != NULL)
-			tabpage_close(FALSE);
+		    tabpage_T	*tp;
+
+		    // Close the current or specified tab page.
+		    if (c1 == -999)
+			tp = curtab;
+		    else
+			tp = find_tabpage(-c1);
+		    if (tp == curtab)
+		    {
+			if (first_tabpage->tp_next != NULL)
+			    tabpage_close(FALSE);
+		    }
+		    else if (tp != NULL)
+			tabpage_close_other(tp, FALSE);
 		}
-		else if (tp != NULL)
-		    tabpage_close_other(tp, FALSE);
 	    }
+	    return TRUE;
+	}
+	else if (is_drag && in_tab_line)
+	{
+	    c1 = TabPageIdxs[mouse_col];
+	    tabpage_move(c1 <= 0 ? 9999 : c1 - 1);
+	    return FALSE;
 	}
-	return TRUE;
-    }
-    else if (is_drag && in_tab_line)
-    {
-	c1 = TabPageIdxs[mouse_col];
-	tabpage_move(c1 <= 0 ? 9999 : c1 - 1);
-	return FALSE;
     }
 
     // When 'mousemodel' is "popup" or "popup_setpos", translate mouse events:
diff --git a/src/testdir/test_tabline.vim b/src/testdir/test_tabline.vim
index e58a412..556b859 100644
--- a/src/testdir/test_tabline.vim
+++ b/src/testdir/test_tabline.vim
@@ -147,4 +147,18 @@ func Test_tabline_20_format_items_no_overrun()
   set showtabline& tabline&
 endfunc
 
+func Test_mouse_click_in_tab()
+  " This used to crash because TabPageIdxs[] was not initialized
+  let lines =<< trim END
+      tabnew
+      set mouse=a
+      exe "norm \<LeftMouse>"
+  END
+  call writefile(lines, 'Xclickscript')
+  call RunVim([], [], "-e -s -S Xclickscript -c qa")
+
+  call delete('Xclickscript')
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
-- 
1.8.3.1

