summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2023-03-09 05:25:09 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2023-04-30 22:36:33 +0200
commit9f7b114232904a7d0e304bff30ed4b255f34a572 (patch)
tree545a36982678624ad3bfde5762289d23a5189695
parent4f49017e37c489397ebc6995fab0fe56a339bd9f (diff)
downloadlibxml2-9f7b114232904a7d0e304bff30ed4b255f34a572.tar.gz
regexp: Fix cycle check in xmlFAReduceEpsilonTransitions
The visited flag must only be reset after the first call to xmlFAReduceEpsilonTransitions has finished. Visiting states multiple times could lead to unnecessary processing of duplicate transitions. Similar to 68eadabd.
-rw-r--r--xmlregexp.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/xmlregexp.c b/xmlregexp.c
index 5638ddc6..ddae0851 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1864,7 +1864,32 @@ xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
}
}
}
+}
+
+/**
+ * xmlFAFinishReduceEpsilonTransitions:
+ * @ctxt: a regexp parser context
+ * @fromnr: the from state
+ * @tonr: the to state
+ * @counter: should that transition be associated to a counted
+ *
+ */
+static void
+xmlFAFinishReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int tonr) {
+ int transnr;
+ xmlRegStatePtr to;
+
+ to = ctxt->states[tonr];
+ if ((to->mark == XML_REGEXP_MARK_START) ||
+ (to->mark == XML_REGEXP_MARK_NORMAL))
+ return;
+
to->mark = XML_REGEXP_MARK_NORMAL;
+ for (transnr = 0;transnr < to->nbTrans;transnr++) {
+ xmlRegTransPtr t1 = &to->trans[transnr];
+ if ((t1->to >= 0) && (t1->atom == NULL))
+ xmlFAFinishReduceEpsilonTransitions(ctxt, t1->to);
+ }
}
/**
@@ -2016,6 +2041,7 @@ xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
state->mark = XML_REGEXP_MARK_START;
xmlFAReduceEpsilonTransitions(ctxt, statenr,
newto, state->trans[transnr].counter);
+ xmlFAFinishReduceEpsilonTransitions(ctxt, newto);
state->mark = XML_REGEXP_MARK_NORMAL;
#ifdef DEBUG_REGEXP_GRAPH
} else {