Skip to content

Commit d9cad07

Browse files
sergey-miryanovpicnixzhugovk
authored
gh-134155: fix AttributeError in email._header_value_parser.get_address (#134194)
Append the defect to defects instead of to the parse tree. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
1 parent 1b55e12 commit d9cad07

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

Lib/email/_header_value_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ def get_dtext(value):
15751575
def _check_for_early_dl_end(value, domain_literal):
15761576
if value:
15771577
return False
1578-
domain_literal.append(errors.InvalidHeaderDefect(
1578+
domain_literal.defects.append(errors.InvalidHeaderDefect(
15791579
"end of input inside domain-literal"))
15801580
domain_literal.append(ValueTerminal(']', 'domain-literal-end'))
15811581
return True
@@ -1594,9 +1594,9 @@ def get_domain_literal(value):
15941594
raise errors.HeaderParseError("expected '[' at start of domain-literal "
15951595
"but found '{}'".format(value))
15961596
value = value[1:]
1597+
domain_literal.append(ValueTerminal('[', 'domain-literal-start'))
15971598
if _check_for_early_dl_end(value, domain_literal):
15981599
return domain_literal, value
1599-
domain_literal.append(ValueTerminal('[', 'domain-literal-start'))
16001600
if value[0] in WSP:
16011601
token, value = get_fws(value)
16021602
domain_literal.append(token)

Lib/test/test_email/test__header_value_parser.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2491,6 +2491,38 @@ def test_get_address_quoted_strings_in_atom_list(self):
24912491
self.assertEqual(address.all_mailboxes[0].domain, 'example.com')
24922492
self.assertEqual(address.all_mailboxes[0].addr_spec, '"example example"@example.com')
24932493

2494+
def test_get_address_with_invalid_domain(self):
2495+
address = self._test_get_x(parser.get_address,
2496+
'<T@[',
2497+
'<T@[]>',
2498+
'<T@[]>',
2499+
[errors.InvalidHeaderDefect, # missing trailing '>' on angle-addr
2500+
errors.InvalidHeaderDefect, # end of input inside domain-literal
2501+
],
2502+
'')
2503+
self.assertEqual(address.token_type, 'address')
2504+
self.assertEqual(len(address.mailboxes), 0)
2505+
self.assertEqual(len(address.all_mailboxes), 1)
2506+
self.assertEqual(address.all_mailboxes[0].domain, '[]')
2507+
self.assertEqual(address.all_mailboxes[0].local_part, 'T')
2508+
self.assertEqual(address.all_mailboxes[0].token_type, 'invalid-mailbox')
2509+
self.assertEqual(address[0].token_type, 'invalid-mailbox')
2510+
2511+
address = self._test_get_x(parser.get_address,
2512+
'!an??:=m==fr2@[C',
2513+
'!an??:=m==fr2@[C];',
2514+
'!an??:=m==fr2@[C];',
2515+
[errors.InvalidHeaderDefect, # end of header in group
2516+
errors.InvalidHeaderDefect, # end of input inside domain-literal
2517+
],
2518+
'')
2519+
self.assertEqual(address.token_type, 'address')
2520+
self.assertEqual(len(address.mailboxes), 0)
2521+
self.assertEqual(len(address.all_mailboxes), 1)
2522+
self.assertEqual(address.all_mailboxes[0].domain, '[C]')
2523+
self.assertEqual(address.all_mailboxes[0].local_part, '=m==fr2')
2524+
self.assertEqual(address.all_mailboxes[0].token_type, 'invalid-mailbox')
2525+
self.assertEqual(address[0].token_type, 'group')
24942526

24952527
# get_address_list
24962528

@@ -2765,6 +2797,19 @@ def test_parse_valid_message_id(self):
27652797
)
27662798
self.assertEqual(message_id.token_type, 'message-id')
27672799

2800+
def test_parse_message_id_with_invalid_domain(self):
2801+
message_id = self._test_parse_x(
2802+
parser.parse_message_id,
2803+
"<T@[",
2804+
"<T@[]>",
2805+
"<T@[]>",
2806+
[errors.ObsoleteHeaderDefect] + [errors.InvalidHeaderDefect] * 2,
2807+
[],
2808+
)
2809+
self.assertEqual(message_id.token_type, 'message-id')
2810+
self.assertEqual(str(message_id.all_defects[-1]),
2811+
"end of input inside domain-literal")
2812+
27682813
def test_parse_message_id_with_remaining(self):
27692814
message_id = self._test_parse_x(
27702815
parser.parse_message_id,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:mod:`email`: Fix parsing of email message ID with invalid domain.

0 commit comments

Comments
 (0)