def decode_payload(self, encoding, payload): """ Decode attachment payload data. :param encoding: The current encoding of the payload data. :param payload: the payload data """ cte = encoding.lower() if cte == 'quoted-printable': return utils._qdecode(payload) elif cte == 'base64': try: return utils._bdecode(payload) except binascii.Error: # Incorrect padding return payload elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): sfp = StringIO() try: uu.decode(StringIO(payload + '\n'), sfp, quiet=True) payload = sfp.getvalue() except uu.Error: # Some decoding problem return payload
def get_payload(self, i=None, decode=False): if i is None: payload = self._payload elif not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) else: payload = self._payload[i] if decode: if self.is_multipart(): return cte = self.get('content-transfer-encoding', '').lower() if cte == 'quoted-printable': return utils._qdecode(payload) if cte == 'base64': try: return utils._bdecode(payload) except binascii.Error: return payload elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): sfp = StringIO() try: uu.decode(StringIO(payload + '\n'), sfp, quiet=True) payload = sfp.getvalue() except uu.Error: return payload return payload
def get_payload(self, i = None, decode = False): if i is None: payload = self._payload elif not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) else: payload = self._payload[i] if decode: if self.is_multipart(): return cte = self.get('content-transfer-encoding', '').lower() if cte == 'quoted-printable': return utils._qdecode(payload) if cte == 'base64': try: return utils._bdecode(payload) except binascii.Error: return payload elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): sfp = StringIO() try: uu.decode(StringIO(payload + '\n'), sfp, quiet=True) payload = sfp.getvalue() except uu.Error: return payload return payload
def get_payload(self, i=None, decode=False): """Return a reference to the payload. The payload will either be a list object or a string. If you mutate the list object, you modify the message's payload in place. Optional i returns that index into the payload. Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding header (default is False). When True and the message is not a multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or the header is missing, or if the payload has bogus data (i.e. bogus base64 or uuencoded data), the payload is returned as-is. If the message is a multipart and the decode flag is True, then None is returned. """ if i is None: payload = self._payload elif not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) else: payload = self._payload[i] if not decode: return payload # Decoded payloads always return bytes. XXX split this part out into # a new method called .get_decoded_payload(). if self.is_multipart(): return None cte = self.get('content-transfer-encoding', '').lower() if cte == 'quoted-printable': return utils._qdecode(payload) elif cte == 'base64': try: if isinstance(payload, str): payload = payload.encode('raw-unicode-escape') return base64.b64decode(payload) #return utils._bdecode(payload) except binascii.Error: # Incorrect padding pass elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): in_file = BytesIO(payload.encode('raw-unicode-escape')) out_file = BytesIO() try: uu.decode(in_file, out_file, quiet=True) return out_file.getvalue() except uu.Error: # Some decoding problem pass # Is there a better way to do this? We can't use the bytes # constructor. if isinstance(payload, str): return payload.encode('raw-unicode-escape') return payload
def get_payload(self, i=None, decode=False): if self.is_multipart(): if decode: return if i is None: return self._payload return self._payload[i] if i is not None and not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) payload = self._payload cte = str(self.get('content-transfer-encoding', '')).lower() if isinstance(payload, str): if utils._has_surrogates(payload): bpayload = payload.encode('ascii', 'surrogateescape') if not decode: try: payload = bpayload.decode( self.get_param('charset', 'ascii'), 'replace') except LookupError: payload = bpayload.decode('ascii', 'replace') if decode: try: bpayload = payload.encode('ascii') except UnicodeError: bpayload = payload.encode('raw-unicode-escape') elif decode: try: bpayload = payload.encode('ascii') except UnicodeError: bpayload = payload.encode('raw-unicode-escape') if not decode: return payload if cte == 'quoted-printable': return utils._qdecode(bpayload) if cte == 'base64': (value, defects) = decode_b(b''.join(bpayload.splitlines())) for defect in defects: self.policy.handle_defect(self, defect) return value if cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): in_file = BytesIO(bpayload) out_file = BytesIO() try: uu.decode(in_file, out_file, quiet=True) return out_file.getvalue() except uu.Error: return bpayload if isinstance(payload, str): return bpayload return payload
def get_payload(self, i=None, decode=False): """Return a reference to the payload. The payload will either be a list object or a string. If you mutate the list object, you modify the message's payload in place. Optional i returns that index into the payload. Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding header (default is False). When True and the message is not a multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or the header is missing, or if the payload has bogus data (i.e. bogus base64 or uuencoded data), the payload is returned as-is. If the message is a multipart and the decode flag is True, then None is returned. """ if i is None: payload = self._payload elif not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) else: payload = self._payload[i] if decode: if self.is_multipart(): return None cte = self.get('content-transfer-encoding', '').lower() if cte == 'quoted-printable': return utils._qdecode(payload) elif cte == 'base64': try: return utils._bdecode(payload) except binascii.Error: # Incorrect padding return payload elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): sfp = StringIO() try: uu.decode(StringIO(payload+'\n'), sfp, quiet=True) payload = sfp.getvalue() except uu.Error: # Some decoding problem return payload # Everything else, including encodings with 8bit or 7bit are returned # unchanged. return payload
def get_payload(self, i=None, decode=False): """Return a reference to the payload. The payload will either be a list object or a string. If you mutate the list object, you modify the message's payload in place. Optional i returns that index into the payload. Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding header (default is False). When True and the message is not a multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or the header is missing, or if the payload has bogus data (i.e. bogus base64 or uuencoded data), the payload is returned as-is. If the message is a multipart and the decode flag is True, then None is returned. """ if i is None: payload = self._payload elif not isinstance(self._payload, list): raise TypeError("Expected list, got %s" % type(self._payload)) else: payload = self._payload[i] if decode: if self.is_multipart(): return None cte = self.get("content-transfer-encoding", "").lower() if cte == "quoted-printable": return utils._qdecode(payload) elif cte == "base64": try: return utils._bdecode(payload) except binascii.Error: # Incorrect padding return payload elif cte in ("x-uuencode", "uuencode", "uue", "x-uue"): sfp = StringIO() try: uu.decode(StringIO(payload + "\n"), sfp, quiet=True) payload = sfp.getvalue() except uu.Error: # Some decoding problem return payload # Everything else, including encodings with 8bit or 7bit are returned # unchanged. return payload
def get_payload(self, i=None, decode=False): if self.is_multipart(): if decode: return if i is None: return self._payload return self._payload[i] if i is not None and not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) payload = self._payload cte = str(self.get('content-transfer-encoding', '')).lower() if isinstance(payload, str): if utils._has_surrogates(payload): bpayload = payload.encode('ascii', 'surrogateescape') if not decode: try: payload = bpayload.decode(self.get_param('charset', 'ascii'), 'replace') except LookupError: payload = bpayload.decode('ascii', 'replace') if decode: try: bpayload = payload.encode('ascii') except UnicodeError: bpayload = payload.encode('raw-unicode-escape') elif decode: try: bpayload = payload.encode('ascii') except UnicodeError: bpayload = payload.encode('raw-unicode-escape') if not decode: return payload if cte == 'quoted-printable': return utils._qdecode(bpayload) if cte == 'base64': (value, defects) = decode_b(b''.join(bpayload.splitlines())) for defect in defects: self.policy.handle_defect(self, defect) return value if cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): in_file = BytesIO(bpayload) out_file = BytesIO() try: uu.decode(in_file, out_file, quiet=True) return out_file.getvalue() except uu.Error: return bpayload if isinstance(payload, str): return bpayload return payload
def get_payload(self, i = None, decode = False): """Return a reference to the payload. The payload will either be a list object or a string. If you mutate the list object, you modify the message's payload in place. Optional i returns that index into the payload. Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding header (default is False). When True and the message is not a multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or the header is missing, or if the payload has bogus data (i.e. bogus base64 or uuencoded data), the payload is returned as-is. If the message is a multipart and the decode flag is True, then None is returned. """ if i is None: payload = self._payload elif not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) else: payload = self._payload[i] if decode: if self.is_multipart(): return cte = self.get('content-transfer-encoding', '').lower() if cte == 'quoted-printable': return utils._qdecode(payload) if cte == 'base64': try: return utils._bdecode(payload) except binascii.Error: return payload elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): sfp = StringIO() try: uu.decode(StringIO(payload + '\n'), sfp, quiet=True) payload = sfp.getvalue() except uu.Error: return payload return payload
def get_payload(self, i=None, decode=False): """Return a reference to the payload. The payload will either be a list object or a string. If you mutate the list object, you modify the message's payload in place. Optional i returns that index into the payload. Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding header (default is False). When True and the message is not a multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or the header is missing, or if the payload has bogus data (i.e. bogus base64 or uuencoded data), the payload is returned as-is. If the message is a multipart and the decode flag is True, then None is returned. """ # Here is the logic table for this code, based on the email5.0.0 code: # i decode is_multipart result # ------ ------ ------------ ------------------------------ # None True True None # i True True None # None False True _payload (a list) # i False True _payload element i (a Message) # i False False error (not a list) # i True False error (not a list) # None False False _payload # None True False _payload decoded (bytes) # Note that Barry planned to factor out the 'decode' case, but that # isn't so easy now that we handle the 8 bit data, which needs to be # converted in both the decode and non-decode path. if self.is_multipart(): if decode: return None if i is None: return self._payload else: return self._payload[i] # For backward compatibility, Use isinstance and this error message # instead of the more logical is_multipart test. if i is not None and not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) payload = self._payload # cte might be a Header, so for now stringify it. cte = str(self.get('content-transfer-encoding', '')).lower() # payload may be bytes here. if isinstance(payload, str): if utils._has_surrogates(payload): bpayload = payload.encode('ascii', 'surrogateescape') if not decode: try: payload = bpayload.decode( self.get_param('charset', 'ascii'), 'replace') except LookupError: payload = bpayload.decode('ascii', 'replace') elif decode: try: bpayload = payload.encode('ascii') except UnicodeError: # This won't happen for RFC compliant messages (messages # containing only ASCII codepoints in the unicode input). # If it does happen, turn the string into bytes in a way # guaranteed not to fail. bpayload = payload.encode('raw-unicode-escape') if not decode: return payload if cte == 'quoted-printable': return utils._qdecode(bpayload) elif cte == 'base64': # XXX: this is a bit of a hack; decode_b should probably be factored # out somewhere, but I haven't figured out where yet. value, defects = decode_b(b''.join(bpayload.splitlines())) for defect in defects: self.policy.handle_defect(self, defect) return value elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): in_file = BytesIO(bpayload) out_file = BytesIO() try: uu.decode(in_file, out_file, quiet=True) return out_file.getvalue() except uu.Error: # Some decoding problem return bpayload if isinstance(payload, str): return bpayload return payload
def get_payload(self, i=None, decode=False): """Return a reference to the payload. The payload will either be a list object or a string. If you mutate the list object, you modify the message's payload in place. Optional i returns that index into the payload. Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding header (default is False). When True and the message is not a multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or the header is missing, or if the payload has bogus data (i.e. bogus base64 or uuencoded data), the payload is returned as-is. If the message is a multipart and the decode flag is True, then None is returned. """ # Here is the logic table for this code, based on the email5.0.0 code: # i decode is_multipart result # ------ ------ ------------ ------------------------------ # None True True None # i True True None # None False True _payload (a list) # i False True _payload element i (a Message) # i False False error (not a list) # i True False error (not a list) # None False False _payload # None True False _payload decoded (bytes) # Note that Barry planned to factor out the 'decode' case, but that # isn't so easy now that we handle the 8 bit data, which needs to be # converted in both the decode and non-decode path. if self.is_multipart(): if decode: return None if i is None: return self._payload else: return self._payload[i] # For backward compatibility, Use isinstance and this error message # instead of the more logical is_multipart test. if i is not None and not isinstance(self._payload, list): raise TypeError('Expected list, got %s' % type(self._payload)) payload = self._payload # cte might be a Header, so for now stringify it. cte = str(self.get('content-transfer-encoding', '')).lower() # payload may be bytes here. if isinstance(payload, str): if utils._has_surrogates(payload): bpayload = payload.encode('ascii', 'surrogateescape') if not decode: try: payload = bpayload.decode(self.get_param('charset', 'ascii'), 'replace') except LookupError: payload = bpayload.decode('ascii', 'replace') elif decode: try: bpayload = payload.encode('ascii') except UnicodeError: # This won't happen for RFC compliant messages (messages # containing only ASCII codepoints in the unicode input). # If it does happen, turn the string into bytes in a way # guaranteed not to fail. bpayload = payload.encode('raw-unicode-escape') if not decode: return payload if cte == 'quoted-printable': return utils._qdecode(bpayload) elif cte == 'base64': # XXX: this is a bit of a hack; decode_b should probably be factored # out somewhere, but I haven't figured out where yet. value, defects = decode_b(b''.join(bpayload.splitlines())) for defect in defects: self.policy.handle_defect(self, defect) return value elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): in_file = BytesIO(bpayload) out_file = BytesIO() try: uu.decode(in_file, out_file, quiet=True) return out_file.getvalue() except uu.Error: # Some decoding problem return bpayload if isinstance(payload, str): return bpayload return payload
def rewrite(part): need_rewrite = False for hdr in part.values(): if max([len(i) for i in hdr.split('\n')]) > MAX_LINE_LENGTH: need_rewrite = True # Force MIME rewrite if we have long headers sys.stderr.write("FIXUP NEXT: Rewrite forced by long header line\n") for hdr, max_lines, max_items, max_bytes in NUKE_HDRS: (hdr, val) = (hdr.lower(), msg.get(hdr)) if (val and ((max_lines >= 0 and len(val.split('\n')) > max_lines) or (max_items >= 0 and len(val.split()) > max_items) or (max_bytes >= 0 and len(val) > max_bytes))): del msg[hdr] sys.stderr.write("FIXUP NEXT: Removed long header line: "+hdr+"\n") need_rewrite = True if part.is_multipart(): for subpart in part.get_payload(): if rewrite(subpart): need_rewrite = True return need_rewrite payload = part.get_payload() max_line_length = max([ len(i) for i in payload.split('\n') ]) cte = part.get('content-transfer-encoding', '').lower().strip() if cte in ['8bit', '7bit', 'binary', '']: # Encode unencoded forms which contain 8bit characters or long lines update_cte = part.replace_header if (cte != '') else part.add_header nonascii_count = [(ord(c) >= 128) for c in payload].count(True) if ((NUKE_8BIT and nonascii_count > 0) or max_line_length > MAX_LINE_LENGTH): if nonascii_count < 100: part.set_payload(qp_encode(payload)) update_cte('Content-Transfer-Encoding', "quoted-printable") else: part.set_payload(utils._bencode(payload)) update_cte('Content-Transfer-Encoding', "base64") need_rewrite = True elif cte in ['quoted-printable', 'base64']: # Recode quoted-printable or base64 with long lines if max_line_length > MAX_LINE_LENGTH: if cte == 'quoted-printable': raw=utils._qdecode(payload) part.set_payload(qp_encode(raw)) need_rewrite = True elif cte == 'base64': try: raw=utils._bdecode(payload) part.set_payload(utils._bencode(raw)) need_rewrite = True except binascii.Error: pass newcte = part.get('content-transfer-encoding', '').lower().strip() if (newcte != cte): part.add_header('X-Mime-Autoconverted', "from " + (cte or "none") + " to " + newcte) sys.stderr.write("FIXUP NEXT: Attachment converted " + "from " + (cte or "none") + " to " + newcte + "\n") return need_rewrite
def rewrite(part): need_rewrite = False for hdr in part.values(): if max([len(i) for i in hdr.split('\n')]) > MAX_LINE_LENGTH: need_rewrite = True # Force MIME rewrite if we have long headers sys.stderr.write( "FIXUP NEXT: Rewrite forced by long header line\n") for hdr, max_lines, max_items, max_bytes in NUKE_HDRS: (hdr, val) = (hdr.lower(), msg.get(hdr)) if (val and ((max_lines >= 0 and len(val.split('\n')) > max_lines) or (max_items >= 0 and len(val.split()) > max_items) or (max_bytes >= 0 and len(val) > max_bytes))): del msg[hdr] sys.stderr.write("FIXUP NEXT: Removed long header line: " + hdr + "\n") need_rewrite = True if part.is_multipart(): for subpart in part.get_payload(): if rewrite(subpart): need_rewrite = True return need_rewrite payload = part.get_payload() max_line_length = max([len(i) for i in payload.split('\n')]) cte = part.get('content-transfer-encoding', '').lower().strip() if cte in ['8bit', '7bit', 'binary', '']: # Encode unencoded forms which contain 8bit characters or long lines update_cte = part.replace_header if (cte != '') else part.add_header nonascii_count = [(ord(c) >= 128) for c in payload].count(True) if ((NUKE_8BIT and nonascii_count > 0) or max_line_length > MAX_LINE_LENGTH): if nonascii_count < 100: part.set_payload(qp_encode(payload)) update_cte('Content-Transfer-Encoding', "quoted-printable") else: part.set_payload(utils._bencode(payload)) update_cte('Content-Transfer-Encoding', "base64") need_rewrite = True elif cte in ['quoted-printable', 'base64']: # Recode quoted-printable or base64 with long lines if max_line_length > MAX_LINE_LENGTH: if cte == 'quoted-printable': raw = utils._qdecode(payload) part.set_payload(qp_encode(raw)) need_rewrite = True elif cte == 'base64': try: raw = utils._bdecode(payload) part.set_payload(utils._bencode(raw)) need_rewrite = True except binascii.Error: pass newcte = part.get('content-transfer-encoding', '').lower().strip() if (newcte != cte): part.add_header('X-Mime-Autoconverted', "from " + (cte or "none") + " to " + newcte) sys.stderr.write("FIXUP NEXT: Attachment converted " + "from " + (cte or "none") + " to " + newcte + "\n") return need_rewrite
def rewrite(part, drop_all_multipart_err): need_rewrite = False if (part.preamble and max_line_len(part.preamble) > MAX_LINE_LENGTH): part.preamble = "\n" sys.stderr.write("FIXUP NEXT: Removed over-long MIME preamble\n") need_rewrite = True if (part.epilogue and max_line_len(part.epilogue) > MAX_LINE_LENGTH): part.epilogue = "\n" sys.stderr.write("FIXUP NEXT: Removed over-long MIME epilogue\n") need_rewrite = True for hdr in part.values(): if max_line_len(hdr) > MAX_LINE_LENGTH: need_rewrite = True # Force MIME rewrite if we have long headers sys.stderr.write("FIXUP NEXT: Rewrite forced by long header line\n") for hdr, max_lines, max_items, max_bytes in NUKE_HDRS: (hdr, val) = (hdr.lower(), part.get(hdr)) if (val and ((max_lines >= 0 and len(val.split('\n')) > max_lines) or (max_items >= 0 and len(val.split()) > max_items) or (max_bytes >= 0 and len(val) > max_bytes))): del part[hdr] sys.stderr.write("FIXUP NEXT: Removed long header line: "+hdr+"\n") need_rewrite = True # Exchange Online can't cope with very long component in address list for hdr in ['To', 'Cc', 'Bcc']: val = part.get(hdr, "") for addr in val.split(','): # Need better parsing here! if len(addr) > 1950: part['X-Broken-' + hdr] = val del part[hdr] sys.stderr.write("FIXUP NEXT: Renamed broken " + hdr + " to X-Broken-" + hdr + "\n") need_rewrite = True ct = part.get_content_type() max_name_len = 0 params = part.get_params() if params: for (key,value) in part.get_params(): if key in ['name', 'filename']: if len(value) > max_name_len: max_name_len = len(value) if max_name_len > MAX_FILENAME: need_rewrite = True part_count=len(part.get_payload()) part_str = ('Removed ' + ct + ' with long filename (' + str(max_name_len) + ' characters) which chokes Exchange Online') nuke_part(part, 1, part_str) return need_rewrite if part.is_multipart(): if (drop_all_multipart_err): need_rewrite = True part_count=len(part.get_payload()) part_str = drop_all_multipart_err nuke_part(part, 0, part_str) elif (len(part.get_payload()) > MAX_SUBPARTS): need_rewrite = True part_count=len(part.get_payload()) part_str = ('Removed ' + ct + ' with ' + str(part_count) + ' subparts/attachments which chokes Exchange Online') nuke_part(part, 1, part_str) elif ct in ['multipart/appledouble']: need_rewrite = True part_str = ('Removed ' + ct + ' which chokes Exchange Online') nuke_part(part, 1, part_str) else: for subpart in part.get_payload(): if rewrite(subpart, drop_all_multipart_err): need_rewrite = True return need_rewrite payload = part.get_payload() max_line_length = max_line_len(payload) cte = part.get('content-transfer-encoding', '').lower().strip() if cte in ['8bit', '7bit', 'binary', '']: # Encode unencoded forms which contain 8bit characters or long lines update_cte = part.replace_header if (cte != '') else part.add_header nonascii_count = [(ord(c) >= 128) for c in payload].count(True) if ((NUKE_8BIT and nonascii_count > 0) or max_line_length > MAX_LINE_LENGTH): if nonascii_count < 100: part.set_payload(qp_encode(payload)) update_cte('Content-Transfer-Encoding', "quoted-printable") else: part.set_payload(utils._bencode(payload)) update_cte('Content-Transfer-Encoding', "base64") need_rewrite = True elif (cte in ['quoted-printable', 'base64']): decode_error = False try: if cte == 'quoted-printable': raw=utils._qdecode(payload) else: raw=utils._bdecode(payload) if (len(payload) > 100) and (len(raw) < len(payload)/10): raise binascii.Error except binascii.Error: decode_error = True if decode_error: # Discard broken attachment which would no decode need_rewrite = True part_str = ('Removed ' + ct + ' with broken attachment which failed to decode') nuke_part(part, 1, part_str) elif max_line_length > MAX_LINE_LENGTH: sys.stderr.write("FIXUP NEXT: Recoded " + (cte or "none") + " attachment [Long lines]\n") # Recode quoted-printable or base64 with long lines need_rewrite = True if cte == 'quoted-printable': part.set_payload(qp_encode(raw)) else: part.set_payload(utils._bencode(raw)) newcte = part.get('content-transfer-encoding', '').lower().strip() if (newcte and (newcte != cte)): part.add_header('X-Mime-Autoconverted', "from " + (cte or "none") + " to " + newcte) if max_line_length > MAX_LINE_LENGTH: sys.stderr.write("FIXUP NEXT: Attachment converted " + "from " + (cte or "none") + " to " + newcte + " [Long lines]\n") else: sys.stderr.write("FIXUP NEXT: Attachment converted " + "from " + (cte or "none") + " to " + newcte + " [Raw Binary data]\n") return need_rewrite