aboutsummaryrefslogtreecommitdiff
path: root/src/backend/regex
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-09-09 20:14:58 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2015-09-09 20:14:58 -0400
commit91cf3135b9079bf44ee9b4b445531987cdb7deee (patch)
tree9ff06b7c2fa78f4f3885bf303a9053a3f1b34465 /src/backend/regex
parent223936e22691ccae02be7e2980b6f565518bff19 (diff)
downloadpostgresql-91cf3135b9079bf44ee9b4b445531987cdb7deee.tar.gz
postgresql-91cf3135b9079bf44ee9b4b445531987cdb7deee.zip
Fix minor bug in regexp makesearch() function.
The list-wrangling here was done wrong, allowing the same state to get put into the list twice. The following loop then would clone it twice. The second clone would wind up with no inarcs, so that there was no observable misbehavior AFAICT, but a useless state in the finished NFA isn't an especially good thing.
Diffstat (limited to 'src/backend/regex')
-rw-r--r--src/backend/regex/regcomp.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index 72b0d76af68..44a472fa69e 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -568,21 +568,26 @@ makesearch(struct vars * v,
* splitting each such state into progress and no-progress states.
*/
- /* first, make a list of the states */
+ /* first, make a list of the states reachable from pre and elsewhere */
slist = NULL;
for (a = pre->outs; a != NULL; a = a->outchain)
{
s = a->to;
for (b = s->ins; b != NULL; b = b->inchain)
+ {
if (b->from != pre)
break;
+ }
+
+ /*
+ * We want to mark states as being in the list already by having non
+ * NULL tmp fields, but we can't just store the old slist value in tmp
+ * because that doesn't work for the first such state. Instead, the
+ * first list entry gets its own address in tmp.
+ */
if (b != NULL && s->tmp == NULL)
{
- /*
- * Must be split if not already in the list (fixes bugs 505048,
- * 230589, 840258, 504785).
- */
- s->tmp = slist;
+ s->tmp = (slist != NULL) ? slist : s;
slist = s;
}
}
@@ -601,7 +606,7 @@ makesearch(struct vars * v,
freearc(nfa, a);
}
}
- s2 = s->tmp;
+ s2 = (s->tmp != s) ? s->tmp : NULL;
s->tmp = NULL; /* clean up while we're at it */
}
}