1
0
forked from aniani/vim

patch 8.0.0645: no error for illegal back reference in NFA engine

Problem:    The new regexp engine does not give an error for using a back
            reference where it is not allowed. (Dominique Pelle)
Solution:   Check the back reference like the old engine. (closes #1774)
This commit is contained in:
Bram Moolenaar
2017-06-17 20:08:20 +02:00
parent 5b1affefd0
commit 1ef9bbe215
6 changed files with 53 additions and 23 deletions

View File

@@ -1294,6 +1294,34 @@ skip_regexp(
return p;
}
/*
* Return TRUE if the back reference is legal. We must have seen the close
* brace.
* TODO: Should also check that we don't refer to something that is repeated
* (+*=): what instance of the repetition should we match?
*/
static int
seen_endbrace(int refnum)
{
if (!had_endbrace[refnum])
{
char_u *p;
/* Trick: check if "@<=" or "@<!" follows, in which case
* the \1 can appear before the referenced match. */
for (p = regparse; *p != NUL; ++p)
if (p[0] == '@' && p[1] == '<' && (p[2] == '!' || p[2] == '='))
break;
if (*p == NUL)
{
EMSG(_("E65: Illegal back reference"));
rc_did_emsg = TRUE;
return FALSE;
}
}
return TRUE;
}
static regprog_T *bt_regcomp(char_u *expr, int re_flags);
static void bt_regfree(regprog_T *prog);
@@ -2099,24 +2127,8 @@ regatom(int *flagp)
int refnum;
refnum = c - Magic('0');
/*
* Check if the back reference is legal. We must have seen the
* close brace.
* TODO: Should also check that we don't refer to something
* that is repeated (+*=): what instance of the repetition
* should we match?
*/
if (!had_endbrace[refnum])
{
/* Trick: check if "@<=" or "@<!" follows, in which case
* the \1 can appear before the referenced match. */
for (p = regparse; *p != NUL; ++p)
if (p[0] == '@' && p[1] == '<'
&& (p[2] == '!' || p[2] == '='))
break;
if (*p == NUL)
EMSG_RET_NULL(_("E65: Illegal back reference"));
}
if (!seen_endbrace(refnum))
return NULL;
ret = regnode(BACKREF + refnum);
}
break;