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