Commit 7ca1eff8 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

vbscript: Make redim fail on fixed-size arrays.

parent 7bf58c89
...@@ -1246,6 +1246,7 @@ static HRESULT interp_dim(exec_ctx_t *ctx) ...@@ -1246,6 +1246,7 @@ static HRESULT interp_dim(exec_ctx_t *ctx)
*array_ref = SafeArrayCreate(VT_VARIANT, array_desc->dim_cnt, array_desc->bounds); *array_ref = SafeArrayCreate(VT_VARIANT, array_desc->dim_cnt, array_desc->bounds);
if(!*array_ref) if(!*array_ref)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
(*array_ref)->fFeatures |= (FADF_FIXEDSIZE | FADF_STATIC);
} }
V_VT(v) = VT_ARRAY|VT_BYREF|VT_VARIANT; V_VT(v) = VT_ARRAY|VT_BYREF|VT_VARIANT;
...@@ -1302,6 +1303,18 @@ static HRESULT interp_redim(exec_ctx_t *ctx) ...@@ -1302,6 +1303,18 @@ static HRESULT interp_redim(exec_ctx_t *ctx)
return E_FAIL; 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); hres = array_bounds_from_stack(ctx, dim_cnt, &bounds);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
...@@ -1311,14 +1324,6 @@ static HRESULT interp_redim(exec_ctx_t *ctx) ...@@ -1311,14 +1324,6 @@ static HRESULT interp_redim(exec_ctx_t *ctx)
if(!array) if(!array)
return E_OUTOFMEMORY; 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); VariantClear(v);
V_VT(v) = VT_ARRAY|VT_VARIANT; V_VT(v) = VT_ARRAY|VT_VARIANT;
V_ARRAY(v) = array; V_ARRAY(v) = array;
...@@ -1361,7 +1366,7 @@ static HRESULT interp_redim_preserve(exec_ctx_t *ctx) ...@@ -1361,7 +1366,7 @@ static HRESULT interp_redim_preserve(exec_ctx_t *ctx)
return E_FAIL; 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); hres = array_bounds_from_stack(ctx, dim_cnt, &bounds);
if(FAILED(hres)) if(FAILED(hres))
......
...@@ -1531,12 +1531,48 @@ e = err.number ...@@ -1531,12 +1531,48 @@ e = err.number
on error goto 0 on error goto 0
ok e = 9, "e = " & e ' VBSE_OUT_OF_BOUNDS, can only change rightmost dimension ok e = 9, "e = " & e ' VBSE_OUT_OF_BOUNDS, can only change rightmost dimension
dim staticarray(4) sub TestReDimFixed
on error resume next on error resume next
redim staticarray(3)
e = err.number dim staticarray(4)
on error goto 0 err.clear
todo_wine_ok e = 10, "e = " & e 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 sub TestReDimList
dim x, y dim x, y
......
...@@ -146,6 +146,7 @@ DEFINE_EXPECT(OnLeaveScript); ...@@ -146,6 +146,7 @@ DEFINE_EXPECT(OnLeaveScript);
#define DISPID_GLOBAL_PROPARGSET 1025 #define DISPID_GLOBAL_PROPARGSET 1025
#define DISPID_GLOBAL_UNKOBJ 1026 #define DISPID_GLOBAL_UNKOBJ 1026
#define DISPID_GLOBAL_THROWEXCEPTION 1027 #define DISPID_GLOBAL_THROWEXCEPTION 1027
#define DISPID_GLOBAL_ISARRAYFIXED 1028
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPGET 2000
#define DISPID_TESTOBJ_PROPPUT 2001 #define DISPID_TESTOBJ_PROPPUT 2001
...@@ -568,7 +569,6 @@ static void test_safearray(SAFEARRAY *safearray, unsigned indims) ...@@ -568,7 +569,6 @@ static void test_safearray(SAFEARRAY *safearray, unsigned indims)
if(!exdims) if(!exdims)
exdims = 1; exdims = 1;
ok(safearray->cDims == exdims, "safearray->cDims = %d, expected %d\n", safearray->cDims, exdims); 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), ok(safearray->fFeatures == (FADF_VARIANT|FADF_HAVEVARTYPE|FADF_FIXEDSIZE|FADF_STATIC),
"safearray->fFeatures = %x\n", safearray->fFeatures); "safearray->fFeatures = %x\n", safearray->fFeatures);
ok(safearray->cbElements == sizeof(VARIANT), "safearray->cbElements = %lx\n", safearray->cbElements); 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 ...@@ -1163,7 +1163,8 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
{ L"testOptionalArg", DISPID_GLOBAL_TESTOPTIONALARG }, { L"testOptionalArg", DISPID_GLOBAL_TESTOPTIONALARG },
{ L"testErrorObject", DISPID_GLOBAL_TESTERROROBJECT }, { L"testErrorObject", DISPID_GLOBAL_TESTERROROBJECT },
{ L"throwWithDesc", DISPID_GLOBAL_THROWWITHDESC }, { L"throwWithDesc", DISPID_GLOBAL_THROWWITHDESC },
{ L"unkObj", DISPID_GLOBAL_UNKOBJ } { L"unkObj", DISPID_GLOBAL_UNKOBJ },
{ L"isArrayFixed", DISPID_GLOBAL_ISARRAYFIXED },
}; };
test_grfdex(grfdex, fdexNameCaseInsensitive); test_grfdex(grfdex, fdexNameCaseInsensitive);
...@@ -1737,6 +1738,34 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, ...@@ -1737,6 +1738,34 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
V_VT(pvarRes) = VT_UNKNOWN; V_VT(pvarRes) = VT_UNKNOWN;
V_UNKNOWN(pvarRes) = &unkObj; V_UNKNOWN(pvarRes) = &unkObj;
return S_OK; 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); ok(0, "unexpected call %ld\n", id);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment