diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2023-12-07 05:57:31 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-07 05:57:31 -0800 |
commit | e42f03264b424450b560a69994879f09b6c555d8 (patch) | |
tree | 4d18136e38aaa7e0afed05e8e7a6b3a754e39089 | |
parent | 5fa88a7ae13effc02d42070313d3082bf98e22a7 (diff) | |
parent | a16218d4c6773c474011149661470af6e8c90892 (diff) | |
download | rneovim-e42f03264b424450b560a69994879f09b6c555d8.tar.gz rneovim-e42f03264b424450b560a69994879f09b6c555d8.tar.bz2 rneovim-e42f03264b424450b560a69994879f09b6c555d8.zip |
Merge #26426 allow empty string key in msgpack => Vim conversion
-rw-r--r-- | src/nvim/api/private/converter.c | 31 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 4 | ||||
-rw-r--r-- | src/nvim/api/vimscript.c | 9 | ||||
-rw-r--r-- | src/nvim/channel.c | 4 | ||||
-rw-r--r-- | src/nvim/context.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 14 | ||||
-rw-r--r-- | src/nvim/mapping.c | 4 | ||||
-rw-r--r-- | test/functional/api/vim_spec.lua | 6 | ||||
-rw-r--r-- | test/functional/vimscript/json_functions_spec.lua | 4 |
9 files changed, 22 insertions, 58 deletions
diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c index ef57bde32d..e7b8934c97 100644 --- a/src/nvim/api/private/converter.c +++ b/src/nvim/api/private/converter.c @@ -258,9 +258,7 @@ Object vim_to_object(typval_T *obj) /// @param tv Conversion result is placed here. On failure member v_type is /// set to VAR_UNKNOWN (no allocation was made for this variable). /// @param err Error object. -/// -/// @returns true if conversion is successful, otherwise false. -bool object_to_vim(Object obj, typval_T *tv, Error *err) +void object_to_vim(Object obj, typval_T *tv, Error *err) { tv->v_type = VAR_UNKNOWN; tv->v_lock = VAR_UNLOCKED; @@ -307,12 +305,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) for (uint32_t i = 0; i < obj.data.array.size; i++) { Object item = obj.data.array.items[i]; typval_T li_tv; - - if (!object_to_vim(item, &li_tv, err)) { - tv_list_free(list); - return false; - } - + object_to_vim(item, &li_tv, err); tv_list_append_owned_tv(list, li_tv); } tv_list_ref(list); @@ -328,24 +321,8 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) for (uint32_t i = 0; i < obj.data.dictionary.size; i++) { KeyValuePair item = obj.data.dictionary.items[i]; String key = item.key; - - if (key.size == 0) { - api_set_error(err, kErrorTypeValidation, - "Empty dictionary keys aren't allowed"); - // cleanup - tv_dict_free(dict); - return false; - } - dictitem_T *const di = tv_dict_item_alloc(key.data); - - if (!object_to_vim(item.value, &di->di_tv, err)) { - // cleanup - tv_dict_item_free(di); - tv_dict_free(dict); - return false; - } - + object_to_vim(item.value, &di->di_tv, err); tv_dict_add(dict, di); } dict->dv_refcount++; @@ -362,6 +339,4 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) break; } } - - return true; } diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index b23684aee9..2772fa8b59 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -253,9 +253,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva typval_T tv; // Convert the object to a vimscript type in the temporary variable - if (!object_to_vim(value, &tv, err)) { - return rv; - } + object_to_vim(value, &tv, err); typval_T oldtv = TV_INITIAL_VALUE; diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index 25a34f769c..3bca988030 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -207,9 +207,7 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) typval_T vim_args[MAX_FUNC_ARGS + 1]; size_t i = 0; // also used for freeing the variables for (; i < args.size; i++) { - if (!object_to_vim(args.items[i], &vim_args[i], err)) { - goto free_vim_args; - } + object_to_vim(args.items[i], &vim_args[i], err); } // Initialize `force_abort` and `suppress_errthrow` at the top level. @@ -243,7 +241,6 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) tv_clear(&rettv); recursive--; -free_vim_args: while (i > 0) { tv_clear(&vim_args[--i]); } @@ -297,9 +294,7 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err) mustfree = true; break; case kObjectTypeDictionary: - if (!object_to_vim(dict, &rettv, err)) { - goto end; - } + object_to_vim(dict, &rettv, err); break; default: api_set_error(err, kErrorTypeValidation, diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 767c8d29b8..ca8cbed8f9 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -233,7 +233,7 @@ void channel_create_event(Channel *chan, const char *ext_source) typval_T tv = TV_INITIAL_VALUE; // TODO(bfredl): do the conversion in one step. Also would be nice // to pretty print top level dict in defined order - (void)object_to_vim(DICTIONARY_OBJ(info), &tv, NULL); + object_to_vim(DICTIONARY_OBJ(info), &tv, NULL); assert(tv.v_type == VAR_DICT); char *str = encode_tv2json(&tv, NULL); ILOG("new channel %" PRIu64 " (%s) : %s", chan->id, source, str); @@ -865,7 +865,7 @@ static void set_info_event(void **argv) dict_T *dict = get_v_event(&save_v_event); Dictionary info = channel_info(chan->id); typval_T retval; - (void)object_to_vim(DICTIONARY_OBJ(info), &retval, NULL); + object_to_vim(DICTIONARY_OBJ(info), &retval, NULL); assert(retval.v_type == VAR_DICT); tv_dict_add_dict(dict, S_LEN("info"), retval.vval.v_dict); tv_dict_set_keys_readonly(dict); diff --git a/src/nvim/context.c b/src/nvim/context.c index 5f47cfc225..28a67061c6 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -326,9 +326,7 @@ static inline msgpack_sbuffer array_to_sbuf(Array array, Error *err) msgpack_sbuffer_init(&sbuf); typval_T list_tv; - if (!object_to_vim(ARRAY_OBJ(array), &list_tv, err)) { - return sbuf; - } + object_to_vim(ARRAY_OBJ(array), &list_tv, err); assert(list_tv.v_type == VAR_LIST); if (!encode_vim_list_to_buf(list_tv.vval.v_list, &sbuf.size, &sbuf.data)) { diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 4029478072..c1c865df60 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -355,10 +355,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) goto end; } - if (!object_to_vim(result, rettv, &err)) { - assert(ERROR_SET(&err)); - semsg(_("Error converting the call result: %s"), err.msg); - } + object_to_vim(result, rettv, &err); end: api_free_array(args); @@ -428,7 +425,7 @@ static void f_and(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) static void f_api_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { Dictionary metadata = api_metadata(); - (void)object_to_vim(DICTIONARY_OBJ(metadata), rettv, NULL); + object_to_vim(DICTIONARY_OBJ(metadata), rettv, NULL); } /// "atan2()" function @@ -1023,7 +1020,7 @@ static void f_ctxget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) Dictionary ctx_dict = ctx_to_dict(ctx); Error err = ERROR_INIT; - (void)object_to_vim(DICTIONARY_OBJ(ctx_dict), rettv, &err); + object_to_vim(DICTIONARY_OBJ(ctx_dict), rettv, &err); api_free_dictionary(ctx_dict); api_clear_error(&err); } @@ -6751,10 +6748,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) goto end; } - if (!object_to_vim(result, rettv, &err)) { - assert(ERROR_SET(&err)); - semsg(_("Error converting the call result: %s"), err.msg); - } + object_to_vim(result, rettv, &err); end: arena_mem_free(res_mem); diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index 56544a9956..345ec45152 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -2199,7 +2199,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) Dictionary dict = mapblock_fill_dict(mp, did_simplify ? keys_simplified : NULL, buffer_local, abbr, true); - (void)object_to_vim(DICTIONARY_OBJ(dict), rettv, NULL); + object_to_vim(DICTIONARY_OBJ(dict), rettv, NULL); api_free_dictionary(dict); } else { // Return an empty dictionary. @@ -2407,7 +2407,7 @@ void f_maplist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) did_simplify ? keys_buf : NULL, buffer_local, abbr, true); typval_T d = TV_INITIAL_VALUE; - (void)object_to_vim(DICTIONARY_OBJ(dict), &d, NULL); + object_to_vim(DICTIONARY_OBJ(dict), &d, NULL); assert(d.v_type == VAR_DICT); tv_list_append_dict(rettv->vval.v_list, d.vval.v_dict); api_free_dictionary(dict); diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 7287666190..abae346701 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1319,6 +1319,10 @@ describe('API', function() eq("Key not found: lua", pcall_err(meths.del_var, 'lua')) meths.set_var('lua', 1) + -- Empty keys are allowed in Vim dicts (and msgpack). + nvim('set_var', 'dict_empty_key', {[''] = 'empty key'}) + eq({[''] = 'empty key'}, nvim('get_var', 'dict_empty_key')) + -- Set locked g: var. command('lockvar lua') eq('Key is locked: lua', pcall_err(meths.del_var, 'lua')) @@ -1983,7 +1987,7 @@ describe('API', function() it('errors when context dictionary is invalid', function() eq('E474: Failed to convert list to msgpack string buffer', pcall_err(nvim, 'load_context', { regs = { {} }, jumps = { {} } })) - eq("Empty dictionary keys aren't allowed", + eq('E474: Failed to convert list to msgpack string buffer', pcall_err(nvim, 'load_context', { regs = { { [''] = '' } } })) end) end) diff --git a/test/functional/vimscript/json_functions_spec.lua b/test/functional/vimscript/json_functions_spec.lua index 53899085e0..c12bcf5099 100644 --- a/test/functional/vimscript/json_functions_spec.lua +++ b/test/functional/vimscript/json_functions_spec.lua @@ -576,8 +576,8 @@ describe('json_encode() function', function() eq('{}', eval('json_encode({})')) eq('{"d": []}', funcs.json_encode({d={}})) eq('{"d": [], "e": []}', funcs.json_encode({d={}, e={}})) - -- Empty keys not allowed (yet?) in object_to_vim() (since 7c01d5ff9286). #25564 - -- eq('{"": []}', funcs.json_encode({['']={}})) + -- Empty keys are allowed per JSON spec (and Vim dicts, and msgpack). + eq('{"": []}', funcs.json_encode({['']={}})) end) it('cannot dump generic mapping with generic mapping keys and values', |