Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dns/ttl.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def from_text(text: str) -> int:
:rtype: int
"""

if text.isdigit():
if text.isdecimal():
total = int(text)
elif len(text) == 0:
raise BadTTL
Expand All @@ -51,7 +51,7 @@ def from_text(text: str) -> int:
current = 0
need_digit = True
for c in text:
if c.isdigit():
if c.isdecimal():
current *= 10
current += int(c)
need_digit = False
Expand Down
6 changes: 6 additions & 0 deletions doc/whatsnew.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ TBD
is the bit position, and dns.flags.from_text() / edns_from_text() parse that form
back, so the conversions round-trip. See issue #1264.

* dns.ttl.from_text() now raises dns.ttl.BadTTL, rather than leaking a bare
ValueError, when the text contains a non-decimal Unicode "digit" (e.g. the
superscript ``\u00b2``). Such characters are accepted by ``str.isdigit()`` but
rejected by ``int()``, so they previously escaped the parser's validation. This
also makes zone files with such a TTL fail with a clean dns.exception.SyntaxError.

2.8.0
-----

Expand Down
9 changes: 9 additions & 0 deletions tests/test_ttl.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,12 @@ def test_ttl_technically_too_big(self):
def test_empty(self):
with self.assertRaises(dns.ttl.BadTTL):
dns.ttl.from_text("")

def test_non_decimal_unicode_digits(self):
# str.isdigit() is True for Unicode "digit" characters (e.g. the
# superscript "\u00b2" or the Ethiopic "\u1369") that int() cannot
# convert, so these must be rejected as a BadTTL rather than leaking a
# bare ValueError.
for text in ("\u00b2", "1\u00b2", "\u00b2w", "1\u00b2s", "\u1369"):
with self.assertRaises(dns.ttl.BadTTL):
dns.ttl.from_text(text)