]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
fix(auth): Properly sort API RRSets by content 16951/head
authorPieter Lexis <pieter.lexis@powerdns.com>
Thu, 5 Mar 2026 13:48:53 +0000 (14:48 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Mon, 9 Mar 2026 13:01:47 +0000 (14:01 +0100)
For content, we need to lexographically sort. I would have preferred
canonical ordering of the content. But as this point we have strings we
don't need to roundtrip through the parser.

This also adds an RRSet ordering test.

pdns/ws-auth.cc
regression-tests.api/test_Zones.py

index 5a0092a92637f782a9941fc321ebf26c8129e218..23f7835af7bd4cf518450cf429faa9ec4fc18e53 100644 (file)
@@ -509,7 +509,7 @@ static void fillZone(UeberBackend& backend, const ZoneName& zonename, HttpRespon
            the records and comments below */
         if (rrA.qname == rrB.qname) {
           if (rrA.qtype == rrB.qtype) {
-            return rrB.content < rrA.content;
+            return rrB.content > rrA.content;
           }
           return rrB.qtype < rrA.qtype;
         }
@@ -532,7 +532,7 @@ static void fillZone(UeberBackend& backend, const ZoneName& zonename, HttpRespon
            the records and comments below */
         if (rrA.qname == rrB.qname) {
           if (rrA.qtype == rrB.qtype) {
-            return rrB.content < rrA.content;
+            return rrB.content > rrA.content;
           }
           return rrB.qtype < rrA.qtype;
         }
index 172bed4e842f1791ebf37497a192a5b321fb5938..d5aed7a9e3b49cfe56af3205cb459982b21d5135 100644 (file)
@@ -52,7 +52,6 @@ def eq_zone_rrsets(rrsets, expected):
 
     assert data_got == data_expected, "%r != %r" % (data_got, data_expected)
 
-
 def assert_eq_rrsets(rrsets, expected):
     """Assert rrsets sets are equal, ignoring sort order."""
     key = lambda rrset: (rrset['name'], rrset['type'])
@@ -369,6 +368,67 @@ class AuthZones(ZonesApiTestCase, AuthZonesHelperMixin):
         # check our record has appeared
         self.assertEqual(get_rrset(data, name, 'A')['records'], rrset['records'])
 
+    def test_create_zone_with_records_ordered(self):
+        name = unique_zone_name()
+        rrset_a = {
+            "name": name,
+            "type": "A",
+            "ttl": 3600,
+            "records": [
+                # The contents are not lexographically ordered when creating
+                {
+                    "content": "4.3.2.1",
+                    "disabled": False,
+                },
+                {
+                    "content": "127.0.0.1",
+                    "disabled": False,
+                },
+            ],
+        }
+
+        rrset_ns = {
+            "name": "foo." + name,
+            "type": "NS",
+            "ttl": 3600,
+            "records": [
+                # The contents are not lexographically ordered when creating
+                {
+                    "content": "ns2.example.com.",
+                    "disabled": False,
+                },
+                {
+                    "content": "ns1.example.net.",
+                    "disabled": False,
+                }
+            ],
+        }
+
+        name, payload, data = self.create_zone(name=name, rrsets=[rrset_a, rrset_ns])
+        # check our record has appeared
+        self.assertEqual(get_rrset(data, name, 'A')['records'], [
+            # The content should be lexographically ordered when retrieving
+            {
+                "content": "127.0.0.1",
+                "disabled": False,
+            },
+            {
+                "content": "4.3.2.1",
+                "disabled": False,
+            },
+        ])
+
+        self.assertEqual(get_rrset(data, rrset_ns['name'], 'NS')['records'], [
+            {
+                "content": "ns1.example.net.",
+                "disabled": False,
+            },
+            {
+                "content": "ns2.example.com.",
+                "disabled": False,
+            }
+        ])
+
     def test_create_zone_with_wildcard_records(self):
         name = unique_zone_name()
         rrset = {