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
7 changes: 3 additions & 4 deletions Lib/email/_header_value_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,11 +639,11 @@ def local_part(self):
for tok in self[0] + [DOT]:
if tok.token_type == 'cfws':
continue
if (last_is_tl and tok.token_type == 'dot' and
if (last_is_tl and tok.token_type == 'dot' and last and
last[-1].token_type == 'cfws'):
res[-1] = TokenList(last[:-1])
is_tl = isinstance(tok, TokenList)
if (is_tl and last.token_type == 'dot' and
if (is_tl and last.token_type == 'dot' and tok and
tok[0].token_type == 'cfws'):
res.append(TokenList(tok[1:]))
else:
Expand Down Expand Up @@ -1249,8 +1249,7 @@ def get_bare_quoted_string(value):
bare_quoted_string = BareQuotedString()
value = value[1:]
if value and value[0] == '"':
token, value = get_qcontent(value)
bare_quoted_string.append(token)
return bare_quoted_string, value[1:]
while value and value[0] != '"':
if value[0] in WSP:
token, value = get_fws(value)
Expand Down
41 changes: 39 additions & 2 deletions Lib/test/test_email/test_headerregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1271,12 +1271,12 @@ class TestAddressHeader(TestHeaderBase):
'example.com',
None),

}

# XXX: Need many more examples, and in particular some with names in
# trailing comments, which aren't currently handled. comments in
# general are not handled yet.

}

def example_as_address(self, source, defects, decoded, display_name,
addr_spec, username, domain, comment):
h = self.make_header('sender', source)
Expand All @@ -1294,6 +1294,43 @@ def example_as_address(self, source, defects, decoded, display_name,
# XXX: we have no comment support yet.
#self.assertEqual(a.comment, comment)

example_broken_header_params = {

'just_dquote':
('"',
[errors.InvalidHeaderDefect]*2,
'<>',
'',
'<>',
'',
'',
),

}

def example_broken_header_as_address(
self,
source,
defects,
decoded,
display_name,
addr_spec,
username,
domain,
):
h = self.make_header('sender', source)
self.assertEqual(h, decoded)
self.assertDefectsEqual(h.defects, defects)
a = h.address
self.assertEqual(str(a), decoded)
self.assertEqual(len(h.groups), 1)
self.assertEqual([a], list(h.groups[0].addresses))
self.assertEqual([a], list(h.addresses))
self.assertEqual(a.display_name, display_name)
self.assertEqual(a.addr_spec, addr_spec)
self.assertEqual(a.username, username)
self.assertEqual(a.domain, domain)

def example_as_group(self, source, defects, decoded, display_name,
addr_spec, username, domain, comment):
source = 'foo: {};'.format(source)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
If an email containing an address header that ended in an open double quote
was parsed with a non-``compat32`` policy, accessing the ``username`` attribute
of the mailbox accessed through that header object would result in an
``IndexError``. It now correctly returns an empty string as the result.
Loading