diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-05-17 10:08:48 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-06-07 11:09:38 -0400 |
commit | 1e5683b167a612bf76d4ae9ba508027e0d473e52 (patch) | |
tree | 5bd336b4f17411122c8ddb152324f8c2922d4d6e /src/common | |
parent | 99618a9641d02b7b99a79c71517203bb70043515 (diff) | |
download | tor-1e5683b167a612bf76d4ae9ba508027e0d473e52.tar.gz tor-1e5683b167a612bf76d4ae9ba508027e0d473e52.zip |
Be more careful calling wcstombs
The function is not guaranteed to NUL-terminate its output. It
*is*, however, guaranteed not to generate more than two bytes per
multibyte character (plus terminating nul), so the general approach
I'm taking is to try to allocate enough space, AND to manually add a
NUL at the end of each buffer just in case I screwed up the "enough
space" thing.
Fixes bug 5909.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.c | 23 | ||||
-rw-r--r-- | src/common/util.c | 3 |
2 files changed, 18 insertions, 8 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index 334ea1b8b4..db2187b836 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -3046,28 +3046,37 @@ format_win32_error(DWORD err) { TCHAR *str = NULL; char *result; + DWORD n; /* Somebody once decided that this interface was better than strerror(). */ - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPVOID)&str, + (LPVOID)&str, 0, NULL); - if (str) { + if (str && n) { #ifdef UNICODE - char abuf[1024] = {0}; - wcstombs(abuf,str,1024); - result = tor_strdup(abuf); + size_t len; + if (n > 128*1024) + len = (128 * 1024) * 2 + 1; /* This shouldn't be possible, but let's + * make sure. */ + else + len = n * 2 + 1; + result = tor_malloc(len); + wcstombs(result,str,len); + result[len-1] = '\0'; #else result = tor_strdup(str); #endif - LocalFree(str); /* LocalFree != free() */ } else { result = tor_strdup("<unformattable error>"); } + if (str) { + LocalFree(str); /* LocalFree != free() */ + } return result; } #endif diff --git a/src/common/util.c b/src/common/util.c index 4c086e86fc..dc8f8b7995 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -2855,7 +2855,7 @@ tor_listdir(const char *dirname) #ifdef _WIN32 char *pattern=NULL; TCHAR tpattern[MAX_PATH] = {0}; - char name[MAX_PATH] = {0}; + char name[MAX_PATH*2+1] = {0}; HANDLE handle; WIN32_FIND_DATA findData; tor_asprintf(&pattern, "%s\\*", dirname); @@ -2872,6 +2872,7 @@ tor_listdir(const char *dirname) while (1) { #ifdef UNICODE wcstombs(name,findData.cFileName,MAX_PATH); + name[sizeof(name)-1] = '\0'; #else strlcpy(name,findData.cFileName,sizeof(name)); #endif |