patch 9.1.1324: undefined behaviour if X11 connection dies

Commit: 
https://github.com/vim/vim/commit/6924eb81f4e69726f59eaa0c121b7442343d770d
Author: Foxe Chen <chen.f...@gmail.com>
Date:   Sat Apr 19 11:25:18 2025 +0200

    patch 9.1.1324: undefined behaviour if X11 connection dies
    
    Problem:  undefined behaviour if X11 connection dies
    Solution: call setjmp() before the main_loop() and restore x11 state
              if the X11 connection dies (Foxe Chen)
    
    fixes: #698
    closes: #17142
    
    Signed-off-by: Foxe Chen <chen.f...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/main.c b/src/main.c
index 9a862c4be..31494e3e8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -449,6 +449,35 @@ main
 #endif // NO_VIM_MAIN
 #endif // PROTO
 
+#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
+/*
+ * Restore the state after a fatal X error.
+ */
+    static void
+x_restore_state(void)
+{
+    State = MODE_NORMAL;
+    VIsual_active = FALSE;
+    got_int = TRUE;
+    need_wait_return = FALSE;
+    global_busy = FALSE;
+    exmode_active = 0;
+    skip_redraw = FALSE;
+    RedrawingDisabled = 0;
+    no_wait_return = 0;
+    vgetc_busy = 0;
+# ifdef FEAT_EVAL
+    emsg_skip = 0;
+# endif
+    emsg_off = 0;
+    setmouse();
+    settmode(TMODE_RAW);
+    starttermcap();
+    scroll_start();
+    redraw_later_clear();
+}
+#endif
+
 /*
  * vim_main2() is needed for FEAT_MZSCHEME, but we define it always to keep
  * things simple.
@@ -790,9 +819,28 @@ vim_main2(void)
            getout(1);
     }
 
-    // Execute any "+", "-c" and "-S" arguments.
-    if (params.n_commands > 0)
-       exe_commands(&params);
+#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
+    // Temporarily set x_jump_env to here in case there is an X11 IO error,
+    // because x_jump_env is only actually set in main_loop(), before
+    // exe_commands(). May not be the best solution since commands passed via
+    // the command line can be very broad like sourcing a file, in which case
+    // an X IO error results in the command being partially done. In theory we
+    // could use SETJMP in RealWaitForChar(), but the stack frame for that may
+    // possibly exit and then LONGJMP is called on it.
+    int jump_result = SETJMP(x_jump_env);
+
+    if (jump_result == 0)
+    {
+#endif
+       // Execute any "+", "-c" and "-S" arguments.
+       if (params.n_commands > 0)
+           exe_commands(&params);
+#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
+    }
+    else
+       // Restore state and continue just like what main_loop() does.
+       x_restore_state();
+#endif
 
     // Must come before the may_req_ calls.
     starting = 0;
@@ -1242,30 +1290,10 @@ main_loop(
 #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
     // Setup to catch a terminating error from the X server.  Just ignore
     // it, restore the state and continue.  This might not always work
-    // properly, but at least we don't exit unexpectedly when the X server
-    // exits while Vim is running in a console.
+    // properly, but at least we hopefully don't exit unexpectedly when the X
+    // server exits while Vim is running in a console.
     if (!cmdwin && !noexmode && SETJMP(x_jump_env))
-    {
-       State = MODE_NORMAL;
-       VIsual_active = FALSE;
-       got_int = TRUE;
-       need_wait_return = FALSE;
-       global_busy = FALSE;
-       exmode_active = 0;
-       skip_redraw = FALSE;
-       RedrawingDisabled = 0;
-       no_wait_return = 0;
-       vgetc_busy = 0;
-# ifdef FEAT_EVAL
-       emsg_skip = 0;
-# endif
-       emsg_off = 0;
-       setmouse();
-       settmode(TMODE_RAW);
-       starttermcap();
-       scroll_start();
-       redraw_later_clear();
-    }
+       x_restore_state();
 #endif
 
     clear_oparg(&oa);
diff --git a/src/version.c b/src/version.c
index db77e4538..e3b55fa94 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1324,
 /**/
     1323,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1u64kx-00CJjv-Ux%40256bit.org.

Raspunde prin e-mail lui