diff options
-rw-r--r-- | src/nvim/cmdhist.c | 8 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 12 | ||||
-rw-r--r-- | test/old/testdir/test_history.vim | 8 |
3 files changed, 26 insertions, 2 deletions
diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c index b0490670fe..f1c57c4613 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -34,6 +34,8 @@ # include "cmdhist.c.generated.h" #endif +static const char e_val_too_large[] = N_("E1510: Value too large: %s"); + static histentry_T *(history[HIST_COUNT]) = { NULL, NULL, NULL, NULL, NULL }; static int hisidx[HIST_COUNT] = { -1, -1, -1, -1, -1 }; ///< lastused entry /// identifying (unique) number of newest history entry @@ -637,7 +639,11 @@ void ex_history(exarg_T *eap) end = arg; } if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL) { - semsg(_(e_trailing_arg), end); + if (*end != NUL) { + semsg(_(e_trailing_arg), end); + } else { + semsg(_(e_val_too_large), arg); + } return; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 9d0e3d542a..93fd62f107 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -4241,6 +4241,11 @@ int get_list_range(char **str, int *num1, int *num2) if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false, NULL); *str += len; + // overflow + if (num > INT_MAX) { + return FAIL; + } + *num1 = (int)num; first = true; } @@ -4249,8 +4254,13 @@ int get_list_range(char **str, int *num1, int *num2) *str = skipwhite((*str) + 1); vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false, NULL); if (len > 0) { - *num2 = (int)num; *str = skipwhite((*str) + len); + // overflow + if (num > INT_MAX) { + return FAIL; + } + + *num2 = (int)num; } else if (!first) { // no number given at all return FAIL; } diff --git a/test/old/testdir/test_history.vim b/test/old/testdir/test_history.vim index bb6d671725..482328ab4a 100644 --- a/test/old/testdir/test_history.vim +++ b/test/old/testdir/test_history.vim @@ -254,4 +254,12 @@ func Test_history_crypt_key() set key& bs& ts& endfunc +" The following used to overflow and causing an use-after-free +func Test_history_max_val() + + set history=10 + call assert_fails(':history 2147483648', 'E1510:') + set history& +endfunc + " vim: shiftwidth=2 sts=2 expandtab |