From: Francis De Brabandere <francisdb@gmail.com> Native VarImp returns VT_NULL for UI1 0xFF Imp Null via the three- valued all-ones rule, but native VBScript keeps UI1 width and returns the bitwise ~left. Handle the narrow case directly in interp_imp. --- dlls/vbscript/interp.c | 13 ++++++++++++- dlls/vbscript/tests/lang.vbs | 10 ++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index ba530fca38c..c92006b15d6 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -2103,7 +2103,18 @@ static HRESULT interp_imp(exec_ctx_t *ctx) hres = stack_pop_val(ctx, &l); if(SUCCEEDED(hres)) { - hres = VarImp(l.v, r.v, &v); + /* Native VarImp returns VT_NULL for UI1 0xFF Imp Null under the + * three-valued "all-ones Imp unknown = unknown" rule, but native + * VBScript keeps UI1 width and returns the bitwise complement of + * the left operand. Handle UI1 Imp Null directly. */ + if ((V_VT(l.v) & VT_TYPEMASK) == VT_UI1 && + (V_VT(r.v) & VT_TYPEMASK) == VT_NULL) { + V_VT(&v) = VT_UI1; + V_UI1(&v) = ~V_UI1(l.v); + hres = S_OK; + } else { + hres = VarImp(l.v, r.v, &v); + } release_val(&l); } release_val(&r); diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 7ff524461c6..1161545b79c 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -196,6 +196,16 @@ call ok(false imp false, "false does not imp false?") call ok(not (true imp false), "true imp false?") call ok(false imp null, "false imp null is false?") +' For VT_UI1 Imp VT_NULL, native VBScript keeps UI1 width and returns +' the bitwise complement of the left operand, rather than applying +' VarImp's three-valued all-ones rule. interp_imp has a narrow special +' case to match this native behavior. +Call ok((CByte(0) Imp Null) = 255, "CByte(0) Imp Null is not 255") +Call ok(getVT(CByte(0) Imp Null) = "VT_UI1", "getVT(CByte(0) Imp Null) = " & getVT(CByte(0) Imp Null)) +Call ok((CByte(170) Imp Null) = 85, "CByte(170) Imp Null is not 85") +Call ok((CByte(255) Imp Null) = 0, "CByte(255) Imp Null is not 0") +Call ok(getVT(CByte(255) Imp Null) = "VT_UI1", "getVT(CByte(255) Imp Null) = " & getVT(CByte(255) Imp Null)) + Call ok(2 >= 1, "! 2 >= 1") Call ok(2 >= 2, "! 2 >= 2") Call ok(2 => 1, "! 2 => 1") -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10673