diff options
Diffstat (limited to 'src/common/compat.c')
-rw-r--r-- | src/common/compat.c | 23 |
1 files changed, 16 insertions, 7 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 |