Skip to content
Closed
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
5 changes: 4 additions & 1 deletion Lib/email/_header_value_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ def value(self):

@property
def all_defects(self):
return sum((x.all_defects for x in self), self.defects)
if not self:
return self.defects
return self.defects + [
defect for token in self for defect in token.all_defects]

def startswith_fws(self):
return self[0].startswith_fws()
Expand Down
1 change: 1 addition & 0 deletions Lib/email/headerregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class UnstructuredHeader:
def parse(cls, value, kwds):
kwds['parse_tree'] = cls.value_parser(value)
kwds['decoded'] = str(kwds['parse_tree'])
kwds['defects'].extend(kwds['parse_tree'].all_defects)


class UniqueUnstructuredHeader(UnstructuredHeader):
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_email/test__header_value_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@

class TestTokens(TestEmailBase):

# TokenList

def test_all_defects_empty(self):
token = parser.TokenList()
self.assertIs(token.all_defects, token.defects)
token.defects.append(errors.InvalidHeaderDefect())
self.assertIs(token.all_defects, token.defects)

def test_all_defects(self):
leaf = parser.ValueTerminal('text\x00', 'utext')
leaf.defects.append(errors.NonPrintableDefect('\x00'))
token = parser.TokenList([parser.TokenList([leaf]), leaf])
token.defects.append(errors.InvalidHeaderDefect())
self.assertEqual(token.all_defects, token.defects + leaf.defects * 2)
self.assertEqual(len(token.defects), 1)
self.assertEqual(len(leaf.defects), 1)

# EWWhiteSpaceTerminal

def test_EWWhiteSpaceTerminal(self):
Expand Down
70 changes: 58 additions & 12 deletions Lib/test/test_email/test_headerregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,67 @@ def test_defects_is_tuple(self):
@parameterize
class TestUnstructuredHeader(TestHeaderBase):

def string_as_value(self,
source,
decoded,
*args):
l = len(args)
defects = args[0] if l>0 else []
header = 'Subject:' + (' ' if source else '')
folded = header + (args[1] if l>1 else source) + '\n'
h = self.make_header('Subject', source)
self.assertEqual(h, decoded)
self.assertDefectsEqual(h.defects, defects)
self.assertEqual(h.fold(policy=policy.default), folded)
def string_as_value(self, source, decoded, defects=(), folded=None):
folded = source if folded is None else folded
for name in ('Subject', 'X-Test'):
with self.subTest(name=name):
h = self.make_header(name, source)
self.assertEqual(h, decoded)
self.assertDefectsEqual(h.defects, defects)
prefix = name + ':' + (' ' if source else '')
self.assertEqual(h.fold(policy=policy.default),
prefix + folded + '\n')

string_params = {

'empty': ('', ''),

'valid_encoded_word': (
'=?utf-8?q?caf=C3=A9?=',
'café',
[]),

'invalid_base64_padding': (
'=?utf-8?b?YQ?=',
'a',
[errors.InvalidBase64PaddingDefect],
'a'),

'invalid_base64_characters': (
'=?utf-8?b?Y!Q==?=',
'a',
[errors.InvalidBase64CharactersDefect],
'a'),

'undecodable_bytes': (
'=?utf-8?q?=FF?=',
'\ufffd',
[errors.UndecodableBytesDefect] * 2,
'=?unknown-8bit?q?=FF?='),

'unknown_charset': (
'=?invalid-charset?q?word?=',
'word',
[errors.CharsetError],
'word'),

'non_printable_text': (
'text\x00value',
'text\x00value',
[errors.NonPrintableDefect]),

'combined_defects': (
'prefix=?utf-8?b?YQ?=',
'prefixa',
[errors.InvalidHeaderDefect, errors.InvalidBase64PaddingDefect],
'prefixa'),

'missing_whitespace': (
'prefix=?utf-8?q?word?=',
'prefixword',
[errors.InvalidHeaderDefect],
'prefixword'),

'rfc2047_simple_quopri': (
'=?utf-8?q?this_is_a_test?=',
'this is a test',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :class:`email.headerregistry.UnstructuredHeader` to include detected
encoded-word and text defects in its public ``defects`` attribute.
Loading