]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1079: leaking memory when defining a user command fails v9.0.1079
authorzeertzjq <zeertzjq@outlook.com>
Mon, 19 Dec 2022 16:49:27 +0000 (16:49 +0000)
committerBram Moolenaar <Bram@vim.org>
Mon, 19 Dec 2022 16:49:27 +0000 (16:49 +0000)
Problem:    Leaking memory when defining a user command fails.
Solution:   Free "compl_arg" when needed. (closes #11726)

src/testdir/test_usercommands.vim
src/usercmd.c
src/version.c

index 57953ced8a22d71ed279539dad16930b8326ef4c..d8b4cb40e0ef4822d6b67bed23611165afc2db7a 100644 (file)
@@ -342,6 +342,11 @@ func Test_CmdErrors()
   call assert_fails('com DoCmd :', 'E174:')
   comclear
   call assert_fails('delcom DoCmd', 'E184:')
+
+  " These used to leak memory
+  call assert_fails('com! -complete=custom,CustomComplete _ :', 'E182:')
+  call assert_fails('com! -complete=custom,CustomComplete docmd :', 'E183:')
+  call assert_fails('com! -complete=custom,CustomComplete -xxx DoCmd :', 'E181:')
 endfunc
 
 func CustomComplete(A, L, P)
index d8783321d8a914aa7c33c4d7d49c1f635fe07dd1..3bd6fd536ff09cd080da69afe65b8d6178b42dea 100644 (file)
@@ -1167,7 +1167,7 @@ ex_command(exarg_T *eap)
        end = skiptowhite(p);
        if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl,
                                           &compl_arg, &addr_type_arg) == FAIL)
-           return;
+           goto theend;
        p = skipwhite(end);
     }
 
@@ -1179,7 +1179,7 @@ ex_command(exarg_T *eap)
     if (!ends_excmd2(eap->arg, p) && !VIM_ISWHITE(*p))
     {
        emsg(_(e_invalid_command_name));
-       return;
+       goto theend;
     }
     end = p;
     name_len = (int)(end - name);
@@ -1188,13 +1188,19 @@ ex_command(exarg_T *eap)
     // we are listing commands
     p = skipwhite(end);
     if (!has_attr && ends_excmd2(eap->arg, p))
+    {
        uc_list(name, end - name);
+    }
     else if (!ASCII_ISUPPER(*name))
+    {
        emsg(_(e_user_defined_commands_must_start_with_an_uppercase_letter));
+    }
     else if ((name_len == 1 && *name == 'X')
          || (name_len <= 4
                  && STRNCMP(name, "Next", name_len > 4 ? 4 : name_len) == 0))
+    {
        emsg(_(e_reserved_name_cannot_be_used_for_user_defined_command));
+    }
     else if (compl > 0 && (argt & EX_EXTRA) == 0)
     {
        // Some plugins rely on silently ignoring the mistake, only make this
@@ -1215,7 +1221,12 @@ ex_command(exarg_T *eap)
        uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
                                                  addr_type_arg, eap->forceit);
        vim_free(tofree);
+
+       return;  // success
     }
+
+theend:
+    vim_free(compl_arg);
 }
 
 /*
index 1ce40429597ffdc2de4c4da4d705e947f1d392d9..401d78bd3b8578aaee1b1da672ca3d73c97d1067 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1079,
 /**/
     1078,
 /**/