]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0870: too many strlen() calls in eval.c v9.1.0870
authorJohn Marriott <basilisk@internode.on.net>
Mon, 18 Nov 2024 19:25:21 +0000 (20:25 +0100)
committerChristian Brabandt <cb@256bit.org>
Mon, 18 Nov 2024 19:26:13 +0000 (20:26 +0100)
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 <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/eval.c
src/evalfunc.c
src/filepath.c
src/proto/eval.pro
src/version.c

index cc289b4535e3c0f52c698c0e10af613c235aef68..fabe9643c3b06dcedd7c320b9a1ebf12c34b6279 100644 (file)
@@ -375,14 +375,12 @@ eval_expr_typval(
 {
     if (expr->v_type == VAR_PARTIAL)
        return eval_expr_partial(expr, argv, argc, fc_arg, rettv);
-    else if (expr->v_type == VAR_INSTR)
+    if (expr->v_type == VAR_INSTR)
        return exe_typval_instr(expr, rettv);
-    else if (expr->v_type == VAR_FUNC || want_func)
+    if (expr->v_type == VAR_FUNC || want_func)
        return eval_expr_func(expr, argv, argc, rettv);
-    else
-       return eval_expr_string(expr, rettv);
 
-    return OK;
+    return eval_expr_string(expr, rettv);
 }
 
 /*
@@ -2248,7 +2246,7 @@ set_var_lval(
 
            // handle +=, -=, *=, /=, %= and .=
            di = NULL;
-           if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
+           if (eval_variable(lp->ll_name, (int)(lp->ll_name_end - lp->ll_name),
                                 lp->ll_sid, &tv, &di, EVAL_VAR_VERBOSE) == OK)
            {
                if (di != NULL && check_typval_is_value(&di->di_tv) == FAIL)
@@ -6153,18 +6151,33 @@ jobchan_tv2string(
 class_tv2string(typval_T *tv, char_u **tofree)
 {
     char_u     *r = NULL;
+    size_t     rsize;
     class_T    *cl = tv->vval.v_class;
+    char_u     *class_name = (char_u *)"[unknown]";
+    size_t     class_namelen = 9;
     char       *s = "class";
+    size_t     slen = 5;
+
+    if (cl != NULL)
+    {
+       class_name = cl->class_name;
+       class_namelen = STRLEN(cl->class_name);
+       if (IS_INTERFACE(cl))
+       {
+           s = "interface";
+           slen = 9;
+       }
+       else if (IS_ENUM(cl))
+       {
+           s = "enum";
+           slen = 4;
+       }
+    }
 
-    if (cl != NULL && IS_INTERFACE(cl))
-       s = "interface";
-    else if (cl != NULL && IS_ENUM(cl))
-       s = "enum";
-    size_t len = STRLEN(s) + 1 +
-                               (cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
-    r = *tofree = alloc(len);
-    vim_snprintf((char *)r, len, "%s %s", s,
-                       cl == NULL ? "[unknown]" : (char *)cl->class_name);
+    rsize = slen + 1 + class_namelen + 1;
+    r = *tofree = alloc(rsize);
+    if (r != NULL)
+       vim_snprintf((char *)r, rsize, "%s %s", s, (char *)class_name);
 
     return r;
 }
@@ -6197,7 +6210,7 @@ object_tv2string(
     else if (copyID != 0 && obj->obj_copyID == copyID
            && obj->obj_class->class_obj_member_count != 0)
     {
-       size_t n = 25 + strlen((char *)obj->obj_class->class_name);
+       size_t n = 25 + STRLEN((char *)obj->obj_class->class_name);
        r = alloc(n);
        if (r != NULL)
            (void)vim_snprintf((char *)r, n, "object of %s {...}",
@@ -6911,14 +6924,14 @@ make_expanded_name(
     temp_result = eval_to_string(expr_start + 1, FALSE, FALSE);
     if (temp_result != NULL)
     {
-       retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
-                                                  + (in_end - expr_end) + 1);
+       size_t  retvalsize = (size_t)(expr_start - in_start)
+                               + STRLEN(temp_result)
+                               + (size_t)(in_end - expr_end) + 1;
+
+       retval = alloc(retvalsize);
        if (retval != NULL)
-       {
-           STRCPY(retval, in_start);
-           STRCAT(retval, temp_result);
-           STRCAT(retval, expr_end + 1);
-       }
+           vim_snprintf((char *)retval, retvalsize, "%s%s%s",
+                               in_start, temp_result, expr_end + 1);
     }
     vim_free(temp_result);
 
@@ -7610,21 +7623,17 @@ last_set_msg(sctx_T script_ctx)
     char_u *
 do_string_sub(
     char_u     *str,
+    size_t     len,
     char_u     *pat,
     char_u     *sub,
     typval_T   *expr,
-    char_u     *flags)
+    char_u     *flags,
+    size_t     *ret_len)               // length of returned buffer
 {
-    int                sublen;
     regmatch_T regmatch;
-    int                i;
-    int                do_all;
-    char_u     *tail;
-    char_u     *end;
     garray_T   ga;
     char_u     *ret;
     char_u     *save_cpo;
-    char_u     *zero_width = NULL;
 
     // Make 'cpoptions' empty, so that the 'l' flag doesn't work here
     save_cpo = p_cpo;
@@ -7632,14 +7641,17 @@ do_string_sub(
 
     ga_init2(&ga, 1, 200);
 
-    do_all = (flags[0] == 'g');
-
     regmatch.rm_ic = p_ic;
     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
     if (regmatch.regprog != NULL)
     {
-       tail = str;
-       end = str + STRLEN(str);
+       char_u  *tail = str;
+       char_u  *end = str + len;
+       int     do_all = (flags[0] == 'g');
+       int     sublen;
+       int     i;
+       char_u  *zero_width = NULL;
+
        while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
        {
            // Skip empty match except for first match.
@@ -7694,12 +7706,20 @@ do_string_sub(
        }
 
        if (ga.ga_data != NULL)
+       {
            STRCPY((char *)ga.ga_data + ga.ga_len, tail);
+           ga.ga_len += (int)(end - tail);
+       }
 
        vim_regfree(regmatch.regprog);
     }
 
-    ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
+    if (ga.ga_data != NULL)
+    {
+       str = (char_u *)ga.ga_data;
+       len = (size_t)ga.ga_len;
+    }
+    ret = vim_strnsave(str, len);
     ga_clear(&ga);
     if (p_cpo == empty_option)
        p_cpo = save_cpo;
@@ -7713,5 +7733,8 @@ do_string_sub(
        free_string_option(save_cpo);
     }
 
+    if (ret_len != NULL)
+       *ret_len = len;
+
     return ret;
 }
index 04967efc323103a66396c9d8cb45a89b5133bcf8..12f7a88b00fe994b8edc724ddfb8a199ce1194ba 100644 (file)
@@ -11489,7 +11489,7 @@ f_substitute(typval_T *argvars, typval_T *rettv)
                                                                || flg == NULL)
        rettv->vval.v_string = NULL;
     else
-       rettv->vval.v_string = do_string_sub(str, pat, sub, expr, flg);
+       rettv->vval.v_string = do_string_sub(str, STRLEN(str), pat, sub, expr, flg, NULL);
 }
 
 /*
index d514aaf8efedabdfc2c2ae5ab8e35b91f0f2a28a..3dd71bc407e92b253b9146286e71ad45156496af 100644 (file)
@@ -668,12 +668,14 @@ repeat:
                        str = vim_strnsave(*fnamep, *fnamelen);
                        if (sub != NULL && str != NULL)
                        {
+                           size_t slen;
+
                            *usedlen = p + 1 - src;
-                           s = do_string_sub(str, pat, sub, NULL, flags);
+                           s = do_string_sub(str, *fnamelen, pat, sub, NULL, flags, &slen);
                            if (s != NULL)
                            {
                                *fnamep = s;
-                               *fnamelen = (int)STRLEN(s);
+                               *fnamelen = slen;
                                vim_free(*bufp);
                                *bufp = s;
                                didit = TRUE;
index 7247265aa11af253a19e1222f88cbf4e756da3c0..e945a284cc678cf396bfa67971e8383f96b112c4 100644 (file)
@@ -73,5 +73,5 @@ int get_echo_attr(void);
 void ex_execute(exarg_T *eap);
 char_u *find_option_end(char_u **arg, int *scope);
 void last_set_msg(sctx_T script_ctx);
-char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
+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);
 /* vim: set ft=c : */
index 3ccae20d7bb2612d21807430a67ffb1eafde4ade..ce6c38a327f3448ef33361630784a41cc7fb80eb 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    870,
 /**/
     869,
 /**/