------------------------------------------------------------
revno: 6508
committer: Mark Sapiro <[EMAIL PROTECTED]>
branch nick: 3.0
timestamp: Fri 2007-06-22 11:53:02 -0700
message:
  Scrubber.py - Malformed RFC 2047 encoded filename= parameter can have
                a null byte or other garbage in the extension. Cleaned this.
              - Improved handling of None payloads.
              - Cleaned up a few charset coercions.
  OutgoingRunner.py - Made probe bounce processing and queuing of bounces
                      conditional on having some permanent failure(s).
modified:
  Mailman/Handlers/Scrubber.py
  Mailman/Queue/OutgoingRunner.py

=== modified file 'Mailman/Handlers/Scrubber.py'
--- a/Mailman/Handlers/Scrubber.py      2007-05-28 20:21:41 +0000
+++ b/Mailman/Handlers/Scrubber.py      2007-06-22 18:53:02 +0000
@@ -277,6 +277,7 @@
             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 @@
                 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 @@
                 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 @@
             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 @@
     # 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 @@
         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 @@
     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 @@
             # 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

=== modified file 'Mailman/Queue/OutgoingRunner.py'
--- a/Mailman/Queue/OutgoingRunner.py   2007-01-19 04:38:06 +0000
+++ b/Mailman/Queue/OutgoingRunner.py   2007-06-22 18:53:02 +0000
@@ -87,7 +87,7 @@
             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 @@
                 # 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.



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to