As reported by Alistair, when doing Unicode conversion for FileName field from IMAGEHLP_LINE64 into IMAGEHLP_LINE64W, both structures would refer to the same buffer allocated by fetch_buffer. So properly detect and handle this situation.
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/symbol.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index b2b4d578910..3b264eb9a52 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -1588,19 +1588,39 @@ static void copy_line_64_from_32(IMAGEHLP_LINE64* l64, const IMAGEHLP_LINE* l32) }
/****************************************************************** - * copy_line_W64_from_32 (internal) + * copy_line_W64_from_64 (internal) * + * Note: upon return, l64w->FileName is always allocated by fetch_buffer(). + * So, if input l64->FileName has *also* been allocated by fetch_buffer() + * before calling this function, l64->FileName will be overwritten + * (as it's the same buffer returned in l64w). + * In consequence, don't use the l64 structure *after* calling this function. */ -static void copy_line_W64_from_64(struct process* pcs, IMAGEHLP_LINEW64* l64w, const IMAGEHLP_LINE64* l64) +static BOOL copy_line_W64_from_64(struct process* pcs, IMAGEHLP_LINEW64* l64w, const IMAGEHLP_LINE64* l64) { - unsigned len; + char* incoming = l64->FileName; + unsigned len = MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, NULL, 0); + + /* detect when l64->FileName has been allocated by fetch_buffer() + * and make a copy before calling fetch_buffer() again + */ + if (incoming >= (char*)pcs->buffer && incoming < (char*)pcs->buffer + pcs->buffer_size) + { + DWORD sz = strlen(incoming) + 1; + char* new = HeapAlloc(GetProcessHeap(), 0, sz); + if (!new) + return FALSE; + incoming = memcpy(new, incoming, sz); + }
l64w->Key = l64->Key; l64w->LineNumber = l64->LineNumber; - len = MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, NULL, 0); - if ((l64w->FileName = fetch_buffer(pcs, len * sizeof(WCHAR)))) - MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, l64w->FileName, len); l64w->Address = l64->Address; + if (!(l64w->FileName = fetch_buffer(pcs, len * sizeof(WCHAR)))) + return FALSE; + MultiByteToWideChar(CP_ACP, 0, incoming, -1, l64w->FileName, len); + if (incoming != l64->FileName) HeapFree(GetProcessHeap(), 0, incoming); + return TRUE; }
/****************************************************************** @@ -1671,8 +1691,7 @@ BOOL WINAPI SymGetLineFromAddrW64(HANDLE hProcess, DWORD64 dwAddr, il64.SizeOfStruct = sizeof(il64); if (!SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, &il64)) return FALSE; - copy_line_W64_from_64(process_find_by_handle(hProcess), Line, &il64); - return TRUE; + return copy_line_W64_from_64(process_find_by_handle(hProcess), Line, &il64); }
/******************************************************************