Skip to content

Commit bd4614f

Browse files
John Marriottchrisbra
authored andcommitted
patch 9.1.0870: too many strlen() calls in eval.c
Problem: too many strlen() calls in eval.c Solution: Refactor eval.c to remove calls to STRLEN() (John Marriott) closes: #16066 Signed-off-by: John Marriott <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent ba9e157 commit bd4614f

5 files changed

Lines changed: 66 additions & 39 deletions

File tree

src/eval.c

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -375,14 +375,12 @@ eval_expr_typval(
375375
{
376376
if (expr->v_type == VAR_PARTIAL)
377377
return eval_expr_partial(expr, argv, argc, fc_arg, rettv);
378-
else if (expr->v_type == VAR_INSTR)
378+
if (expr->v_type == VAR_INSTR)
379379
return exe_typval_instr(expr, rettv);
380-
else if (expr->v_type == VAR_FUNC || want_func)
380+
if (expr->v_type == VAR_FUNC || want_func)
381381
return eval_expr_func(expr, argv, argc, rettv);
382-
else
383-
return eval_expr_string(expr, rettv);
384382

385-
return OK;
383+
return eval_expr_string(expr, rettv);
386384
}
387385

388386
/*
@@ -2248,7 +2246,7 @@ set_var_lval(
22482246

22492247
// handle +=, -=, *=, /=, %= and .=
22502248
di = NULL;
2251-
if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
2249+
if (eval_variable(lp->ll_name, (int)(lp->ll_name_end - lp->ll_name),
22522250
lp->ll_sid, &tv, &di, EVAL_VAR_VERBOSE) == OK)
22532251
{
22542252
if (di != NULL && check_typval_is_value(&di->di_tv) == FAIL)
@@ -6153,18 +6151,33 @@ jobchan_tv2string(
61536151
class_tv2string(typval_T *tv, char_u **tofree)
61546152
{
61556153
char_u *r = NULL;
6154+
size_t rsize;
61566155
class_T *cl = tv->vval.v_class;
6156+
char_u *class_name = (char_u *)"[unknown]";
6157+
size_t class_namelen = 9;
61576158
char *s = "class";
6159+
size_t slen = 5;
6160+
6161+
if (cl != NULL)
6162+
{
6163+
class_name = cl->class_name;
6164+
class_namelen = STRLEN(cl->class_name);
6165+
if (IS_INTERFACE(cl))
6166+
{
6167+
s = "interface";
6168+
slen = 9;
6169+
}
6170+
else if (IS_ENUM(cl))
6171+
{
6172+
s = "enum";
6173+
slen = 4;
6174+
}
6175+
}
61586176

6159-
if (cl != NULL && IS_INTERFACE(cl))
6160-
s = "interface";
6161-
else if (cl != NULL && IS_ENUM(cl))
6162-
s = "enum";
6163-
size_t len = STRLEN(s) + 1 +
6164-
(cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
6165-
r = *tofree = alloc(len);
6166-
vim_snprintf((char *)r, len, "%s %s", s,
6167-
cl == NULL ? "[unknown]" : (char *)cl->class_name);
6177+
rsize = slen + 1 + class_namelen + 1;
6178+
r = *tofree = alloc(rsize);
6179+
if (r != NULL)
6180+
vim_snprintf((char *)r, rsize, "%s %s", s, (char *)class_name);
61686181

61696182
return r;
61706183
}
@@ -6197,7 +6210,7 @@ object_tv2string(
61976210
else if (copyID != 0 && obj->obj_copyID == copyID
61986211
&& obj->obj_class->class_obj_member_count != 0)
61996212
{
6200-
size_t n = 25 + strlen((char *)obj->obj_class->class_name);
6213+
size_t n = 25 + STRLEN((char *)obj->obj_class->class_name);
62016214
r = alloc(n);
62026215
if (r != NULL)
62036216
(void)vim_snprintf((char *)r, n, "object of %s {...}",
@@ -6911,14 +6924,14 @@ make_expanded_name(
69116924
temp_result = eval_to_string(expr_start + 1, FALSE, FALSE);
69126925
if (temp_result != NULL)
69136926
{
6914-
retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
6915-
+ (in_end - expr_end) + 1);
6927+
size_t retvalsize = (size_t)(expr_start - in_start)
6928+
+ STRLEN(temp_result)
6929+
+ (size_t)(in_end - expr_end) + 1;
6930+
6931+
retval = alloc(retvalsize);
69166932
if (retval != NULL)
6917-
{
6918-
STRCPY(retval, in_start);
6919-
STRCAT(retval, temp_result);
6920-
STRCAT(retval, expr_end + 1);
6921-
}
6933+
vim_snprintf((char *)retval, retvalsize, "%s%s%s",
6934+
in_start, temp_result, expr_end + 1);
69226935
}
69236936
vim_free(temp_result);
69246937

@@ -7610,36 +7623,35 @@ last_set_msg(sctx_T script_ctx)
76107623
char_u *
76117624
do_string_sub(
76127625
char_u *str,
7626+
size_t len,
76137627
char_u *pat,
76147628
char_u *sub,
76157629
typval_T *expr,
7616-
char_u *flags)
7630+
char_u *flags,
7631+
size_t *ret_len) // length of returned buffer
76177632
{
7618-
int sublen;
76197633
regmatch_T regmatch;
7620-
int i;
7621-
int do_all;
7622-
char_u *tail;
7623-
char_u *end;
76247634
garray_T ga;
76257635
char_u *ret;
76267636
char_u *save_cpo;
7627-
char_u *zero_width = NULL;
76287637

76297638
// Make 'cpoptions' empty, so that the 'l' flag doesn't work here
76307639
save_cpo = p_cpo;
76317640
p_cpo = empty_option;
76327641

76337642
ga_init2(&ga, 1, 200);
76347643

7635-
do_all = (flags[0] == 'g');
7636-
76377644
regmatch.rm_ic = p_ic;
76387645
regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
76397646
if (regmatch.regprog != NULL)
76407647
{
7641-
tail = str;
7642-
end = str + STRLEN(str);
7648+
char_u *tail = str;
7649+
char_u *end = str + len;
7650+
int do_all = (flags[0] == 'g');
7651+
int sublen;
7652+
int i;
7653+
char_u *zero_width = NULL;
7654+
76437655
while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
76447656
{
76457657
// Skip empty match except for first match.
@@ -7694,12 +7706,20 @@ do_string_sub(
76947706
}
76957707

76967708
if (ga.ga_data != NULL)
7709+
{
76977710
STRCPY((char *)ga.ga_data + ga.ga_len, tail);
7711+
ga.ga_len += (int)(end - tail);
7712+
}
76987713

76997714
vim_regfree(regmatch.regprog);
77007715
}
77017716

7702-
ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
7717+
if (ga.ga_data != NULL)
7718+
{
7719+
str = (char_u *)ga.ga_data;
7720+
len = (size_t)ga.ga_len;
7721+
}
7722+
ret = vim_strnsave(str, len);
77037723
ga_clear(&ga);
77047724
if (p_cpo == empty_option)
77057725
p_cpo = save_cpo;
@@ -7713,5 +7733,8 @@ do_string_sub(
77137733
free_string_option(save_cpo);
77147734
}
77157735

7736+
if (ret_len != NULL)
7737+
*ret_len = len;
7738+
77167739
return ret;
77177740
}

src/evalfunc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11489,7 +11489,7 @@ f_substitute(typval_T *argvars, typval_T *rettv)
1148911489
|| flg == NULL)
1149011490
rettv->vval.v_string = NULL;
1149111491
else
11492-
rettv->vval.v_string = do_string_sub(str, pat, sub, expr, flg);
11492+
rettv->vval.v_string = do_string_sub(str, STRLEN(str), pat, sub, expr, flg, NULL);
1149311493
}
1149411494

1149511495
/*

src/filepath.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,12 +668,14 @@ modify_fname(
668668
str = vim_strnsave(*fnamep, *fnamelen);
669669
if (sub != NULL && str != NULL)
670670
{
671+
size_t slen;
672+
671673
*usedlen = p + 1 - src;
672-
s = do_string_sub(str, pat, sub, NULL, flags);
674+
s = do_string_sub(str, *fnamelen, pat, sub, NULL, flags, &slen);
673675
if (s != NULL)
674676
{
675677
*fnamep = s;
676-
*fnamelen = (int)STRLEN(s);
678+
*fnamelen = slen;
677679
vim_free(*bufp);
678680
*bufp = s;
679681
didit = TRUE;

src/proto/eval.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,5 @@ int get_echo_attr(void);
7373
void ex_execute(exarg_T *eap);
7474
char_u *find_option_end(char_u **arg, int *scope);
7575
void last_set_msg(sctx_T script_ctx);
76-
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
76+
char_u *do_string_sub(char_u *str, size_t str_len, char_u *pat, char_u *sub, typval_T *expr, char_u *flags, size_t *ret_len);
7777
/* vim: set ft=c : */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ static char *(features[]) =
704704

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
870,
707709
/**/
708710
869,
709711
/**/

0 commit comments

Comments
 (0)