Commit 0393d43c authored by Alexandre Julliard's avatar Alexandre Julliard

Fixed WM_GETTEXT handling to avoid strncpy and return correct lengths.

parent 4a75c5c6
...@@ -1518,101 +1518,101 @@ static LRESULT COMBO_ItemOp( LPHEADCOMBO lphc, UINT msg, LPARAM lParam ) ...@@ -1518,101 +1518,101 @@ static LRESULT COMBO_ItemOp( LPHEADCOMBO lphc, UINT msg, LPARAM lParam )
return SendMessageW(lphc->owner, msg, id, lParam); return SendMessageW(lphc->owner, msg, id, lParam);
} }
/*********************************************************************** /***********************************************************************
* COMBO_GetText * COMBO_GetTextW
*
* NOTE! LB_GETTEXT does not count terminating \0, WM_GETTEXT does.
* also LB_GETTEXT might return values < 0, WM_GETTEXT doesn't.
*/ */
static LRESULT COMBO_GetText( LPHEADCOMBO lphc, INT N, LPARAM lParam, BOOL unicode) static LRESULT COMBO_GetTextW( LPHEADCOMBO lphc, INT count, LPWSTR buf )
{ {
if( lphc->wState & CBF_EDIT ) INT length;
return unicode ? SendMessageW(lphc->hWndEdit, WM_GETTEXT, (WPARAM)N, lParam) :
SendMessageA(lphc->hWndEdit, WM_GETTEXT, (WPARAM)N, lParam);
/* get it from the listbox */ if( lphc->wState & CBF_EDIT )
return SendMessageW( lphc->hWndEdit, WM_GETTEXT, count, (LPARAM)buf );
if( lphc->hWndLBox ) /* get it from the listbox */
{
INT idx = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
if( idx != LB_ERR )
{
INT n = 0;
INT length = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN,
(WPARAM)idx, 0 );
if(length == LB_ERR)
FIXME("LB_ERR probably not handled yet\n");
if(unicode)
{
LPWSTR lpBuffer, lpText = (LPWSTR)lParam;
/* 'length' is without the terminating character */ if (!count || !buf) return 0;
if(length >= N) if( lphc->hWndLBox )
lpBuffer = HeapAlloc(GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR)); {
else INT idx = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
lpBuffer = lpText; if (idx == LB_ERR) goto error;
length = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, idx, 0 );
if (length == LB_ERR) goto error;
/* 'length' is without the terminating character */
if (length >= count)
{
LPWSTR lpBuffer = HeapAlloc(GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR));
if (!lpBuffer) goto error;
length = SendMessageW(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)lpBuffer);
/* truncate if buffer is too short */
if (length != LB_ERR)
{
lstrcpynW( buf, lpBuffer, count );
length = count;
}
HeapFree( GetProcessHeap(), 0, lpBuffer );
}
else length = SendMessageW(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)buf);
if(lpBuffer) if (length == LB_ERR) return 0;
{ return length;
n = SendMessageW(lphc->hWndLBox, LB_GETTEXT, (WPARAM)idx, (LPARAM)lpBuffer); }
/* truncate if buffer is too short */ error: /* error - truncate string, return zero */
if(length >= N) buf[0] = 0;
{ return 0;
if(N && lpText) }
{
if(n != LB_ERR)
strncpyW(lpText, lpBuffer, (N > n) ? n+1 : N-1);
lpText[N - 1] = '\0';
}
HeapFree( GetProcessHeap(), 0, lpBuffer );
}
}
}
else
{
LPSTR lpBuffer, lpText = (LPSTR)lParam;
/* 'length' is without the terminating character */
if(length >= N)
lpBuffer = HeapAlloc(GetProcessHeap(), 0, length + 1);
else
lpBuffer = lpText;
if(lpBuffer) /***********************************************************************
{ * COMBO_GetTextA
n = SendMessageA(lphc->hWndLBox, LB_GETTEXT, (WPARAM)idx, (LPARAM)lpBuffer); *
* NOTE! LB_GETTEXT does not count terminating \0, WM_GETTEXT does.
* also LB_GETTEXT might return values < 0, WM_GETTEXT doesn't.
*/
static LRESULT COMBO_GetTextA( LPHEADCOMBO lphc, INT count, LPSTR buf )
{
INT length;
/* truncate if buffer is too short */ if( lphc->wState & CBF_EDIT )
if(length >= N) return SendMessageA( lphc->hWndEdit, WM_GETTEXT, count, (LPARAM)buf );
{
if(N && lpText) /* get it from the listbox */
{
if(n != LB_ERR) if (!count || !buf) return 0;
strncpy(lpText, lpBuffer, (N > n) ? n+1 : N-1); if( lphc->hWndLBox )
lpText[N - 1] = '\0'; {
} INT idx = SendMessageA(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
HeapFree( GetProcessHeap(), 0, lpBuffer ); if (idx == LB_ERR) goto error;
} length = SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, idx, 0 );
} if (length == LB_ERR) goto error;
}
if (n<0) /* 'length' is without the terminating character */
n=0; if (length >= count)
else {
n++; LPSTR lpBuffer = HeapAlloc(GetProcessHeap(), 0, (length + 1) );
return (LRESULT)n; if (!lpBuffer) goto error;
} length = SendMessageA(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)lpBuffer);
}
/* LB_GETCURSEL returned LB_ERR - truncate string, return zero */ /* truncate if buffer is too short */
if (unicode) if (length != LB_ERR)
{ {
LPWSTR lpText = (LPWSTR)lParam; lstrcpynA( buf, lpBuffer, count );
lpText[0] = '\0'; length = count;
} else { }
LPSTR lpText = (LPSTR)lParam; HeapFree( GetProcessHeap(), 0, lpBuffer );
lpText[0] = '\0'; }
} else length = SendMessageA(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)buf);
return 0;
if (length == LB_ERR) return 0;
return length;
}
error: /* error - truncate string, return zero */
buf[0] = 0;
return 0;
} }
...@@ -1991,7 +1991,8 @@ static LRESULT ComboWndProc_common( HWND hwnd, UINT message, ...@@ -1991,7 +1991,8 @@ static LRESULT ComboWndProc_common( HWND hwnd, UINT message,
case WM_COMMAND: case WM_COMMAND:
return COMBO_Command( lphc, wParam, WIN_GetFullHandle( (HWND)lParam ) ); return COMBO_Command( lphc, wParam, WIN_GetFullHandle( (HWND)lParam ) );
case WM_GETTEXT: case WM_GETTEXT:
return COMBO_GetText( lphc, (INT)wParam, lParam, unicode ); return unicode ? COMBO_GetTextW( lphc, wParam, (LPWSTR)lParam )
: COMBO_GetTextA( lphc, wParam, (LPSTR)lParam );
case WM_SETTEXT: case WM_SETTEXT:
case WM_GETTEXTLENGTH: case WM_GETTEXTLENGTH:
case WM_CLEAR: case WM_CLEAR:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment