summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Mailman/Handlers/Scrubber.py28
-rw-r--r--Mailman/Queue/OutgoingRunner.py6
2 files changed, 20 insertions, 14 deletions
diff --git a/Mailman/Handlers/Scrubber.py b/Mailman/Handlers/Scrubber.py
index 4c53b11ac..d7b9c2ce7 100644
--- a/Mailman/Handlers/Scrubber.py
+++ b/Mailman/Handlers/Scrubber.py
@@ -277,6 +277,7 @@ URL: %(url)s
size = len(payload)
url = save_attachment(mlist, part, dir)
desc = part.get('content-description', _('not available'))
+ desc = Utils.oneline(desc, lcset)
filename = part.get_filename(_('not available'))
filename = Utils.oneline(filename, lcset)
replace_payload_by_text(part, _("""\
@@ -318,23 +319,23 @@ URL: %(url)s
text.append(_('Skipped content of type %(partctype)s\n'))
continue
try:
- t = part.get_payload(decode=True)
+ t = part.get_payload(decode=True) or ''
# MAS: TypeError exception can occur if payload is None. This
# was observed with a message that contained an attached
# message/delivery-status part. Because of the special parsing
# of this type, this resulted in a text/plain sub-part with a
# null body. See bug 1430236.
except (binascii.Error, TypeError):
- t = part.get_payload()
+ t = part.get_payload() or ''
# Email problem was solved by Mark Sapiro. (TK)
partcharset = part.get_content_charset('us-ascii')
try:
t = unicode(t, partcharset, 'replace')
except (UnicodeError, LookupError, ValueError, TypeError,
AssertionError):
- # What is the cause to come this exception now ?
+ # We can get here if partcharset is bogus in come way.
# Replace funny characters. We use errors='replace'.
- u = unicode(t, 'ascii', 'replace')
+ t = unicode(t, 'ascii', 'replace')
# Separation is useful
if isinstance(t, basestring):
if not t.endswith('\n'):
@@ -344,12 +345,11 @@ URL: %(url)s
charsets.append(partcharset)
# Now join the text and set the payload
sep = _('-------------- next part --------------\n')
- # The i18n separator is in the list's charset. Coerce it to the
- # message charset.
+ # The i18n separator is in the list's charset. Coerce to unicode.
try:
- s = unicode(sep, lcset, 'replace')
- sep = s.encode(charset, 'replace')
+ sep = unicode(sep, lcset, 'replace')
except (UnicodeError, LookupError, ValueError):
+ # This shouldn't occur.
pass
rept = sep.join(text)
# Replace entire message with text and scrubbed notice.
@@ -360,7 +360,9 @@ URL: %(url)s
try:
replace_payload_by_text(msg, rept, charset)
break
- except UnicodeError:
+ # Bogus charset can throw several exceptions
+ except (UnicodeError, LookupError, ValueError, TypeError,
+ AssertionError):
pass
if format:
msg.set_param('format', format)
@@ -396,7 +398,7 @@ def save_attachment(mlist, msg, dir, filter_html=True):
# i18n file name is encoded
lcset = Utils.GetCharSet(mlist.preferred_language)
filename = Utils.oneline(msg.get_filename(''), lcset)
- fnext = os.path.splitext(filename)[1]
+ filename, fnext = os.path.splitext(filename)
# For safety, we should confirm this is valid ext for content-type
# but we can use fnext if we introduce fnext filtering
if config.SCRUBBER_USE_ATTACHMENT_FILENAME_EXTENSION:
@@ -404,6 +406,8 @@ def save_attachment(mlist, msg, dir, filter_html=True):
ext = fnext or guess_extension(ctype, fnext)
else:
ext = guess_extension(ctype, fnext)
+ # Allow only alphanumerics, dash, underscore, and dot
+ ext = sre.sub('', ext)
if not ext:
# We don't know what it is, so assume it's just a shapeless
# application/octet-stream, unless the Content-Type: is
@@ -421,7 +425,6 @@ def save_attachment(mlist, msg, dir, filter_html=True):
try:
# Now base the filename on what's in the attachment, uniquifying it if
# necessary.
- filename = msg.get_filename()
if not filename or config.SCRUBBER_DONT_USE_ATTACHMENT_FILENAME:
filebase = 'attachment'
else:
@@ -436,7 +439,8 @@ def save_attachment(mlist, msg, dir, filter_html=True):
# which one should we go with? For now, let's go with the one we
# guessed so attachments can't lie about their type. Also, if the
# filename /has/ no extension, then tack on the one we guessed.
- filebase, ignore = os.path.splitext(filename)
+ # The extension was removed from the name above.
+ filebase = filename
# Now we're looking for a unique name for this file on the file
# system. If msgdir/filebase.ext isn't unique, we'll add a counter
# after filebase, e.g. msgdir/filebase-cnt.ext
diff --git a/Mailman/Queue/OutgoingRunner.py b/Mailman/Queue/OutgoingRunner.py
index a7ad3584d..1dd780ca4 100644
--- a/Mailman/Queue/OutgoingRunner.py
+++ b/Mailman/Queue/OutgoingRunner.py
@@ -87,7 +87,7 @@ class OutgoingRunner(Runner, BounceMixin):
return True
except Errors.SomeRecipientsFailed, e:
# Handle local rejects of probe messages differently.
- if msgdata.get('probe_token'):
+ if msgdata.get('probe_token') and e.permfailures:
self._probe_bounce(mlist, msgdata['probe_token'])
else:
# Delivery failed at SMTP time for some or all of the
@@ -99,7 +99,9 @@ class OutgoingRunner(Runner, BounceMixin):
# this is what's sent to the user in the probe message. Maybe
# we should craft a bounce-like message containing information
# about the permanent SMTP failure?
- self._queue_bounces(mlist.fqdn_listname, e.permfailures, msg)
+ if e.permfailures:
+ self._queue_bounces(mlist.fqdn_listname, e.permfailures,
+ msg)
# Move temporary failures to the qfiles/retry queue which will
# occasionally move them back here for another shot at
# delivery.