From cb080e70de859d6f422d5964e536d8e203533734 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 6 Sep 2014 23:40:57 -0400 Subject: [PATCH] Parser - Added disqualifier for id sequences in the form of a set of acceptable characters. Prevents strange problems due to the 'split' calls that are used in the implementation. --- src/Parser.cpp | 257 +++++++++++++++++++++++++------------------------ 1 file changed, 132 insertions(+), 125 deletions(-) diff --git a/src/Parser.cpp b/src/Parser.cpp index 087af735c..43e94ab23 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -1292,150 +1292,157 @@ void Parser::findIdSequence () if (! (*i)->hasTag ("?")) continue; + // Easy disqualifiers. + if (raw.find_first_not_of ("0123456789,-") != std::string::npos) + break; + // Container for min/max ID ranges. std::vector > ranges; // Split the ID list into elements. std::vector elements; split (elements, raw, ','); - if (elements.size ()) + + bool not_an_id = false; + std::vector ::iterator e; + for (e = elements.begin (); e != elements.end (); ++e) { - bool not_an_id = false; - std::vector ::iterator e; - for (e = elements.begin (); e != elements.end (); ++e) + // Split the ID range into min/max. + std::vector terms; + split (terms, *e, '-'); + + if (terms.size () == 1) { - // Split the ID range into min/max. - std::vector terms; - split (terms, *e, '-'); - - if (terms.size () == 1) + if (! digitsOnly (terms[0])) { - if (! digitsOnly (terms[0])) - { - not_an_id = true; - break; - } - - Nibbler n (terms[0]); - int id; - if (n.getUnsignedInt (id) && - n.depleted ()) - { - ranges.push_back (std::pair (id, id)); - } - else - { - not_an_id = true; - break; - } - } - else if (terms.size () == 2) - { - if (! digitsOnly (terms[0]) || - ! digitsOnly (terms[1])) - { - not_an_id = true; - break; - } - - Nibbler n_min (terms[0]); - Nibbler n_max (terms[1]); - int id_min; - int id_max; - if (n_min.getUnsignedInt (id_min) && - n_min.depleted () && - n_max.getUnsignedInt (id_max) && - n_max.depleted ()) - { - if (id_min > id_max) - throw std::string (STRING_PARSER_RANGE_INVERTED); - - ranges.push_back (std::pair (id_min, id_max)); - } - else - { - not_an_id = true; - break; - } - } - } - - if (not_an_id) - continue; - - // Now convert the ranges into an infix expression. - (*i)->unTag ("?"); - (*i)->removeAllBranches (); - (*i)->tag ("ID"); - - Tree* branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "("); - branch->tag ("OP"); - - std::vector >::iterator r; - for (r = ranges.begin (); r != ranges.end (); ++r) - { - if (r != ranges.begin ()) - { - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "or"); - branch->tag ("OP"); + not_an_id = true; + break; } - if (r->first == r->second) + Nibbler n (terms[0]); + int id; + if (n.getUnsignedInt (id) && + n.depleted ()) { - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "id"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "=="); - branch->tag ("OP"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", r->first); + ranges.push_back (std::pair (id, id)); } else { - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "("); - branch->tag ("OP"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "id"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", ">="); - branch->tag ("OP"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", r->first); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "and"); - branch->tag ("OP"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "id"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", "<="); - branch->tag ("OP"); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", r->second); - - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", ")"); - branch->tag ("OP"); + not_an_id = true; + break; } } + else if (terms.size () == 2) + { + if (! digitsOnly (terms[0]) || + ! digitsOnly (terms[1])) + { + not_an_id = true; + break; + } - branch = (*i)->addBranch (new Tree ("argSeq")); - branch->attribute ("raw", ")"); - branch->tag ("OP"); - action = true; - break; + Nibbler n_min (terms[0]); + Nibbler n_max (terms[1]); + int id_min; + int id_max; + if (n_min.getUnsignedInt (id_min) && + n_min.depleted () && + n_max.getUnsignedInt (id_max) && + n_max.depleted ()) + { + if (id_min > id_max) + throw std::string (STRING_PARSER_RANGE_INVERTED); + + ranges.push_back (std::pair (id_min, id_max)); + } + else + { + not_an_id = true; + break; + } + } + else + { + not_an_id = true; + break; + } } + + if (not_an_id) + continue; + + // Now convert the ranges into an infix expression. + (*i)->unTag ("?"); + (*i)->removeAllBranches (); + (*i)->tag ("ID"); + + Tree* branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "("); + branch->tag ("OP"); + + std::vector >::iterator r; + for (r = ranges.begin (); r != ranges.end (); ++r) + { + if (r != ranges.begin ()) + { + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "or"); + branch->tag ("OP"); + } + + if (r->first == r->second) + { + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "id"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "=="); + branch->tag ("OP"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", r->first); + } + else + { + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "("); + branch->tag ("OP"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "id"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", ">="); + branch->tag ("OP"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", r->first); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "and"); + branch->tag ("OP"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "id"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", "<="); + branch->tag ("OP"); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", r->second); + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", ")"); + branch->tag ("OP"); + } + } + + branch = (*i)->addBranch (new Tree ("argSeq")); + branch->attribute ("raw", ")"); + branch->tag ("OP"); + action = true; + break; } } while (action);