Hallo,
i currently digg in comctl32 to find why my app fails. I found that string conversation AtoW in some places silently fails. The problem is that the destination for string is just a fresh pointer (not NULL). Str_SetPtrAtoW check if it is NULL pointer and if not it trys to ReAlloc. There was no Alloc before so ReAlloc returns NULL. Because there is no other checks, Str_SetPtrAtoW just go back without converting the string.
Here is affected code: dlls/comctl32/comctl32undoc.c:999
BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc) { TRACE("(%p %s)\n", lppDest, lpSrc);
if (lpSrc) { INT len = MultiByteToWideChar(CP_ACP,0,lpSrc,-1,NULL,0); LPWSTR ptr = ReAlloc (*lppDest, len*sizeof(WCHAR)); if (!ptr) { ERR("last error %x\n", GetLastError()); return FALSE; } MultiByteToWideChar(CP_ACP,0,lpSrc,-1,ptr,len); *lppDest = ptr; } else { Free (*lppDest); *lppDest = NULL; } return TRUE;
}
The question is, is it appropriate reaction of ReAlloc and if it so, may be it make more sense to do this:
--- a/dlls/comctl32/comctl32undoc.c +++ b/dlls/comctl32/comctl32undoc.c @@ -998,18 +998,26 @@ INT Str_GetPtrAtoW (LPCSTR lpSrc, LPWSTR lpDest, INT nMaxLen) */ BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc) { - TRACE("(%p %s)\n", lppDest, lpSrc); + TRACE("(%p, %s)\n", *lppDest, debugstr_a(lpSrc));
if (lpSrc) { + if (*lppDest) { + Free (*lppDest); + *lppDest = NULL; + } INT len = MultiByteToWideChar(CP_ACP,0,lpSrc,-1,NULL,0); - LPWSTR ptr = ReAlloc (*lppDest, len*sizeof(WCHAR)); + LPWSTR ptr = Alloc (len*sizeof(WCHAR));
- if (!ptr) + if (!ptr) { + ERR("Can't allocait memory size: %u," + " for string %s.\n", len*sizeof(WCHAR), lpSrc); return FALSE; + } MultiByteToWideChar(CP_ACP,0,lpSrc,-1,ptr,len); *lppDest = ptr; } else { + TRACE("lpSrc = NULL, nothing to convert.\n"); Free (*lppDest); *lppDest = NULL; }