From: Aki Tuomi Date: Fri, 31 Jul 2015 19:38:55 +0000 (+0300) Subject: Add SimpleMatch matcher X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~58^2~2^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac84f00c869c0e494d034a91a45713ac0c872e97;p=thirdparty%2Fpdns.git Add SimpleMatch matcher This utility class lets you do simple * and ? based matching. --- diff --git a/pdns/misc.hh b/pdns/misc.hh index eaeff786a0..63816c8a88 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -558,6 +558,57 @@ private: regex_t d_preg; }; +class SimpleMatch +{ +public: + SimpleMatch(const string &mask, bool caseFold = false) + { + this->d_mask = mask; + this->d_fold = caseFold; + } + + bool match(string::const_iterator mi, string::const_iterator mend, string::const_iterator vi, string::const_iterator vend) + { + for(;;mi++) { + if (mi == mend) { + return vi == vend; + } else if (*mi == '?') { + if (vi == vend) return false; + vi++; + } else if (*mi == '*') { + while(*mi == '*') mi++; + if (mi == d_mask.end()) return true; + while(vi != vend) { + if (match(mi,mend,vi,vend)) return true; + vi++; + } + return false; + } else { + if ((mi == mend && vi != vend)|| + (mi != mend && vi == vend)) return false; + if (d_fold) { + if (dns_tolower(*mi) != dns_tolower(*vi)) return false; + } else { + if (*mi != *vi) return false; + } + vi++; + } + } + } + + bool match(const string& value) { + return match(d_mask.begin(), d_mask.end(), value.begin(), value.end()); + } + + bool match(const DNSName& name) { + return match(name.toStringNoDot()); + } + +private: + string d_mask; + bool d_fold; +}; + union ComboAddress; void addCMsgSrcAddr(struct msghdr* msgh, void* cmsgbuf, const ComboAddress* source); diff --git a/pdns/test-misc_hh.cc b/pdns/test-misc_hh.cc index 1d081b4aa9..117b0eebd9 100644 --- a/pdns/test-misc_hh.cc +++ b/pdns/test-misc_hh.cc @@ -145,5 +145,31 @@ BOOST_AUTO_TEST_CASE(test_parseService) { BOOST_CHECK_EQUAL(tp.port, 25); } +BOOST_AUTO_TEST_CASE(test_SimpleMatch) { + BOOST_CHECK_EQUAL(SimpleMatch("").match(std::string("")), true); + BOOST_CHECK_EQUAL(SimpleMatch("?").match(std::string("")), false); + BOOST_CHECK_EQUAL(SimpleMatch("*").match(std::string("")), true); + + BOOST_CHECK_EQUAL(SimpleMatch("abc").match(std::string("abc")), true); + BOOST_CHECK_EQUAL(SimpleMatch("abc").match(std::string("ab")), false); + BOOST_CHECK_EQUAL(SimpleMatch("abc").match(std::string("bc")), false); + + BOOST_CHECK_EQUAL(SimpleMatch("?").match(std::string("a")), true); + BOOST_CHECK_EQUAL(SimpleMatch("a?c").match(std::string("abc")), true); + BOOST_CHECK_EQUAL(SimpleMatch("a?c").match(std::string("ab")), false); + BOOST_CHECK_EQUAL(SimpleMatch("a?c").match(std::string("bc")), false); + + BOOST_CHECK_EQUAL(SimpleMatch("*").match(std::string("*")), true); + BOOST_CHECK_EQUAL(SimpleMatch("a*c").match(std::string("abc")), true); + BOOST_CHECK_EQUAL(SimpleMatch("a*c").match(std::string("ab")), false); + BOOST_CHECK_EQUAL(SimpleMatch("a*c").match(std::string("bc")), false); + + BOOST_CHECK_EQUAL(SimpleMatch("*").match(std::string("abcdefghj")), true); + BOOST_CHECK_EQUAL(SimpleMatch("*a").match(std::string("abca")), true); + BOOST_CHECK_EQUAL(SimpleMatch("*a").match(std::string("abcb")), false); + BOOST_CHECK_EQUAL(SimpleMatch("abc*").match(std::string("abcabcabcabacabac")), true); + BOOST_CHECK_EQUAL(SimpleMatch("abc*").match(std::string("abc")), true); +} + BOOST_AUTO_TEST_SUITE_END()