[PATCH 01/11] dbghelp: fix NameLen usage in SYMBOL_INFO(W)

Eric Pouech eric.pouech at gmail.com
Mon Aug 30 02:24:04 CDT 2021


SYMBOL_INFO.NameLen should be the actual length of the symbol,
not the length of the (potentially truncated) string returned
in SYMBOL_INFO.Name

Added an helper (symbol_setname) to set those fields properly

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 dlls/dbghelp/dbghelp_private.h |    1 +
 dlls/dbghelp/symbol.c          |   47 ++++++++++++++++++++++++++++++----------
 dlls/dbghelp/type.c            |   11 +--------
 3 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 3415fc1557c..035d5b2b495 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -704,6 +704,7 @@ extern WCHAR*       symt_get_nameW(const struct symt* sym) DECLSPEC_HIDDEN;
 extern BOOL         symt_get_address(const struct symt* type, ULONG64* addr) DECLSPEC_HIDDEN;
 extern int __cdecl  symt_cmp_addr(const void* p1, const void* p2) DECLSPEC_HIDDEN;
 extern void         copy_symbolW(SYMBOL_INFOW* siw, const SYMBOL_INFO* si) DECLSPEC_HIDDEN;
+extern void         symbol_setname(SYMBOL_INFO* si, const char* name) DECLSPEC_HIDDEN;
 extern struct symt_ht*
                     symt_find_nearest(struct module* module, DWORD_PTR addr) DECLSPEC_HIDDEN;
 extern struct symt_compiland*
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 570e2adb8b6..3fc3438eeba 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -35,6 +35,9 @@
 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
 
+extern char * CDECL __unDName(char *buffer, const char *mangled, int len,
+        void * (CDECL *pfn_alloc)(size_t), void (CDECL *pfn_free)(void *), unsigned short flags);
+
 static const WCHAR starW[] = {'*','\0'};
 
 static inline int cmp_addr(ULONG64 a1, ULONG64 a2)
@@ -561,6 +564,7 @@ static void symt_fill_sym_info(struct module_pair* pair,
 {
     const char* name;
     DWORD64 size;
+    char* tmp;
 
     if (!symt_get_info(pair->effective, sym, TI_GET_TYPE, &sym_info->TypeIndex))
         sym_info->TypeIndex = 0;
@@ -697,17 +701,16 @@ static void symt_fill_sym_info(struct module_pair* pair,
     sym_info->Scope = 0; /* FIXME */
     sym_info->Tag = sym->tag;
     name = symt_get_name(sym);
-    if (sym_info->MaxNameLen)
+    if (sym_info->MaxNameLen &&
+        sym->tag == SymTagPublicSymbol && (dbghelp_options & SYMOPT_UNDNAME) &&
+        (tmp = __unDName(NULL, name, 0, malloc, free, UNDNAME_NAME_ONLY)) != NULL)
     {
-        if (sym->tag != SymTagPublicSymbol || !(dbghelp_options & SYMOPT_UNDNAME) ||
-            ((sym_info->NameLen = UnDecorateSymbolName(name, sym_info->Name,
-                                                       sym_info->MaxNameLen, UNDNAME_NAME_ONLY)) == 0))
-        {
-            sym_info->NameLen = min(strlen(name), sym_info->MaxNameLen - 1);
-            memcpy(sym_info->Name, name, sym_info->NameLen);
-            sym_info->Name[sym_info->NameLen] = '\0';
-        }
+        symbol_setname(sym_info, tmp);
+        free(tmp);
     }
+    else
+        symbol_setname(sym_info, name);
+
     TRACE_(dbghelp_symt)("%p => %s %u %s\n",
                          sym, sym_info->Name, sym_info->Size,
                          wine_dbgstr_longlong(sym_info->Address));
@@ -992,6 +995,29 @@ static BOOL symt_enum_locals(struct process* pcs, const WCHAR* mask,
     return FALSE;
 }
 
+/**********************************************************
+ *              symbol_setname
+ *
+ * Properly sets Name and NameLen in SYMBOL_INFO
+ * according to MaxNameLen value
+ */
+void symbol_setname(SYMBOL_INFO* sym_info, const char* name)
+{
+    SIZE_T len = 0;
+    if (name)
+    {
+        sym_info->NameLen = strlen(name);
+        if (sym_info->MaxNameLen)
+        {
+            len = min(sym_info->NameLen, sym_info->MaxNameLen - 1);
+            memcpy(sym_info->Name, name, len);
+        }
+    }
+    else
+        sym_info->NameLen = 0;
+    sym_info->Name[len] = '\0';
+}
+
 /******************************************************************
  *		copy_symbolW
  *
@@ -1811,9 +1837,6 @@ BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecName
                                 UNDNAME_COMPLETE) != 0;
 }
 
-extern char * CDECL __unDName(char *buffer, const char *mangled, int len,
-        void * (CDECL *pfn_alloc)(size_t), void (CDECL *pfn_free)(void *), unsigned short flags);
-
 /***********************************************************************
  *		UnDecorateSymbolName (DBGHELP.@)
  */
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c
index 374b69aeb08..1a76ec70bbb 100644
--- a/dlls/dbghelp/type.c
+++ b/dlls/dbghelp/type.c
@@ -450,7 +450,6 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
     struct module_pair  pair;
     char                buffer[sizeof(SYMBOL_INFO) + 256];
     SYMBOL_INFO*        sym_info = (SYMBOL_INFO*)buffer;
-    const char*         tmp;
     struct symt*        type;
     DWORD64             size;
     unsigned int        i;
@@ -480,15 +479,7 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
         sym_info->Register = 0; /* FIXME */
         sym_info->Scope = 0; /* FIXME */
         sym_info->Tag = type->tag;
-        tmp = symt_get_name(type);
-        if (tmp)
-        {
-            sym_info->NameLen = min(strlen(tmp),sym_info->MaxNameLen-1);
-            memcpy(sym_info->Name, tmp, sym_info->NameLen);
-            sym_info->Name[sym_info->NameLen] = '\0';
-        }
-        else
-           sym_info->Name[sym_info->NameLen = 0] = '\0';
+        symbol_setname(sym_info, symt_get_name(type));
         if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break;
     }
     return TRUE;




More information about the wine-devel mailing list