mirror of
				https://github.com/vim/vim.git
				synced 2025-10-31 09:57:14 -04:00 
			
		
		
		
	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
						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