Opened 5 years ago

Closed 5 years ago

#13682 closed (invalid)

Email attachments not support russian unicode symbols in filename and body

Reported by: satels Owned by: nobody
Component: Core (Mail) Version: 1.2
Severity: Keywords: mail, unicode
Cc: roman@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description (last modified by kmtracey)

#encoding:utf8
from django import test
from django.core import mail

def send_mail(subject='', body='', from_email=None, to=None,
              connection=None, bcc=None, attachments=None, headers=None,
              netangels_headers=None, fail_silently=True, autosubmitted=False):

    email = mail.EmailMessage(subject=subject,
                         body=body,
                         from_email=from_email,
                         to=to,
                         bcc=bcc,
                         connection=connection,
                         attachments=attachments,
                         headers=headers,
                         netangels_headers=netangels_headers,
                         autosubmitted=autosubmitted)
    # Отправка сообщения
    email.send(fail_silently=fail_silently)

class MailBaseFunctionalTest(test.TestCase):

    def setUp(self):
        self.subject = u'Это тестовый заголовок'
        self.body = u"""
Это тестовое тело сообщения"""
        self.from_email = u'Это тестовый отправитель <info@netangels>'
        self.to = [
            u'Это первый тестовый получатель <satels@gmail.com>'
            'roman@netangels.ru'
        ]
        self.bcc = [
            'info@netangels.ru'
        ]
        self.attachments = [
            (u'Это файл 1.rtf', u"Содержание первого файла", 'text/richtext'),
            (u'Это файл 2.doc', u"Содержание второго файла\n", 'application/msword')
        ]
        self.autosubmitted = True
        self.headers = {
            'Test-Header-1': "It test header 1"
        }
        self.netangels_headers = {
            'Test-Header-2': "It test header 2"
        }
        self.connection = mail.get_connection(
            backend='django.core.mail.backends.filebased.EmailBackend')
        send_mail(subject=self.subject,
                  body=self.body,
                  from_email=self.from_email,
                  to=self.to,
                  connection=self.connection,
                  bcc=self.bcc,
                  attachments=self.attachments,
                  headers=self.headers,
                  netangels_headers=self.netangels_headers,
                  fail_silently=False,
                  autosubmitted=self.autosubmitted)

-- return error

======================================================================
ERROR: testBaseFunctional (netangels.engine.tests.mail.MailBaseFunctionalTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/ivan/workspace/ivan_panel/netangels/engine/tests/mail.py", line 43, in setUp
    autosubmitted=self.autosubmitted)
  File "/home/ivan/workspace/ivan_panel/netangels/engine/mail.py", line 68, in send_mail
    email.send(fail_silently=fail_silently)
  File "/usr/local/lib/python2.6/dist-packages/django/core/mail/message.py", line 175, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/usr/local/lib/python2.6/dist-packages/django/core/mail/backends/console.py", line 26, in send_messages
    self.stream.write('%s\n' % message.message().as_string())
  File "/usr/local/lib/python2.6/dist-packages/django/core/mail/message.py", line 144, in message
    msg = self._create_message(msg)
  File "/usr/local/lib/python2.6/dist-packages/django/core/mail/message.py", line 199, in _create_message
    return self._create_attachments(msg)
  File "/usr/local/lib/python2.6/dist-packages/django/core/mail/message.py", line 212, in _create_attachments
    msg.attach(self._create_attachment(*attachment))
  File "/usr/local/lib/python2.6/dist-packages/django/core/mail/message.py", line 239, in _create_attachment
    attachment = self._create_mime_attachment(content, mimetype)
  File "/usr/local/lib/python2.6/dist-packages/django/core/mail/message.py", line 227, in _create_mime_attachment
    Encoders.encode_base64(attachment)
  File "/usr/lib/python2.6/email/encoders.py", line 45, in encode_base64
    encdata = _bencode(orig)
  File "/usr/lib/python2.6/email/encoders.py", line 32, in _bencode
    value = base64.encodestring(s)
  File "/usr/lib/python2.6/base64.py", line 315, in encodestring
    pieces.append(binascii.b2a_base64(chunk))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-9: ordinal not in range(128)

----------------------------------------------------------------------

Change History (3)

comment:1 Changed 5 years ago by satels

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

This error only in body set

comment:2 Changed 5 years ago by kmtracey

  • Description modified (diff)

Fixed traceback formatting.

comment:3 Changed 5 years ago by kmtracey

  • Resolution set to invalid
  • Status changed from new to closed

This attachment specification:

           (u'Это файл 2.doc', u"Содержание второго файла\n", 'application/msword')

looks wrong to me. Content of a real ms word .doc file would be a binary data, not a unicode string. A non-text attachment gets encoded in base64, and that's running into trouble when the payload is unicode instead of a bytestring. If you specify the attachment payload as a bytestring (and remove the netangels_headers and autosubmitted arguments to mail.EmailMessage -- what are those? they are not accepted by Django's mail.EmailMessage), and actually define a test method so that setUp gets called, the test passes. So I think the correct fix is to properly specify the payload of a binary attachment as binary data, not a unicode string.

Note: See TracTickets for help on using tickets.
Back to Top