changeset 15806:6a4e9d9f1d66 v8.1.0910

patch 8.1.0910: crash with tricky search pattern commit https://github.com/vim/vim/commit/15bbd6ec871a0efdd16256e1fccbaac0fd374cbd Author: Bram Moolenaar <Bram@vim.org> Date: Wed Feb 13 20:31:50 2019 +0100 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 https://github.com/vim/vim/issues/3950)
author Bram Moolenaar <Bram@vim.org>
date Wed, 13 Feb 2019 20:45:07 +0100
parents 85eae2bd0e19
children 55ffa98b7166
files src/regexp_nfa.c src/testdir/test_regexp_latin.vim src/version.c
diffstat 3 files changed, 26 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -4449,7 +4449,8 @@ skip_add:
 	     * be (a lot) bigger than anticipated. */
 	    if (l->n == l->len)
 	    {
-		int newlen = l->len * 3 / 2 + 50;
+		int		newlen = l->len * 3 / 2 + 50;
+		nfa_thread_T	*newt;
 
 		if (subs != &temp_subs)
 		{
@@ -4463,8 +4464,14 @@ skip_add:
 		    subs = &temp_subs;
 		}
 
-		/* TODO: check for vim_realloc() returning NULL. */
-		l->t = vim_realloc(l->t, newlen * sizeof(nfa_thread_T));
+		newt = vim_realloc(l->t, newlen * sizeof(nfa_thread_T));
+		if (newt == NULL)
+		{
+		    // out of memory
+		    --depth;
+		    return NULL;
+		}
+		l->t = newt;
 		l->len = newlen;
 	    }
 
@@ -4756,7 +4763,7 @@ addstate_here(
      * addstate(). */
     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
     if (listidx + 1 == tlen)
@@ -4777,12 +4784,13 @@ addstate_here(
 	{
 	    /* not enough space to move the new states, reallocate the list
 	     * and move the states to the right position */
-	    nfa_thread_T *newl;
-
-	    l->len = l->len * 3 / 2 + 50;
-	    newl = (nfa_thread_T *)alloc(l->len * sizeof(nfa_thread_T));
+	    int		    newlen = l->len * 3 / 2 + 50;
+	    nfa_thread_T    *newl;
+
+	    newl = (nfa_thread_T *)alloc(newlen * sizeof(nfa_thread_T));
 	    if (newl == NULL)
-		return r;
+		return NULL;
+	    l->len = newlen;
 	    mch_memmove(&(newl[0]),
 		    &(l->t[0]),
 		    sizeof(nfa_thread_T) * listidx);
--- a/src/testdir/test_regexp_latin.vim
+++ b/src/testdir/test_regexp_latin.vim
@@ -90,3 +90,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
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    910,
+/**/
     909,
 /**/
     908,