From 08de84078eb46cfc02d03bbac2d65244feb2d442 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sun, 6 Oct 2024 18:44:36 -0700 Subject: [PATCH] idna_decode barfs on .., so needs a work-around --- octodns/idna.py | 5 ++++- tests/test_octodns_idna.py | 6 ++++-- tests/test_octodns_record.py | 12 ++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/octodns/idna.py b/octodns/idna.py index 38af0f6..046116e 100644 --- a/octodns/idna.py +++ b/octodns/idna.py @@ -45,7 +45,10 @@ def idna_decode(name): if name.startswith('*'): # idna.decode doesn't like the * return f'*.{_decode(name[2:])}' - return _decode(name) + # idna.decode doesn't like .. so we stick a unique placeholder + # anywhere we see it and then remove it again afterwards. + name = name.replace('..', '.pl-a-ce--hold-e--r.') + return _decode(name).replace('.pl-a-ce--hold-e--r.', '..') except _IDNAError as e: raise IdnaError(e) # not idna, just return as-is diff --git a/tests/test_octodns_idna.py b/tests/test_octodns_idna.py index 4571065..08694fa 100644 --- a/tests/test_octodns_idna.py +++ b/tests/test_octodns_idna.py @@ -66,8 +66,10 @@ class TestIdna(TestCase): self.assertEqual('Empty Label', str(ctx.exception)) with self.assertRaises(IdnaError) as ctx: - idna_decode('xn--djvu-1na6c..com.') - self.assertEqual('Empty Label', str(ctx.exception)) + idna_decode('xn--djvu-1na6c.something-.com.') + self.assertEqual( + 'Label must not start or end with a hyphen', str(ctx.exception) + ) class TestIdnaDict(TestCase): diff --git a/tests/test_octodns_record.py b/tests/test_octodns_record.py index b87b13c..a35afce 100644 --- a/tests/test_octodns_record.py +++ b/tests/test_octodns_record.py @@ -692,6 +692,18 @@ class TestRecordValidation(TestCase): reason, ) + # double dots in idna names + with self.assertRaises(ValidationError) as ctx: + Record.new( + self.zone, + 'niño.', + {'ttl': 301, 'type': 'A', 'value': '1.2.3.4'}, + ) + reason = ctx.exception.reasons[0] + self.assertEqual( + 'invalid name, double `.` in "niño..unit.tests."', reason + ) + # no ttl with self.assertRaises(ValidationError) as ctx: Record.new(self.zone, '', {'type': 'A', 'value': '1.2.3.4'})