Prevent array underflow in MsiFormat

Bill Medland billmedland at mercuryspeed.com
Tue Dec 20 16:19:14 CST 2005


Bill Medland (billmedland at mercuryspeed.com)
Prevent array underflow in MsiFormat when measuring with zero length buffer

Index: wine/dlls/kernel/tests/codepage.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/tests/codepage.c,v
retrieving revision 1.6
diff -u -r1.6 codepage.c
--- wine/dlls/kernel/tests/codepage.c 18 Aug 2005 10:50:46 -0000 1.6
+++ wine/dlls/kernel/tests/codepage.c 20 Dec 2005 22:14:38 -0000
@@ -29,6 +29,7 @@
 {
     int len;
     DWORD GLE;
+    static const WCHAR empty[] = {0};
 
     SetLastError(0);
     len = WideCharToMultiByte(CP_ACP, 0, NULL, 0, NULL, 0, NULL, NULL);
@@ -36,6 +37,14 @@
     ok(!len && GLE == ERROR_INVALID_PARAMETER,
         "WideCharToMultiByte returned %d with GLE=%ld (expected 0 with ERROR_INVALID_PARAMETER)\n", 
         len, GLE);
+
+    /* Normally you can specify how many characters to process, but not for 0 */
+    SetLastError(0);
+    len = WideCharToMultiByte(CP_ACP, 0, empty, 0, NULL, 0, NULL, NULL);
+    GLE = GetLastError();
+    ok(!len && GLE == ERROR_INVALID_PARAMETER,
+        "WideCharToMultiByte returned %d with GLE=%ld (expected 0 with ERROR_INVALID_PARAMETER)\n", 
+        len, GLE);
 }
 
 /* lstrcmpW is not supported on Win9x! */
Index: wine/dlls/msi/format.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/format.c,v
retrieving revision 1.26
diff -u -r1.26 format.c
--- wine/dlls/msi/format.c 19 Dec 2005 20:25:23 -0000 1.26
+++ wine/dlls/msi/format.c 20 Dec 2005 22:14:56 -0000
@@ -639,10 +639,15 @@
 
     len = deformat_string_internal(package,rec,&deformated,strlenW(rec),
                                    record, NULL);
+    /* If len is zero then WideCharToMultiByte will return 0 indicating 
+     * failure, but that will do just as well since we are ignoring
+     * possible errors.
+     */
     lenA = WideCharToMultiByte(CP_ACP,0,deformated,len,NULL,0,NULL,NULL);
 
     if (buffer)
     {
+        /* Ditto above */
         WideCharToMultiByte(CP_ACP,0,deformated,len,buffer,*size,NULL, NULL);
         if (*size>lenA)
         {
@@ -652,7 +657,8 @@
         else
         {
             rc = ERROR_MORE_DATA;
-            buffer[(*size)-1] = 0;    
+            if (*size)
+                buffer[(*size)-1] = 0;    
         }
     }
     else
Index: wine/dlls/msi/tests/format.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/tests/format.c,v
retrieving revision 1.2
diff -u -r1.2 format.c
--- wine/dlls/msi/tests/format.c 26 Sep 2005 09:55:12 -0000 1.2
+++ wine/dlls/msi/tests/format.c 20 Dec 2005 22:15:04 -0000
@@ -109,7 +109,7 @@
     char buffer[100];
     MSIHANDLE hrec;
     UINT r;
-    DWORD sz=100;
+    DWORD sz;
 
     r = MsiFormatRecord(0, 0, NULL, NULL );
     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
@@ -122,6 +122,11 @@
     ok( r == ERROR_SUCCESS, "format failed\n");
     buffer[0] = 'x';
     buffer[1] = 0;
+    sz=0;
+    r = MsiFormatRecord(0, hrec, buffer+1, &sz);
+    ok( r == ERROR_MORE_DATA && buffer[0] == 'x', "format failed measuring with buffer\n");
+    ok( sz == 16, "size wrong\n");
+    sz=100;
     r = MsiFormatRecord(0, hrec, buffer, &sz);
     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
     ok( sz == 16, "size wrong\n");



More information about the wine-patches mailing list