]> granicus.if.org Git - re2c/commitdiff
Skeleton: fixed comparison of transition tags during construction.
authorUlya Trofimovich <skvadrik@gmail.com>
Fri, 18 Nov 2016 16:37:40 +0000 (16:37 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Fri, 18 Nov 2016 16:37:40 +0000 (16:37 +0000)
At the time of skeleton construction DFA has just been build and
all tags in it are just raw pointers to lists of commands. These
pointers are unique for each transition (tags are not shared between
transitions). This means, comparing tags for different transitions
will always result in 'not equal', except if both transitions have
no tags (pointers are NULLs).

Found by slyfox's fuzzer. ;)

re2c/src/ir/skeleton/skeleton.cc

index f2af092de39aff37aa53b2c98ae63fd36d164dc1..81aa5bb570878690bf5d46e80f2ed3e8b9e52898 100644 (file)
@@ -14,6 +14,11 @@ Node::Node()
        , cmd(NULL)
 {}
 
+static bool same(const tcmd_t &x, const tcmd_t &y)
+{
+       return x.save == y.save && x.copy == y.copy;
+}
+
 void Node::init(const dfa_state_t *s, const charset_t &cs, size_t nil)
 {
        const size_t nc = cs.size() - 1;
@@ -21,7 +26,7 @@ void Node::init(const dfa_state_t *s, const charset_t &cs, size_t nil)
 
                size_t j = s->arcs[c];
                const tcmd_t &t = s->tcmd[c];
-               for (; ++c < nc && s->arcs[c] == j && !s->tcmd[c].save && !s->tcmd[c].copy;);
+               for (; ++c < nc && s->arcs[c] == j && same(s->tcmd[c], t););
                if (j == dfa_t::NIL) j = nil;
 
                // all arcs go to default node => this node is final