summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.0905
diff options
context:
space:
mode:
Diffstat (limited to 'data/vim/patches/8.1.0905')
-rw-r--r--data/vim/patches/8.1.0905371
1 files changed, 371 insertions, 0 deletions
diff --git a/data/vim/patches/8.1.0905 b/data/vim/patches/8.1.0905
new file mode 100644
index 000000000..ad92ff458
--- /dev/null
+++ b/data/vim/patches/8.1.0905
@@ -0,0 +1,371 @@
+To: vim_dev@googlegroups.com
+Subject: Patch 8.1.0905
+Fcc: outbox
+From: Bram Moolenaar <Bram@moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 8.1.0905
+Problem: Complicated regexp causes a crash. (Kuang-che Wu)
+Solution: Limit the recursiveness of addstate(). (closes #3941)
+Files: src/regexp_nfa.c, src/testdir/test_regexp_latin.vim
+
+
+*** ../vim-8.1.0904/src/regexp_nfa.c 2019-01-31 15:34:35.864056935 +0100
+--- src/regexp_nfa.c 2019-02-12 23:05:19.968038497 +0100
+***************
+*** 4284,4289 ****
+--- 4284,4290 ----
+ /*
+ * 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(
+***************
+*** 4310,4315 ****
+--- 4311,4325 ----
+ #ifdef ENABLE_LOG
+ 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)
+ {
+***************
+*** 4421,4426 ****
+--- 4431,4437 ----
+ abs(state->id), l->id, state->c, code,
+ pim == NULL ? "NULL" : "yes", l->has_pim, found);
+ #endif
++ --depth;
+ return subs;
+ }
+ }
+***************
+*** 4595,4601 ****
+ }
+
+ subs = addstate(l, state->out, subs, pim, off_arg);
+! /* "subs" may have changed, need to set "sub" again */
+ #ifdef FEAT_SYN_HL
+ if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
+ sub = &subs->synt;
+--- 4606,4614 ----
+ }
+
+ subs = addstate(l, state->out, subs, pim, off_arg);
+! if (subs == NULL)
+! break;
+! // "subs" may have changed, need to set "sub" again
+ #ifdef FEAT_SYN_HL
+ if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
+ sub = &subs->synt;
+***************
+*** 4619,4625 ****
+ ? subs->norm.list.multi[0].end_lnum >= 0
+ : subs->norm.list.line[0].end != NULL))
+ {
+! /* Do not overwrite the position set by \ze. */
+ subs = addstate(l, state->out, subs, pim, off_arg);
+ break;
+ }
+--- 4632,4638 ----
+ ? subs->norm.list.multi[0].end_lnum >= 0
+ : subs->norm.list.line[0].end != NULL))
+ {
+! // Do not overwrite the position set by \ze.
+ subs = addstate(l, state->out, subs, pim, off_arg);
+ break;
+ }
+***************
+*** 4695,4700 ****
+--- 4708,4715 ----
+ }
+
+ subs = addstate(l, state->out, subs, pim, off_arg);
++ if (subs == NULL)
++ break;
+ /* "subs" may have changed, need to set "sub" again */
+ #ifdef FEAT_SYN_HL
+ if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9)
+***************
+*** 4710,4715 ****
+--- 4725,4731 ----
+ sub->in_use = save_in_use;
+ break;
+ }
++ --depth;
+ return subs;
+ }
+
+***************
+*** 4719,4725 ****
+ * 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 */
+--- 4735,4741 ----
+ * This makes sure the order of states to be tried does not change, which
+ * matters for alternatives.
+ */
+! static regsubs_T *
+ addstate_here(
+ nfa_list_T *l, /* runtime state list */
+ nfa_state_T *state, /* state to update */
+***************
+*** 4730,4752 ****
+ int tlen = l->n;
+ int count;
+ int listidx = *ip;
+
+ /* 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);
+
+! /* when "*ip" was at the end of the list, nothing to do */
+ if (listidx + 1 == tlen)
+! return;
+
+! /* 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 == 1)
+ {
+! /* overwrite the current state */
+ l->t[listidx] = l->t[l->n - 1];
+ }
+ else if (count > 1)
+--- 4746,4771 ----
+ int tlen = l->n;
+ int count;
+ int listidx = *ip;
++ regsubs_T *r;
+
+ /* 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(). */
+! 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 r;
+
+! // re-order to put the new state at the current position
+ count = l->n - tlen;
+ if (count == 0)
+! return r; // no state got added
+ if (count == 1)
+ {
+! // overwrite the current state
+ l->t[listidx] = l->t[l->n - 1];
+ }
+ else if (count > 1)
+***************
+*** 4760,4766 ****
+ l->len = l->len * 3 / 2 + 50;
+ newl = (nfa_thread_T *)alloc(l->len * sizeof(nfa_thread_T));
+ if (newl == NULL)
+! return;
+ mch_memmove(&(newl[0]),
+ &(l->t[0]),
+ sizeof(nfa_thread_T) * listidx);
+--- 4779,4785 ----
+ l->len = l->len * 3 / 2 + 50;
+ newl = (nfa_thread_T *)alloc(l->len * sizeof(nfa_thread_T));
+ if (newl == NULL)
+! return r;
+ mch_memmove(&(newl[0]),
+ &(l->t[0]),
+ sizeof(nfa_thread_T) * listidx);
+***************
+*** 4787,4792 ****
+--- 4806,4813 ----
+ }
+ --l->n;
+ *ip = listidx - 1;
++
++ return r;
+ }
+
+ /*
+***************
+*** 5493,5498 ****
+--- 5514,5520 ----
+ int add_count;
+ int add_off = 0;
+ int toplevel = start->c == NFA_MOPEN;
++ regsubs_T *r;
+ #ifdef NFA_REGEXP_DEBUG_LOG
+ FILE *debug;
+ #endif
+***************
+*** 5567,5576 ****
+ else
+ m->norm.list.line[0].start = rex.input;
+ m->norm.in_use = 1;
+! addstate(thislist, start->out, m, NULL, 0);
+ }
+ else
+! addstate(thislist, start, m, NULL, 0);
+
+ #define ADD_STATE_IF_MATCH(state) \
+ if (result) { \
+--- 5589,5603 ----
+ else
+ m->norm.list.line[0].start = rex.input;
+ m->norm.in_use = 1;
+! 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) { \
+***************
+*** 5874,5881 ****
+ /* 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);
+ }
+ }
+ break;
+--- 5901,5912 ----
+ /* t->state->out1 is the corresponding END_INVISIBLE
+ * node; Add its out to the current list (zero-width
+ * match). */
+! if (addstate_here(thislist, t->state->out1->out,
+! &t->subs, &pim, &listidx) == NULL)
+! {
+! nfa_match = NFA_TOO_EXPENSIVE;
+! goto theend;
+! }
+ }
+ }
+ break;
+***************
+*** 6749,6761 ****
+ }
+
+ 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)
+ nextlist->t[nextlist->n - 1].count = add_count;
+ }
+ }
+
+ } /* for (thislist = thislist; thislist->state; thislist++) */
+--- 6780,6798 ----
+ }
+
+ 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++) */
+***************
+*** 6831,6841 ****
+ (colnr_T)(rex.input - rex.line) + clen;
+ else
+ m->norm.list.line[0].start = rex.input + clen;
+! addstate(nextlist, start->out, m, NULL, clen);
+ }
+ }
+ else
+! addstate(nextlist, start, m, NULL, clen);
+ }
+
+ #ifdef ENABLE_LOG
+--- 6868,6888 ----
+ (colnr_T)(rex.input - rex.line) + clen;
+ else
+ m->norm.list.line[0].start = rex.input + clen;
+! if (addstate(nextlist, start->out, m, NULL, clen) == NULL)
+! {
+! nfa_match = NFA_TOO_EXPENSIVE;
+! goto theend;
+! }
+ }
+ }
+ else
+! {
+! if (addstate(nextlist, start, m, NULL, clen) == NULL)
+! {
+! nfa_match = NFA_TOO_EXPENSIVE;
+! goto theend;
+! }
+! }
+ }
+
+ #ifdef ENABLE_LOG
+*** ../vim-8.1.0904/src/testdir/test_regexp_latin.vim 2019-01-14 23:19:26.244853406 +0100
+--- src/testdir/test_regexp_latin.vim 2019-02-12 23:04:40.336347263 +0100
+***************
+*** 84,86 ****
+--- 84,92 ----
+ 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
+*** ../vim-8.1.0904/src/version.c 2019-02-12 22:37:24.181961482 +0100
+--- src/version.c 2019-02-12 22:58:41.059230984 +0100
+***************
+*** 785,786 ****
+--- 785,788 ----
+ { /* Add new patch number below this line */
++ /**/
++ 905,
+ /**/
+
+--
+To keep milk from turning sour: Keep it in the cow.
+
+ /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
+/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
+\\\ an exciting new programming language -- http://www.Zimbu.org ///
+ \\\ help me help AIDS victims -- http://ICCF-Holland.org ///