From: Christian Hofstaedtler Date: Mon, 17 Mar 2014 15:39:38 +0000 (+0100) Subject: Make API search case insensitive X-Git-Tag: rec-3.6.0-rc1~126^2^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F1334%2Fhead;p=thirdparty%2Fpdns.git Make API search case insensitive --- diff --git a/pdns/misc.hh b/pdns/misc.hh index 60855138fb..917fd36ccf 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -338,6 +338,15 @@ inline bool pdns_iequals(const std::string& a, const std::string& b) return true; } +inline bool pdns_iequals_ch(const char a, const char b) __attribute__((pure)); +inline bool pdns_iequals_ch(const char a, const char b) +{ + if ((a != b) && (dns_tolower(a) != dns_tolower(b))) + return false; + + return true; +} + // lifted from boost, with thanks class AtomicCounter { @@ -438,6 +447,17 @@ struct CIStringPairCompare: public std::binary_function, } }; +inline size_t pdns_ci_find(const string& haystack, const string& needle) +{ + string::const_iterator it = std::search(haystack.begin(), haystack.end(), + needle.begin(), needle.end(), pdns_iequals_ch); + if (it == haystack.end()) { + // not found + return string::npos; + } else { + return it - haystack.begin(); + } +} pair splitField(const string& inp, char sepa); diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 0a86b704bd..9569e14ee3 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -747,7 +747,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) { BOOST_FOREACH(const DomainInfo& di, domains) { string zoneId = apiZoneNameToId(di.zone); - if (di.zone.find(q) != string::npos) { + if (pdns_ci_find(di.zone, q) != string::npos) { Value object; object.SetObject(); object.AddMember("type", "zone", doc.GetAllocator()); @@ -768,7 +768,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) { if (!rr.qtype.getCode()) continue; // skip empty non-terminals - if (rr.qname.find(q) == string::npos && rr.content.find(q) == string::npos) + if (pdns_ci_find(rr.qname, q) == string::npos && pdns_ci_find(rr.content, q) == string::npos) continue; Value object; @@ -787,7 +787,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) { di.backend->listComments(di.id); while(di.backend->getComment(comment)) { - if (comment.qname.find(q) == string::npos && comment.content.find(q) == string::npos) + if (pdns_ci_find(comment.qname, q) == string::npos && pdns_ci_find(comment.content, q) == string::npos) continue; Value object; diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 78e9ed62cf..7995f0a724 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -509,6 +509,15 @@ class AuthZones(ApiTestCase): # should return zone, SOA, ns1, ns2 self.assertEquals(len(r.json()), 4) + def test_SearchRRCaseInsensitive(self): + name = 'search-rr-insenszone.name' + self.create_zone(name=name) + r = self.session.get(self.url("/servers/localhost/search-data?q=rr-insensZONE")) + self.assertSuccessJson(r) + print r.json() + # should return zone, SOA, ns1, ns2 + self.assertEquals(len(r.json()), 4) + @unittest.skipIf(not isRecursor(), "Not applicable") class RecursorZones(ApiTestCase):