From: Maotong Zhang zmtong1988@gmail.com
Use VarNumFromStr for VT_BSTR conversion in VarAnd、VarOr、VarImp --- dlls/oleaut32/variant.c | 118 ++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 47 deletions(-)
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c index fbe035a5576..2251cc4bfe1 100644 --- a/dlls/oleaut32/variant.c +++ b/dlls/oleaut32/variant.c @@ -2563,6 +2563,69 @@ VarNumFromParseNum_DecOverflow: return DISP_E_OVERFLOW; /* No more output choices */ }
+/********************************************************************** + * VarNumFromStr + * + * Converts a BSTR VARIANT to a numeric or boolean VARIANT. + * + * PARAMETERS + * pVar [I] VARIANT to convert in place. + * presvt [I] Receives the resulting VARTYPE. + * + * RETURNS + * S_OK on success, or an HRESULT error code on failure. + */ +static inline HRESULT VarNumFromStr(VARIANT *pVar, VARTYPE *presvt) +{ + HRESULT hres = S_OK; + if (V_VT(pVar) == VT_BSTR) + { + LONGLONG val64; + HRESULT tmpres = VarI8FromStr(V_BSTR(pVar), LOCALE_USER_DEFAULT, 0, &val64); + if (SUCCEEDED(tmpres)) + { + VARIANT tmpvar; + VariantInit(&tmpvar); + + if (val64 >= LONG_MIN && val64 <= LONG_MAX) + { + V_VT(&tmpvar) = VT_I4; + V_I4(&tmpvar) = (LONG)val64; + *presvt = VT_I4; + } + else + { + V_VT(&tmpvar) = VT_I8; + V_I8(&tmpvar) = val64; + *presvt = VT_I8; + } + + VariantClear(pVar); + hres = VariantCopy(pVar, &tmpvar); + VariantClear(&tmpvar); + } + else + { + double d; + if (FAILED(VarR8FromStr(V_BSTR(pVar), LOCALE_USER_DEFAULT, 0, &d))) + { + hres = VariantChangeType(pVar, pVar, VARIANT_LOCALBOOL, VT_BOOL); + } + else + { + if (V_VT(pVar) != *presvt) + hres = VariantChangeType(pVar, pVar, 0, *presvt); + } + } + if (FAILED(hres)) return hres; + } + + if (SUCCEEDED(hres) && V_VT(pVar) != *presvt) + hres = VariantChangeType(pVar, pVar, 0, *presvt); + + return hres; +} + /********************************************************************** * VarCat [OLEAUT32.318] * @@ -3106,15 +3169,7 @@ 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 && - FAILED(VarR8FromStr(V_BSTR(&varLeft), - LOCALE_USER_DEFAULT, 0, &d))) - hres = VariantChangeType(&varLeft,&varLeft, - VARIANT_LOCALBOOL, VT_BOOL); - if (SUCCEEDED(hres) && V_VT(&varLeft) != resvt) - hres = VariantChangeType(&varLeft,&varLeft,0,resvt); + hres = VarNumFromStr(&varLeft, &resvt); if (FAILED(hres)) goto VarAnd_Exit; }
@@ -3122,15 +3177,7 @@ 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 && - 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) - hres = VariantChangeType(&varRight, &varRight, 0, resvt); + hres = VarNumFromStr(&varRight, &resvt); if (FAILED(hres)) goto VarAnd_Exit; }
@@ -4252,30 +4299,16 @@ VarOr_AsEmpty: V_VT(&varLeft) = VT_I4; /* Don't overflow */ else { - DOUBLE d; - - if (V_VT(&varLeft) == VT_BSTR && - FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d))) - hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL); - if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt) - hRet = VariantChangeType(&varLeft, &varLeft, 0, vt); - if (FAILED(hRet)) - goto VarOr_Exit; + hRet = VarNumFromStr(&varLeft, &vt); + if (FAILED(hRet)) goto VarOr_Exit; }
if (vt == VT_I4 && V_VT(&varRight) == VT_UI4) V_VT(&varRight) = VT_I4; /* Don't overflow */ else { - DOUBLE d; - - if (V_VT(&varRight) == VT_BSTR && - FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d))) - hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL); - if (SUCCEEDED(hRet) && V_VT(&varRight) != vt) - hRet = VariantChangeType(&varRight, &varRight, 0, vt); - if (FAILED(hRet)) - goto VarOr_Exit; + hRet = VarNumFromStr(&varRight, &vt); + if (FAILED(hRet)) goto VarOr_Exit; }
V_VT(pVarOut) = vt; @@ -5757,7 +5790,6 @@ HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result) VARTYPE leftvt,rightvt; VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags; VARIANT lv,rv; - DOUBLE d; VARIANT tempLeft, tempRight;
VariantInit(&lv); @@ -5943,18 +5975,10 @@ HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result) if (FAILED(hres)) goto VarImp_Exit; }
- if (V_VT(&lv) == VT_BSTR && - FAILED(VarR8FromStr(V_BSTR(&lv),LOCALE_USER_DEFAULT, 0, &d))) - hres = VariantChangeType(&lv,&lv,VARIANT_LOCALBOOL, VT_BOOL); - if (SUCCEEDED(hres) && V_VT(&lv) != resvt) - hres = VariantChangeType(&lv,&lv,0,resvt); + hres = VarNumFromStr(&lv, &resvt); if (FAILED(hres)) goto VarImp_Exit;
- if (V_VT(&rv) == VT_BSTR && - FAILED(VarR8FromStr(V_BSTR(&rv),LOCALE_USER_DEFAULT, 0, &d))) - hres = VariantChangeType(&rv, &rv,VARIANT_LOCALBOOL, VT_BOOL); - if (SUCCEEDED(hres) && V_VT(&rv) != resvt) - hres = VariantChangeType(&rv, &rv, 0, resvt); + hres = VarNumFromStr(&rv, &resvt); if (FAILED(hres)) goto VarImp_Exit;
/* do the math */