Sebastian Lackner : oleaut32: Align terminating null character in SysAllocStringByteLen.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 29 15:49:00 CST 2015


Module: wine
Branch: master
Commit: e559ec2ad3ca41b7e169ab157e0d73c39b4c75b3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e559ec2ad3ca41b7e169ab157e0d73c39b4c75b3

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Fri Dec 25 06:38:10 2015 +0100

oleaut32: Align terminating null character in SysAllocStringByteLen.

Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/oleaut32/oleaut.c        | 14 ++++++--------
 dlls/oleaut32/tests/vartype.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/dlls/oleaut32/oleaut.c b/dlls/oleaut32/oleaut.c
index 75f9cb4..78cb083 100644
--- a/dlls/oleaut32/oleaut.c
+++ b/dlls/oleaut32/oleaut.c
@@ -149,12 +149,9 @@ static bstr_t *alloc_bstr(size_t size)
 
         if(cache_entry) {
             if(WARN_ON(heap)) {
-                size_t tail;
-
-                memset(ret, ARENA_INUSE_FILLER, FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)]));
-                tail = bstr_alloc_size(size) - FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)]);
-                if(tail)
-                    memset(ret->u.ptr+size+sizeof(WCHAR), ARENA_TAIL_FILLER, tail);
+                size_t fill_size = (FIELD_OFFSET(bstr_t, u.ptr[size])+2*sizeof(WCHAR)-1) & ~(sizeof(WCHAR)-1);
+                memset(ret, ARENA_INUSE_FILLER, fill_size);
+                memset((char *)ret+fill_size, ARENA_TAIL_FILLER, bstr_alloc_size(size)-fill_size);
             }
             ret->size = size;
             return ret;
@@ -418,10 +415,11 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
 
     if(str) {
         memcpy(bstr->u.ptr, str, len);
-        bstr->u.ptr[len] = bstr->u.ptr[len+1] = 0;
+        bstr->u.ptr[len] = 0;
     }else {
-        memset(bstr->u.ptr, 0, len+sizeof(WCHAR));
+        memset(bstr->u.ptr, 0, len+1);
     }
+    bstr->u.str[(len+sizeof(WCHAR)-1)/sizeof(WCHAR)] = 0;
 
     return bstr->u.str;
 }
diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c
index 7cbb059..d905d37 100644
--- a/dlls/oleaut32/tests/vartype.c
+++ b/dlls/oleaut32/tests/vartype.c
@@ -5444,7 +5444,9 @@ static void test_SysAllocStringByteLen(void)
 {
   const OLECHAR szTest[10] = { 'T','e','s','t','\0' };
   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
+  char *buf;
   BSTR str;
+  int i;
 
   if (sizeof(void *) == 4)  /* not limited to 0x80000000 on Win64 */
   {
@@ -5487,6 +5489,7 @@ static void test_SysAllocStringByteLen(void)
 
     ok (bstr->dwLen == 3, "Expected 3, got %d\n", bstr->dwLen);
     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
+    ok (!bstr->szString[2], "String not terminated\n");
     SysFreeString(str);
   }
 
@@ -5500,6 +5503,32 @@ static void test_SysAllocStringByteLen(void)
     ok (!lstrcmpW(bstr->szString, szTest), "String different\n");
     SysFreeString(str);
   }
+
+  /* Make sure terminating null is aligned properly */
+  buf = HeapAlloc(GetProcessHeap(), 0, 1025);
+  ok (buf != NULL, "Expected non-NULL\n");
+  for (i = 0; i < 1024; i++)
+  {
+    LPINTERNAL_BSTR bstr;
+
+    str = SysAllocStringByteLen(NULL, i);
+    ok (str != NULL, "Expected non-NULL\n");
+    bstr = Get(str);
+    ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen);
+    ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n");
+    SysFreeString(str);
+
+    memset(buf, 0xaa, 1025);
+    str = SysAllocStringByteLen(buf, i);
+    ok (str != NULL, "Expected non-NULL\n");
+    bstr = Get(str);
+    ok (bstr->dwLen == i, "Expected %d, got %d\n", i, bstr->dwLen);
+    buf[i] = 0;
+    ok (!lstrcmpA((LPCSTR)bstr->szString, buf), "String different\n");
+    ok (!bstr->szString[(i+sizeof(WCHAR)-1)/sizeof(WCHAR)], "String not terminated\n");
+    SysFreeString(str);
+  }
+  HeapFree(GetProcessHeap(), 0, buf);
 }
 
 static void test_SysReAllocString(void)




More information about the wine-cvs mailing list