Skip to content

Commit 6826fe4

Browse files
committed
fix encoding issues when using umlauts in from/to headers.
1 parent c5c8f5d commit 6826fe4

2 files changed

Lines changed: 26 additions & 22 deletions

File tree

CHANGES.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ Changelog
111111

112112
- make ReCaptcha fields not required during PloneFormGen migration [ThibautBorn]
113113

114+
- Fix encoding issues when using umlauts in FROM/TO/REPLAY-TO headers
115+
[MrTango]
116+
114117

115118
4.1.3 (2023-05-16)
116119
------------------

src/collective/easyform/actions.py

Lines changed: 23 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(
@@ -315,10 +316,10 @@ def get_header_info(
315316
(to, from_addr, reply) = self.get_addresses(fields, request, context)
316317

317318
headerinfo = OrderedDict()
318-
headerinfo["To"] = self.secure_header_line(to)
319-
headerinfo["From"] = self.secure_header_line(from_addr)
319+
headerinfo["To"] = safe_bytes(self.secure_header_line(to))
320+
headerinfo["From"] = safe_bytes(self.secure_header_line(from_addr))
320321
if reply:
321-
headerinfo["Reply-To"] = self.secure_header_line(reply)
322+
headerinfo["Reply-To"] = safe_bytes(self.secure_header_line(reply))
322323
headerinfo["Subject"] = self.get_subject(fields, request, context)
323324

324325
# CC
@@ -358,7 +359,7 @@ def get_header_row(self):
358359
encoded_titles = []
359360
for t in titles:
360361
if six.PY2 and isinstance(t, six.text_type):
361-
t = t.encode("utf-8")
362+
t = safe_bytes(t)
362363
encoded_titles.append(t)
363364
return encoded_titles
364365

@@ -411,7 +412,7 @@ def get_attachments(self, fields, request):
411412
if not is_file_data(field):
412413
val = self.serialize(field)
413414
if six.PY2:
414-
val = val.encode("utf-8")
415+
val = safe_bytes(val)
415416
csvdata += (val,)
416417

417418
if sendXML:
@@ -434,7 +435,7 @@ def get_attachments(self, fields, request):
434435
writer.writerow(csvdata)
435436
csv = output.getvalue()
436437
if six.PY3:
437-
csv = csv.encode("utf-8")
438+
csv = safe_bytes(csv)
438439
now = DateTime().ISO().replace(" ", "-").replace(":", "")
439440
filename = "formdata_{0}.csv".format(now)
440441
# Set MIME type of attachment to 'application' so that it will be encoded with base64
@@ -482,14 +483,14 @@ def get_mail_text(self, fields, request, context):
482483
headerinfo = self.get_header_info(fields, request, context)
483484
body = self.get_mail_body(fields, request, context)
484485
if six.PY2 and isinstance(body, six.text_type):
485-
body = body.encode("utf-8")
486+
body = safe_bytes(body)
486487
email_charset = "utf-8"
487488
# always use text/plain for encrypted bodies
488489
subtype = (
489490
getattr(self, "gpg_keyid", False) and "plain" or self.body_type or "html"
490491
)
491492
mime_text = MIMEText(
492-
safe_unicode(body).encode(email_charset, "replace"),
493+
safe_bytes(body),
493494
_subtype=subtype,
494495
_charset=email_charset,
495496
)
@@ -538,7 +539,7 @@ def get_mail_text(self, fields, request, context):
538539

539540
# Set the filename parameter
540541
if six.PY2 and isinstance(filename, six.text_type):
541-
filename = filename.encode("utf-8")
542+
filename = safe_bytes(filename)
542543
msg.add_header(
543544
"Content-Disposition", "attachment", filename=("utf-8", "", filename)
544545
)
@@ -588,7 +589,7 @@ def getScript(self, context):
588589
script.manage_proxy((role,))
589590

590591
if six.PY2 and isinstance(body, six.text_type):
591-
body = body.encode("utf-8")
592+
body = safe_bytes(body)
592593
params = "fields, easyform, request"
593594
script.ZPythonScript_edit(params, body)
594595
return script
@@ -691,7 +692,7 @@ def get_header_row(self):
691692
encoded_titles = []
692693
for t in titles:
693694
if six.PY2 and isinstance(t, six.text_type):
694-
t = t.encode("utf-8")
695+
t = safe_bytes(t)
695696
encoded_titles.append(t)
696697
return encoded_titles
697698

@@ -705,11 +706,11 @@ def get_data(row, i):
705706
if is_file_data(data):
706707
data = data.filename
707708
if six.PY2 and isinstance(data, six.text_type):
708-
return data.encode("utf-8")
709+
return safe_bytes(data)
709710
if isinstance(data, (list, tuple, set)):
710711
data = '|'.join(data)
711712
if six.PY2:
712-
return data.encode('utf-8')
713+
return safe_bytes(data)
713714
return data
714715

715716
return [get_data(row, i) for i in names]
@@ -800,7 +801,7 @@ def download_csv(self, response, delimiter):
800801
getattr(self, "UseColumnNames", False), delimiter=delimiter
801802
)
802803
if isinstance(value, six.text_type):
803-
value = value.encode("utf-8")
804+
value = safe_bytes(value)
804805
response.write(value)
805806

806807
def download_tsv(self, response):
@@ -815,7 +816,7 @@ def download_tsv(self, response):
815816
getattr(self, "UseColumnNames", False), delimiter="\t"
816817
)
817818
if isinstance(value, six.text_type):
818-
value = value.encode("utf-8")
819+
value = safe_bytes(value)
819820
response.write(value)
820821

821822
def download_xlsx(self, response):

0 commit comments

Comments
 (0)