Commit 2a0c37d8 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

oleaut32: Correctly handle NULLs embedded in BSTRs, with tests.

parent 22d7f141
......@@ -4898,8 +4898,8 @@ static void test_VarBstrFromDec(void)
#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();
......
......@@ -6584,27 +6584,31 @@ HRESULT WINAPI VarBstrFromDisp(IDispatch* pdispIn, LCID lcid, ULONG dwFlags, BST
*/
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, BSTR pbstrRight, BSTR *pbstrOut)
*/
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, BSTR pbstrRight, LCID lcid, DWORD dwFl
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;
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment