Skip to content

Commit db6dbf0

Browse files
committed
fix encoding issues when using umlauts in from/to headers
1 parent d638ed7 commit db6dbf0

2 files changed

Lines changed: 26 additions & 23 deletions

File tree

CHANGES.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ Changelog
55
4.1.4 (unreleased)
66
------------------
77

8-
- Nothing changed yet.
8+
- Fix encoding issues when using umlauts in FROM/TO/REPLAY-TO headers
9+
[MrTango]
910

1011

1112
4.1.3 (2023-05-16)

src/collective/easyform/actions.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
from plone.registry.interfaces import IRegistry
4646
from plone.supermodel.exportimport import BaseHandler
4747
from Products.CMFCore.utils import getToolByName
48-
from Products.CMFPlone.utils import safe_unicode
48+
from plone.base.utils import safe_text
49+
from plone.base.utils import safe_bytes
4950
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
5051
from Products.PythonScripts.PythonScript import PythonScript
5152
from six import BytesIO
@@ -122,8 +123,8 @@ def serialize(self, field):
122123
if isinstance(field, (int, float, Decimal, bool)):
123124
return str(field)
124125
if isinstance(field, six.string_types):
125-
return safe_unicode(field)
126-
return safe_unicode(repr(field))
126+
return safe_text(field)
127+
return safe_text(repr(field))
127128

128129
def onSuccess(self, fields, request):
129130
raise NotImplementedError(
@@ -291,15 +292,15 @@ def get_subject(self, fields, request, context):
291292
subject = dollar_replacer(subject, fields)
292293

293294
if isinstance(subject, six.string_types):
294-
subject = safe_unicode(subject)
295+
subject = safe_text(subject)
295296
elif subject and isinstance(subject, (set, tuple, list)):
296-
subject = ", ".join([safe_unicode(s) for s in subject])
297+
subject = ", ".join([safe_text(s) for s in subject])
297298
else:
298299
subject = nosubject
299300

300-
# transform subject into mail header encoded string
301301
email_charset = "utf-8"
302-
msgSubject = self.secure_header_line(subject).encode(email_charset, "replace")
302+
# transform subject into mail header encoded string
303+
msgSubject = safe_bytes(self.secure_header_line(subject))
303304
return Header(msgSubject, email_charset)
304305

305306
def get_header_info(
@@ -314,11 +315,12 @@ def get_header_info(
314315
"""
315316
(to, from_addr, reply) = self.get_addresses(fields, request, context)
316317

318+
email_charset = "utf-8"
317319
headerinfo = OrderedDict()
318-
headerinfo["To"] = self.secure_header_line(to)
319-
headerinfo["From"] = self.secure_header_line(from_addr)
320+
headerinfo["To"] = safe_bytes(self.secure_header_line(to))
321+
headerinfo["From"] = safe_bytes(self.secure_header_line(from_addr))
320322
if reply:
321-
headerinfo["Reply-To"] = self.secure_header_line(reply)
323+
headerinfo["Reply-To"] = safe_bytes(self.secure_header_line(reply))
322324
headerinfo["Subject"] = self.get_subject(fields, request, context)
323325

324326
# CC
@@ -358,7 +360,7 @@ def get_header_row(self):
358360
encoded_titles = []
359361
for t in titles:
360362
if six.PY2 and isinstance(t, six.text_type):
361-
t = t.encode("utf-8")
363+
t = safe_bytes(t)
362364
encoded_titles.append(t)
363365
return encoded_titles
364366

@@ -411,7 +413,7 @@ def get_attachments(self, fields, request):
411413
if not is_file_data(field):
412414
val = self.serialize(field)
413415
if six.PY2:
414-
val = val.encode("utf-8")
416+
val = safe_bytes(val)
415417
csvdata += (val,)
416418

417419
if sendXML:
@@ -434,7 +436,7 @@ def get_attachments(self, fields, request):
434436
writer.writerow(csvdata)
435437
csv = output.getvalue()
436438
if six.PY3:
437-
csv = csv.encode("utf-8")
439+
csv = safe_bytes(csv)
438440
now = DateTime().ISO().replace(" ", "-").replace(":", "")
439441
filename = "formdata_{0}.csv".format(now)
440442
# Set MIME type of attachment to 'application' so that it will be encoded with base64
@@ -482,14 +484,14 @@ def get_mail_text(self, fields, request, context):
482484
headerinfo = self.get_header_info(fields, request, context)
483485
body = self.get_mail_body(fields, request, context)
484486
if six.PY2 and isinstance(body, six.text_type):
485-
body = body.encode("utf-8")
487+
body = safe_bytes(body)
486488
email_charset = "utf-8"
487489
# always use text/plain for encrypted bodies
488490
subtype = (
489491
getattr(self, "gpg_keyid", False) and "plain" or self.body_type or "html"
490492
)
491493
mime_text = MIMEText(
492-
safe_unicode(body).encode(email_charset, "replace"),
494+
safe_bytes(body),
493495
_subtype=subtype,
494496
_charset=email_charset,
495497
)
@@ -538,7 +540,7 @@ def get_mail_text(self, fields, request, context):
538540

539541
# Set the filename parameter
540542
if six.PY2 and isinstance(filename, six.text_type):
541-
filename = filename.encode("utf-8")
543+
filename = safe_bytes(filename)
542544
msg.add_header(
543545
"Content-Disposition", "attachment", filename=("utf-8", "", filename)
544546
)
@@ -579,7 +581,7 @@ def getScript(self, context):
579581
script.manage_proxy((role,))
580582

581583
if six.PY2 and isinstance(body, six.text_type):
582-
body = body.encode("utf-8")
584+
body = safe_bytes(body)
583585
params = "fields, easyform, request"
584586
script.ZPythonScript_edit(params, body)
585587
return script
@@ -682,7 +684,7 @@ def get_header_row(self):
682684
encoded_titles = []
683685
for t in titles:
684686
if six.PY2 and isinstance(t, six.text_type):
685-
t = t.encode("utf-8")
687+
t = safe_bytes(t)
686688
encoded_titles.append(t)
687689
return encoded_titles
688690

@@ -696,11 +698,11 @@ def get_data(row, i):
696698
if is_file_data(data):
697699
data = data.filename
698700
if six.PY2 and isinstance(data, six.text_type):
699-
return data.encode("utf-8")
701+
return safe_bytes(data)
700702
if isinstance(data, (list, tuple, set)):
701703
data = '|'.join(data)
702704
if six.PY2:
703-
return data.encode('utf-8')
705+
return safe_bytes(data)
704706
return data
705707

706708
return [get_data(row, i) for i in names]
@@ -791,7 +793,7 @@ def download_csv(self, response, delimiter):
791793
getattr(self, "UseColumnNames", False), delimiter=delimiter
792794
)
793795
if isinstance(value, six.text_type):
794-
value = value.encode("utf-8")
796+
value = safe_bytes(value)
795797
response.write(value)
796798

797799
def download_tsv(self, response):
@@ -806,7 +808,7 @@ def download_tsv(self, response):
806808
getattr(self, "UseColumnNames", False), delimiter="\t"
807809
)
808810
if isinstance(value, six.text_type):
809-
value = value.encode("utf-8")
811+
value = safe_bytes(value)
810812
response.write(value)
811813

812814
def download_xlsx(self, response):

0 commit comments

Comments
 (0)