gh-134152: Fix UnboundLocalError in email._header_value_parser _get_ptext_to_endchars (#134233)

Fix an UnboundLocalError that can occur when parsing certain delimited constructs in headers (domain literals, quoted strings, comments). After the fix the _get_ptext_to_endchars returns an empty string if there is no content after the opening delimiter. The calling code is responsible for handling the lack of the trailing delimiter, which it already does; this edge case was the header ending immediately after the opening delimiter.
This commit is contained in:
R. David Murray 2025-05-25 18:09:32 -04:00 committed by GitHub
parent 7b1a700231
commit a32ea45699
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 0 deletions

View file

@ -1020,6 +1020,8 @@ def _get_ptext_to_endchars(value, endchars):
a flag that is True iff there were any quoted printables decoded.
"""
if not value:
return '', '', False
fragment, *remainder = _wsp_splitter(value, 1)
vchars = []
escape = False

View file

@ -463,6 +463,19 @@ class TestParser(TestParserMixin, TestEmailBase):
[errors.NonPrintableDefect], ')')
self.assertEqual(ptext.defects[0].non_printables[0], '\x00')
def test_get_qp_ctext_close_paren_only(self):
self._test_get_x(parser.get_qp_ctext,
')', '', ' ', [], ')')
def test_get_qp_ctext_open_paren_only(self):
self._test_get_x(parser.get_qp_ctext,
'(', '', ' ', [], '(')
def test_get_qp_ctext_no_end_char(self):
self._test_get_x(parser.get_qp_ctext,
'', '', ' ', [], '')
# get_qcontent
def test_get_qcontent_only(self):
@ -503,6 +516,14 @@ class TestParser(TestParserMixin, TestEmailBase):
[errors.NonPrintableDefect], '"')
self.assertEqual(ptext.defects[0].non_printables[0], '\x00')
def test_get_qcontent_empty(self):
self._test_get_x(parser.get_qcontent,
'"', '', '', [], '"')
def test_get_qcontent_no_end_char(self):
self._test_get_x(parser.get_qcontent,
'', '', '', [], '')
# get_atext
def test_get_atext_only(self):
@ -1283,6 +1304,18 @@ class TestParser(TestParserMixin, TestEmailBase):
self._test_get_x(parser.get_dtext,
'foo[bar', 'foo', 'foo', [], '[bar')
def test_get_dtext_open_bracket_only(self):
self._test_get_x(parser.get_dtext,
'[', '', '', [], '[')
def test_get_dtext_close_bracket_only(self):
self._test_get_x(parser.get_dtext,
']', '', '', [], ']')
def test_get_dtext_empty(self):
self._test_get_x(parser.get_dtext,
'', '', '', [], '')
# get_domain_literal
def test_get_domain_literal_only(self):

View file

@ -0,0 +1,2 @@
Fixed :exc:`UnboundLocalError` that could occur during :mod:`email` header
parsing if an expected trailing delimiter is missing in some contexts.