------------------------------------------------------------ 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