Add VT_BSTR convert VT_I2 VT_I4 VT_I8 judge.
From: Maotong Zhang zmtong1988@gmail.com
--- dlls/oleaut32/tests/vartest.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/oleaut32/tests/vartest.c b/dlls/oleaut32/tests/vartest.c index eb1639e3990..6593f64201b 100644 --- a/dlls/oleaut32/tests/vartest.c +++ b/dlls/oleaut32/tests/vartest.c @@ -7451,6 +7451,8 @@ static void test_VarAnd(void) VARAND(BSTR,false_str,BSTR,false_str,BOOL,0); VARAND(BSTR,true_str,BSTR,false_str,BOOL,VARIANT_FALSE); VARAND(BSTR,true_str,BSTR,true_str,BOOL,VARIANT_TRUE); + VARAND(BSTR, SysAllocString(L"2147483647"), I2, 15, I4, (2147483647 & 15)); + VARAND(BSTR, SysAllocString(L"9223372036854775807"), I2, 15, I8, (9223372036854775807 & 15)); VARANDCY(BSTR,true_str,10000,I4,1); VARANDCY(BSTR,false_str,10000,I4,0);
From: Maotong Zhang zmtong1988@gmail.com
Add VT_BSTR convert VT_I2 VT_I4 VT_I8 judge.
Wine-Bug:https://bugs.winehq.org/show_bug.cgi?id=56280 --- dlls/oleaut32/variant.c | 102 ++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 14 deletions(-)
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c index fbe035a5576..e839fbed511 100644 --- a/dlls/oleaut32/variant.c +++ b/dlls/oleaut32/variant.c @@ -3106,15 +3106,48 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result) V_VT(&varLeft) = VT_I4; /* Don't overflow */ else { - DOUBLE d; + if (V_VT(&varLeft) == VT_BSTR) + { + LONGLONG val64; + HRESULT tmpres = VarI8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &val64); + if (SUCCEEDED(tmpres)) + { + VARIANT tmpvar; + VariantInit(&tmpvar);
- if (V_VT(&varLeft) == VT_BSTR && - FAILED(VarR8FromStr(V_BSTR(&varLeft), - LOCALE_USER_DEFAULT, 0, &d))) - hres = VariantChangeType(&varLeft,&varLeft, - VARIANT_LOCALBOOL, VT_BOOL); + if (val64 >= SHRT_MIN && val64 <= SHRT_MAX) + { + V_VT(&tmpvar) = VT_I2; + V_I2(&tmpvar) = (SHORT)val64; + resvt = VT_I2; + } + else if (val64 >= LONG_MIN && val64 <= LONG_MAX) + { + V_VT(&tmpvar) = VT_I4; + V_I4(&tmpvar) = (LONG)val64; + resvt = VT_I4; + } + else + { + V_VT(&tmpvar) = VT_I8; + V_I8(&tmpvar) = val64; + resvt = VT_I8; + } + + VariantClear(&varLeft); + hres = VariantCopy(&varLeft, &tmpvar); + VariantClear(&tmpvar); + } + else + { + double d; + if (FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d))) + hres = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL); + } + if (FAILED(hres)) goto VarAnd_Exit; + } if (SUCCEEDED(hres) && V_VT(&varLeft) != resvt) - hres = VariantChangeType(&varLeft,&varLeft,0,resvt); + hres = VariantChangeType(&varLeft, &varLeft, 0, resvt); if (FAILED(hres)) goto VarAnd_Exit; }
@@ -3122,15 +3155,56 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result) V_VT(&varRight) = VT_I4; /* Don't overflow */ else { - DOUBLE d; + if (V_VT(&varRight) == VT_BSTR) + { + LONGLONG val64; + HRESULT tmpres = VarI8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &val64); + if (SUCCEEDED(tmpres)) + { + VARIANT tmpvar; + VariantInit(&tmpvar);
- if (V_VT(&varRight) == VT_BSTR && - FAILED(VarR8FromStr(V_BSTR(&varRight), - LOCALE_USER_DEFAULT, 0, &d))) - hres = VariantChangeType(&varRight, &varRight, - VARIANT_LOCALBOOL, VT_BOOL); - if (SUCCEEDED(hres) && V_VT(&varRight) != resvt) + if (val64 >= SHRT_MIN && val64 <= SHRT_MAX) + { + V_VT(&tmpvar) = VT_I2; + V_I2(&tmpvar) = (SHORT)val64; + resvt = VT_I2; + } + else if (val64 >= LONG_MIN && val64 <= LONG_MAX) + { + V_VT(&tmpvar) = VT_I4; + V_I4(&tmpvar) = (LONG)val64; + resvt = VT_I4; + } + else + { + V_VT(&tmpvar) = VT_I8; + V_I8(&tmpvar) = val64; + resvt = VT_I8; + } + + VariantClear(&varRight); + hres = VariantCopy(&varRight, &tmpvar); + VariantClear(&tmpvar); + } + else + { + double d; + if (FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d))) + hres = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL); + } + if (FAILED(hres)) goto VarAnd_Exit; + } + + if (SUCCEEDED(hres) && (V_VT(&varRight) != resvt || V_VT(&varLeft) != resvt)) + { + if(V_VT(&varLeft) != resvt) + { + hres = VariantChangeType(&varLeft, &varLeft, 0, resvt); + if (FAILED(hres)) goto VarAnd_Exit; + } hres = VariantChangeType(&varRight, &varRight, 0, resvt); + } if (FAILED(hres)) goto VarAnd_Exit; }
This should be made more generic, and is likely useful for other functions. I would start by adding more tests.
On Fri Jul 25 00:17:43 2025 +0000, Nikolay Sivov wrote:
This should be made more generic, and is likely useful for other functions. I would start by adding more tests.
Ok,Thank you.