From 2385039623a8afcfd6d3d446c3272ac167d9b586 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 23 Jul 2019 22:23:28 -0400 Subject: [PATCH 01/11] vim-patch:8.1.0899: no need to check restricted mode for setwinvar() Problem: No need to check restricted mode for setwinvar(). Solution: Remove check_restricted(). https://github.com/vim/vim/commit/e0fb7d1e38e1cf699412e212cda863420f5f8bd2 --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4e5c310fb6..8e79ff59b6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -15731,7 +15731,7 @@ static void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void setwinvar(typval_T *argvars, typval_T *rettv, int off) { - if (check_restricted() || check_secure()) { + if (check_secure()) { return; } From 80487b59c92361f445396fa2faaf2f7f14ee4666 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 23 Jul 2019 22:35:12 -0400 Subject: [PATCH 02/11] vim-patch:8.1.0903: struct uses more bytes than needed Problem: Struct uses more bytes than needed. Solution: Reorder members of regitem_S. (Dominique Pelle, closes vim/vim#3936) https://github.com/vim/vim/commit/beb7574d6b0eea1cae70aa2913a690da56de5307 --- src/nvim/regexp.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index eb1e565b1f..414472a8f3 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -247,9 +247,9 @@ #define BRACE_COMPLEX 140 /* -149 node Match nodes between m & n times */ -#define NOPEN 150 /* Mark this point in input as start of - \%( subexpr. */ -#define NCLOSE 151 /* Analogous to NOPEN. */ +#define NOPEN 150 // Mark this point in input as start of + // \%( subexpr. +#define NCLOSE 151 // Analogous to NOPEN. #define MULTIBYTECODE 200 /* mbc Match one multi-byte character */ #define RE_BOF 201 /* Match "" at beginning of file. */ @@ -348,13 +348,13 @@ typedef enum regstate_E { * more things. */ typedef struct regitem_S { - regstate_T rs_state; /* what we are doing, one of RS_ above */ - char_u *rs_scan; /* current node in program */ + regstate_T rs_state; // what we are doing, one of RS_ above + uint16_t rs_no; // submatch nr or BEHIND/NOBEHIND + char_u *rs_scan; // current node in program union { save_se_T sesave; regsave_T regsave; - } rs_un; /* room for saving reginput */ - short rs_no; /* submatch nr or BEHIND/NOBEHIND */ + } rs_un; // room for saving reginput } regitem_T; From 9ea449085da08eaa5ccb826dd5e37f480c871e79 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 24 Jul 2019 20:38:36 -0400 Subject: [PATCH 03/11] vim-patch:8.1.1746: ":dl" is seen as ":dlist" instead of ":delete" Problem: ":dl" is seen as ":dlist" instead of ":delete". Solution: Do not use cmdidxs2[] if the length is 1. (closes vim/vim#4721) https://github.com/vim/vim/commit/94f82cbacf76767b5ac32f813e1d670501dbd0e6 --- src/nvim/ex_docmd.c | 2 +- src/nvim/testdir/test_excmd.vim | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/nvim/testdir/test_excmd.vim diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index af5635ddba..28c7bc300f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2451,7 +2451,7 @@ static char_u *find_command(exarg_T *eap, int *full) if (ASCII_ISLOWER(eap->cmd[0])) { const int c1 = eap->cmd[0]; - const int c2 = eap->cmd[1]; + const int c2 = len == 1 ? NUL : eap->cmd[1]; if (command_count != (int)CMD_SIZE) { iemsg((char *)_("E943: Command table needs to be updated, run 'make'")); diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim new file mode 100644 index 0000000000..f5ce979208 --- /dev/null +++ b/src/nvim/testdir/test_excmd.vim @@ -0,0 +1,10 @@ +" Tests for various Ex commands. + +func Test_ex_delete() + new + call setline(1, ['a', 'b', 'c']) + 2 + " :dl is :delete with the "l" flag, not :dlist + .dl + call assert_equal(['a', 'c'], getline(1, 2)) +endfunc From 43f4e5d5be44c4d836eabd479dcee9ff7d3bfa2a Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Tue, 23 Jul 2019 22:54:14 -0400 Subject: [PATCH 04/11] vim-patch:8.1.0908: can't handle large value for %{nr}v in regexp Problem: Can't handle large value for %{nr}v in regexp. (Kuang-che Wu) Solution: Give an error if the value is too large. (closes vim/vim#3948) https://github.com/vim/vim/commit/9403a2168db82b7de80f792984084bb3f00e2263 --- src/nvim/regexp_nfa.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index a8919560a0..ab189c0c03 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1503,6 +1503,8 @@ static int nfa_regatom(void) c = getchr(); } if (c == 'l' || c == 'c' || c == 'v') { + int limit = INT_MAX; + if (c == 'l') { // \%{n}l \%{n}l EMIT(cmp == '<' ? NFA_LNUM_LT : @@ -1518,13 +1520,12 @@ static int nfa_regatom(void) // \%{n}v \%{n}v EMIT(cmp == '<' ? NFA_VCOL_LT : cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); + limit = INT_MAX / MB_MAXBYTES; } -#if SIZEOF_INT < SIZEOF_LONG - if (n > INT_MAX) { + if (n >= limit) { EMSG(_("E951: \\% value too large")); return FAIL; } -#endif EMIT((int)n); break; } else if (c == '\'' && n == 0) { From 33ce6a7f62c5203ca0f6903327c2e3e5ec54344c Mon Sep 17 00:00:00 2001 From: Gabriel Date: Wed, 22 May 2019 16:59:49 -0300 Subject: [PATCH 05/11] Checks for overflow when parsing string to int --- src/nvim/regexp_nfa.c | 4 ++++ test/functional/eval/match_functions_spec.lua | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index ab189c0c03..abbb5a3867 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1499,6 +1499,10 @@ static int nfa_regatom(void) if (c == '<' || c == '>') c = getchr(); while (ascii_isdigit(c)) { + if (n > (INT_MAX - (c - '0')) / 10) { + EMSG(_("E951: \\% value too large")); + return FAIL; + } n = n * 10 + (c - '0'); c = getchr(); } diff --git a/test/functional/eval/match_functions_spec.lua b/test/functional/eval/match_functions_spec.lua index 0ec465a34c..421b9e7ea3 100644 --- a/test/functional/eval/match_functions_spec.lua +++ b/test/functional/eval/match_functions_spec.lua @@ -156,3 +156,12 @@ describe('matchaddpos()', function() ]], {[1] = {foreground = Screen.colors.Red}, [2] = {bold = true, foreground = Screen.colors.Blue1}}) end) end) + +describe('nfa_regatom() column search', function() + it('fails when column value is greater than a 64-bit integer value', function() + expect_err("Vim:E951: \\%% value too large", command, "/\\v%18446744071562067968c") + end) + it('fails when column value is greater than a 32-bit integer value', function() + expect_err("Vim:E951: \\%% value too large", command, "/\\v%2147483648c") + end) +end) From 8e490b98ccad1aa701d88d5aba41bf7f8698be91 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 24 Jul 2019 19:55:32 -0400 Subject: [PATCH 06/11] regexp: use fixed types to avoid overflow --- src/nvim/regexp_nfa.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index abbb5a3867..a930fe5993 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -1493,13 +1493,13 @@ static int nfa_regatom(void) default: { - long n = 0; - int cmp = c; + int64_t n = 0; + const int cmp = c; if (c == '<' || c == '>') c = getchr(); while (ascii_isdigit(c)) { - if (n > (INT_MAX - (c - '0')) / 10) { + if (n > (INT32_MAX - (c - '0')) / 10) { EMSG(_("E951: \\% value too large")); return FAIL; } @@ -1507,7 +1507,7 @@ static int nfa_regatom(void) c = getchr(); } if (c == 'l' || c == 'c' || c == 'v') { - int limit = INT_MAX; + int32_t limit = INT32_MAX; if (c == 'l') { // \%{n}l \%{n}l @@ -1524,7 +1524,7 @@ static int nfa_regatom(void) // \%{n}v \%{n}v EMIT(cmp == '<' ? NFA_VCOL_LT : cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); - limit = INT_MAX / MB_MAXBYTES; + limit = INT32_MAX / MB_MAXBYTES; } if (n >= limit) { EMSG(_("E951: \\% value too large")); From a77e5b3606bd40e524e5e3ab428b58ca2b3f0ac2 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 25 Jul 2019 01:41:42 -0400 Subject: [PATCH 07/11] vim-patch:8.1.0905: complicated regexp causes a crash Problem: Complicated regexp causes a crash. (Kuang-che Wu) Solution: Limit the recursiveness of addstate(). (closes vim/vim#3941) https://github.com/vim/vim/commit/5567ad48b66dff13670af52a48509059acc34dfe --- src/nvim/regexp_nfa.c | 100 ++++++++++++++++++------- src/nvim/testdir/test_regexp_latin.vim | 6 ++ 2 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index a930fe5993..425da6c055 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -3931,6 +3931,7 @@ state_in_list ( // Add "state" and possibly what follows to state list ".". // Returns "subs_arg", possibly copied into temp_subs. +// Returns NULL when recursiveness is too deep. static regsubs_T * addstate ( nfa_list_T *l, /* runtime state list */ @@ -3956,6 +3957,14 @@ addstate ( #ifdef REGEXP_DEBUG int did_print = FALSE; #endif + static int depth = 0; + + // This function is called recursively. When the depth is too much we run + // out of stack and crash, limit recursiveness here. + if (++depth >= 10000 || subs == NULL) { + depth--; + return NULL; + } if (off_arg <= -ADDSTATE_HERE_OFFSET) { add_here = true; @@ -4059,6 +4068,7 @@ skip_add: abs(state->id), l->id, state->c, code, pim == NULL ? "NULL" : "yes", l->has_pim, found); #endif + depth--; return subs; } } @@ -4202,6 +4212,9 @@ skip_add: } subs = addstate(l, state->out, subs, pim, off_arg); + if (subs == NULL) { + break; + } // "subs" may have changed, need to set "sub" again. if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) { // -V560 sub = &subs->synt; @@ -4223,7 +4236,7 @@ skip_add: if (nfa_has_zend && (REG_MULTI ? subs->norm.list.multi[0].end_lnum >= 0 : subs->norm.list.line[0].end != NULL)) { - /* Do not overwrite the position set by \ze. */ + // Do not overwrite the position set by \ze. subs = addstate(l, state->out, subs, pim, off_arg); break; } @@ -4284,6 +4297,9 @@ skip_add: } subs = addstate(l, state->out, subs, pim, off_arg); + if (subs == NULL) { + break; + } // "subs" may have changed, need to set "sub" again. if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) { // -V560 sub = &subs->synt; @@ -4299,6 +4315,7 @@ skip_add: sub->in_use = save_in_use; break; } + depth--; return subs; } @@ -4308,12 +4325,11 @@ skip_add: * This makes sure the order of states to be tried does not change, which * matters for alternatives. */ -static void -addstate_here ( - nfa_list_T *l, /* runtime state list */ - nfa_state_T *state, /* state to update */ - regsubs_T *subs, /* pointers to subexpressions */ - nfa_pim_T *pim, /* postponed look-behind match */ +static regsubs_T *addstate_here( + nfa_list_T *l, // runtime state list + nfa_state_T *state, // state to update + regsubs_T *subs, // pointers to subexpressions + nfa_pim_T *pim, // postponed look-behind match int *ip ) { @@ -4324,18 +4340,23 @@ addstate_here ( /* First add the state(s) at the end, so that we know how many there are. * Pass the listidx as offset (avoids adding another argument to * addstate(). */ - addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET); + regsubs_T *r = addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET); + if (r == NULL) { + return r; + } - /* when "*ip" was at the end of the list, nothing to do */ - if (listidx + 1 == tlen) - return; + // when "*ip" was at the end of the list, nothing to do + if (listidx + 1 == tlen) { + return r; + } - /* re-order to put the new state at the current position */ + // re-order to put the new state at the current position count = l->n - tlen; - if (count == 0) - return; /* no state got added */ + if (count == 0) { + return r; // no state got added + } if (count == 1) { - /* overwrite the current state */ + // overwrite the current state l->t[listidx] = l->t[l->n - 1]; } else if (count > 1) { if (l->n + count - 1 >= l->len) { @@ -4368,6 +4389,8 @@ addstate_here ( } --l->n; *ip = listidx - 1; + + return r; } /* @@ -4997,6 +5020,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, int add_count; int add_off = 0; int toplevel = start->c == NFA_MOPEN; + regsubs_T *r; #ifdef NFA_REGEXP_DEBUG_LOG FILE *debug = fopen(NFA_REGEXP_DEBUG_LOG, "a"); @@ -5064,9 +5088,14 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, } else m->norm.list.line[0].start = reginput; m->norm.in_use = 1; - addstate(thislist, start->out, m, NULL, 0); - } else - addstate(thislist, start, m, NULL, 0); + r = addstate(thislist, start->out, m, NULL, 0); + } else { + r = addstate(thislist, start, m, NULL, 0); + } + if (r == NULL) { + nfa_match = NFA_TOO_EXPENSIVE; + goto theend; + } #define ADD_STATE_IF_MATCH(state) \ if (result) { \ @@ -5333,8 +5362,11 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, // t->state->out1 is the corresponding END_INVISIBLE // node; Add its out to the current list (zero-width // match). - addstate_here(thislist, t->state->out1->out, &t->subs, - &pim, &listidx); + if (addstate_here(thislist, t->state->out1->out, &t->subs, + &pim, &listidx) == NULL) { + nfa_match = NFA_TOO_EXPENSIVE; + goto theend; + } } } break; @@ -6150,12 +6182,17 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, pim = &pim_copy; } - if (add_here) - addstate_here(thislist, add_state, &t->subs, pim, &listidx); - else { - addstate(nextlist, add_state, &t->subs, pim, add_off); - if (add_count > 0) + if (add_here) { + r = addstate_here(thislist, add_state, &t->subs, pim, &listidx); + } else { + r = addstate(nextlist, add_state, &t->subs, pim, add_off); + if (add_count > 0) { nextlist->t[nextlist->n - 1].count = add_count; + } + } + if (r == NULL) { + nfa_match = NFA_TOO_EXPENSIVE; + goto theend; } } } // for (thislist = thislist; thislist->state; thislist++) @@ -6225,10 +6262,17 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, (colnr_T)(reginput - regline) + clen; else m->norm.list.line[0].start = reginput + clen; - addstate(nextlist, start->out, m, NULL, clen); + if (addstate(nextlist, start->out, m, NULL, clen) == NULL) { + nfa_match = NFA_TOO_EXPENSIVE; + goto theend; + } } - } else - addstate(nextlist, start, m, NULL, clen); + } else { + if (addstate(nextlist, start, m, NULL, clen) == NULL) { + nfa_match = NFA_TOO_EXPENSIVE; + goto theend; + } + } } #ifdef REGEXP_DEBUG diff --git a/src/nvim/testdir/test_regexp_latin.vim b/src/nvim/testdir/test_regexp_latin.vim index de209fa9ec..5fb6e78baa 100644 --- a/src/nvim/testdir/test_regexp_latin.vim +++ b/src/nvim/testdir/test_regexp_latin.vim @@ -85,3 +85,9 @@ func Test_multi_failure() call assert_fails('/a\{a}', 'E870:') set re=0 endfunc + +func Test_recursive_addstate() + " This will call addstate() recursively until it runs into the limit. + let lnum = search('\v((){328}){389}') + call assert_equal(0, lnum) +endfunc From fb059a1741b49e253e0a90717d1ff983bcee90ab Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 25 Jul 2019 02:20:55 -0400 Subject: [PATCH 08/11] vim-patch:8.1.0907: CI tests on AppVeyor are failing Problem: CI tests on AppVeyor are failing. Solution: Reduce the recursiveness limit for regexp. https://github.com/vim/vim/commit/5382f12c910b7f8e46acdde5488f26a86f9fcac1 --- src/nvim/regexp_nfa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 425da6c055..fbdf4b9630 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -3961,7 +3961,7 @@ addstate ( // This function is called recursively. When the depth is too much we run // out of stack and crash, limit recursiveness here. - if (++depth >= 10000 || subs == NULL) { + if (++depth >= 5000 || subs == NULL) { depth--; return NULL; } From 52488ea6fbda4db821e8bad305241504d7fda1c0 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 25 Jul 2019 02:22:02 -0400 Subject: [PATCH 09/11] vim-patch:8.1.0910: crash with tricky search pattern Problem: Crash with tricky search pattern. (Kuang-che Wu) Solution: Check for runnning out of memory. (closes vim/vim#3950) https://github.com/vim/vim/commit/15bbd6ec871a0efdd16256e1fccbaac0fd374cbd --- src/nvim/regexp_nfa.c | 12 +++++++----- src/nvim/testdir/test_regexp_latin.vim | 7 +++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index fbdf4b9630..322317658c 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4082,7 +4082,7 @@ skip_add: /* When there are backreferences or PIMs the number of states may * be (a lot) bigger than anticipated. */ if (l->n == l->len) { - int newlen = l->len * 3 / 2 + 50; + const int newlen = l->len * 3 / 2 + 50; if (subs != &temp_subs) { /* "subs" may point into the current array, need to make a @@ -4093,7 +4093,8 @@ skip_add: subs = &temp_subs; } - l->t = xrealloc(l->t, newlen * sizeof(nfa_thread_T)); + nfa_thread_T *const newt = xrealloc(l->t, newlen * sizeof(*newt)); + l->t = newt; l->len = newlen; } @@ -4342,7 +4343,7 @@ static regsubs_T *addstate_here( * addstate(). */ regsubs_T *r = addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET); if (r == NULL) { - return r; + return NULL; } // when "*ip" was at the end of the list, nothing to do @@ -4362,9 +4363,10 @@ static regsubs_T *addstate_here( if (l->n + count - 1 >= l->len) { /* not enough space to move the new states, reallocate the list * and move the states to the right position */ + const int newlen = l->len * 3 / 2 + 50; - l->len = l->len * 3 / 2 + 50; - nfa_thread_T *newl = xmalloc(l->len * sizeof(nfa_thread_T)); + nfa_thread_T *const newl = xmalloc(newlen * sizeof(*newl)); + l->len = newlen; memmove(&(newl[0]), &(l->t[0]), sizeof(nfa_thread_T) * listidx); diff --git a/src/nvim/testdir/test_regexp_latin.vim b/src/nvim/testdir/test_regexp_latin.vim index 5fb6e78baa..b5e99b0ed3 100644 --- a/src/nvim/testdir/test_regexp_latin.vim +++ b/src/nvim/testdir/test_regexp_latin.vim @@ -91,3 +91,10 @@ func Test_recursive_addstate() let lnum = search('\v((){328}){389}') call assert_equal(0, lnum) endfunc + +func Test_out_of_memory() + new + s/^/,n + " This will be slow... + call assert_fails('call search("\\v((n||<)+);")', 'E363:') +endfunc From 98fcf66b7ac1d36c29b9e1a2c1f18366d62d8184 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 25 Jul 2019 02:50:33 -0400 Subject: [PATCH 10/11] vim-patch:8.1.0913: CI crashes when running out of memory Problem: CI crashes when running out of memory. Solution: Apply 'maxmempattern' also to new regexp engine. https://github.com/vim/vim/commit/688b3983d8b321e0d32dd51914fa474a0988daf6 --- src/nvim/regexp_nfa.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 322317658c..787d6380e9 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4079,11 +4079,17 @@ skip_add: goto skip_add; } - /* When there are backreferences or PIMs the number of states may - * be (a lot) bigger than anticipated. */ + // When there are backreferences or PIMs the number of states may + // be (a lot) bigger than anticipated. if (l->n == l->len) { const int newlen = l->len * 3 / 2 + 50; + const size_t newsize = newlen * sizeof(nfa_thread_T); + if ((long)(newsize >> 10) >= p_mmp) { + EMSG(_(e_maxmempat)); + depth--; + return NULL; + } if (subs != &temp_subs) { /* "subs" may point into the current array, need to make a * copy before it becomes invalid. */ @@ -4093,7 +4099,7 @@ skip_add: subs = &temp_subs; } - nfa_thread_T *const newt = xrealloc(l->t, newlen * sizeof(*newt)); + nfa_thread_T *const newt = xrealloc(l->t, newsize); l->t = newt; l->len = newlen; } @@ -4364,8 +4370,13 @@ static regsubs_T *addstate_here( /* not enough space to move the new states, reallocate the list * and move the states to the right position */ const int newlen = l->len * 3 / 2 + 50; + const size_t newsize = newlen * sizeof(nfa_thread_T); - nfa_thread_T *const newl = xmalloc(newlen * sizeof(*newl)); + if ((long)(newsize >> 10) >= p_mmp) { + EMSG(_(e_maxmempat)); + return NULL; + } + nfa_thread_T *const newl = xmalloc(newsize); l->len = newlen; memmove(&(newl[0]), &(l->t[0]), From 0925afcfcfd3fb024a35d10ee8f584b67bdc9000 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 25 Jul 2019 03:31:25 -0400 Subject: [PATCH 11/11] regexp: add function attributes --- src/nvim/regexp_nfa.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 787d6380e9..c0129a00fb 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -3932,13 +3932,13 @@ state_in_list ( // Add "state" and possibly what follows to state list ".". // Returns "subs_arg", possibly copied into temp_subs. // Returns NULL when recursiveness is too deep. -static regsubs_T * -addstate ( - nfa_list_T *l, /* runtime state list */ - nfa_state_T *state, /* state to update */ - regsubs_T *subs_arg, /* pointers to subexpressions */ - nfa_pim_T *pim, /* postponed look-behind match */ - int off_arg) /* byte offset, when -1 go to next line */ +static regsubs_T *addstate( + nfa_list_T *l, // runtime state list + nfa_state_T *state, // state to update + regsubs_T *subs_arg, // pointers to subexpressions + nfa_pim_T *pim, // postponed look-behind match + int off_arg) // byte offset, when -1 go to next line + FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT { int subidx; int off = off_arg; @@ -4339,6 +4339,7 @@ static regsubs_T *addstate_here( nfa_pim_T *pim, // postponed look-behind match int *ip ) + FUNC_ATTR_NONNULL_ARG(1, 2, 5) FUNC_ATTR_WARN_UNUSED_RESULT { int tlen = l->n; int count;