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.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
baa8c90cc0
commit
6924eb81f4
80
src/main.c
80
src/main.c
@ -449,6 +449,35 @@ main
|
|||||||
#endif // NO_VIM_MAIN
|
#endif // NO_VIM_MAIN
|
||||||
#endif // PROTO
|
#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
|
* vim_main2() is needed for FEAT_MZSCHEME, but we define it always to keep
|
||||||
* things simple.
|
* things simple.
|
||||||
@ -790,9 +819,28 @@ vim_main2(void)
|
|||||||
getout(1);
|
getout(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute any "+", "-c" and "-S" arguments.
|
#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
|
||||||
if (params.n_commands > 0)
|
// Temporarily set x_jump_env to here in case there is an X11 IO error,
|
||||||
exe_commands(¶ms);
|
// 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(¶ms);
|
||||||
|
#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.
|
// Must come before the may_req_ calls.
|
||||||
starting = 0;
|
starting = 0;
|
||||||
@ -1242,30 +1290,10 @@ main_loop(
|
|||||||
#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
|
#if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
|
||||||
// Setup to catch a terminating error from the X server. Just ignore
|
// Setup to catch a terminating error from the X server. Just ignore
|
||||||
// it, restore the state and continue. This might not always work
|
// it, restore the state and continue. This might not always work
|
||||||
// properly, but at least we don't exit unexpectedly when the X server
|
// properly, but at least we hopefully don't exit unexpectedly when the X
|
||||||
// exits while Vim is running in a console.
|
// server exits while Vim is running in a console.
|
||||||
if (!cmdwin && !noexmode && SETJMP(x_jump_env))
|
if (!cmdwin && !noexmode && SETJMP(x_jump_env))
|
||||||
{
|
x_restore_state();
|
||||||
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
|
#endif
|
||||||
|
|
||||||
clear_oparg(&oa);
|
clear_oparg(&oa);
|
||||||
|
|||||||
@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1324,
|
||||||
/**/
|
/**/
|
||||||
1323,
|
1323,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user