[Django] #36746: IndexError in prep_address() when parsing invalid email addresses like 'to@'

13 views
Skip to first unread message

Django

unread,
Nov 19, 2025, 8:34:52 PM (10 days ago) Nov 19
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+---------------------------------------
Reporter: Mahdi Dehghan | Type: Bug
Status: new | Component: Core (Mail)
Version: dev | Severity: Normal
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+---------------------------------------
When parsing invalid email addresses (such as 'to@') in the SMTP backend's
prep_address() method, Python's email parser raises an IndexError instead
of the expected ValueError. This causes the test
test_avoids_sending_to_invalid_addresses to fail.

**Steps to reproduce:
1. Run Django's test suite: `./runtests.py
mail.tests.SMTPBackendTests.test_avoids_sending_to_invalid_addresses`
2. The test fails with IndexError when trying to parse 'to@'

**Root cause:
The prep_address() method at line 172 in
`django/core/mail/backends/smtp.py` directly calls
`AddressHeader.value_parser(address)` without exception handling. When
parsing malformed addresses like 'to@', Python's email parser first raises
HeaderParseError, then during exception handling attempts to parse the
address differently, which leads to an IndexError when trying to access
`value[0]` on an empty string.

**Proposed solution:
Wrap the `AddressHeader.value_parser()` call in a try-except block to
catch `HeaderParseError`, `IndexError`, and `ValueError` exceptions,
converting them to `ValueError` with an appropriate message. This matches
the pattern already used in the deprecated `sanitize_address()` function
in `django/core/mail/message.py` (line 115).

**Expected behavior:
The prep_address() method should catch parsing exceptions and raise
ValueError with message "Invalid address" for invalid addresses, matching
the test's expectation.

**Actual behavior:
IndexError: string index out of range is raised from Python's
email._header_value_parser when parsing addresses like 'to@'.

**Error traceback:
ERROR: test_avoids_sending_to_invalid_addresses
(mail.tests.SMTPBackendTests.test_avoids_sending_to_invalid_addresses)
[<object object at 0x12d0aff70>] (email_address='to@')
Verify invalid addresses can't sneak into SMTP commands through
----------------------------------------------------------------------
Traceback (most recent call last):
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1965, in get_address
token, value = get_group(value)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1923, in get_group
raise errors.HeaderParseError("expected ':' at end of group "
^^^^^^^^^^^^^^^^^
email.errors.HeaderParseError: expected ':' at end of group display name
but found '@'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1791, in get_mailbox
token, value = get_name_addr(value)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1777, in get_name_addr
token, value = get_angle_addr(value)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1702, in get_angle_addr
raise errors.HeaderParseError(
^^^^^^^^^^^^^^^^^
email.errors.HeaderParseError: expected angle-addr but found '@'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/unittest/case.py",
line 58, in testPartExecutor
yield
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/unittest/case.py",
line 539, in subTest
yield
File "tests/mail/tests.py", line 3070, in
test_avoids_sending_to_invalid_addresses
backend.send_messages([email])
^^^^^^^^^^^^^^^^^
File "django/core/mail/backends/smtp.py", line 138, in send_messages
sent = self._send(message)
^^^^^^^^^^^^^^^^^
File "django/core/mail/backends/smtp.py", line 151, in _send
recipients = [self.prep_address(addr) for addr in
email_message.recipients()]
^^^^^^^^^^^^^^^^^
File "django/core/mail/backends/smtp.py", line 172, in prep_address
parsed = AddressHeader.value_parser(address)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/headerregistry.py",
line 333, in value_parser
address_list, value = parser.get_address_list(value)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1988, in get_address_list
token, value = get_address(value)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1968, in get_address
token, value = get_mailbox(value)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1794, in get_mailbox
token, value = get_addr_spec(value)
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1647, in get_addr_spec
token, value = get_domain(value[1:])
^^^^^^^^^^^^^^^^^
File
"/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/email/_header_value_parser.py",
line 1604, in get_domain
if value[0] in CFWS_LEADER:
^^^^^^^^^^^^^^^^^
IndexError: string index out of range
--
Ticket URL: <https://code.djangoproject.com/ticket/36746>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 19, 2025, 8:35:24 PM (10 days ago) Nov 19
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+--------------------------------------
Reporter: Mahdi Dehghan | Owner: (none)
Type: Bug | Status: new
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Mahdi Dehghan):

I'd like to work on this issue. I have a fix ready.
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:1>

Django

unread,
Nov 19, 2025, 8:35:58 PM (10 days ago) Nov 19
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: assigned
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Changes (by Mahdi Dehghan):

* owner: (none) => Mahdi Dehghan
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:2>

Django

unread,
Nov 19, 2025, 8:46:27 PM (10 days ago) Nov 19
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: assigned
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Comment (by Mahdi Dehghan):

Pull request created: https://github.com/django/django/pull/XXXXX
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:3>

Django

unread,
Nov 20, 2025, 7:38:33 AM (10 days ago) Nov 20
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: assigned
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Description changed by Mariusz Felisiak:

Old description:
New description:
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:4>

Django

unread,
Nov 21, 2025, 11:50:52 AM (9 days ago) Nov 21
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: closed
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Changes (by Jacob Walls):

* resolution: => needsinfo
* status: assigned => closed

Comment:

Thanks -- what version of Python 3.12 was this? We only officially support
the latest point release, which at the time I write is 3.12.12.
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:5>

Django

unread,
Nov 25, 2025, 1:53:39 PM (5 days ago) Nov 25
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: closed
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Description changed by Mike Edmunds:
**Steps to reproduce:**
1. Run Django's test suite: `./runtests.py
mail.tests.SMTPBackendTests.test_avoids_sending_to_invalid_addresses`
2. The test fails with IndexError when trying to parse 'to@'

**Root cause:**
The prep_address() method at line 172 in
`django/core/mail/backends/smtp.py` directly calls
`AddressHeader.value_parser(address)` without exception handling. When
parsing malformed addresses like 'to@', Python's email parser first raises
HeaderParseError, then during exception handling attempts to parse the
address differently, which leads to an IndexError when trying to access
`value[0]` on an empty string.

**Proposed solution:**
Wrap the `AddressHeader.value_parser()` call in a try-except block to
catch `HeaderParseError`, `IndexError`, and `ValueError` exceptions,
converting them to `ValueError` with an appropriate message. This matches
the pattern already used in the deprecated `sanitize_address()` function
in `django/core/mail/message.py` (line 115).

**Expected behavior:**
The prep_address() method should catch parsing exceptions and raise
ValueError with message "Invalid address" for invalid addresses, matching
the test's expectation.

**Actual behavior:**
IndexError: string index out of range is raised from Python's
email._header_value_parser when parsing addresses like 'to@'.

**Error traceback:**
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:6>

Django

unread,
Nov 25, 2025, 2:13:53 PM (5 days ago) Nov 25
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: closed
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Comment (by Mike Edmunds):

[This was CPython issue https://github.com/python/cpython/issues/85116. It
was marked completed in April 2024, but without reference to a specific
patch, so I can't tell which Python releases first included the fix.
Current supported Python releases parse 'to@' without raising an error,
instead identifying it as an InvalidHeaderDefect('invalid address in
address-list'). Django 6.0's SMTPBackend.prep_address() converts that
defect to a ValueError as expected.]
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:7>

Django

unread,
Nov 25, 2025, 4:40:56 PM (5 days ago) Nov 25
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: closed
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Changes (by Jacob Walls):

* has_patch: 1 => 0
* resolution: needsinfo => invalid

Comment:

Thanks Mike. Looks like it was 3.12.4, see the tags at the top of
https://github.com/python/cpython/commit/2eaf9ba9ceb4a9d1595b1413bf872db0a4978b13.
I don't think it's worth adjusting the test.
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:8>

Django

unread,
Nov 25, 2025, 5:04:06 PM (5 days ago) Nov 25
to django-...@googlegroups.com
#36746: IndexError in prep_address() when parsing invalid email addresses like
'to@'
-------------------------------+-----------------------------------------
Reporter: Mahdi Dehghan | Owner: Mahdi Dehghan
Type: Bug | Status: closed
Component: Core (Mail) | Version: dev
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+-----------------------------------------
Comment (by Jacob Walls):

#36752 was a dupe.
--
Ticket URL: <https://code.djangoproject.com/ticket/36746#comment:9>
Reply all
Reply to author
Forward
0 new messages