comparison src/dosinst.c @ 15941:b9098585d945 v8.1.0976

patch 8.1.0976: dosinstall still has buffer overflow problems commit https://github.com/vim/vim/commit/e4963c543ddcfc4845fa0d42893b6a4e1aa27c47 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Feb 22 19:41:08 2019 +0100 patch 8.1.0976: dosinstall still has buffer overflow problems Problem: Dosinstall still has buffer overflow problems. Solution: Adjust buffer sizes. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/4002)
author Bram Moolenaar <Bram@vim.org>
date Fri, 22 Feb 2019 19:45:12 +0100
parents e43b5e6d9190
children cd5c83115ec6
comparison
equal deleted inserted replaced
15940:00844735e936 15941:b9098585d945
386 FILE *fd; 386 FILE *fd;
387 char fname[BUFSIZE]; 387 char fname[BUFSIZE];
388 388
389 /* First get $VIMRUNTIME. If it's set, remove the tail. */ 389 /* First get $VIMRUNTIME. If it's set, remove the tail. */
390 vim = getenv("VIMRUNTIME"); 390 vim = getenv("VIMRUNTIME");
391 if (vim != NULL && *vim != 0 && strlen(vim) < BUFSIZE) 391 if (vim != NULL && *vim != 0 && strlen(vim) < sizeof(buf))
392 { 392 {
393 strcpy(buf, vim); 393 strcpy(buf, vim);
394 remove_tail(buf); 394 remove_tail(buf);
395 vim = buf; 395 vim = buf;
396 } 396 }
409 } 409 }
410 } 410 }
411 411
412 /* NSIS also uses GetTempPath(), thus we should get the same directory 412 /* NSIS also uses GetTempPath(), thus we should get the same directory
413 * name as where NSIS will look for vimini.ini. */ 413 * name as where NSIS will look for vimini.ini. */
414 GetTempPath(BUFSIZE, fname); 414 GetTempPath(sizeof(fname) - 12, fname);
415 add_pathsep(fname); 415 add_pathsep(fname);
416 strcat(fname, "vimini.ini"); 416 strcat(fname, "vimini.ini");
417 417
418 fd = fopen(fname, "w"); 418 fd = fopen(fname, "w");
419 if (fd != NULL) 419 if (fd != NULL)
454 * Run the uninstaller silently. 454 * Run the uninstaller silently.
455 */ 455 */
456 static int 456 static int
457 run_silent_uninstall(char *uninst_exe) 457 run_silent_uninstall(char *uninst_exe)
458 { 458 {
459 char vimrt_dir[MAX_PATH]; 459 char vimrt_dir[BUFSIZE];
460 char temp_uninst[BUFSIZE]; 460 char temp_uninst[BUFSIZE];
461 char temp_dir[MAX_PATH]; 461 char temp_dir[MAX_PATH];
462 char buf[BUFSIZE * 2 + 10]; 462 char buf[BUFSIZE * 2 + 10];
463 int i; 463 int i;
464 DWORD tick; 464 DWORD tick;
504 HKEY key_handle; 504 HKEY key_handle;
505 HKEY uninstall_key_handle; 505 HKEY uninstall_key_handle;
506 char *uninstall_key = "software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; 506 char *uninstall_key = "software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
507 char subkey_name_buff[BUFSIZE]; 507 char subkey_name_buff[BUFSIZE];
508 char temp_string_buffer[BUFSIZE-2]; 508 char temp_string_buffer[BUFSIZE-2];
509 DWORD local_bufsize = BUFSIZE; 509 DWORD local_bufsize;
510 FILETIME temp_pfiletime; 510 FILETIME temp_pfiletime;
511 DWORD key_index; 511 DWORD key_index;
512 char input; 512 char input;
513 long code; 513 long code;
514 DWORD value_type; 514 DWORD value_type;
519 519
520 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, uninstall_key, 0, 520 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, uninstall_key, 0,
521 KEY_WOW64_64KEY | KEY_READ, &key_handle); 521 KEY_WOW64_64KEY | KEY_READ, &key_handle);
522 CHECK_REG_ERROR(code); 522 CHECK_REG_ERROR(code);
523 523
524 for (key_index = 0; 524 key_index = 0;
525 RegEnumKeyEx(key_handle, key_index, subkey_name_buff, &local_bufsize, 525 while (TRUE)
526 NULL, NULL, NULL, &temp_pfiletime) != ERROR_NO_MORE_ITEMS; 526 {
527 key_index++) 527 local_bufsize = sizeof(subkey_name_buff);
528 { 528 if (RegEnumKeyEx(key_handle, key_index, subkey_name_buff, &local_bufsize,
529 local_bufsize = BUFSIZE; 529 NULL, NULL, NULL, &temp_pfiletime) == ERROR_NO_MORE_ITEMS)
530 break;
531
530 if (strncmp("Vim", subkey_name_buff, 3) == 0) 532 if (strncmp("Vim", subkey_name_buff, 3) == 0)
531 { 533 {
532 /* Open the key named Vim* */ 534 /* Open the key named Vim* */
533 code = RegOpenKeyEx(key_handle, subkey_name_buff, 0, 535 code = RegOpenKeyEx(key_handle, subkey_name_buff, 0,
534 KEY_WOW64_64KEY | KEY_READ, &uninstall_key_handle); 536 KEY_WOW64_64KEY | KEY_READ, &uninstall_key_handle);
535 CHECK_REG_ERROR(code); 537 CHECK_REG_ERROR(code);
536 538
537 /* get the DisplayName out of it to show the user */ 539 /* get the DisplayName out of it to show the user */
540 local_bufsize = sizeof(temp_string_buffer);
538 code = RegQueryValueEx(uninstall_key_handle, "displayname", 0, 541 code = RegQueryValueEx(uninstall_key_handle, "displayname", 0,
539 &value_type, (LPBYTE)temp_string_buffer, 542 &value_type, (LPBYTE)temp_string_buffer,
540 &local_bufsize); 543 &local_bufsize);
541 local_bufsize = BUFSIZE;
542 CHECK_REG_ERROR(code); 544 CHECK_REG_ERROR(code);
543 545
544 allow_silent = 0; 546 allow_silent = 0;
545 if (skip_question) 547 if (skip_question)
546 { 548 {
566 else 568 else
567 printf("\nDo you want to uninstall \"%s\" now?\n(y)es/(n)o) ", temp_string_buffer); 569 printf("\nDo you want to uninstall \"%s\" now?\n(y)es/(n)o) ", temp_string_buffer);
568 fflush(stdout); 570 fflush(stdout);
569 571
570 /* get the UninstallString */ 572 /* get the UninstallString */
573 local_bufsize = sizeof(temp_string_buffer);
571 code = RegQueryValueEx(uninstall_key_handle, "uninstallstring", 0, 574 code = RegQueryValueEx(uninstall_key_handle, "uninstallstring", 0,
572 &value_type, (LPBYTE)temp_string_buffer, &local_bufsize); 575 &value_type, (LPBYTE)temp_string_buffer, &local_bufsize);
573 local_bufsize = BUFSIZE;
574 CHECK_REG_ERROR(code); 576 CHECK_REG_ERROR(code);
575 577
576 /* Remember the directory, it is used as the default for NSIS. */ 578 /* Remember the directory, it is used as the default for NSIS. */
577 default_vim_dir = alloc(strlen(temp_string_buffer) + 1); 579 default_vim_dir = alloc(strlen(temp_string_buffer) + 1);
578 strcpy(default_vim_dir, temp_string_buffer); 580 strcpy(default_vim_dir, temp_string_buffer);
681 683
682 } while (input != 'n' && input != 'y'); 684 } while (input != 'n' && input != 'y');
683 685
684 RegCloseKey(uninstall_key_handle); 686 RegCloseKey(uninstall_key_handle);
685 } 687 }
688
689 key_index++;
686 } 690 }
687 RegCloseKey(key_handle); 691 RegCloseKey(key_handle);
688 692
689 return foundone; 693 return foundone;
690 } 694 }
1824 wchar_t wsz[BUFSIZE]; 1828 wchar_t wsz[BUFSIZE];
1825 1829
1826 /* translate the (possibly) multibyte shortcut filename to windows 1830 /* translate the (possibly) multibyte shortcut filename to windows
1827 * Unicode so it can be used as a file name. 1831 * Unicode so it can be used as a file name.
1828 */ 1832 */
1829 MultiByteToWideChar(CP_ACP, 0, shortcut_name, -1, wsz, BUFSIZE); 1833 MultiByteToWideChar(CP_ACP, 0, shortcut_name, -1, wsz, sizeof(wsz)/sizeof(wsz[0]));
1830 1834
1831 /* set the attributes */ 1835 /* set the attributes */
1832 shelllink_ptr->lpVtbl->SetPath(shelllink_ptr, shortcut_target); 1836 shelllink_ptr->lpVtbl->SetPath(shelllink_ptr, shortcut_target);
1833 shelllink_ptr->lpVtbl->SetWorkingDirectory(shelllink_ptr, 1837 shelllink_ptr->lpVtbl->SetWorkingDirectory(shelllink_ptr,
1834 workingdir); 1838 workingdir);
2133 /* 2137 /*
2134 * Remove the last part of directory "path[]" to get its parent, and put the 2138 * Remove the last part of directory "path[]" to get its parent, and put the
2135 * result in "to[]". 2139 * result in "to[]".
2136 */ 2140 */
2137 static void 2141 static void
2138 dir_remove_last(const char *path, char to[BUFSIZE]) 2142 dir_remove_last(const char *path, char to[MAX_PATH])
2139 { 2143 {
2140 char c; 2144 char c;
2141 long last_char_to_copy; 2145 long last_char_to_copy;
2142 long path_length = strlen(path); 2146 long path_length = strlen(path);
2143 2147
2204 homedrive = getenv("HOMEDRIVE"); 2208 homedrive = getenv("HOMEDRIVE");
2205 homepath = getenv("HOMEPATH"); 2209 homepath = getenv("HOMEPATH");
2206 if (homepath == NULL || *homepath == NUL) 2210 if (homepath == NULL || *homepath == NUL)
2207 homepath = "\\"; 2211 homepath = "\\";
2208 if (homedrive != NULL 2212 if (homedrive != NULL
2209 && strlen(homedrive) + strlen(homepath) < MAX_PATH) 2213 && strlen(homedrive) + strlen(homepath) < sizeof(buf))
2210 { 2214 {
2211 sprintf(buf, "%s%s", homedrive, homepath); 2215 sprintf(buf, "%s%s", homedrive, homepath);
2212 if (buf[0] != NUL) 2216 if (buf[0] != NUL)
2213 var = buf; 2217 var = buf;
2214 } 2218 }
2232 { 2236 {
2233 strncpy(buf, var + 1, p - (var + 1)); 2237 strncpy(buf, var + 1, p - (var + 1));
2234 buf[p - (var + 1)] = NUL; 2238 buf[p - (var + 1)] = NUL;
2235 exp = getenv(buf); 2239 exp = getenv(buf);
2236 if (exp != NULL && *exp != NUL 2240 if (exp != NULL && *exp != NUL
2237 && strlen(exp) + strlen(p) < MAX_PATH) 2241 && strlen(exp) + strlen(p) < sizeof(buf))
2238 { 2242 {
2239 _snprintf(buf, MAX_PATH, "%s%s", exp, p + 1); 2243 sprintf(buf, "%s%s", exp, p + 1);
2240 buf[MAX_PATH - 1] = NUL;
2241 var = buf; 2244 var = buf;
2242 } 2245 }
2243 } 2246 }
2244 } 2247 }
2245 2248
2349 choices[choice_count].installfunc = install_vimfilesdir; 2352 choices[choice_count].installfunc = install_vimfilesdir;
2350 choices[choice_count].active = 1; 2353 choices[choice_count].active = 1;
2351 2354
2352 // Check if the "compiler" directory already exists. That's a good 2355 // Check if the "compiler" directory already exists. That's a good
2353 // indication that the plugin directories were already created. 2356 // indication that the plugin directories were already created.
2354 if (getenv("HOME") != NULL) 2357 p = getenv("HOME");
2358 if (p != NULL)
2355 { 2359 {
2356 vimfiles_dir_choice = (int)vimfiles_dir_home; 2360 vimfiles_dir_choice = (int)vimfiles_dir_home;
2357 sprintf(tmp_dirname, "%s\\vimfiles\\compiler", getenv("HOME")); 2361 sprintf(tmp_dirname, "%s\\vimfiles\\compiler", p);
2358 if (stat(tmp_dirname, &st) == 0) 2362 if (stat(tmp_dirname, &st) == 0)
2359 vimfiles_dir_choice = (int)vimfiles_dir_none; 2363 vimfiles_dir_choice = (int)vimfiles_dir_none;
2360 } 2364 }
2361 else 2365 else
2362 { 2366 {