To: vim_dev@googlegroups.com Subject: Patch 8.2.3402 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3402 Problem: Invalid memory access when using :retab with large value. Solution: Check the number is positive. Files: src/indent.c, src/option.c, src/optionstr.c, src/testdir/test_retab.vim *** ../vim-8.2.3401/src/indent.c 2021-08-29 22:12:50.230287220 +0200 --- src/indent.c 2021-09-04 18:41:52.357535428 +0200 *************** *** 18,35 **** /* * Set the integer values corresponding to the string setting of 'vartabstop'. * "array" will be set, caller must free it if needed. */ int tabstop_set(char_u *var, int **array) { ! int valcount = 1; ! int t; ! char_u *cp; if (var[0] == NUL || (var[0] == '0' && var[1] == NUL)) { *array = NULL; ! return TRUE; } for (cp = var; *cp != NUL; ++cp) --- 18,36 ---- /* * 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; if (var[0] == NUL || (var[0] == '0' && var[1] == NUL)) { *array = NULL; ! return OK; } for (cp = var; *cp != NUL; ++cp) *************** *** 43,50 **** if (cp != end) emsg(_(e_positive)); else ! emsg(_(e_invarg)); ! return FALSE; } } --- 44,51 ---- if (cp != end) emsg(_(e_positive)); else ! semsg(_(e_invarg2), cp); ! return FAIL; } } *************** *** 55,80 **** ++valcount; continue; } ! emsg(_(e_invarg)); ! return FALSE; } *array = ALLOC_MULT(int, valcount + 1); if (*array == NULL) ! return FALSE; (*array)[0] = valcount; t = 1; for (cp = var; *cp != NUL;) { ! (*array)[t++] = atoi((char *)cp); ! while (*cp != NUL && *cp != ',') ++cp; if (*cp != NUL) ++cp; } ! return TRUE; } /* --- 56,88 ---- ++valcount; continue; } ! semsg(_(e_invarg2), var); ! return FAIL; } *array = ALLOC_MULT(int, valcount + 1); if (*array == NULL) ! return FAIL; (*array)[0] = valcount; t = 1; for (cp = var; *cp != NUL;) { ! 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 OK; } /* *************** *** 1591,1597 **** #ifdef FEAT_VARTABS new_ts_str = eap->arg; ! if (!tabstop_set(eap->arg, &new_vts_array)) return; while (vim_isdigit(*(eap->arg)) || *(eap->arg) == ',') ++(eap->arg); --- 1599,1605 ---- #ifdef FEAT_VARTABS new_ts_str = eap->arg; ! if (tabstop_set(eap->arg, &new_vts_array) == FAIL) return; while (vim_isdigit(*(eap->arg)) || *(eap->arg) == ',') ++(eap->arg); *** ../vim-8.2.3401/src/option.c 2021-08-03 18:33:04.651157866 +0200 --- src/option.c 2021-09-04 18:42:42.481427059 +0200 *************** *** 2449,2457 **** #endif #ifdef FEAT_VARTABS vim_free(curbuf->b_p_vsts_array); ! 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); #endif } --- 2449,2457 ---- #endif #ifdef FEAT_VARTABS vim_free(curbuf->b_p_vsts_array); ! (void)tabstop_set(curbuf->b_p_vsts, &curbuf->b_p_vsts_array); vim_free(curbuf->b_p_vts_array); ! (void)tabstop_set(curbuf->b_p_vts, &curbuf->b_p_vts_array); #endif } *************** *** 5947,5953 **** 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); else buf->b_p_vsts_array = 0; buf->b_p_vsts_nopaste = p_vsts_nopaste --- 5947,5953 ---- buf->b_p_vsts = vim_strsave(p_vsts); COPY_OPT_SCTX(buf, BV_VSTS); if (p_vsts && p_vsts != empty_option) ! (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,6113 **** 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); else buf->b_p_vts_array = NULL; #endif --- 6107,6113 ---- buf->b_p_isk = save_p_isk; #ifdef FEAT_VARTABS if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) ! (void)tabstop_set(p_vts, &buf->b_p_vts_array); else buf->b_p_vts_array = NULL; #endif *************** *** 6122,6128 **** 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); else buf->b_p_vts_array = NULL; #endif --- 6122,6128 ---- 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) ! (void)tabstop_set(p_vts, &buf->b_p_vts_array); else buf->b_p_vts_array = NULL; #endif *************** *** 6818,6824 **** 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); else buf->b_p_vsts_array = 0; #endif --- 6818,6824 ---- if (buf->b_p_vsts_array) vim_free(buf->b_p_vsts_array); if (buf->b_p_vsts && buf->b_p_vsts != empty_option) ! (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array); else buf->b_p_vsts_array = 0; #endif *** ../vim-8.2.3401/src/optionstr.c 2021-08-03 18:33:04.651157866 +0200 --- src/optionstr.c 2021-09-04 18:43:12.277362595 +0200 *************** *** 2240,2246 **** if (errmsg == NULL) { int *oldarray = curbuf->b_p_vsts_array; ! if (tabstop_set(*varp, &(curbuf->b_p_vsts_array))) { if (oldarray) vim_free(oldarray); --- 2240,2246 ---- if (errmsg == NULL) { int *oldarray = curbuf->b_p_vsts_array; ! if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)) == OK) { if (oldarray) vim_free(oldarray); *************** *** 2279,2285 **** { int *oldarray = curbuf->b_p_vts_array; ! if (tabstop_set(*varp, &(curbuf->b_p_vts_array))) { vim_free(oldarray); #ifdef FEAT_FOLDING --- 2279,2285 ---- { int *oldarray = curbuf->b_p_vts_array; ! if (tabstop_set(*varp, &(curbuf->b_p_vts_array)) == OK) { vim_free(oldarray); #ifdef FEAT_FOLDING *** ../vim-8.2.3401/src/testdir/test_retab.vim 2020-08-12 18:50:31.883655785 +0200 --- src/testdir/test_retab.vim 2021-09-04 18:47:01.832735304 +0200 *************** *** 75,80 **** --- 75,83 ---- 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 *** ../vim-8.2.3401/src/version.c 2021-09-04 14:49:52.467212124 +0200 --- src/version.c 2021-09-04 18:33:40.470590687 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3402, /**/ -- Engineers are widely recognized as superior marriage material: intelligent, dependable, employed, honest, and handy around the house. (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///