# HG changeset patch # User Bram Moolenaar # Date 1372627448 -7200 # Node ID 1cacf785299e771ca463c493c8c870e395c09cd0 # Parent e53f245dec886f1a08cbee45ab20863ebc4b588c updated for version 7.3.1280 Problem: Reading memory already freed since patch 7.3.1247. (Simon Ruderich, Dominique Pelle) Solution: Copy submatches before reallocating the state list. diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -3538,7 +3538,7 @@ static int sub_equal __ARGS((regsub_T *s static int match_backref __ARGS((regsub_T *sub, int subidx, int *bytelen)); static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs)); static int state_in_list __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs)); -static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int off)); +static regsubs_T *addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs_arg, nfa_pim_T *pim, int off)); static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int *ip)); /* @@ -3832,13 +3832,18 @@ state_in_list(l, state, subs) return FALSE; } - static void -addstate(l, state, subs, pim, off) - 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 off; /* byte offset, when -1 go to next line */ +/* + * Add "state" and possibly what follows to state list ".". + * Returns "subs_arg", possibly copied into temp_subs. + */ + + static regsubs_T * +addstate(l, state, subs_arg, pim, off) + 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; /* byte offset, when -1 go to next line */ { int subidx; nfa_thread_T *thread; @@ -3847,6 +3852,8 @@ addstate(l, state, subs, pim, off) char_u *save_ptr; int i; regsub_T *sub; + regsubs_T *subs = subs_arg; + static regsubs_T temp_subs; #ifdef ENABLE_LOG int did_print = FALSE; #endif @@ -3941,7 +3948,7 @@ skip_add: fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n", abs(state->id), l->id, state->c, code); #endif - return; + return subs; } /* Do not add the state again when it exists with the same @@ -3956,6 +3963,18 @@ skip_add: { int newlen = l->len * 3 / 2 + 50; + if (subs != &temp_subs) + { + /* "subs" may point into the current array, need to make a + * copy before it becomes invalid. */ + copy_sub(&temp_subs.norm, &subs->norm); +#ifdef FEAT_SYN_HL + if (nfa_has_zsubexpr) + copy_sub(&temp_subs.synt, &subs->synt); +#endif + subs = &temp_subs; + } + l->t = vim_realloc(l->t, newlen * sizeof(nfa_thread_T)); l->len = newlen; } @@ -3991,14 +4010,14 @@ skip_add: case NFA_SPLIT: /* order matters here */ - addstate(l, state->out, subs, pim, off); - addstate(l, state->out1, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out1, subs, pim, off); break; case NFA_SKIP_CHAR: case NFA_NOPEN: case NFA_NCLOSE: - addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off); break; case NFA_MOPEN: @@ -4094,7 +4113,7 @@ skip_add: sub->list.line[subidx].start = reginput + off; } - addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off); if (save_in_use == -1) { @@ -4112,7 +4131,7 @@ skip_add: { /* Do not overwrite the position set by \ze. If no \ze * encountered end will be set in nfa_regtry(). */ - addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off); break; } case NFA_MCLOSE1: @@ -4181,7 +4200,7 @@ skip_add: sub->list.line[subidx].end = reginput + off; } - addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off); if (REG_MULTI) sub->list.multi[subidx].end = save_lpos; @@ -4190,6 +4209,7 @@ skip_add: sub->in_use = save_in_use; break; } + return subs; } /* diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1280, +/**/ 1279, /**/ 1278,