Skip to content
Open
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
11 changes: 7 additions & 4 deletions Lib/encodings/idna.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def ToASCII(label): # type: (str) -> bytes
if len(label) == 0:
raise UnicodeEncodeError("idna", label, 0, 1, "label empty")
else:
raise UnicodeEncodeError("idna", label, 0, len(label), "label too long")
raise UnicodeEncodeError("idna", label, 0, len(label),
f"label too long: {label!r}")

# Step 2: nameprep
label = nameprep(label)
Expand All @@ -95,7 +96,8 @@ def ToASCII(label): # type: (str) -> bytes
if len(label) == 0:
raise UnicodeEncodeError("idna", label, 0, 1, "label empty")
else:
raise UnicodeEncodeError("idna", label, 0, len(label), "label too long")
raise UnicodeEncodeError("idna", label, 0, len(label),
f"label too long: {label!r}")

# Step 5: Check ACE prefix
if label.lower().startswith(sace_prefix):
Expand All @@ -112,7 +114,8 @@ def ToASCII(label): # type: (str) -> bytes
# do not check for empty as we prepend ace_prefix.
if len(label_ascii) < 64:
return label_ascii
raise UnicodeEncodeError("idna", label, 0, len(label), "label too long")
raise UnicodeEncodeError("idna", label, 0, len(label),
f"label too long: {label!r}")

def ToUnicode(label):
if len(label) > 1024:
Expand Down Expand Up @@ -201,7 +204,7 @@ def encode(self, input, errors='strict'):
if len(label) >= 64:
offset = sum(len(l) for l in labels[:i]) + i
raise UnicodeEncodeError("idna", input, offset, offset+len(label),
"label too long")
f"label too long: {label.decode('ascii')!r}")
return result, len(input)

result = bytearray()
Expand Down
23 changes: 23 additions & 0 deletions Lib/test/test_codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,29 @@ def test_builtin_decode_length_limit(self):
with self.assertRaisesRegex(UnicodeDecodeError, "too long"):
(b"xn--016c"+b"a"*70).decode("idna")

def test_error_message_label_too_long(self):
# gh-53891: "label too long" errors should include the offending label
long_label = "a" * 70
domain = f"{long_label}.com"
with self.assertRaises(UnicodeEncodeError) as cm:
domain.encode("idna")
self.assertIn(long_label, cm.exception.reason)
self.assertIn("label too long", cm.exception.reason)

def test_error_message_label_too_long_non_ascii(self):
# gh-53891: non-ASCII labels should also be included in the message
long_label = "\xe4" * 70
domain = f"{long_label}.com"
with self.assertRaises(UnicodeEncodeError) as cm:
domain.encode("idna")
self.assertIn("label too long", cm.exception.reason)

def test_error_message_label_empty(self):
# gh-53891: empty label errors should have a clear reason
with self.assertRaises(UnicodeEncodeError) as cm:
"a..com".encode("idna")
self.assertEqual(cm.exception.reason, "label empty")

def test_stream(self):
r = codecs.getreader("idna")(io.BytesIO(b"abc"))
r.read(3)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Include the offending label value in IDNA codec "label too long" error
messages to make them more informative and easier to debug.
Loading