[PATCH] Copy bytes instead of WCHARs in VarBstrCat

Nikolay Sivov nsivov at codeweavers.com
Mon May 31 17:20:08 CDT 2010


---
 dlls/oleaut32/tests/vartype.c |   46 +++++++++++++++++++++++++++++++++++++++-
 dlls/oleaut32/vartype.c       |   11 +++++----
 2 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c
index c46ad8a..361342e 100644
--- a/dlls/oleaut32/tests/vartype.c
+++ b/dlls/oleaut32/tests/vartype.c
@@ -5486,12 +5486,17 @@ static void test_VarBstrCat(void)
     static const WCHAR s1[] = { 'a',0 };
     static const WCHAR s2[] = { 'b',0 };
     static const WCHAR s1s2[] = { 'a',0,'b',0 };
+    static const char str1A[] = "Have ";
+    static const char str2A[] = "A Cigar";
     HRESULT ret;
     BSTR str1, str2, res;
+    UINT len;
 
-    /* Crash
+if (0)
+{
+    /* Crash */
     ret = VarBstrCat(NULL, NULL, NULL);
-     */
+}
 
     /* Concatenation of two NULL strings works */
     ret = VarBstrCat(NULL, NULL, &res);
@@ -5543,6 +5548,43 @@ static void test_VarBstrCat(void)
 
     SysFreeString(str2);
     SysFreeString(str1);
+
+    /* Concatenation of ansi BSTRs, both odd byte count not including termination */
+    str1 = SysAllocStringByteLen(str1A, sizeof(str1A)-1);
+    str2 = SysAllocStringByteLen(str2A, sizeof(str2A)-1);
+    len = SysStringLen(str1);
+    ok(len == (sizeof(str1A)-1)/sizeof(WCHAR), "got length %u\n", len);
+    len = SysStringLen(str2);
+    ok(len == (sizeof(str2A)-1)/sizeof(WCHAR), "got length %u\n", len);
+
+    ret = VarBstrCat(str1, str2, &res);
+    ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
+    ok(res != NULL, "Expected a string\n");
+    len = (sizeof(str1A) + sizeof(str2A) - 2)/sizeof(WCHAR);
+    ok(SysStringLen(res) == len, "got %d, expected %u\n", SysStringLen(res), len);
+    ok(!memcmp(res, "Have A Cigar", sizeof(str1A) + sizeof(str2A) - 1), "got (%s)\n", (char*)res);
+    SysFreeString(res);
+
+    SysFreeString(str2);
+    SysFreeString(str1);
+
+    /* Concatenation of ansi BSTRs, both 1 byte length not including termination */
+    str1 = SysAllocStringByteLen(str1A, 1);
+    str2 = SysAllocStringByteLen(str2A, 1);
+    len = SysStringLen(str1);
+    ok(len == 0, "got length %u\n", len);
+    len = SysStringLen(str2);
+    ok(len == 0, "got length %u\n", len);
+
+    ret = VarBstrCat(str1, str2, &res);
+    ok(ret == S_OK, "VarBstrCat failed: %08x\n", ret);
+    ok(res != NULL, "Expected a string\n");
+    ok(SysStringLen(res) == 1, "got %d, expected 1\n", SysStringLen(res));
+    ok(!memcmp(res, "HA", 2), "got (%s)\n", (char*)res);
+    SysFreeString(res);
+
+    SysFreeString(str2);
+    SysFreeString(str1);
 }
 
 /* IUnknown */
diff --git a/dlls/oleaut32/vartype.c b/dlls/oleaut32/vartype.c
index 1aa71fb..8f54eae 100644
--- a/dlls/oleaut32/vartype.c
+++ b/dlls/oleaut32/vartype.c
@@ -6932,20 +6932,21 @@ HRESULT WINAPI VarBstrCat(BSTR pbstrLeft, BSTR pbstrRight, BSTR *pbstrOut)
   if (!pbstrOut)
     return E_INVALIDARG;
 
-  lenLeft = pbstrLeft ? SysStringLen(pbstrLeft) : 0;
-  lenRight = pbstrRight ? SysStringLen(pbstrRight) : 0;
+  /* use byte length here to properly handle ansi-allocated BSTRs */
+  lenLeft = pbstrLeft ? SysStringByteLen(pbstrLeft) : 0;
+  lenRight = pbstrRight ? SysStringByteLen(pbstrRight) : 0;
 
-  *pbstrOut = SysAllocStringLen(NULL, lenLeft + lenRight);
+  *pbstrOut = SysAllocStringByteLen(NULL, lenLeft + lenRight);
   if (!*pbstrOut)
     return E_OUTOFMEMORY;
 
   (*pbstrOut)[0] = '\0';
 
   if (pbstrLeft)
-    memcpy(*pbstrOut, pbstrLeft, lenLeft * sizeof(WCHAR));
+    memcpy(*pbstrOut, pbstrLeft, lenLeft);
 
   if (pbstrRight)
-    memcpy(*pbstrOut + lenLeft, pbstrRight, lenRight * sizeof(WCHAR));
+    memcpy((CHAR*)*pbstrOut + lenLeft, pbstrRight, lenRight);
 
   TRACE("%s\n", debugstr_wn(*pbstrOut, SysStringLen(*pbstrOut)));
   return S_OK;
-- 
1.5.6.5


--------------040302000604030509060807--



More information about the wine-patches mailing list