vbscript: Make redim fail on fixed-size arrays.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53964
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov 2022-11-23 08:35:01 +03:00 committed by Alexandre Julliard
parent 7bf58c895c
commit 7ca1eff8e1
3 changed files with 87 additions and 17 deletions

View file

@ -1246,6 +1246,7 @@ static HRESULT interp_dim(exec_ctx_t *ctx)
*array_ref = SafeArrayCreate(VT_VARIANT, array_desc->dim_cnt, array_desc->bounds);
if(!*array_ref)
return E_OUTOFMEMORY;
(*array_ref)->fFeatures |= (FADF_FIXEDSIZE | FADF_STATIC);
}
V_VT(v) = VT_ARRAY|VT_BYREF|VT_VARIANT;
@ -1302,6 +1303,18 @@ static HRESULT interp_redim(exec_ctx_t *ctx)
return E_FAIL;
}
v = ref.u.v;
if(V_VT(v) == (VT_VARIANT|VT_BYREF)) {
v = V_VARIANTREF(v);
}
if(V_ISARRAY(v)) {
SAFEARRAY *sa = V_ISBYREF(v) ? *V_ARRAYREF(v) : V_ARRAY(v);
if(sa->fFeatures & FADF_FIXEDSIZE)
return MAKE_VBSERROR(VBSE_ARRAY_LOCKED);
}
hres = array_bounds_from_stack(ctx, dim_cnt, &bounds);
if(FAILED(hres))
return hres;
@ -1311,14 +1324,6 @@ static HRESULT interp_redim(exec_ctx_t *ctx)
if(!array)
return E_OUTOFMEMORY;
/* FIXME: We should check if we're not modifying an existing static array here */
v = ref.u.v;
if(V_VT(v) == (VT_VARIANT|VT_BYREF)) {
v = V_VARIANTREF(v);
}
VariantClear(v);
V_VT(v) = VT_ARRAY|VT_VARIANT;
V_ARRAY(v) = array;
@ -1361,7 +1366,7 @@ static HRESULT interp_redim_preserve(exec_ctx_t *ctx)
return E_FAIL;
}
array = V_ARRAY(v);
array = V_ISBYREF(v) ? *V_ARRAYREF(v) : V_ARRAY(v);
hres = array_bounds_from_stack(ctx, dim_cnt, &bounds);
if(FAILED(hres))

View file

@ -1531,12 +1531,48 @@ e = err.number
on error goto 0
ok e = 9, "e = " & e ' VBSE_OUT_OF_BOUNDS, can only change rightmost dimension
dim staticarray(4)
on error resume next
redim staticarray(3)
e = err.number
on error goto 0
todo_wine_ok e = 10, "e = " & e
sub TestReDimFixed
on error resume next
dim staticarray(4)
err.clear
redim staticarray(3)
call ok(err.number = 10, "err.number = " & err.number)
call ok(isArrayFixed(staticarray), "Expected fixed size array")
err.clear
redim staticarray("abc")
call ok(err.number = 10, "err.number = " & err.number)
dim staticarray2(4)
err.clear
redim preserve staticarray2(5)
call ok(err.number = 10, "err.number = " & err.number)
call ok(isArrayFixed(staticarray2), "Expected fixed size array")
err.clear
redim preserve staticarray2("abc")
' Win10+ builds return INVALID_CALL (5)
call ok(err.number = 5 or err.number = 13, "err.number = " & err.number)
end sub
Call TestRedimFixed
sub TestRedimInputArg
on error resume next
dim x
x = Array(1)
err.clear
redim x("abc")
call ok(err.number = 13, "err.number = " & err.number)
err.clear
redim preserve x("abc")
' Win10+ builds return INVALID_CALL (5)
call ok(err.number = 5 or err.number = 13, "err.number = " & err.number)
end sub
Call TestRedimInputArg
sub TestReDimList
dim x, y

View file

@ -146,6 +146,7 @@ DEFINE_EXPECT(OnLeaveScript);
#define DISPID_GLOBAL_PROPARGSET 1025
#define DISPID_GLOBAL_UNKOBJ 1026
#define DISPID_GLOBAL_THROWEXCEPTION 1027
#define DISPID_GLOBAL_ISARRAYFIXED 1028
#define DISPID_TESTOBJ_PROPGET 2000
#define DISPID_TESTOBJ_PROPPUT 2001
@ -568,7 +569,6 @@ static void test_safearray(SAFEARRAY *safearray, unsigned indims)
if(!exdims)
exdims = 1;
ok(safearray->cDims == exdims, "safearray->cDims = %d, expected %d\n", safearray->cDims, exdims);
todo_wine
ok(safearray->fFeatures == (FADF_VARIANT|FADF_HAVEVARTYPE|FADF_FIXEDSIZE|FADF_STATIC),
"safearray->fFeatures = %x\n", safearray->fFeatures);
ok(safearray->cbElements == sizeof(VARIANT), "safearray->cbElements = %lx\n", safearray->cbElements);
@ -1163,7 +1163,8 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
{ L"testOptionalArg", DISPID_GLOBAL_TESTOPTIONALARG },
{ L"testErrorObject", DISPID_GLOBAL_TESTERROROBJECT },
{ L"throwWithDesc", DISPID_GLOBAL_THROWWITHDESC },
{ L"unkObj", DISPID_GLOBAL_UNKOBJ }
{ L"unkObj", DISPID_GLOBAL_UNKOBJ },
{ L"isArrayFixed", DISPID_GLOBAL_ISARRAYFIXED },
};
test_grfdex(grfdex, fdexNameCaseInsensitive);
@ -1737,6 +1738,34 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
V_VT(pvarRes) = VT_UNKNOWN;
V_UNKNOWN(pvarRes) = &unkObj;
return S_OK;
case DISPID_GLOBAL_ISARRAYFIXED:
{
BOOL is_fixed = FALSE;
VARIANT *v;
ok(pdp != NULL, "pdp == NULL\n");
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
ok(pvarRes != NULL, "pvarRes == NULL\n");
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
ok(pei != NULL, "pei == NULL\n");
ok(V_VT(pdp->rgvarg) == (VT_VARIANT|VT_BYREF), "Unexpected argument type %d.\n", V_VT(pdp->rgvarg));
v = V_VARIANTREF(pdp->rgvarg);
ok(V_VT(v) == (VT_VARIANT|VT_ARRAY|VT_BYREF), "Unexpected argument type %d.\n", V_VT(v));
if (V_ISARRAY(v))
{
SAFEARRAY *sa = V_ISBYREF(v) ? *V_ARRAYREF(v) : V_ARRAY(v);
is_fixed = (sa->fFeatures & (FADF_FIXEDSIZE | FADF_STATIC)) == (FADF_FIXEDSIZE | FADF_STATIC);
}
V_VT(pvarRes) = VT_BOOL;
V_BOOL(pvarRes) = is_fixed ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
}
ok(0, "unexpected call %ld\n", id);