From: Alanas Tebuev alanas.00@mail.ru
• Multiplication by 2 (also known as sizeof(WCHAR)) happens inside COMCTL32_WCHAR_array_reserve • Use DWORD instead of INT for *size for consistency with Alloc and negative buffer size doesn't make sense. • Don't forget old *array when ReAlloc returns NULL. --- dlls/comctl32/comctl32.h | 4 ++++ dlls/comctl32/commctrl.c | 22 ++++++++++++++++++++++ dlls/comctl32/pager.c | 37 ++++++++++++------------------------- 3 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index f44b4ae132f..0aa2e520d8d 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -216,6 +216,10 @@ typedef struct int running; } SUBCLASS_INFO, *LPSUBCLASS_INFO;
+/* WM_NOTIFY unicode to ansi conversion and forwarding stuff */ + +BOOL COMCTL32_WCHAR_array_reserve(WCHAR **array, DWORD *size, DWORD count); + /* undocumented functions */
BOOL WINAPI Free (LPVOID); diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index d87e63e813e..78c9b87d94b 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -2691,3 +2691,25 @@ LRESULT WINAPI SendNotifyEx(HWND hwndTo, HWND hwndFrom, UINT code, NMHDR *hdr, D
return DoNotify(¬ify, code, hdr); } + +/* reallocate *array if needed so it can hold at least count WCHARs */ +/* *size measured in bytes, count measured is WCHARs */ +/* return FALSE means failed (*array still valid but too small) */ +/* return TRUE means successful */ +BOOL COMCTL32_WCHAR_array_reserve(WCHAR **array, DWORD *size, DWORD count) +{ + WCHAR *new_array; + DWORD needed_size; + + if (count > (DWORD)-1 / sizeof(WCHAR)) + return FALSE; + needed_size = count * sizeof(WCHAR); + if (*size >= needed_size) + return TRUE; + new_array = *array ? ReAlloc(*array, needed_size) : Alloc(needed_size); + if (!new_array) + return FALSE; + *array = new_array; + *size = needed_size; + return TRUE; +} diff --git a/dlls/comctl32/pager.c b/dlls/comctl32/pager.c index 07484c6ebf5..c9a430d1a63 100644 --- a/dlls/comctl32/pager.c +++ b/dlls/comctl32/pager.c @@ -84,8 +84,8 @@ typedef struct INT TLbtnState; /* state of top or left btn */ INT BRbtnState; /* state of bottom or right btn */ INT direction; /* direction of the scroll, (e.g. PGF_SCROLLUP) */ - WCHAR *pwszBuffer;/* text buffer for converted notifications */ - INT nBufferSize;/* size of the above buffer */ + WCHAR *unicodeBuffer;/* used in WN_NOTIFY forwarding if bUnicode */ + DWORD unicodeBufferSize;/* used in WN_NOTIFY forwarding if bUnicode */ } PAGER_INFO;
#define TIMERID1 1 @@ -611,7 +611,7 @@ static LRESULT PAGER_Destroy (PAGER_INFO *infoPtr) { SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0); - Free (infoPtr->pwszBuffer); + Free (infoPtr->unicodeBuffer); Free (infoPtr); return 0; } @@ -1096,19 +1096,6 @@ static UINT PAGER_GetAnsiNtfCode(UINT code) return code; }
-static BOOL PAGER_AdjustBuffer(PAGER_INFO *infoPtr, INT size) -{ - if (!infoPtr->pwszBuffer) - infoPtr->pwszBuffer = Alloc(size); - else if (infoPtr->nBufferSize < size) - infoPtr->pwszBuffer = ReAlloc(infoPtr->pwszBuffer, size); - - if (!infoPtr->pwszBuffer) return FALSE; - if (infoPtr->nBufferSize < size) infoPtr->nBufferSize = size; - - return TRUE; -} - /* Convert text to Unicode and return the original text address */ static WCHAR *PAGER_ConvertText(WCHAR **text) { @@ -1229,7 +1216,7 @@ static LRESULT PAGER_Notify(PAGER_INFO *infoPtr, NMHDR *hdr) { NMDATETIMEFORMATW *nmdtf = (NMDATETIMEFORMATW *)hdr; WCHAR *oldFormat; - INT textLength; + DWORD textLength;
hdr->code = PAGER_GetAnsiNtfCode(hdr->code); oldFormat = PAGER_ConvertText((WCHAR **)&nmdtf->pszFormat); @@ -1239,14 +1226,14 @@ static LRESULT PAGER_Notify(PAGER_INFO *infoPtr, NMHDR *hdr) if (nmdtf->pszDisplay) { textLength = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmdtf->pszDisplay, -1, 0, 0); - if (!PAGER_AdjustBuffer(infoPtr, textLength * sizeof(WCHAR))) return ret; - MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmdtf->pszDisplay, -1, infoPtr->pwszBuffer, textLength); + if (!COMCTL32_WCHAR_array_reserve(&infoPtr->unicodeBuffer, &infoPtr->unicodeBufferSize, textLength)) return ret; + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmdtf->pszDisplay, -1, infoPtr->unicodeBuffer, textLength); if (nmdtf->pszDisplay != nmdtf->szDisplay) - nmdtf->pszDisplay = infoPtr->pwszBuffer; + nmdtf->pszDisplay = infoPtr->unicodeBuffer; else { textLength = min(textLength, ARRAY_SIZE(nmdtf->szDisplay)); - memcpy(nmdtf->szDisplay, infoPtr->pwszBuffer, textLength * sizeof(WCHAR)); + memcpy(nmdtf->szDisplay, infoPtr->unicodeBuffer, textLength * sizeof(WCHAR)); } }
@@ -1346,7 +1333,7 @@ static LRESULT PAGER_Notify(PAGER_INFO *infoPtr, NMHDR *hdr) { NMTTDISPINFOW *nmttdiW = (NMTTDISPINFOW *)hdr; NMTTDISPINFOA nmttdiA = {{0}}; - INT size; + DWORD size;
nmttdiA.hdr.code = PAGER_GetAnsiNtfCode(nmttdiW->hdr.code); nmttdiA.hdr.hwndFrom = nmttdiW->hdr.hwndFrom; @@ -1373,9 +1360,9 @@ static LRESULT PAGER_Notify(PAGER_INFO *infoPtr, NMHDR *hdr) size = MultiByteToWideChar(CP_ACP, 0, nmttdiA.lpszText, -1, 0, 0); if (size > ARRAY_SIZE(nmttdiW->szText)) { - if (!PAGER_AdjustBuffer(infoPtr, size * sizeof(WCHAR))) return ret; - MultiByteToWideChar(CP_ACP, 0, nmttdiA.lpszText, -1, infoPtr->pwszBuffer, size); - nmttdiW->lpszText = infoPtr->pwszBuffer; + if (!COMCTL32_WCHAR_array_reserve(&infoPtr->unicodeBuffer, &infoPtr->unicodeBufferSize, size)) return ret; + MultiByteToWideChar(CP_ACP, 0, nmttdiA.lpszText, -1, infoPtr->unicodeBuffer, size); + nmttdiW->lpszText = infoPtr->unicodeBuffer; /* Override content in szText */ memcpy(nmttdiW->szText, nmttdiW->lpszText, min(sizeof(nmttdiW->szText), size * sizeof(WCHAR))); }