aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Dewar <seandewar@users.noreply.github.com>2022-01-31 18:28:56 +0000
committerGitHub <noreply@github.com>2022-01-31 18:28:56 +0000
commitc00b844988ddbb5c0dc2ee2b6b4dbbc2901b5fbe (patch)
treee36add48e180e7be4756ae09d18549f3328867f5
parentbddce4b0ff0eb7ac1f652eea6fce81b3e2cc5044 (diff)
parent15c9d88bb70b8ee9bdcf3c6fe7debc01a1ee5f36 (diff)
downloadrneovim-c00b844988ddbb5c0dc2ee2b6b4dbbc2901b5fbe.tar.gz
rneovim-c00b844988ddbb5c0dc2ee2b6b4dbbc2901b5fbe.tar.bz2
rneovim-c00b844988ddbb5c0dc2ee2b6b4dbbc2901b5fbe.zip
Merge pull request #17231 from seandewar/vim-8.2.4245
vim-patch:8.2.4245: ":retab 0" may cause illegal memory access
-rw-r--r--src/nvim/buffer.c6
-rw-r--r--src/nvim/option.c27
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/testdir/test_options.vim2
4 files changed, 15 insertions, 22 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index eee5a0b46c..52a7db3be2 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1899,10 +1899,8 @@ void free_buf_options(buf_T *buf, int free_p_ff)
clear_string_option(&buf->b_p_flp);
clear_string_option(&buf->b_p_isk);
clear_string_option(&buf->b_p_vsts);
- xfree(buf->b_p_vsts_nopaste);
- buf->b_p_vsts_nopaste = NULL;
- xfree(buf->b_p_vsts_array);
- buf->b_p_vsts_array = NULL;
+ XFREE_CLEAR(buf->b_p_vsts_nopaste);
+ XFREE_CLEAR(buf->b_p_vsts_array);
clear_string_option(&buf->b_p_vts);
XFREE_CLEAR(buf->b_p_vts_array);
clear_string_option(&buf->b_p_keymap);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 2fb1966cda..80dde2eda6 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -3178,10 +3178,7 @@ ambw_end:
char_u *cp;
if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) {
- if (curbuf->b_p_vsts_array) {
- xfree(curbuf->b_p_vsts_array);
- curbuf->b_p_vsts_array = 0;
- }
+ XFREE_CLEAR(curbuf->b_p_vsts_array);
} else {
for (cp = *varp; *cp; cp++) {
if (ascii_isdigit(*cp)) {
@@ -3206,10 +3203,7 @@ ambw_end:
char_u *cp;
if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) {
- if (curbuf->b_p_vts_array) {
- xfree(curbuf->b_p_vts_array);
- curbuf->b_p_vts_array = NULL;
- }
+ XFREE_CLEAR(curbuf->b_p_vts_array);
} else {
for (cp = *varp; *cp; cp++) {
if (ascii_isdigit(*cp)) {
@@ -4420,6 +4414,8 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf,
} else if (pp == &curbuf->b_p_ts || pp == &p_ts) {
if (value < 1) {
errmsg = e_positive;
+ } else if (value > TABSTOP_MAX) {
+ errmsg = e_invarg;
}
} else if (pp == &curbuf->b_p_tw || pp == &p_tw) {
if (value < 0) {
@@ -6416,7 +6412,7 @@ void buf_copy_options(buf_T *buf, int flags)
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_array = NULL;
}
buf->b_p_vsts_nopaste = p_vsts_nopaste
? vim_strsave(p_vsts_nopaste)
@@ -7153,10 +7149,7 @@ static void paste_option_changed(void)
free_string_option(buf->b_p_vsts);
}
buf->b_p_vsts = empty_option;
- if (buf->b_p_vsts_array) {
- xfree(buf->b_p_vsts_array);
- }
- buf->b_p_vsts_array = 0;
+ XFREE_CLEAR(buf->b_p_vsts_array);
}
// set global options
@@ -7193,13 +7186,11 @@ static void paste_option_changed(void)
buf->b_p_vsts = buf->b_p_vsts_nopaste
? vim_strsave(buf->b_p_vsts_nopaste)
: empty_option;
- if (buf->b_p_vsts_array) {
- xfree(buf->b_p_vsts_array);
- }
+ xfree(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;
+ buf->b_p_vsts_array = NULL;
}
}
@@ -7560,7 +7551,7 @@ bool tabstop_set(char_u *var, long **array)
int n = atoi((char *)cp);
// Catch negative values, overflow and ridiculous big values.
- if (n < 0 || n > 9999) {
+ if (n < 0 || n > TABSTOP_MAX) {
semsg(_(e_invarg2), cp);
XFREE_CLEAR(*array);
return false;
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 5d6aca9574..d88cd6b9b9 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -903,6 +903,8 @@ enum {
#define SB_MAX 100000 // Maximum 'scrollback' value.
+#define TABSTOP_MAX 9999
+
/// Stores an identifier of a script or channel that last set an option.
typedef struct {
sctx_T script_ctx; /// script context where the option was last set
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 2312df5450..f7bfa48943 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -259,6 +259,8 @@ func Test_set_errors()
call assert_fails('set shiftwidth=-1', 'E487:')
call assert_fails('set sidescroll=-1', 'E487:')
call assert_fails('set tabstop=-1', 'E487:')
+ call assert_fails('set tabstop=10000', 'E474:')
+ call assert_fails('set tabstop=5500000000', 'E474:')
call assert_fails('set textwidth=-1', 'E487:')
call assert_fails('set timeoutlen=-1', 'E487:')
call assert_fails('set updatecount=-1', 'E487:')