comparison src/evalvars.c @ 22240:88927d5f275d v8.2.1669

patch 8.2.1669: Vim9: memory leak when storing a value fails Commit: https://github.com/vim/vim/commit/b0fa5e17c587d9c71596bd10836918af713ffff6 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Sep 12 19:51:42 2020 +0200 patch 8.2.1669: Vim9: memory leak when storing a value fails Problem: Vim9: memory leak when storing a value fails. Solution: Free the value when not storing it.
author Bram Moolenaar <Bram@vim.org>
date Sat, 12 Sep 2020 20:00:04 +0200
parents 7899b4e2880c
children 23f5750146d9
comparison
equal deleted inserted replaced
22239:3e8d7529c28f 22240:88927d5f275d
2948 2948
2949 ht = find_var_ht(name, &varname); 2949 ht = find_var_ht(name, &varname);
2950 if (ht == NULL || *varname == NUL) 2950 if (ht == NULL || *varname == NUL)
2951 { 2951 {
2952 semsg(_(e_illvar), name); 2952 semsg(_(e_illvar), name);
2953 return; 2953 goto failed;
2954 } 2954 }
2955 is_script_local = ht == get_script_local_ht(); 2955 is_script_local = ht == get_script_local_ht();
2956 2956
2957 if (in_vim9script() 2957 if (in_vim9script()
2958 && !is_script_local 2958 && !is_script_local
2959 && (flags & LET_NO_COMMAND) == 0 2959 && (flags & LET_NO_COMMAND) == 0
2960 && name[1] == ':') 2960 && name[1] == ':')
2961 { 2961 {
2962 vim9_declare_error(name); 2962 vim9_declare_error(name);
2963 return; 2963 goto failed;
2964 } 2964 }
2965 2965
2966 di = find_var_in_ht(ht, 0, varname, TRUE); 2966 di = find_var_in_ht(ht, 0, varname, TRUE);
2967 2967
2968 // Search in parent scope which is possible to reference from lambda 2968 // Search in parent scope which is possible to reference from lambda
2969 if (di == NULL) 2969 if (di == NULL)
2970 di = find_var_in_scoped_ht(name, TRUE); 2970 di = find_var_in_scoped_ht(name, TRUE);
2971 2971
2972 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) 2972 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
2973 && var_wrong_func_name(name, di == NULL)) 2973 && var_wrong_func_name(name, di == NULL))
2974 return; 2974 goto failed;
2975 2975
2976 if (need_convert_to_bool(type, tv)) 2976 if (need_convert_to_bool(type, tv))
2977 { 2977 {
2978 // Destination is a bool and the value is not, but it can be converted. 2978 // Destination is a bool and the value is not, but it can be converted.
2979 CLEAR_FIELD(bool_tv); 2979 CLEAR_FIELD(bool_tv);
2987 if ((di->di_flags & DI_FLAGS_RELOAD) == 0) 2987 if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
2988 { 2988 {
2989 if (flags & LET_IS_CONST) 2989 if (flags & LET_IS_CONST)
2990 { 2990 {
2991 emsg(_(e_cannot_mod)); 2991 emsg(_(e_cannot_mod));
2992 return; 2992 goto failed;
2993 } 2993 }
2994 2994
2995 if (is_script_local && in_vim9script()) 2995 if (is_script_local && in_vim9script())
2996 { 2996 {
2997 if ((flags & LET_NO_COMMAND) == 0) 2997 if ((flags & LET_NO_COMMAND) == 0)
2998 { 2998 {
2999 semsg(_(e_redefining_script_item_str), name); 2999 semsg(_(e_redefining_script_item_str), name);
3000 return; 3000 goto failed;
3001 } 3001 }
3002 3002
3003 // check the type and adjust to bool if needed 3003 // check the type and adjust to bool if needed
3004 if (check_script_var_type(&di->di_tv, tv, name) == FAIL) 3004 if (check_script_var_type(&di->di_tv, tv, name) == FAIL)
3005 return; 3005 goto failed;
3006 } 3006 }
3007 3007
3008 if (var_check_ro(di->di_flags, name, FALSE) 3008 if (var_check_ro(di->di_flags, name, FALSE)
3009 || var_check_lock(di->di_tv.v_lock, name, FALSE)) 3009 || var_check_lock(di->di_tv.v_lock, name, FALSE))
3010 return; 3010 goto failed;
3011 } 3011 }
3012 else 3012 else
3013 // can only redefine once 3013 // can only redefine once
3014 di->di_flags &= ~DI_FLAGS_RELOAD; 3014 di->di_flags &= ~DI_FLAGS_RELOAD;
3015 3015
3035 { 3035 {
3036 // Take over the string to avoid an extra alloc/free. 3036 // Take over the string to avoid an extra alloc/free.
3037 di->di_tv.vval.v_string = tv->vval.v_string; 3037 di->di_tv.vval.v_string = tv->vval.v_string;
3038 tv->vval.v_string = NULL; 3038 tv->vval.v_string = NULL;
3039 } 3039 }
3040 return; 3040 goto failed;
3041 } 3041 }
3042 else if (di->di_tv.v_type == VAR_NUMBER) 3042 else if (di->di_tv.v_type == VAR_NUMBER)
3043 { 3043 {
3044 di->di_tv.vval.v_number = tv_get_number(tv); 3044 di->di_tv.vval.v_number = tv_get_number(tv);
3045 if (STRCMP(varname, "searchforward") == 0) 3045 if (STRCMP(varname, "searchforward") == 0)
3049 { 3049 {
3050 no_hlsearch = !di->di_tv.vval.v_number; 3050 no_hlsearch = !di->di_tv.vval.v_number;
3051 redraw_all_later(SOME_VALID); 3051 redraw_all_later(SOME_VALID);
3052 } 3052 }
3053 #endif 3053 #endif
3054 return; 3054 goto failed;
3055 } 3055 }
3056 else if (di->di_tv.v_type != tv->v_type) 3056 else if (di->di_tv.v_type != tv->v_type)
3057 { 3057 {
3058 semsg(_("E963: setting %s to value with wrong type"), name); 3058 semsg(_("E963: setting %s to value with wrong type"), name);
3059 return; 3059 goto failed;
3060 } 3060 }
3061 } 3061 }
3062 3062
3063 clear_tv(&di->di_tv); 3063 clear_tv(&di->di_tv);
3064 } 3064 }
3066 { 3066 {
3067 // Can't add "v:" or "a:" variable. 3067 // Can't add "v:" or "a:" variable.
3068 if (ht == &vimvarht || ht == get_funccal_args_ht()) 3068 if (ht == &vimvarht || ht == get_funccal_args_ht())
3069 { 3069 {
3070 semsg(_(e_illvar), name); 3070 semsg(_(e_illvar), name);
3071 return; 3071 goto failed;
3072 } 3072 }
3073 3073
3074 // Make sure the variable name is valid. 3074 // Make sure the variable name is valid.
3075 if (!valid_varname(varname)) 3075 if (!valid_varname(varname))
3076 return; 3076 goto failed;
3077 3077
3078 di = alloc(sizeof(dictitem_T) + STRLEN(varname)); 3078 di = alloc(sizeof(dictitem_T) + STRLEN(varname));
3079 if (di == NULL) 3079 if (di == NULL)
3080 return; 3080 goto failed;
3081 STRCPY(di->di_key, varname); 3081 STRCPY(di->di_key, varname);
3082 if (hash_add(ht, DI2HIKEY(di)) == FAIL) 3082 if (hash_add(ht, DI2HIKEY(di)) == FAIL)
3083 { 3083 {
3084 vim_free(di); 3084 vim_free(di);
3085 return; 3085 goto failed;
3086 } 3086 }
3087 di->di_flags = DI_FLAGS_ALLOC; 3087 di->di_flags = DI_FLAGS_ALLOC;
3088 if (flags & LET_IS_CONST) 3088 if (flags & LET_IS_CONST)
3089 di->di_flags |= DI_FLAGS_LOCK; 3089 di->di_flags |= DI_FLAGS_LOCK;
3090 3090
3126 if (flags & LET_IS_CONST) 3126 if (flags & LET_IS_CONST)
3127 // Like :lockvar! name: lock the value and what it contains, but only 3127 // Like :lockvar! name: lock the value and what it contains, but only
3128 // if the reference count is up to one. That locks only literal 3128 // if the reference count is up to one. That locks only literal
3129 // values. 3129 // values.
3130 item_lock(&di->di_tv, DICT_MAXNEST, TRUE, TRUE); 3130 item_lock(&di->di_tv, DICT_MAXNEST, TRUE, TRUE);
3131 return;
3132 failed:
3133 if (!copy)
3134 clear_tv(tv_arg);
3131 } 3135 }
3132 3136
3133 /* 3137 /*
3134 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 3138 * Return TRUE if di_flags "flags" indicates variable "name" is read-only.
3135 * Also give an error message. 3139 * Also give an error message.