Module: wine Branch: refs/heads/master Commit: 2a0c37d8b99f2c1aae3bf988588cac095e78048d URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=2a0c37d8b99f2c1aae3bf988...
Author: Juan Lang juan_lang@yahoo.com Date: Wed Jun 21 23:56:58 2006 +0200
oleaut32: Correctly handle NULLs embedded in BSTRs, with tests.
---
dlls/oleaut32/tests/vartype.c | 109 ++++++++++++++++++++++++++++++++++++++--- dlls/oleaut32/vartype.c | 29 ++++++++--- 2 files changed, 122 insertions(+), 16 deletions(-)
diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c index 347b256..5e2de4d 100644 --- a/dlls/oleaut32/tests/vartype.c +++ b/dlls/oleaut32/tests/vartype.c @@ -4898,8 +4898,8 @@ #undef BSTR_DEC64 #define _VARBSTRCMP(left,right,lcid,flags,result) \ hres = pVarBstrCmp(left,right,lcid,flags); \ ok(hres == result, "VarBstrCmp: expected " #result ", got hres=0x%lx\n", hres) -#define VARBSTRCMP(left,right,result) \ - _VARBSTRCMP(left,right,lcid,0,result) +#define VARBSTRCMP(left,right,flags,result) \ + _VARBSTRCMP(left,right,lcid,flags,result)
static void test_VarBstrCmp(void) { @@ -4907,7 +4907,11 @@ static void test_VarBstrCmp(void) HRESULT hres; static const WCHAR sz[] = {'W','u','r','s','c','h','t','\0'}; static const WCHAR szempty[] = {'\0'}; - BSTR bstr, bstrempty; + static const WCHAR sz1[] = { 'a',0 }; + static const WCHAR sz2[] = { 'A',0 }; + static const WCHAR s1[] = { 'a',0 }; + static const WCHAR s2[] = { 'a',0,'b' }; + BSTR bstr, bstrempty, bstr2;
CHECKPTR(VarBstrCmp);
@@ -4916,13 +4920,34 @@ static void test_VarBstrCmp(void) bstrempty = SysAllocString(szempty);
/* NULL handling. Yepp, MSDN is totaly wrong here */ - VARBSTRCMP(NULL,NULL,VARCMP_EQ); - VARBSTRCMP(bstr,NULL,VARCMP_GT); - VARBSTRCMP(NULL,bstr,VARCMP_LT); + VARBSTRCMP(NULL,NULL,0,VARCMP_EQ); + VARBSTRCMP(bstr,NULL,0,VARCMP_GT); + VARBSTRCMP(NULL,bstr,0,VARCMP_LT);
/* NULL and empty string comparisions */ - VARBSTRCMP(bstrempty,NULL,VARCMP_EQ); - VARBSTRCMP(NULL,bstrempty,VARCMP_EQ); + VARBSTRCMP(bstrempty,NULL,0,VARCMP_EQ); + VARBSTRCMP(NULL,bstrempty,0,VARCMP_EQ); + + SysFreeString(bstr); + bstr = SysAllocString(sz1); + + bstr2 = SysAllocString(sz2); + VARBSTRCMP(bstr,bstr2,0,VARCMP_LT); + VARBSTRCMP(bstr,bstr2,NORM_IGNORECASE,VARCMP_EQ); + SysFreeString(bstr2); + /* These two strings are considered equal even though one is + * NULL-terminated and the other not. + */ + bstr2 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR)); + VARBSTRCMP(bstr,bstr2,0,VARCMP_EQ); + SysFreeString(bstr2); + + /* These two strings are not equal */ + bstr2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR)); + VARBSTRCMP(bstr,bstr2,0,VARCMP_LT); + SysFreeString(bstr2); + + SysFreeString(bstr); }
/* Get the internal representation of a BSTR */ @@ -5175,6 +5200,73 @@ static void test_BstrCopy(void) } }
+static void test_VarBstrCat(void) +{ + static const WCHAR sz1[] = { 'a',0 }; + static const WCHAR sz2[] = { 'b',0 }; + static const WCHAR sz1sz2[] = { 'a','b',0 }; + static const WCHAR s1[] = { 'a',0 }; + static const WCHAR s2[] = { 'b',0 }; + static const WCHAR s1s2[] = { 'a',0,'b',0 }; + HRESULT ret; + BSTR str1, str2, res; + + /* Crash + ret = VarBstrCat(NULL, NULL, NULL); + */ + + /* Concatenation of two NULL strings works */ + ret = VarBstrCat(NULL, NULL, &res); + ok(ret == S_OK, "VarBstrCat failed: %08lx\n", ret); + ok(res != NULL, "Expected a string\n"); + ok(SysStringLen(res) == 0, "Expected a 0-length string\n"); + SysFreeString(res); + + str1 = SysAllocString(sz1); + + /* Concatenation with one NULL arg */ + ret = VarBstrCat(NULL, str1, &res); + ok(ret == S_OK, "VarBstrCat failed: %08lx\n", ret); + ok(res != NULL, "Expected a string\n"); + ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n"); + ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n"); + SysFreeString(res); + ret = VarBstrCat(str1, NULL, &res); + ok(ret == S_OK, "VarBstrCat failed: %08lx\n", ret); + ok(res != NULL, "Expected a string\n"); + ok(SysStringLen(res) == SysStringLen(str1), "Unexpected length\n"); + ok(!memcmp(res, sz1, SysStringLen(str1)), "Unexpected value\n"); + SysFreeString(res); + + /* Concatenation of two zero-terminated strings */ + str2 = SysAllocString(sz2); + ret = VarBstrCat(str1, str2, &res); + ok(ret == S_OK, "VarBstrCat failed: %08lx\n", ret); + ok(res != NULL, "Expected a string\n"); + ok(SysStringLen(res) == sizeof(sz1sz2) / sizeof(WCHAR) - 1, + "Unexpected length\n"); + ok(!memcmp(res, sz1sz2, sizeof(sz1sz2)), "Unexpected value\n"); + SysFreeString(res); + + SysFreeString(str2); + SysFreeString(str1); + + /* Concatenation of two strings with embedded NULLs */ + str1 = SysAllocStringLen(s1, sizeof(s1) / sizeof(WCHAR)); + str2 = SysAllocStringLen(s2, sizeof(s2) / sizeof(WCHAR)); + + ret = VarBstrCat(str1, str2, &res); + ok(ret == S_OK, "VarBstrCat failed: %08lx\n", ret); + ok(res != NULL, "Expected a string\n"); + ok(SysStringLen(res) == sizeof(s1s2) / sizeof(WCHAR), + "Unexpected length\n"); + ok(!memcmp(res, s1s2, sizeof(s1s2)), "Unexpected value\n"); + SysFreeString(res); + + SysFreeString(str2); + SysFreeString(str1); +} + /* IUnknown */
static void test_IUnknownClear(void) @@ -5940,6 +6032,7 @@ START_TEST(vartype) test_SysReAllocString(); test_SysReAllocStringLen(); test_BstrCopy(); + test_VarBstrCat();
test_IUnknownClear(); test_IUnknownCopy(); diff --git a/dlls/oleaut32/vartype.c b/dlls/oleaut32/vartype.c index e08a7c0..519c9e0 100644 --- a/dlls/oleaut32/vartype.c +++ b/dlls/oleaut32/vartype.c @@ -6584,27 +6584,31 @@ HRESULT WINAPI VarBstrFromDisp(IDispatch */ HRESULT WINAPI VarBstrCat(BSTR pbstrLeft, BSTR pbstrRight, BSTR *pbstrOut) { - unsigned int len; + unsigned int lenLeft, lenRight; + + TRACE("%s,%s,%p\n", + debugstr_wn(pbstrLeft, SysStringLen(pbstrLeft)), + debugstr_wn(pbstrRight, SysStringLen(pbstrRight)), pbstrOut);
if (!pbstrOut) return E_INVALIDARG;
- len = pbstrLeft ? strlenW(pbstrLeft) : 0; - if (pbstrRight) - len += strlenW(pbstrRight); + lenLeft = pbstrLeft ? SysStringLen(pbstrLeft) : 0; + lenRight = pbstrRight ? SysStringLen(pbstrRight) : 0;
- *pbstrOut = SysAllocStringLen(NULL, len); + *pbstrOut = SysAllocStringLen(NULL, lenLeft + lenRight); if (!*pbstrOut) return E_OUTOFMEMORY;
(*pbstrOut)[0] = '\0';
if (pbstrLeft) - strcpyW(*pbstrOut, pbstrLeft); + memcpy(*pbstrOut, pbstrLeft, lenLeft * sizeof(WCHAR));
if (pbstrRight) - strcatW(*pbstrOut, pbstrRight); + memcpy(*pbstrOut + lenLeft, pbstrRight, lenRight * sizeof(WCHAR));
+ TRACE("%s\n", debugstr_wn(*pbstrOut, SysStringLen(*pbstrOut))); return S_OK; }
@@ -6629,6 +6633,12 @@ HRESULT WINAPI VarBstrCat(BSTR pbstrLeft */ HRESULT WINAPI VarBstrCmp(BSTR pbstrLeft, BSTR pbstrRight, LCID lcid, DWORD dwFlags) { + HRESULT hres; + + TRACE("%s,%s,%ld,%08lx\n", + debugstr_wn(pbstrLeft, SysStringLen(pbstrLeft)), + debugstr_wn(pbstrRight, SysStringLen(pbstrRight)), lcid, dwFlags); + if (!pbstrLeft || !*pbstrLeft) { if (!pbstrRight || !*pbstrRight) @@ -6638,7 +6648,10 @@ HRESULT WINAPI VarBstrCmp(BSTR pbstrLeft else if (!pbstrRight || !*pbstrRight) return VARCMP_GT;
- return CompareStringW(lcid, dwFlags, pbstrLeft, -1, pbstrRight, -1) - 1; + hres = CompareStringW(lcid, dwFlags, pbstrLeft, SysStringLen(pbstrLeft), + pbstrRight, SysStringLen(pbstrRight)) - 1; + TRACE("%ld\n", hres); + return hres; }
/*