Opened 4 years ago

Closed 4 years ago

#31817 closed Bug (wontfix)

sanitize_address() raises TypeError for bytestrings.

Reported by: Mike Edmunds Owned by: nobody
Component: Core (Mail) Version: 3.1
Severity: Normal Keywords:
Cc: Florian Apolloner Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The code below works in 3.1b1 (and earlier released versions), but results in a TypeError in 3.1rc1:

$ python manage.py version
3.1rc1
$ python manage.py shell
>>> from django.core.mail.message import sanitize_address
>>> sanitize_address(("Name".encode('utf-8'), "to@example.com"), 'utf-8')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    sanitize_address(("Name".encode('utf-8'), "to@example.com"), 'utf-8')
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/django/core/mail/message.py", line 99, in sanitize_address
    address_parts = nm + localpart + domain
TypeError: can't concat str to bytes

Expected behavior:

$ python manage.py version
3.1b1
$ python manage.py shell
>>> from django.core.mail.message import sanitize_address
>>> sanitize_address(("Name".encode('utf-8'), "to@example.com"), 'utf-8')
'=?utf-8?q?Name?= <to@example.com>'

(Python 3.6, 3.7, 3.8)

This usage comes from the django-anymail package (which I maintain). I realize sanitize_address is not technically a documented Django API, and I'm sure I could find another approach for the particular case this breaks. But I was concerned about it appearing between beta and RC. (FWIW, a quick GitHub search turns up several other apparent uses of sanitize_address in the wild, some with the encoding parameter specified as above.)

Related to the changes for #31784.

Change History (1)

comment:1 by Mariusz Felisiak, 4 years ago

Cc: Florian Apolloner added
Resolution: wontfix
Status: newclosed
Summary: 3.1rc1 injection: TypeError in sanitize_addresssanitize_address() raises TypeError for bytestrings.

Thanks for this report, however sanitize_address() is an internal, undocumented method that expects strings. Moreover there is no need to pass encoded display names or to force encoding on them, e.g.

>>> sanitize_address(('Name', 'to@example.com'), 'utf-8')
'Name <to@example.com>'
>>> sanitize_address(('gęśla jaźń', 'to@example.com'), 'utf-8')
'=?utf-8?b?Z8SZxZtsYSBqYcW6xYQ=?= <to@example.com>'

works as expected. You will get a similar error from email.headerregistry.Address() on Python 3.6.11+, 3.7.8+, and 3.8.4+:

>>> Address(display_name='Name'.encode('utf-8'), username='to', domain='example.com')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/email/headerregistry.py", line 35, in __init__
    inputs = ''.join(filter(None, (display_name, username, domain, addr_spec)))
TypeError: sequence item 0: expected str instance, bytes found
Note: See TracTickets for help on using tickets.
Back to Top