summaryrefslogtreecommitdiff
path: root/src/vim9execute.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-02-18 18:38:37 +0000
committerBram Moolenaar <Bram@vim.org>2023-02-18 18:38:37 +0000
commit2c1c803c7e0cc356dd55a2cd49fbffbbf7db766e (patch)
treea9b33c47978efd0ffaf3f1ef10e547edc15d5b3e /src/vim9execute.c
parentd114975b9bec30ec1486ebc70db6b802d0f1cfb8 (diff)
downloadvim-git-2c1c803c7e0cc356dd55a2cd49fbffbbf7db766e.tar.gz
patch 9.0.1322: crash when indexing "any" which is an objectv9.0.1322
Problem: Crash when indexing "any" which is an object. Solution: Check the index is a number. Do not check the member type of an object. (closes #12019)
Diffstat (limited to 'src/vim9execute.c')
-rw-r--r--src/vim9execute.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 4bbed8259..638dbc5ca 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2126,9 +2126,13 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
vartype_T dest_type = iptr->isn_arg.storeindex.si_vartype;
typval_T *tv;
typval_T *tv_idx = STACK_TV_BOT(-2);
+ long lidx = 0;
typval_T *tv_dest = STACK_TV_BOT(-1);
int status = OK;
+ if (tv_idx->v_type == VAR_NUMBER)
+ lidx = (long)tv_idx->vval.v_number;
+
// Stack contains:
// -3 value to be stored
// -2 index
@@ -2140,7 +2144,41 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
dest_type = tv_dest->v_type;
if (dest_type == VAR_DICT)
status = do_2string(tv_idx, TRUE, FALSE);
- else if (dest_type == VAR_LIST && tv_idx->v_type != VAR_NUMBER)
+ else if (dest_type == VAR_OBJECT && tv_idx->v_type == VAR_STRING)
+ {
+ // Need to get the member index now that the class is known.
+ object_T *obj = tv_dest->vval.v_object;
+ class_T *cl = obj->obj_class;
+ char_u *member = tv_idx->vval.v_string;
+
+ ocmember_T *m = NULL;
+ for (int i = 0; i < cl->class_obj_member_count; ++i)
+ {
+ m = &cl->class_obj_members[i];
+ if (STRCMP(member, m->ocm_name) == 0)
+ {
+ if (*member == '_')
+ {
+ semsg(_(e_cannot_access_private_member_str),
+ m->ocm_name);
+ status = FAIL;
+ }
+
+ lidx = i;
+ break;
+ }
+ m = NULL;
+ }
+
+ if (m == NULL)
+ {
+ semsg(_(e_member_not_found_on_object_str_str),
+ cl->class_name, member);
+ status = FAIL;
+ }
+ }
+ else if ((dest_type == VAR_LIST || dest_type == VAR_OBJECT)
+ && tv_idx->v_type != VAR_NUMBER)
{
emsg(_(e_number_expected));
status = FAIL;
@@ -2151,7 +2189,6 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
{
if (dest_type == VAR_LIST)
{
- long lidx = (long)tv_idx->vval.v_number;
list_T *list = tv_dest->vval.v_list;
if (list == NULL)
@@ -2224,7 +2261,6 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
}
else if (dest_type == VAR_BLOB)
{
- long lidx = (long)tv_idx->vval.v_number;
blob_T *blob = tv_dest->vval.v_blob;
varnumber_T nr;
int error = FALSE;
@@ -2255,18 +2291,17 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
}
else if (dest_type == VAR_CLASS || dest_type == VAR_OBJECT)
{
- long idx = (long)tv_idx->vval.v_number;
object_T *obj = tv_dest->vval.v_object;
typval_T *otv = (typval_T *)(obj + 1);
class_T *itf = iptr->isn_arg.storeindex.si_class;
if (itf != NULL)
// convert interface member index to class member index
- idx = object_index_from_itf_index(itf, FALSE,
- idx, obj->obj_class);
+ lidx = object_index_from_itf_index(itf, FALSE,
+ lidx, obj->obj_class);
- clear_tv(&otv[idx]);
- otv[idx] = *tv;
+ clear_tv(&otv[lidx]);
+ otv[lidx] = *tv;
}
else
{