]> granicus.if.org Git - vim/commitdiff
patch 8.2.3402: invalid memory access when using :retab with large value v8.2.3402
authorBram Moolenaar <Bram@vim.org>
Sat, 4 Sep 2021 16:47:28 +0000 (18:47 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 4 Sep 2021 16:47:28 +0000 (18:47 +0200)
Problem:    Invalid memory access when using :retab with large value.
Solution:   Check the number is positive.

src/indent.c
src/option.c
src/optionstr.c
src/testdir/test_retab.vim
src/version.c

index f4c398219a40aa7f653a5e2da5e90d13c5c64072..cd03f25d25842e86cdce8fe1fa0ddfb1a72303f5 100644 (file)
 /*
  * Set the integer values corresponding to the string setting of 'vartabstop'.
  * "array" will be set, caller must free it if needed.
+ * Return FAIL for an error.
  */
     int
 tabstop_set(char_u *var, int **array)
 {
-    int valcount = 1;
-    int t;
-    char_u *cp;
+    int            valcount = 1;
+    int            t;
+    char_u  *cp;
 
     if (var[0] == NUL || (var[0] == '0' && var[1] == NUL))
     {
        *array = NULL;
-       return TRUE;
+       return OK;
     }
 
     for (cp = var; *cp != NUL; ++cp)
@@ -43,8 +44,8 @@ tabstop_set(char_u *var, int **array)
                if (cp != end)
                    emsg(_(e_positive));
                else
-                   emsg(_(e_invarg));
-               return FALSE;
+                   semsg(_(e_invarg2), cp);
+               return FAIL;
            }
        }
 
@@ -55,26 +56,33 @@ tabstop_set(char_u *var, int **array)
            ++valcount;
            continue;
        }
-       emsg(_(e_invarg));
-       return FALSE;
+       semsg(_(e_invarg2), var);
+       return FAIL;
     }
 
     *array = ALLOC_MULT(int, valcount + 1);
     if (*array == NULL)
-       return FALSE;
+       return FAIL;
     (*array)[0] = valcount;
 
     t = 1;
     for (cp = var; *cp != NUL;)
     {
-       (*array)[t++] = atoi((char *)cp);
-       while (*cp  != NUL && *cp != ',')
+       int n = atoi((char *)cp);
+
+       if (n < 0 || n > 9999)
+       {
+           semsg(_(e_invarg2), cp);
+           return FAIL;
+       }
+       (*array)[t++] = n;
+       while (*cp != NUL && *cp != ',')
            ++cp;
        if (*cp != NUL)
            ++cp;
     }
 
-    return TRUE;
+    return OK;
 }
 
 /*
@@ -1591,7 +1599,7 @@ ex_retab(exarg_T *eap)
 
 #ifdef FEAT_VARTABS
     new_ts_str = eap->arg;
-    if (!tabstop_set(eap->arg, &new_vts_array))
+    if (tabstop_set(eap->arg, &new_vts_array) == FAIL)
        return;
     while (vim_isdigit(*(eap->arg)) || *(eap->arg) == ',')
        ++(eap->arg);
index 4e0e5a6ac6acd306f76288b945e1e2a59cf96f9e..124f76bbf7509fbf7fb4c80c1fabf85cdc7df39a 100644 (file)
@@ -2449,9 +2449,9 @@ didset_options2(void)
 #endif
 #ifdef FEAT_VARTABS
     vim_free(curbuf->b_p_vsts_array);
-    tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
+    (void)tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array);
     vim_free(curbuf->b_p_vts_array);
-    tabstop_set(curbuf->b_p_vts,  &curbuf->b_p_vts_array);
+    (void)tabstop_set(curbuf->b_p_vts,  &curbuf->b_p_vts_array);
 #endif
 }
 
@@ -5947,7 +5947,7 @@ buf_copy_options(buf_T *buf, int flags)
            buf->b_p_vsts = vim_strsave(p_vsts);
            COPY_OPT_SCTX(buf, BV_VSTS);
            if (p_vsts && p_vsts != empty_option)
-               tabstop_set(p_vsts, &buf->b_p_vsts_array);
+               (void)tabstop_set(p_vsts, &buf->b_p_vsts_array);
            else
                buf->b_p_vsts_array = 0;
            buf->b_p_vsts_nopaste = p_vsts_nopaste
@@ -6107,7 +6107,7 @@ buf_copy_options(buf_T *buf, int flags)
                buf->b_p_isk = save_p_isk;
 #ifdef FEAT_VARTABS
                if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
-                   tabstop_set(p_vts, &buf->b_p_vts_array);
+                   (void)tabstop_set(p_vts, &buf->b_p_vts_array);
                else
                    buf->b_p_vts_array = NULL;
 #endif
@@ -6122,7 +6122,7 @@ buf_copy_options(buf_T *buf, int flags)
                buf->b_p_vts = vim_strsave(p_vts);
                COPY_OPT_SCTX(buf, BV_VTS);
                if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
-                   tabstop_set(p_vts, &buf->b_p_vts_array);
+                   (void)tabstop_set(p_vts, &buf->b_p_vts_array);
                else
                    buf->b_p_vts_array = NULL;
 #endif
@@ -6818,7 +6818,7 @@ paste_option_changed(void)
            if (buf->b_p_vsts_array)
                vim_free(buf->b_p_vsts_array);
            if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
-               tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
+               (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
            else
                buf->b_p_vsts_array = 0;
 #endif
index a394d8d06f6c322ce021ad14e1fa7d3cc4bf39c6..ff1321881a06bec4cf2ebd4e4e35b5216a300cac 100644 (file)
@@ -2240,7 +2240,7 @@ ambw_end:
            if (errmsg == NULL)
            {
                int *oldarray = curbuf->b_p_vsts_array;
-               if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)))
+               if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)) == OK)
                {
                    if (oldarray)
                        vim_free(oldarray);
@@ -2279,7 +2279,7 @@ ambw_end:
            {
                int *oldarray = curbuf->b_p_vts_array;
 
-               if (tabstop_set(*varp, &(curbuf->b_p_vts_array)))
+               if (tabstop_set(*varp, &(curbuf->b_p_vts_array)) == OK)
                {
                    vim_free(oldarray);
 #ifdef FEAT_FOLDING
index b792da514eb59887905939f91b78c4e16b025ee3..c7190aaa6699d9119de84a6ee79908f63622e39d 100644 (file)
@@ -75,6 +75,9 @@ endfunc
 func Test_retab_error()
   call assert_fails('retab -1',  'E487:')
   call assert_fails('retab! -1', 'E487:')
+  call assert_fails('ret -1000', 'E487:')
+  call assert_fails('ret 10000', 'E475:')
+  call assert_fails('ret 80000000000000000000', 'E475:')
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
index 8f502cc9c63d3cbaae9820c34d116f6ecaf7eb84..a5e931cfad1fd8d694c63f70473c6e628ae8eb29 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3402,
 /**/
     3401,
 /**/