dict_set_var: check value before checking its container

- When setting a fixed/locked/readonly var, it is more relevant to
  report on the key, not its container dict. If its container dict (v:)
  is readonly, that does not mean the key itself is readonly.
- Allow modifying a "fixed" var. "fixed" only prevents deletion.
This commit is contained in:
Justin M. Keyes 2019-01-14 00:40:26 +01:00
parent a3d8cd3f69
commit 0b8c4b995a

View File

@ -184,35 +184,28 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del,
bool retval, Error *err)
{
Object rv = OBJECT_INIT;
if (dict->dv_lock) {
api_set_error(err, kErrorTypeException, "Dictionary is locked");
return rv;
}
if (key.size == 0) {
api_set_error(err, kErrorTypeValidation, "Key name is empty");
return rv;
}
if (key.size > INT_MAX) {
api_set_error(err, kErrorTypeValidation, "Key name is too long");
return rv;
}
dictitem_T *di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size);
if (di != NULL) {
if (di->di_flags & DI_FLAGS_RO) {
api_set_error(err, kErrorTypeException, "Key is read-only: %s", key.data);
return rv;
} else if (di->di_flags & DI_FLAGS_FIX) {
api_set_error(err, kErrorTypeException, "Key is fixed: %s", key.data);
return rv;
} else if (di->di_flags & DI_FLAGS_LOCK) {
api_set_error(err, kErrorTypeException, "Key is locked: %s", key.data);
return rv;
} else if (del && (di->di_flags & DI_FLAGS_FIX)) {
api_set_error(err, kErrorTypeException, "Key is fixed: %s", key.data);
return rv;
}
} else if (dict->dv_lock) {
api_set_error(err, kErrorTypeException, "Dictionary is locked");
return rv;
} else if (key.size == 0) {
api_set_error(err, kErrorTypeValidation, "Key name is empty");
return rv;
} else if (key.size > INT_MAX) {
api_set_error(err, kErrorTypeValidation, "Key name is too long");
return rv;
}
if (del) {