# HG changeset patch # User Bram Moolenaar # Date 1642097703 -3600 # Node ID 92e0b1f2b72f9c6cb58886ae2cb5dd1902079b0b # Parent 98aa9f353206b1b3e34d073dfdc334ab3b591e50 patch 8.2.4081: CodeQL reports problem in if_cscope causing it to fail Commit: https://github.com/vim/vim/commit/4050305bfd24e7d0e241f617519bd0fa86263b9a Author: ichizok Date: Thu Jan 13 18:09:11 2022 +0000 patch 8.2.4081: CodeQL reports problem in if_cscope causing it to fail Problem: CodeQL reports problem in if_cscope causing it to fail. Solution: Use execvp() instead of execl(). Merge the header file into the source file. (Ozaki Kiichi, closes #9519) diff --git a/Filelist b/Filelist --- a/Filelist +++ b/Filelist @@ -497,7 +497,6 @@ SRC_UNIX = \ SRC_DOS_UNIX = \ src/gui_xim.c \ src/if_cscope.c \ - src/if_cscope.h \ src/if_lua.c \ src/if_mzsch.c \ src/if_mzsch.h \ diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -1237,7 +1237,7 @@ endif $(OUTDIR)/gui_w32.o: gui_w32.c $(INCL) $(GUI_INCL) version.h $(CC) -c $(CFLAGS) gui_w32.c -o $@ -$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h +$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) $(CC) -c $(CFLAGS) if_cscope.c -o $@ $(OUTDIR)/if_mzsch.o: if_mzsch.c $(INCL) $(MZSCHEME_INCL) $(MZ_EXTRA_DEP) diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -1670,7 +1670,7 @@ test_vim9: $(OUTDIR)/gui_dwrite.obj: $(OUTDIR) gui_dwrite.cpp gui_dwrite.h -$(OUTDIR)/if_cscope.obj: $(OUTDIR) if_cscope.c $(INCL) if_cscope.h +$(OUTDIR)/if_cscope.obj: $(OUTDIR) if_cscope.c $(INCL) $(OUTDIR)/if_lua.obj: $(OUTDIR) if_lua.c $(INCL) $(CC) $(CFLAGS_OUTDIR) $(LUA_INC) if_lua.c diff --git a/src/Make_vms.mms b/src/Make_vms.mms --- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -908,7 +908,7 @@ highlight.obj : highlight.c vim.h [.auto if_cscope.obj : if_cscope.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ - errors.h globals.h if_cscope.h + errors.h globals.h if_xcmdsrv.obj : if_xcmdsrv.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ diff --git a/src/Makefile b/src/Makefile --- a/src/Makefile +++ b/src/Makefile @@ -3922,7 +3922,7 @@ objects/highlight.o: highlight.c vim.h p objects/if_cscope.o: if_cscope.c vim.h protodef.h auto/config.h feature.h \ os_unix.h auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ - proto.h globals.h errors.h if_cscope.h + proto.h globals.h errors.h objects/if_xcmdsrv.o: if_xcmdsrv.c vim.h protodef.h auto/config.h feature.h \ os_unix.h auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/if_cscope.c b/src/if_cscope.c --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -18,7 +18,62 @@ #if defined(UNIX) # include #endif -#include "if_cscope.h" + +#if defined (MSWIN) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +#endif + +#define CSCOPE_SUCCESS 0 +#define CSCOPE_FAILURE -1 + +#define CSCOPE_DBFILE "cscope.out" +#define CSCOPE_PROMPT ">> " + +/* + * See ":help cscope-find" for the possible queries. + */ + +typedef struct { + char * name; + int (*func)(exarg_T *eap); + char * help; + char * usage; + int cansplit; // if supports splitting window +} cscmd_T; + +typedef struct csi { + char * fname; // cscope db name + char * ppath; // path to prepend (the -P option) + char * flags; // additional cscope flags/options (e.g, -p2) +#if defined(UNIX) + pid_t pid; // PID of the connected cscope process. + dev_t st_dev; // ID of dev containing cscope db + ino_t st_ino; // inode number of cscope db +#else +# if defined(MSWIN) + DWORD pid; // PID of the connected cscope process. + HANDLE hProc; // cscope process handle + DWORD nVolume; // Volume serial number, instead of st_dev + DWORD nIndexHigh; // st_ino has no meaning in the Windows + DWORD nIndexLow; +# endif +#endif + + FILE * fr_fp; // from cscope: FILE. + FILE * to_fp; // to cscope: FILE. +} csinfo_T; + +typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e; + +typedef enum { + Store, + Get, + Free, + Print +} mcmd_e; static int cs_add(exarg_T *eap); static int cs_add_common(char *, char *, char *); @@ -811,12 +866,16 @@ err_closing: return CSCOPE_FAILURE; } - switch (csinfo[i].pid = fork()) + if ((csinfo[i].pid = fork()) == -1) { - case -1: (void)emsg(_(e_could_not_fork_for_cscope)); goto err_closing; - case 0: // child: run cscope. + } + else if (csinfo[i].pid == 0) // child: run cscope. + { + char **argv = NULL; + int argc = 0; + if (dup2(to_cs[0], STDIN_FILENO) == -1) PERROR("cs_create_connection 1"); if (dup2(from_cs[1], STDOUT_FILENO) == -1) @@ -856,7 +915,7 @@ err_closing: if ((prog = alloc(MAXPATHL + 1)) == NULL) { #ifdef UNIX - return CSCOPE_FAILURE; + exit(EXIT_FAILURE); #else // MSWIN goto err_closing; @@ -873,7 +932,7 @@ err_closing: { vim_free(prog); #ifdef UNIX - return CSCOPE_FAILURE; + exit(EXIT_FAILURE); #else // MSWIN goto err_closing; @@ -892,20 +951,16 @@ err_closing: vim_free(prog); vim_free(ppath); #ifdef UNIX - return CSCOPE_FAILURE; + exit(EXIT_FAILURE); #else // MSWIN goto err_closing; #endif } - // run the cscope command; is there execl for non-unix systems? -#if defined(UNIX) - (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname); -#else - // MSWIN + // run the cscope command (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname); -#endif + if (csinfo[i].ppath != NULL) { (void)strcat(cmd, " -P"); @@ -932,12 +987,17 @@ err_closing: PERROR(_("cs_create_connection setpgid failed")); # endif # endif - if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1) + if (build_argv_from_string((char_u *)cmd, &argv, &argc) == FAIL) + exit(EXIT_FAILURE); + + if (execvp(argv[0], argv) == -1) PERROR(_("cs_create_connection exec failed")); exit(127); // NOTREACHED - default: // parent. + } + else // parent. + { /* * Save the file descriptors for later duplication, and * reopen as streams. @@ -950,10 +1010,7 @@ err_closing: // close unused (void)close(to_cs[0]); (void)close(from_cs[1]); - - break; } - #else // MSWIN // Create a new process to run cscope and use pipes to talk with it diff --git a/src/if_cscope.h b/src/if_cscope.h deleted file mode 100644 --- a/src/if_cscope.h +++ /dev/null @@ -1,71 +0,0 @@ -/* vi:set ts=8 sts=4 sw=4 noet: - * - * CSCOPE support for Vim added by Andy Kahn - * Ported to Win32 by Sergey Khorev - * - * The basic idea/structure of cscope for Vim was borrowed from Nvi. - * There might be a few lines of code that look similar to what Nvi - * has. If this is a problem and requires inclusion of the annoying - * BSD license, then sue me; I'm not worth much anyway. - */ - -#if defined(FEAT_CSCOPE) || defined(PROTO) - -#if defined (MSWIN) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -#endif - -#define CSCOPE_SUCCESS 0 -#define CSCOPE_FAILURE -1 - -#define CSCOPE_DBFILE "cscope.out" -#define CSCOPE_PROMPT ">> " - -/* - * See ":help cscope-find" for the possible queries. - */ - -typedef struct { - char * name; - int (*func)(exarg_T *eap); - char * help; - char * usage; - int cansplit; // if supports splitting window -} cscmd_T; - -typedef struct csi { - char * fname; // cscope db name - char * ppath; // path to prepend (the -P option) - char * flags; // additional cscope flags/options (e.g, -p2) -#if defined(UNIX) - pid_t pid; // PID of the connected cscope process. - dev_t st_dev; // ID of dev containing cscope db - ino_t st_ino; // inode number of cscope db -#else -# if defined(MSWIN) - DWORD pid; // PID of the connected cscope process. - HANDLE hProc; // cscope process handle - DWORD nVolume; // Volume serial number, instead of st_dev - DWORD nIndexHigh; // st_ino has no meaning in the Windows - DWORD nIndexLow; -# endif -#endif - - FILE * fr_fp; // from cscope: FILE. - FILE * to_fp; // to cscope: FILE. -} csinfo_T; - -typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e; - -typedef enum { - Store, - Get, - Free, - Print -} mcmd_e; - - -#endif // FEAT_CSCOPE diff --git a/src/testdir/test_cscope.vim b/src/testdir/test_cscope.vim --- a/src/testdir/test_cscope.vim +++ b/src/testdir/test_cscope.vim @@ -246,7 +246,7 @@ func Test_cscopeWithCscopeConnections() " Test: 'csprg' option call assert_equal('cscope', &csprg) set csprg=doesnotexist - call assert_fails('cscope add Xcscope2.out', 'E609:') + call assert_fails('cscope add Xcscope2.out', 'E262:') set csprg=cscope " Test: multiple cscope connections diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4081, +/**/ 4080, /**/ 4079,