To: vim-dev@vim.org Subject: Patch 6.1.459 (extra) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.1.459 (extra) Problem: Win32: libcall() may return an invalid pointer and cause Vim to crash. Solution: Add a strict check for the returned pointer. (Bruce Mellows) Files: src/os_mswin.c *** ../vim61.458/src/os_mswin.c Sun Apr 13 17:16:31 2003 --- src/os_mswin.c Fri Apr 11 10:54:36 2003 *************** *** 661,666 **** --- 661,706 ---- typedef int (*MYINTPROCINT)(int); #endif + /* + * Check if a pointer points to a valid NUL terminated string. + * Return the length of the string, including terminating NUL. + * Returns 0 for an invalid pointer, 1 for an empty string. + */ + static size_t + check_str_len(char_u *str) + { + SYSTEM_INFO si; + MEMORY_BASIC_INFORMATION mbi; + size_t length = 0; + size_t i; + const char *p; + + /* get page size */ + GetSystemInfo(&si); + + /* get memory information */ + if (VirtualQuery(str, &mbi, sizeof(mbi))) + { + /* pre cast these (typing savers) */ + DWORD dwStr = (DWORD)str; + DWORD dwBaseAddress = (DWORD)mbi.BaseAddress; + + /* get start address of page that str is on */ + DWORD strPage = dwStr - (dwStr - dwBaseAddress) % si.dwPageSize; + + /* get length from str to end of page */ + DWORD pageLength = si.dwPageSize - (dwStr - strPage); + + for (p = str; !IsBadReadPtr(p, pageLength); + p += pageLength, pageLength = si.dwPageSize) + for (i = 0; i < pageLength; ++i, ++length) + if (p[i] == NUL) + return length + 1; + } + + return 0; + } + int mch_libcall( char_u *libname, *************** *** 675,680 **** --- 715,721 ---- MYINTPROCSTR ProcAddI; char_u *retval_str = NULL; int retval_int = 0; + size_t len; BOOL fRunTimeLinkSuccess = FALSE; *************** *** 713,723 **** // Assume that a "1" result is an illegal pointer. if (string_result == NULL) *number_result = retval_int; ! else if (retval_str != NULL ! && retval_str != (char_u *)1 ! && retval_str != (char_u *)-1 ! && !IsBadStringPtr(retval_str, INT_MAX)) ! *string_result = vim_strsave(retval_str); // Free the DLL module. (void)FreeLibrary(hinstLib); --- 754,765 ---- // Assume that a "1" result is an illegal pointer. if (string_result == NULL) *number_result = retval_int; ! else if (retval_str != NULL && (len = check_str_len(retval_str)) > 0) ! { ! *string_result = lalloc((long_u)len, TRUE); ! if (*string_result != NULL) ! mch_memmove(*string_result, retval_str, len); ! } // Free the DLL module. (void)FreeLibrary(hinstLib); *** ../vim61.458/src/version.c Sun Apr 13 20:05:37 2003 --- src/version.c Sun Apr 13 20:24:11 2003 *************** *** 613,614 **** --- 613,616 ---- { /* Add new patch number below this line */ + /**/ + 459, /**/ -- ARTHUR: Old woman! DENNIS: Man! ARTHUR: Man. I'm sorry. Old man, What knight live in that castle over there? DENNIS: I'm thirty-seven. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///