aboutsummaryrefslogtreecommitdiff
path: root/src/backend/regex
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/regex')
-rw-r--r--src/backend/regex/regc_nfa.c71
-rw-r--r--src/backend/regex/regcomp.c6
2 files changed, 77 insertions, 0 deletions
diff --git a/src/backend/regex/regc_nfa.c b/src/backend/regex/regc_nfa.c
index a10a346e8f8..77b860cb0fd 100644
--- a/src/backend/regex/regc_nfa.c
+++ b/src/backend/regex/regc_nfa.c
@@ -1383,6 +1383,77 @@ duptraverse(struct nfa *nfa,
}
/*
+ * removeconstraints - remove any constraints in an NFA
+ *
+ * Constraint arcs are replaced by empty arcs, essentially treating all
+ * constraints as automatically satisfied.
+ */
+static void
+removeconstraints(struct nfa *nfa,
+ struct state *start, /* process subNFA starting here */
+ struct state *stop) /* and stopping here */
+{
+ if (start == stop)
+ return;
+
+ stop->tmp = stop;
+ removetraverse(nfa, start);
+ /* done, except for clearing out the tmp pointers */
+
+ stop->tmp = NULL;
+ cleartraverse(nfa, start);
+}
+
+/*
+ * removetraverse - recursive heart of removeconstraints
+ */
+static void
+removetraverse(struct nfa *nfa,
+ struct state *s)
+{
+ struct arc *a;
+ struct arc *oa;
+
+ /* Since this is recursive, it could be driven to stack overflow */
+ if (STACK_TOO_DEEP(nfa->v->re))
+ {
+ NERR(REG_ETOOBIG);
+ return;
+ }
+
+ if (s->tmp != NULL)
+ return; /* already done */
+
+ s->tmp = s;
+ for (a = s->outs; a != NULL && !NISERR(); a = oa)
+ {
+ removetraverse(nfa, a->to);
+ if (NISERR())
+ break;
+ oa = a->outchain;
+ switch (a->type)
+ {
+ case PLAIN:
+ case EMPTY:
+ /* nothing to do */
+ break;
+ case AHEAD:
+ case BEHIND:
+ case '^':
+ case '$':
+ case LACON:
+ /* replace it */
+ newarc(nfa, EMPTY, 0, s, a->to);
+ freearc(nfa, a);
+ break;
+ default:
+ NERR(REG_ASSERT);
+ break;
+ }
+ }
+}
+
+/*
* cleartraverse - recursive cleanup for algorithms that leave tmp ptrs set
*/
static void
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index 1f7fa513b26..3c7627a955e 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -150,6 +150,8 @@ static void delsub(struct nfa *, struct state *, struct state *);
static void deltraverse(struct nfa *, struct state *, struct state *);
static void dupnfa(struct nfa *, struct state *, struct state *, struct state *, struct state *);
static void duptraverse(struct nfa *, struct state *, struct state *);
+static void removeconstraints(struct nfa *, struct state *, struct state *);
+static void removetraverse(struct nfa *, struct state *);
static void cleartraverse(struct nfa *, struct state *);
static struct state *single_color_transition(struct state *, struct state *);
static void specialcolors(struct nfa *);
@@ -1182,6 +1184,10 @@ parseqatom(struct vars *v,
dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
atom->begin, atom->end);
NOERR();
+
+ /* The backref node's NFA should not enforce any constraints */
+ removeconstraints(v->nfa, atom->begin, atom->end);
+ NOERR();
}
/*