PATCH: listbox LB_*TEXT* wrappers dynamic
Marcus Meissner
marcus at jet.franken.de
Sat Mar 5 08:12:48 CST 2005
Hi,
An app tried to add a 300 character filter string to a common dialog
FileOpenDialog. Which crashed in the WtoA mapper.
I fixed it by calling LB_GETTEXTLEN within the mapper (which might not
be designed for it, but I guess this is acceptable.)
I have also added listbox testcases that crash before and now don't.
I fixed 4 places (the 32<->16 mappers I did not fix).
I did exercise just 1 or 2 places of those (LB_GETTEXT*), but not CB_.
Ciao, Marcus
Changelog:
Dynamically allocate text buffers when mapping LB_GETTEXT
and CB_GETLBTEXT.
Added testcase.
Index: windows/winproc.c
===================================================================
RCS file: /home/wine/wine/windows/winproc.c,v
retrieving revision 1.128
diff -u -r1.128 winproc.c
--- windows/winproc.c 15 Feb 2005 21:51:06 -0000 1.128
+++ windows/winproc.c 5 Mar 2005 14:05:58 -0000
@@ -764,13 +764,14 @@
}
return (*plparam ? 1 : -1);
- case LB_GETTEXT: /* FIXME: fixed sized buffer */
- { if ( WINPROC_TestLBForStr( hwnd ))
- { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
+ case LB_GETTEXT:
+ if ( WINPROC_TestLBForStr( hwnd ))
+ {
+ DWORD len = SendMessageW (hwnd, LB_GETTEXTLEN, *pwparam, 0);
+ LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) + sizeof(LPARAM) );
if (!ptr) return -1;
*ptr++ = *plparam; /* Store previous lParam */
*plparam = (LPARAM)ptr;
- }
}
return 1;
@@ -789,14 +790,14 @@
}
return (*plparam ? 1 : -1);
- case CB_GETLBTEXT: /* FIXME: fixed sized buffer */
- { if ( WINPROC_TestCBForStr( hwnd ))
- { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
+ case CB_GETLBTEXT:
+ if ( WINPROC_TestCBForStr( hwnd ))
+ { DWORD len = SendMessageW( hwnd, CB_GETLBTEXTLEN, *pwparam, 0);
+ LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) + sizeof(LPARAM) );
if (!ptr) return -1;
*ptr++ = *plparam; /* Store previous lParam */
*plparam = (LPARAM)ptr;
- }
- }
+ }
return 1;
/* Multiline edit */
@@ -1059,13 +1060,14 @@
}
return (*plparam ? 1 : -1);
- case LB_GETTEXT: /* FIXME: fixed sized buffer */
- { if ( WINPROC_TestLBForStr( hwnd ))
- { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
+ case LB_GETTEXT:
+ if ( WINPROC_TestLBForStr( hwnd ))
+ {
+ DWORD len = SendMessageA( hwnd, LB_GETTEXTLEN, *pwparam, 0);
+ LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, len + sizeof(LPARAM) );
if (!ptr) return -1;
*ptr++ = *plparam; /* Store previous lParam */
*plparam = (LPARAM)ptr;
- }
}
return 1;
@@ -1085,14 +1087,15 @@
}
return (*plparam ? 1 : -1);
- case CB_GETLBTEXT: /* FIXME: fixed sized buffer */
- { if ( WINPROC_TestCBForStr( hwnd ))
- { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
+ case CB_GETLBTEXT:
+ if ( WINPROC_TestCBForStr( hwnd ))
+ {
+ DWORD len = SendMessageA( hwnd, CB_GETLBTEXTLEN, *pwparam, 0);
+ LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, len + sizeof(LPARAM) );
if (!ptr) return -1;
*ptr++ = *plparam; /* Store previous lParam */
*plparam = (LPARAM)ptr;
- }
- }
+ }
return 1;
/* Multiline edit */
Index: dlls/user/tests/listbox.c
===================================================================
RCS file: /home/wine/wine/dlls/user/tests/listbox.c,v
retrieving revision 1.6
diff -u -r1.6 listbox.c
--- dlls/user/tests/listbox.c 2 Feb 2005 19:10:59 -0000 1.6
+++ dlls/user/tests/listbox.c 5 Mar 2005 14:05:58 -0000
@@ -30,6 +30,13 @@
#define REDRAW
#endif
+static const char *strings[4] = {
+ "First added",
+ "Second added",
+ "Third added",
+ "Fourth added which is very long because at some time we only had a 256 byte character buffer and that was overflowing in one of those applications that had a common dialog file open box and tried to add a 300 characters long custom filter string which of course the code did not like and crashed. Just make sure this string is longer than 256 characters."
+};
+
HWND
create_listbox (DWORD add_style)
{
@@ -39,9 +46,10 @@
NULL, NULL, NULL, 0);
assert (handle);
- SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "First added");
- SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "Second added");
- SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "Third added");
+ SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[0]);
+ SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[1]);
+ SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[2]);
+ SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[3]);
#ifdef VISIBLE
ShowWindow (handle, SW_SHOW);
@@ -119,6 +127,7 @@
struct listbox_stat answer;
HWND hLB=create_listbox (test.prop.add_style);
RECT second_item;
+ int i;
listbox_query (hLB, &answer);
listbox_ok (test, init, answer);
@@ -140,6 +149,24 @@
SendMessage (hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2));
listbox_query (hLB, &answer);
listbox_ok (test, sel, answer);
+
+ for (i=0;i<4;i++) {
+ DWORD size = SendMessage (hLB, LB_GETTEXTLEN, i, 0);
+ CHAR *txt;
+ WCHAR *txtw;
+
+ txt = HeapAlloc (GetProcessHeap(), 0, size+1);
+ SendMessageA(hLB, LB_GETTEXT, i, (LPARAM)txt);
+ ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
+
+ txtw = HeapAlloc (GetProcessHeap(), 0, 2*size+2);
+ SendMessageW(hLB, LB_GETTEXT, i, (LPARAM)txtw);
+ WideCharToMultiByte( CP_ACP, 0, txtw, -1, txt, size, NULL, NULL );
+ ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
+
+ HeapFree (GetProcessHeap(), 0, txtw);
+ HeapFree (GetProcessHeap(), 0, txt);
+ }
WAIT;
DestroyWindow (hLB);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050305/b2a670c3/attachment.pgp
More information about the wine-patches
mailing list