[PATCH 0/2] MR8635: oleaut32: Fix VarAnd(VT_BSTR, VT_I2), VT_BSTR length exceed VT_I2 fail
Add VT_BSTR convert VT_I2 VT_I4 VT_I8 judge. Wine-Bug:https://bugs.winehq.org/show_bug.cgi?id=56280 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8635
From: Maotong Zhang <zmtong1988(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8635
From: Maotong Zhang <zmtong1988(a)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; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8635
This should be made more generic, and is likely useful for other functions. I would start by adding more tests. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8635#note_110894
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.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/8635#note_110967
participants (3)
-
Maotong Zhang -
Maotong Zhang (@xiaotong) -
Nikolay Sivov (@nsivov)