comparison src/evalfunc.c @ 19201:e7b4fff348dd v8.2.0159

patch 8.2.0159: non-materialized range() list causes problems Commit: https://github.com/vim/vim/commit/50985eb1f0bd3c73ce727f9bbd66c839c92ef0da Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jan 27 22:09:39 2020 +0100 patch 8.2.0159: non-materialized range() list causes problems Problem: Non-materialized range() list causes problems. (Fujiwara Takuya) Solution: Materialize the list where needed.
author Bram Moolenaar <Bram@vim.org>
date Mon, 27 Jan 2020 22:15:07 +0100
parents 94eda51ba9ba
children d776967d0f0d
comparison
equal deleted inserted replaced
19200:654ef8f794a6 19201:e7b4fff348dd
1854 n = argvars[0].vval.v_float == 0.0; 1854 n = argvars[0].vval.v_float == 0.0;
1855 break; 1855 break;
1856 #endif 1856 #endif
1857 case VAR_LIST: 1857 case VAR_LIST:
1858 n = argvars[0].vval.v_list == NULL 1858 n = argvars[0].vval.v_list == NULL
1859 || argvars[0].vval.v_list->lv_first == NULL; 1859 || argvars[0].vval.v_list->lv_len == 0;
1860 break; 1860 break;
1861 case VAR_DICT: 1861 case VAR_DICT:
1862 n = argvars[0].vval.v_dict == NULL 1862 n = argvars[0].vval.v_dict == NULL
1863 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 1863 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0;
1864 break; 1864 break;
2062 rettv->v_type = VAR_STRING; 2062 rettv->v_type = VAR_STRING;
2063 2063
2064 if (argvars[arg_off].v_type == VAR_LIST) 2064 if (argvars[arg_off].v_type == VAR_LIST)
2065 { 2065 {
2066 list = argvars[arg_off].vval.v_list; 2066 list = argvars[arg_off].vval.v_list;
2067 if (list == NULL || list->lv_first == NULL) 2067 if (list == NULL || list->lv_len == 0)
2068 // empty list, no commands, empty output 2068 // empty list, no commands, empty output
2069 return; 2069 return;
2070 ++list->lv_refcount; 2070 ++list->lv_refcount;
2071 } 2071 }
2072 else if (argvars[arg_off].v_type == VAR_JOB 2072 else if (argvars[arg_off].v_type == VAR_JOB
2112 2112
2113 if (cmd != NULL) 2113 if (cmd != NULL)
2114 do_cmdline_cmd(cmd); 2114 do_cmdline_cmd(cmd);
2115 else 2115 else
2116 { 2116 {
2117 listitem_T *item = list->lv_first; 2117 listitem_T *item;
2118 2118
2119 range_list_materialize(list);
2120 item = list->lv_first;
2119 do_cmdline(NULL, get_list_line, (void *)&item, 2121 do_cmdline(NULL, get_list_line, (void *)&item,
2120 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED); 2122 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED);
2121 --list->lv_refcount; 2123 --list->lv_refcount;
2122 } 2124 }
2123 2125
2641 goto theend; 2643 goto theend;
2642 } 2644 }
2643 for (i = 0; i < arg_len; i++) 2645 for (i = 0; i < arg_len; i++)
2644 copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]); 2646 copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
2645 if (lv_len > 0) 2647 if (lv_len > 0)
2648 {
2649 range_list_materialize(list);
2646 for (li = list->lv_first; li != NULL; 2650 for (li = list->lv_first; li != NULL;
2647 li = li->li_next) 2651 li = li->li_next)
2648 copy_tv(&li->li_tv, &pt->pt_argv[i++]); 2652 copy_tv(&li->li_tv, &pt->pt_argv[i++]);
2653 }
2649 } 2654 }
2650 2655
2651 // For "function(dict.func, [], dict)" and "func" is a partial 2656 // For "function(dict.func, [], dict)" and "func" is a partial
2652 // use "dict". That is backwards compatible. 2657 // use "dict". That is backwards compatible.
2653 if (dict_idx > 0) 2658 if (dict_idx > 0)
4056 } 4061 }
4057 4062
4058 l = argvars[0].vval.v_list; 4063 l = argvars[0].vval.v_list;
4059 if (l != NULL) 4064 if (l != NULL)
4060 { 4065 {
4066 range_list_materialize(l);
4061 item = l->lv_first; 4067 item = l->lv_first;
4062 if (argvars[2].v_type != VAR_UNKNOWN) 4068 if (argvars[2].v_type != VAR_UNKNOWN)
4063 { 4069 {
4064 // Start at specified item. Use the cached index that list_find() 4070 // Start at specified item. Use the cached index that list_find()
4065 // sets, so that a negative number also works. 4071 // sets, so that a negative number also works.
4137 * "inputlist()" function 4143 * "inputlist()" function
4138 */ 4144 */
4139 static void 4145 static void
4140 f_inputlist(typval_T *argvars, typval_T *rettv) 4146 f_inputlist(typval_T *argvars, typval_T *rettv)
4141 { 4147 {
4148 list_T *l;
4142 listitem_T *li; 4149 listitem_T *li;
4143 int selected; 4150 int selected;
4144 int mouse_used; 4151 int mouse_used;
4145 4152
4146 #ifdef NO_CONSOLE_INPUT 4153 #ifdef NO_CONSOLE_INPUT
4159 msg_row = Rows - 1; // for when 'cmdheight' > 1 4166 msg_row = Rows - 1; // for when 'cmdheight' > 1
4160 lines_left = Rows; // avoid more prompt 4167 lines_left = Rows; // avoid more prompt
4161 msg_scroll = TRUE; 4168 msg_scroll = TRUE;
4162 msg_clr_eos(); 4169 msg_clr_eos();
4163 4170
4164 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 4171 l = argvars[0].vval.v_list;
4172 range_list_materialize(l);
4173 for (li = l->lv_first; li != NULL; li = li->li_next)
4165 { 4174 {
4166 msg_puts((char *)tv_get_string(&li->li_tv)); 4175 msg_puts((char *)tv_get_string(&li->li_tv));
4167 msg_putchar('\n'); 4176 msg_putchar('\n');
4168 } 4177 }
4169 4178
4642 4651
4643 if (argvars[0].v_type == VAR_LIST) 4652 if (argvars[0].v_type == VAR_LIST)
4644 { 4653 {
4645 if ((l = argvars[0].vval.v_list) == NULL) 4654 if ((l = argvars[0].vval.v_list) == NULL)
4646 goto theend; 4655 goto theend;
4656 range_list_materialize(l);
4647 li = l->lv_first; 4657 li = l->lv_first;
4648 } 4658 }
4649 else 4659 else
4650 { 4660 {
4651 expr = str = tv_get_string(&argvars[0]); 4661 expr = str = tv_get_string(&argvars[0]);
4871 listitem_T *li; 4881 listitem_T *li;
4872 4882
4873 l = argvars[0].vval.v_list; 4883 l = argvars[0].vval.v_list;
4874 if (l != NULL) 4884 if (l != NULL)
4875 { 4885 {
4886 range_list_materialize(l);
4876 li = l->lv_first; 4887 li = l->lv_first;
4877 if (li != NULL) 4888 if (li != NULL)
4878 { 4889 {
4879 n = tv_get_number_chk(&li->li_tv, &error); 4890 n = tv_get_number_chk(&li->li_tv, &error);
4880 for (;;) 4891 for (;;)
5320 // be called. 5331 // be called.
5321 list->lv_first = &range_list_item; 5332 list->lv_first = &range_list_item;
5322 list->lv_start = start; 5333 list->lv_start = start;
5323 list->lv_end = end; 5334 list->lv_end = end;
5324 list->lv_stride = stride; 5335 list->lv_stride = stride;
5325 list->lv_len = (end - start + 1) / stride; 5336 list->lv_len = (end - start) / stride + 1;
5326 } 5337 }
5327 } 5338 }
5328 5339
5329 /* 5340 /*
5330 * If "list" is a non-materialized list then materialize it now. 5341 * If "list" is a non-materialized list then materialize it now.
6788 return; 6799 return;
6789 curval = lstval; 6800 curval = lstval;
6790 allocval = lstval + len + 2; 6801 allocval = lstval + len + 2;
6791 curallocval = allocval; 6802 curallocval = allocval;
6792 6803
6793 for (li = ll == NULL ? NULL : ll->lv_first; li != NULL; 6804 if (ll != NULL)
6794 li = li->li_next) 6805 {
6795 { 6806 range_list_materialize(ll);
6796 strval = tv_get_string_buf_chk(&li->li_tv, buf); 6807 for (li = ll->lv_first; li != NULL; li = li->li_next)
6797 if (strval == NULL)
6798 goto free_lstval;
6799 if (strval == buf)
6800 { 6808 {
6801 // Need to make a copy, next tv_get_string_buf_chk() will 6809 strval = tv_get_string_buf_chk(&li->li_tv, buf);
6802 // overwrite the string.
6803 strval = vim_strsave(buf);
6804 if (strval == NULL) 6810 if (strval == NULL)
6805 goto free_lstval; 6811 goto free_lstval;
6806 *curallocval++ = strval; 6812 if (strval == buf)
6813 {
6814 // Need to make a copy, next tv_get_string_buf_chk() will
6815 // overwrite the string.
6816 strval = vim_strsave(buf);
6817 if (strval == NULL)
6818 goto free_lstval;
6819 *curallocval++ = strval;
6820 }
6821 *curval++ = strval;
6807 } 6822 }
6808 *curval++ = strval;
6809 } 6823 }
6810 *curval++ = NULL; 6824 *curval++ = NULL;
6811 6825
6812 write_reg_contents_lst(regname, lstval, -1, 6826 write_reg_contents_lst(regname, lstval, -1,
6813 append, yank_type, block_len); 6827 append, yank_type, block_len);