From 8409c4c372b159232a426ea2e70d2b6b0a7f6b54 Mon Sep 17 00:00:00 2001 From: reb00ter Date: Mon, 22 Jan 2018 06:46:33 +0300 Subject: [PATCH 1/9] Update generator.py add_header when email dont have it --- Lib/email/generator.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/email/generator.py b/Lib/email/generator.py index ae670c2353c858a..55d2959eb950e93 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -186,8 +186,14 @@ def _write(self, msg): # If we munged the cte, copy the message again and re-fix the CTE. if munge_cte: msg = deepcopy(msg) - msg.replace_header('content-transfer-encoding', munge_cte[0]) - msg.replace_header('content-type', munge_cte[1]) + try: + msg.replace_header('content-transfer-encoding', munge_cte[0]) + except KeyError: + msg.add_header('content-transfer-encoding', munge_cte[0]) + try: + msg.replace_header('content-type', munge_cte[1]) + except KeyError: + msg.add_header('content-type', munge_cte[1]) # Write the headers. First we see if the message object wants to # handle that itself. If not, we'll do it generically. meth = getattr(msg, '_write_headers', None) From da3bef675f8037c8a06c417fe92077a7aaa7013b Mon Sep 17 00:00:00 2001 From: reb00ter Date: Mon, 22 Jan 2018 09:59:53 +0300 Subject: [PATCH 2/9] Update generator.py --- Lib/email/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/email/generator.py b/Lib/email/generator.py index 55d2959eb950e93..ec9ba96c4a47c0f 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -189,7 +189,7 @@ def _write(self, msg): try: msg.replace_header('content-transfer-encoding', munge_cte[0]) except KeyError: - msg.add_header('content-transfer-encoding', munge_cte[0]) + msg.add_header('content-transfer-encoding', munge_cte[0]) try: msg.replace_header('content-type', munge_cte[1]) except KeyError: From 8100bd0675ecd19ce29cc26be236faea17f436e6 Mon Sep 17 00:00:00 2001 From: reb00ter Date: Tue, 23 Jan 2018 11:15:46 +0300 Subject: [PATCH 3/9] Update generator.py --- Lib/email/generator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/email/generator.py b/Lib/email/generator.py index ec9ba96c4a47c0f..9a0f6c33491eb55 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -186,9 +186,11 @@ def _write(self, msg): # If we munged the cte, copy the message again and re-fix the CTE. if munge_cte: msg = deepcopy(msg) + # Try to replace header with new data and extend it + # if some records are missed try: msg.replace_header('content-transfer-encoding', munge_cte[0]) - except KeyError: + except KeyError: msg.add_header('content-transfer-encoding', munge_cte[0]) try: msg.replace_header('content-type', munge_cte[1]) From bd72eab2dd65ec3fd90f78ffe5c721210ed7fec9 Mon Sep 17 00:00:00 2001 From: reb00ter Date: Tue, 23 Jan 2018 11:42:45 +0300 Subject: [PATCH 4/9] whitespase issue --- Lib/email/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/email/generator.py b/Lib/email/generator.py index 9a0f6c33491eb55..c14e2658ca49b4c 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -186,7 +186,7 @@ def _write(self, msg): # If we munged the cte, copy the message again and re-fix the CTE. if munge_cte: msg = deepcopy(msg) - # Try to replace header with new data and extend it + # Try to replace header with new data and extend it # if some records are missed try: msg.replace_header('content-transfer-encoding', munge_cte[0]) From 34d6bcc7e1551744943152ccc4625c9158489536 Mon Sep 17 00:00:00 2001 From: reb00ter Date: Tue, 23 Jan 2018 14:06:59 +0300 Subject: [PATCH 5/9] if-else instead of try-except --- Lib/email/generator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/email/generator.py b/Lib/email/generator.py index c14e2658ca49b4c..c0bf7a28b76d049 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -188,13 +188,13 @@ def _write(self, msg): msg = deepcopy(msg) # Try to replace header with new data and extend it # if some records are missed - try: + if msg.get('content-transfer-encoding', None) is not None: msg.replace_header('content-transfer-encoding', munge_cte[0]) - except KeyError: + else: msg.add_header('content-transfer-encoding', munge_cte[0]) - try: + if msg.get('content-type', None) is not None: msg.replace_header('content-type', munge_cte[1]) - except KeyError: + else: msg.add_header('content-type', munge_cte[1]) # Write the headers. First we see if the message object wants to # handle that itself. If not, we'll do it generically. From 27c6ebf1f0e370c14a348e7a7037e6964fdf563c Mon Sep 17 00:00:00 2001 From: reb00ter Date: Tue, 23 Jan 2018 14:07:32 +0300 Subject: [PATCH 6/9] Update generator.py --- Lib/email/generator.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/email/generator.py b/Lib/email/generator.py index c0bf7a28b76d049..31b8306ab035c63 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -186,8 +186,6 @@ def _write(self, msg): # If we munged the cte, copy the message again and re-fix the CTE. if munge_cte: msg = deepcopy(msg) - # Try to replace header with new data and extend it - # if some records are missed if msg.get('content-transfer-encoding', None) is not None: msg.replace_header('content-transfer-encoding', munge_cte[0]) else: From db1e114cad08b376ad548367c45cd7486c3b34de Mon Sep 17 00:00:00 2001 From: reb00ter Date: Tue, 23 Jan 2018 14:13:36 +0300 Subject: [PATCH 7/9] create news.d record --- Misc/NEWS.d/next/Library/018-01-23-14-12-23.bpo-32634.KLH3kj.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/018-01-23-14-12-23.bpo-32634.KLH3kj.rst diff --git a/Misc/NEWS.d/next/Library/018-01-23-14-12-23.bpo-32634.KLH3kj.rst b/Misc/NEWS.d/next/Library/018-01-23-14-12-23.bpo-32634.KLH3kj.rst new file mode 100644 index 000000000000000..0a87264020a6b35 --- /dev/null +++ b/Misc/NEWS.d/next/Library/018-01-23-14-12-23.bpo-32634.KLH3kj.rst @@ -0,0 +1 @@ +Fix chrashing email message parsing when incomplete headers given From a33c87d56c42352d12751af09f39136f950f9820 Mon Sep 17 00:00:00 2001 From: reb00ter Date: Tue, 23 Jan 2018 14:14:10 +0300 Subject: [PATCH 8/9] Rename 018-01-23-14-12-23.bpo-32634.KLH3kj.rst to 2018-01-23-14-12-23.bpo-32634.KLH3kj.rst --- ...-32634.KLH3kj.rst => 2018-01-23-14-12-23.bpo-32634.KLH3kj.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/Library/{018-01-23-14-12-23.bpo-32634.KLH3kj.rst => 2018-01-23-14-12-23.bpo-32634.KLH3kj.rst} (100%) diff --git a/Misc/NEWS.d/next/Library/018-01-23-14-12-23.bpo-32634.KLH3kj.rst b/Misc/NEWS.d/next/Library/2018-01-23-14-12-23.bpo-32634.KLH3kj.rst similarity index 100% rename from Misc/NEWS.d/next/Library/018-01-23-14-12-23.bpo-32634.KLH3kj.rst rename to Misc/NEWS.d/next/Library/2018-01-23-14-12-23.bpo-32634.KLH3kj.rst From 42a04278a45b1b12fd104adae34233cce5764433 Mon Sep 17 00:00:00 2001 From: reb00ter Date: Tue, 23 Jan 2018 15:19:07 +0300 Subject: [PATCH 9/9] make codestyle pep8 satisfying --- Lib/email/generator.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Lib/email/generator.py b/Lib/email/generator.py index 31b8306ab035c63..2b4e7ddc4dd0262 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -22,7 +22,6 @@ fcre = re.compile(r'^From ', re.MULTILINE) - class Generator: """Generates output from a Message object tree. @@ -122,7 +121,7 @@ def clone(self, fp): """Clone this generator with the exact same options.""" return self.__class__(fp, self._mangle_from_, - None, # Use policy setting, which we've adjusted + None, # Use policy setting, which we've adjusted policy=self.policy) # @@ -159,7 +158,7 @@ def _write_lines(self, lines): # XXX logic tells me this else should be needed, but the tests fail # with it and pass without it. (NLCRE.split ends with a blank element # if and only if there was a trailing newline.) - #else: + # else: # self.write(self._NL) def _write(self, msg): @@ -188,7 +187,7 @@ def _write(self, msg): msg = deepcopy(msg) if msg.get('content-transfer-encoding', None) is not None: msg.replace_header('content-transfer-encoding', munge_cte[0]) - else: + else: msg.add_header('content-transfer-encoding', munge_cte[0]) if msg.get('content-type', None) is not None: msg.replace_header('content-type', munge_cte[1]) @@ -383,7 +382,8 @@ def _make_boundary(cls, text=None): b = boundary counter = 0 while True: - cre = cls._compile_re('^--' + re.escape(b) + '(--)?$', re.MULTILINE) + cre = cls._compile_re('^--' + re.escape(b) + '(--)?$', + re.MULTILINE) if not cre.search(text): break b = boundary + '.' + str(counter) @@ -430,12 +430,12 @@ def _handle_text(self, msg): # just write it back out. if msg._payload is None: return - if _has_surrogates(msg._payload) and not self.policy.cte_type=='7bit': + if _has_surrogates(msg._payload) and self.policy.cte_type != '7bit': if self._mangle_from_: msg._payload = fcre.sub(">From ", msg._payload) self._write_lines(msg._payload) else: - super(BytesGenerator,self)._handle_text(msg) + super(BytesGenerator, self)._handle_text(msg) # Default body handler _writeBody = _handle_text @@ -445,17 +445,17 @@ def _compile_re(cls, s, flags): return re.compile(s.encode('ascii'), flags) - _FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]' + class DecodedGenerator(Generator): """Generates a text representation of a message. Like the Generator base class, except that non-text parts are substituted with a format string representing the part. """ - def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, - policy=None): + def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, fmt=None, + *, policy=None): """Like Generator.__init__() except that an additional optional argument is allowed. @@ -494,18 +494,17 @@ def _dispatch(self, msg): pass else: print(self._fmt % { - 'type' : part.get_content_type(), - 'maintype' : part.get_content_maintype(), - 'subtype' : part.get_content_subtype(), - 'filename' : part.get_filename('[no filename]'), + 'type': part.get_content_type(), + 'maintype': part.get_content_maintype(), + 'subtype': part.get_content_subtype(), + 'filename': part.get_filename('[no filename]'), 'description': part.get('Content-Description', '[no description]'), - 'encoding' : part.get('Content-Transfer-Encoding', - '[no encoding]'), + 'encoding': part.get('Content-Transfer-Encoding', + '[no encoding]'), }, file=self) - # Helper used by Generator._make_boundary _width = len(repr(sys.maxsize-1)) _fmt = '%%0%dd' % _width