From e8c4910e2ef184cfb58a1802f6ad4dbe157b37c8 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Fri, 27 May 2016 15:53:49 +0200 Subject: [PATCH] fix segfaults casused by size_t format specifier win32/msvc cc does not recognize the %z format specifier which caused invalid references and segfaults on win32. Until FreeRDP gets format specifier macros we'll cast size_t to unsigned long and use the %lu specifier. Also simplified winpr_backtrace_symbols() a little bit and fixed it to allocate the correct amount of bytes for the return buffer. --- .../primitives/test/TestPrimitivesYUV.c | 10 ++-- winpr/libwinpr/utils/debug.c | 51 ++++++++----------- winpr/libwinpr/utils/print.c | 4 +- winpr/libwinpr/utils/test/TestBacktrace.c | 2 +- winpr/libwinpr/utils/test/TestImage.c | 6 +-- winpr/libwinpr/utils/wlog/wlog.c | 2 +- 6 files changed, 33 insertions(+), 42 deletions(-) diff --git a/libfreerdp/primitives/test/TestPrimitivesYUV.c b/libfreerdp/primitives/test/TestPrimitivesYUV.c index a4b34f7e8..910010059 100644 --- a/libfreerdp/primitives/test/TestPrimitivesYUV.c +++ b/libfreerdp/primitives/test/TestPrimitivesYUV.c @@ -25,7 +25,7 @@ static BOOL similar(const BYTE* src, const BYTE* dst, size_t size) if (abs(diff) > 2) { - fprintf(stderr, "%zd %02X : %02X diff=%lf\n", x, val1, val2, diff); + fprintf(stderr, "%lu %02X : %02X diff=%lf\n", (unsigned long)x, val1, val2, diff); return FALSE; } } @@ -66,8 +66,8 @@ static BOOL check_padding(const BYTE* psrc, size_t size, size_t padding, const c while((x < halfPad) && (*esrc++ != 'A')) x++; - fprintf(stderr, "Buffer underflow detected %02x != %02X %s [%zd-%zd]\n", - d, 'A', buffer, start, x); + fprintf(stderr, "Buffer underflow detected %02x != %02X %s [%lu-%lu]\n", + d, 'A', buffer, (unsigned long)start, (unsigned long)x); return FALSE; } if(d != 'A') @@ -76,8 +76,8 @@ static BOOL check_padding(const BYTE* psrc, size_t size, size_t padding, const c while((x < halfPad) && (*esrc++ != 'A')) x++; - fprintf(stderr, "Buffer overflow detected %02x != %02X %s [%zd-%zd]\n", - d, 'A', buffer, start, x); + fprintf(stderr, "Buffer overflow detected %02x != %02X %s [%lu-%lu]\n", + d, 'A', buffer, (unsigned long)start, (unsigned long)x); return FALSE; } } diff --git a/winpr/libwinpr/utils/debug.c b/winpr/libwinpr/utils/debug.c index e6538a575..91f18435f 100644 --- a/winpr/libwinpr/utils/debug.c +++ b/winpr/libwinpr/utils/debug.c @@ -357,25 +357,22 @@ char** winpr_backtrace_symbols(void* buffer, size_t* used) { size_t line_len = (data->max > 1024) ? data->max : 1024; size_t i; - char* lines = calloc(data->used + 1, sizeof(char *) * line_len); - char** vlines = (char**) lines; + size_t array_size = data->used * sizeof(char*); + size_t lines_size = data->used * line_len; + char **vlines = calloc(1, array_size + lines_size); + backtrace_symbol_t* symbols = calloc(data->used, sizeof(backtrace_symbol_t)); - if (!lines || !symbols) + if (!vlines || !symbols) { - if (lines) - free(lines); - - if (symbols) - free(symbols); - + free(vlines); + free(symbols); return NULL; } - /* To allow a char** malloced array to be returned, allocate n+1 lines - * and fill in the first lines[i] char with the address of lines[(i+1) * 1024] */ + /* Set the pointers in the allocated buffer's initial array section */ for (i = 0; i < data->used; i++) - vlines[i] = &lines[(i + 1) * line_len]; + vlines[i] = (char*)vlines + array_size + i * line_len; fkt->get_backtrace_symbols(data->buffer, data->used, symbols); @@ -388,7 +385,7 @@ char** winpr_backtrace_symbols(void* buffer, size_t* used) if (used) *used = data->used; - return (char**) lines; + return vlines; } #elif (defined(_WIN32) || defined(_WIN64)) && !defined(_UWP) { @@ -396,22 +393,17 @@ char** winpr_backtrace_symbols(void* buffer, size_t* used) size_t line_len = 1024; HANDLE process = GetCurrentProcess(); t_win_stack* data = (t_win_stack*) buffer; - char *lines = calloc(data->used + 1, sizeof(char*) * line_len); - char **vlines = (char**) lines; + size_t array_size = data->used * sizeof(char*); + size_t lines_size = data->used * line_len; + char **vlines = calloc(1, array_size + lines_size); SYMBOL_INFO* symbol = calloc(sizeof(SYMBOL_INFO) + line_len * sizeof(char), 1); IMAGEHLP_LINE64* line = (IMAGEHLP_LINE64*) calloc(1, sizeof(IMAGEHLP_LINE64)); - if (!lines || !symbol || !line) + if (!vlines || !symbol || !line) { - if (lines) - free(lines); - - if (symbol) - free(symbol); - - if (line) - free(line); - + free(vlines); + free(symbol); + free(line); return NULL; } @@ -419,10 +411,9 @@ char** winpr_backtrace_symbols(void* buffer, size_t* used) symbol->MaxNameLen = line_len; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - /* To allow a char** malloced array to be returned, allocate n+1 lines - * and fill in the first lines[i] char with the address of lines[(i+1) * 1024] */ + /* Set the pointers in the allocated buffer's initial array section */ for (i = 0; i < data->used; i++) - vlines[i] = &lines[(i + 1) * line_len]; + vlines[i] = (char*)vlines + array_size + i * line_len; for (i = 0; i < data->used; i++) { @@ -445,7 +436,7 @@ char** winpr_backtrace_symbols(void* buffer, size_t* used) free(symbol); free(line); - return (char**) lines; + return vlines; } #else LOGF(support_msg); @@ -504,7 +495,7 @@ void winpr_log_backtrace(const char* tag, DWORD level, DWORD size) if (msg) { for (x=0; x