]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
svcbbase: add docpath SvcParamKey (#1262)
authorMartine Lenders <martine.lenders@tu-dresden.de>
Sun, 15 Mar 2026 22:41:50 +0000 (23:41 +0100)
committerGitHub <noreply@github.com>
Sun, 15 Mar 2026 22:41:50 +0000 (15:41 -0700)
* svcbbase: add docpath SvcParamKey

* tests: add tests for docpath

* svcbbase: remove debug print

* Allow for empty docpath to be printed without ""

* Remove now unnecessary DoCPathParam construtor

dns/rdtypes/svcbbase.py
tests/test_svcb.py

index 148c263cd865b9ebd0926e45d741bb44352f317c..60d9555cf54a7178f2aef817eac2ad99907c7e85 100644 (file)
@@ -37,6 +37,7 @@ class ParamKey(dns.enum.IntEnum):
     IPV6HINT = 6
     DOHPATH = 7
     OHTTP = 8
+    DOCPATH = 10
 
     @classmethod
     def _maximum(cls):
@@ -428,6 +429,25 @@ class OHTTPParam(Param):
         raise NotImplementedError  # pragma: no cover
 
 
+@dns.immutable.immutable
+class DoCPathParam(ALPNParam):
+    @classmethod
+    def emptiness(cls):
+        return Emptiness.ALLOWED
+
+    @classmethod
+    def from_value(cls, value):
+        if value is None or value == "":
+            return None
+        return super().from_value(value)
+
+    @classmethod
+    def from_wire_parser(cls, parser, origin=None):  # pylint: disable=W0613
+        if parser.remaining() == 0:
+            return None
+        return super().from_wire_parser(parser, origin=origin)
+
+
 _class_for_key: dict[ParamKey, Any] = {
     ParamKey.MANDATORY: MandatoryParam,
     ParamKey.ALPN: ALPNParam,
@@ -437,6 +457,7 @@ _class_for_key: dict[ParamKey, Any] = {
     ParamKey.ECH: ECHParam,
     ParamKey.IPV6HINT: IPv6HintParam,
     ParamKey.OHTTP: OHTTPParam,
+    ParamKey.DOCPATH: DoCPathParam,
 }
 
 
index c62a393e23dccfe8b61d62c406e3fa8fdc99a54c..c1a8a6abfaf0b3ce84e955f4e0446c8ce6e98ac9 100644 (file)
@@ -225,6 +225,50 @@ class SVCBTestCase(unittest.TestCase):
         )
         self.check_invalid_inputs(invalid_inputs)
 
+    def test_svcb_docpath(self):
+        valid_inputs_two_items = (
+            '1 . docpath="n,s"',
+            "1 . docpath=n,s",
+            "1 . docpath=\\110,s",
+            '1 . docpath="\\110,s"',
+            "1 . docpath=\\n,s",
+            '1 . docpath="n\\,s"',
+            "1 . docpath=n\\,s",
+            "1 . docpath=n\\044s",
+            "1 . key10=\\001n\\001s",
+        )
+        self.check_valid_inputs(valid_inputs_two_items)
+
+        valid_inputs_one_item = (
+            '1 . docpath="n\\\\,s"',
+            "1 . docpath=n\\\\,s",
+            "1 . docpath=n\\092\\044s",
+            "1 . key10=\\003n,s",
+        )
+        self.check_valid_inputs(valid_inputs_one_item)
+
+        valid_inputs_no_item = (
+            "1 . docpath",
+            '1 . docpath=""',
+            '1 . key10=""',
+            "1 . key10",
+        )
+        self.check_valid_inputs(valid_inputs_no_item)
+
+        invalid_inputs = (
+            "1 . docpath=n,,s",
+            "1 . docpath=01234567890abcdef01234567890abcdef01234567890abcdef"
+            "01234567890abcdef01234567890abcdef01234567890abcdef"
+            "01234567890abcdef01234567890abcdef01234567890abcdef"
+            "01234567890abcdef01234567890abcdef01234567890abcdef"
+            "01234567890abcdef01234567890abcdef01234567890abcdef"
+            "01234567890abcdef",
+            '1 . docpath=",n,s"',
+            '1 . docpath="n,s,"',
+        )
+        self.check_invalid_inputs(invalid_inputs)
+
+
     def test_svcb_unknown(self):
         valid_inputs_one_key = (
             '1 . key23="key45"',
@@ -260,6 +304,18 @@ class SVCBTestCase(unittest.TestCase):
         )
         self.check_valid_inputs(valid_inputs)
 
+        valid_inputs = (
+            '1 . alpn="co" docpath="n,s"',
+            "\\# 18 0001 00 0001000302636f 000a0004016e0173",
+        )
+        self.check_valid_inputs(valid_inputs)
+
+        valid_inputs = (
+            '1 . alpn="co" docpath',
+            "\\# 14 0001 00 0001000302636f 000a0000",
+        )
+        self.check_valid_inputs(valid_inputs)
+
         everything = (
             '100 foo.com. mandatory="alpn,port" alpn="h2,h3" '
             '             no-default-alpn port="12345" ech="abcd" '