Ticket #6918: emailmessage-header-encoding.diff
File emailmessage-header-encoding.diff, 5.4 KB (added by , 15 years ago) |
---|
-
django/core/mail/message.py
54 54 return msgid 55 55 56 56 57 def forbid_multi_line_headers(name, val ):57 def forbid_multi_line_headers(name, val, encoding): 58 58 """Forbids multi-line headers, to prevent header injection.""" 59 59 val = force_unicode(val) 60 60 if '\n' in val or '\r' in val: … … 65 65 if name.lower() in ('to', 'from', 'cc'): 66 66 result = [] 67 67 for nm, addr in getaddresses((val,)): 68 nm = str(Header(nm , settings.DEFAULT_CHARSET))68 nm = str(Header(nm.encode(encoding), encoding)) 69 69 result.append(formataddr((nm, str(addr)))) 70 70 val = ', '.join(result) 71 71 else: 72 val = Header(val , settings.DEFAULT_CHARSET)72 val = Header(val.encode(encoding), encoding) 73 73 else: 74 74 if name.lower() == 'subject': 75 75 val = Header(val) 76 76 return name, val 77 77 78 79 78 class SafeMIMEText(MIMEText): 80 def __setitem__(self, name, val): 81 name, val = forbid_multi_line_headers(name, val) 79 80 def __init__(self, text, subtype, charset): 81 self.encoding = charset 82 MIMEText.__init__(self, text, subtype, charset) 83 84 def __setitem__(self, name, val): 85 name, val = forbid_multi_line_headers(name, val, self.encoding) 82 86 MIMEText.__setitem__(self, name, val) 83 87 84 85 88 class SafeMIMEMultipart(MIMEMultipart): 89 90 def __init__(self, _subtype='mixed', boundary=None, _subparts=None, encoding=None, **_params): 91 self.encoding = encoding 92 MIMEMultipart.__init__(self, _subtype, boundary, _subparts, **_params) 93 86 94 def __setitem__(self, name, val): 87 name, val = forbid_multi_line_headers(name, val )95 name, val = forbid_multi_line_headers(name, val, self.encoding) 88 96 MIMEMultipart.__setitem__(self, name, val) 89 97 90 91 98 class EmailMessage(object): 92 99 """ 93 100 A container for email information. … … 190 197 191 198 def _create_attachments(self, msg): 192 199 if self.attachments: 200 encoding = self.encoding or settings.DEFAULT_CHARSET 193 201 body_msg = msg 194 msg = SafeMIMEMultipart(_subtype=self.mixed_subtype )202 msg = SafeMIMEMultipart(_subtype=self.mixed_subtype, encoding=encoding) 195 203 if self.body: 196 204 msg.attach(body_msg) 197 205 for attachment in self.attachments: … … 206 214 Converts the content, mimetype pair into a MIME attachment object. 207 215 """ 208 216 basetype, subtype = mimetype.split('/', 1) 217 encoding = self.encoding or settings.DEFAULT_CHARSET 218 209 219 if basetype == 'text': 210 220 attachment = SafeMIMEText(smart_str(content, 211 settings.DEFAULT_CHARSET), subtype, settings.DEFAULT_CHARSET)221 encoding), subtype, encoding) 212 222 else: 213 223 # Encode non-text attachments with base64. 214 224 attachment = MIMEBase(basetype, subtype) … … 263 273 return self._create_attachments(self._create_alternatives(msg)) 264 274 265 275 def _create_alternatives(self, msg): 276 encoding = self.encoding or settings.DEFAULT_CHARSET 266 277 if self.alternatives: 267 278 body_msg = msg 268 msg = SafeMIMEMultipart(_subtype=self.alternative_subtype )279 msg = SafeMIMEMultipart(_subtype=self.alternative_subtype, encoding=encoding) 269 280 if self.body: 270 281 msg.attach(body_msg) 271 282 for alternative in self.alternatives: -
tests/regressiontests/mail/tests.py
112 112 >>> email.message()['To'] 113 113 '=?utf-8?q?S=C3=BCrname=2C_Firstname?= <to@example.com>, other@example.com' 114 114 115 # Regression for #6918 - When a to/from/cc header contains unicode, 116 # make sure headers can be set with a different encoding than utf-8 117 >>> email = EmailMessage('Message from Firstname Sürname', 'Content', 'from@example.com', ['"Sürname, Firstname" <to@example.com>','other@example.com']) 118 >>> email.encoding = 'iso-8859-1' 119 >>> email.message()['To'] 120 '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <to@example.com>, other@example.com' 121 >>> email.message()['Subject'].encode() 122 u'=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=' 123 124 # Make sure headers can be set with a different encoding than utf-8 in SafeMIMEMultipart aswell 125 >>> headers = {"Date": "Fri, 09 Nov 2001 01:08:47 -0000", "Message-ID": "foo"} 126 >>> subject, from_email, to = 'hello', 'from@example.com', '"Sürname, Firstname" <to@example.com>' 127 >>> text_content = 'This is an important message.' 128 >>> html_content = '<p>This is an <strong>important</strong> message.</p>' 129 >>> msg = EmailMultiAlternatives('Message from Firstname Sürname', text_content, from_email, [to], headers=headers) 130 >>> msg.attach_alternative(html_content, "text/html") 131 >>> email.message()['To'] 132 '=?iso-8859-1?q?S=FCrname=2C_Firstname?= <to@example.com>, other@example.com' 133 >>> email.message()['Subject'].encode() 134 u'=?iso-8859-1?q?Message_from_Firstname_S=FCrname?=' 135 115 136 # Handle attachments within an multipart/alternative mail correctly (#9367) 116 137 # (test is not as precise/clear as it could be w.r.t. email tree structure, 117 138 # but it's good enough.)