]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist-2.0.x: Backport pdns_ilexicographical_compare_three_way
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 22 Aug 2025 13:11:40 +0000 (15:11 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 22 Aug 2025 13:12:30 +0000 (15:12 +0200)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/misc.hh

index 0b2d0883833edec5fd1c77c17bdec0951b6505f2..19a15499c9873ab2a5309c7eeeffbe3539ed7bbe 100644 (file)
@@ -379,20 +379,38 @@ inline bool operator<(const struct timespec& lhs, const struct timespec& rhs)
 }
 
 
-inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)  __attribute__((pure));
-inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)
+inline int pdns_ilexicographical_compare_three_way(std::string_view a, std::string_view b)  __attribute__((pure));
+inline int pdns_ilexicographical_compare_three_way(std::string_view a, std::string_view b)
 {
-  const unsigned char *aPtr = (const unsigned char*)a.c_str(), *bPtr = (const unsigned char*)b.c_str();
+  const unsigned char *aPtr = (const unsigned char*)a.data(), *bPtr = (const unsigned char*)b.data();
   const unsigned char *aEptr = aPtr + a.length(), *bEptr = bPtr + b.length();
   while(aPtr != aEptr && bPtr != bEptr) {
-    if ((*aPtr != *bPtr) && (dns_tolower(*aPtr) - dns_tolower(*bPtr)))
-      return (dns_tolower(*aPtr) - dns_tolower(*bPtr)) < 0;
+    if (*aPtr != *bPtr) {
+      if (int rc = dns_tolower(*aPtr) - dns_tolower(*bPtr); rc != 0) {
+        return rc;
+      }
+    }
     aPtr++;
     bPtr++;
   }
-  if(aPtr == aEptr && bPtr == bEptr) // strings are equal (in length)
-    return false;
-  return aPtr == aEptr; // true if first string was shorter
+  // At this point, one of the strings has been completely processed.
+  // Either both have the same length, and they are equal, or one of them
+  // is larger, and compares as higher.
+  if (aPtr == aEptr) {
+    if (bPtr != bEptr) {
+      return -1; // a < b
+    }
+  }
+  else {
+    return 1; // a > b
+  }
+  return 0; // a == b
+}
+
+inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)  __attribute__((pure));
+inline bool pdns_ilexicographical_compare(const std::string& a, const std::string& b)
+{
+  return pdns_ilexicographical_compare_three_way(a, b) < 0;
 }
 
 inline bool pdns_iequals(const std::string& a, const std::string& b) __attribute__((pure));
@@ -401,15 +419,7 @@ inline bool pdns_iequals(const std::string& a, const std::string& b)
   if (a.length() != b.length())
     return false;
 
-  const char *aPtr = a.c_str(), *bPtr = b.c_str();
-  const char *aEptr = aPtr + a.length();
-  while(aPtr != aEptr) {
-    if((*aPtr != *bPtr) && (dns_tolower(*aPtr) != dns_tolower(*bPtr)))
-      return false;
-    aPtr++;
-    bPtr++;
-  }
-  return true;
+  return pdns_ilexicographical_compare_three_way(a, b) == 0;
 }
 
 inline bool pdns_iequals_ch(const char a, const char b) __attribute__((pure));