Commit 10424f0d authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Provide extra space in buffers used to dispatch string getter messages.

parent 2c1dcf4b
......@@ -241,6 +241,7 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz
HHOOK prev = thread_info->hook;
BOOL prev_unicode = thread_info->hook_unicode;
struct win_hook_params *params = info;
size_t reply_size;
void *ret_ptr;
ULONG ret_len;
......@@ -252,7 +253,7 @@ static LRESULT call_hook( struct win_hook_params *info, const WCHAR *module, siz
{
CBT_CREATEWNDW *cbtc = (CBT_CREATEWNDW *)params->lparam;
message_size = user_message_size( (HWND)params->wparam, WM_NCCREATE,
0, (LPARAM)cbtc->lpcs, TRUE, FALSE );
0, (LPARAM)cbtc->lpcs, TRUE, FALSE, &reply_size );
lparam_size = lparam_ret_size = 0;
}
......
......@@ -1624,11 +1624,15 @@ static size_t copy_string( void *ptr, const void *str, BOOL ansi )
* Calculate size of packed message buffer.
*/
size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
BOOL other_process, BOOL ansi )
BOOL other_process, BOOL ansi, size_t *reply_size )
{
const void *lparam_ptr = (const void *)lparam;
size_t size = 0;
/* Windows provices space for at least 2048 bytes for string getters, which
* mitigates problems with buffer overflows. */
static const size_t min_string_buffer_size = 2048;
switch (message)
{
case WM_NCCREATE:
......@@ -1645,8 +1649,8 @@ size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
break;
case WM_GETTEXT:
case WM_ASKCBFORMATNAME:
size = wparam * char_size( ansi );
break;
*reply_size = wparam * char_size( ansi );
return max( *reply_size, min_string_buffer_size );
case WM_WININICHANGE:
case WM_SETTEXT:
case WM_DEVMODECHANGE:
......@@ -1730,13 +1734,17 @@ size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
size = wparam * sizeof(UINT);
break;
case CB_GETLBTEXT:
size = send_message_timeout( hwnd, CB_GETLBTEXTLEN, wparam, 0, SMTO_NORMAL, 0, ansi );
size = (size + 1) * char_size( ansi );
break;
{
size_t len = send_message_timeout( hwnd, CB_GETLBTEXTLEN, wparam, 0, SMTO_NORMAL, 0, ansi );
*reply_size = (len + 1) * char_size( ansi );
return max( *reply_size, min_string_buffer_size );
}
case LB_GETTEXT:
size = send_message_timeout( hwnd, LB_GETTEXTLEN, wparam, 0, SMTO_NORMAL, 0, ansi );
size = (size + 1) * char_size( ansi );
break;
{
size_t len = send_message_timeout( hwnd, LB_GETTEXTLEN, wparam, 0, SMTO_NORMAL, 0, ansi );
*reply_size = (len + 1) * char_size( ansi );
return max( *reply_size, min_string_buffer_size );
}
case LB_GETSELITEMS:
size = wparam * sizeof(UINT);
break;
......@@ -1766,7 +1774,7 @@ size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
break;
}
return size;
return *reply_size = size;
}
/***********************************************************************
......@@ -1859,6 +1867,10 @@ void pack_user_message( void *buffer, size_t size, UINT message,
return;
}
break;
case CB_GETLBTEXT:
case LB_GETTEXT:
if (size) memset( buffer, 0, size );
return;
}
if (size) memcpy( buffer, lparam_ptr, size );
......@@ -2167,7 +2179,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
{
struct win_proc_params p, *params = &p;
BOOL ansi = ansi_dst && type == MSG_ASCII;
size_t packed_size = 0, offset = sizeof(*params);
size_t packed_size = 0, offset = sizeof(*params), reply_size;
LRESULT result = 0;
CWPSTRUCT cwp;
CWPRETSTRUCT cwpret;
......@@ -2179,7 +2191,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
if (!is_current_thread_window( hwnd )) return 0;
packed_size = user_message_size( hwnd, msg, wparam, lparam, type == MSG_OTHER_PROCESS, ansi );
packed_size = user_message_size( hwnd, msg, wparam, lparam, type == MSG_OTHER_PROCESS, ansi, &reply_size );
/* first the WH_CALLWNDPROC hook */
cwp.lParam = lparam;
......@@ -2208,7 +2220,7 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
result = dispatch_win_proc_params( params, offset + packed_size, &ret_ptr, &ret_len );
if (params != &p) free( params );
copy_user_result( ret_ptr, min( ret_len, packed_size ), result, msg, wparam, lparam, ansi );
copy_user_result( ret_ptr, min( ret_len, reply_size ), result, msg, wparam, lparam, ansi );
/* and finally the WH_CALLWNDPROCRET hook */
cwpret.lResult = result;
......
......@@ -1382,6 +1382,19 @@ static LPARAM callwnd_hook_lparam, callwnd_hook_lparam2, retwnd_hook_lparam, ret
static LPARAM wndproc_lparam;
static char lparam_buffer[521];
static void check_zero_memory( const char *mem, size_t size )
{
size_t i;
for (i = 0; i < size; i++)
{
if (mem[i])
{
ok( 0, "non-zero byte %x at offset %Iu\n", mem[i], i );
return;
}
}
}
static void check_params( const struct lparam_hook_test *test, UINT message,
WPARAM wparam, LPARAM lparam, BOOL is_ret )
{
......@@ -1428,8 +1441,14 @@ static void check_params( const struct lparam_hook_test *test, UINT message,
}
break;
case CB_GETLBTEXT:
case LB_GETTEXT:
check_zero_memory( (const char *)lparam, 2048 );
break;
default:
if (test->check_size) {
if (test->check_size)
{
const void *expected;
if (is_ret && test->check_lparam)
expected = test->check_lparam;
......
......@@ -141,7 +141,7 @@ extern BOOL send_notify_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar
extern LRESULT send_message_timeout( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
UINT flags, UINT timeout, BOOL ansi );
extern size_t user_message_size( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
BOOL other_process, BOOL ansi );
BOOL other_process, BOOL ansi, size_t *reply_size );
extern void pack_user_message( void *buffer, size_t size, UINT message,
WPARAM wparam, LPARAM lparam, BOOL ansi );
......
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