sync community bugfix patches
This commit is contained in:
parent
6f1ffbd1fe
commit
ef6501552c
@ -0,0 +1,128 @@
|
|||||||
|
From d2cc04cd3024869101e894f73307944d98d187c8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Miss Islington (bot)"
|
||||||
|
<31488909+miss-islington@users.noreply.github.com>
|
||||||
|
Date: Mon, 30 Aug 2021 12:16:24 -0700
|
||||||
|
Subject: [PATCH] [3.7] bpo-43124: Fix smtplib multiple CRLF injection
|
||||||
|
(GH-25987) (GH-28037)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Co-authored-by: Miguel Brito <5544985+miguendes@users.noreply.github.com>
|
||||||
|
|
||||||
|
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
|
||||||
|
(cherry picked from commit 0897253f426068ea6a6fbe0ada01689af9ef1019)
|
||||||
|
---
|
||||||
|
Lib/smtplib.py | 11 +++--
|
||||||
|
Lib/test/test_smtplib.py | 55 ++++++++++++++++++++++
|
||||||
|
.../2021-05-08-11-50-46.bpo-43124.2CTM6M.rst | 2 +
|
||||||
|
3 files changed, 65 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Security/2021-05-08-11-50-46.bpo-43124.2CTM6M.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
|
||||||
|
index 22d5097..345f03d 100755
|
||||||
|
--- a/Lib/smtplib.py
|
||||||
|
+++ b/Lib/smtplib.py
|
||||||
|
@@ -361,10 +361,15 @@ def send(self, s):
|
||||||
|
def putcmd(self, cmd, args=""):
|
||||||
|
"""Send a command to the server."""
|
||||||
|
if args == "":
|
||||||
|
- str = '%s%s' % (cmd, CRLF)
|
||||||
|
+ s = cmd
|
||||||
|
else:
|
||||||
|
- str = '%s %s%s' % (cmd, args, CRLF)
|
||||||
|
- self.send(str)
|
||||||
|
+ s = f'{cmd} {args}'
|
||||||
|
+ if '\r' in s or '\n' in s:
|
||||||
|
+ s = s.replace('\n', '\\n').replace('\r', '\\r')
|
||||||
|
+ raise ValueError(
|
||||||
|
+ f'command and arguments contain prohibited newline characters: {s}'
|
||||||
|
+ )
|
||||||
|
+ self.send(f'{s}{CRLF}')
|
||||||
|
|
||||||
|
def getreply(self):
|
||||||
|
"""Get a reply from the server.
|
||||||
|
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
|
||||||
|
index b4149d3..a8c7402 100644
|
||||||
|
--- a/Lib/test/test_smtplib.py
|
||||||
|
+++ b/Lib/test/test_smtplib.py
|
||||||
|
@@ -282,6 +282,16 @@ def testEXPNNotImplemented(self):
|
||||||
|
self.assertEqual(smtp.getreply(), expected)
|
||||||
|
smtp.quit()
|
||||||
|
|
||||||
|
+ def test_issue43124_putcmd_escapes_newline(self):
|
||||||
|
+ # see: https://bugs.python.org/issue43124
|
||||||
|
+ smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost',
|
||||||
|
+ timeout=10) # support.LOOPBACK_TIMEOUT in newer Pythons
|
||||||
|
+ self.addCleanup(smtp.close)
|
||||||
|
+ with self.assertRaises(ValueError) as exc:
|
||||||
|
+ smtp.putcmd('helo\nX-INJECTED')
|
||||||
|
+ self.assertIn("prohibited newline characters", str(exc.exception))
|
||||||
|
+ smtp.quit()
|
||||||
|
+
|
||||||
|
def testVRFY(self):
|
||||||
|
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
|
||||||
|
expected = (252, b'Cannot VRFY user, but will accept message ' + \
|
||||||
|
@@ -351,6 +361,51 @@ def testSendNeedingDotQuote(self):
|
||||||
|
mexpect = '%s%s\n%s' % (MSG_BEGIN, m, MSG_END)
|
||||||
|
self.assertEqual(self.output.getvalue(), mexpect)
|
||||||
|
|
||||||
|
+ def test_issue43124_escape_localhostname(self):
|
||||||
|
+ # see: https://bugs.python.org/issue43124
|
||||||
|
+ # connect and send mail
|
||||||
|
+ m = 'wazzuuup\nlinetwo'
|
||||||
|
+ smtp = smtplib.SMTP(HOST, self.port, local_hostname='hi\nX-INJECTED',
|
||||||
|
+ timeout=10) # support.LOOPBACK_TIMEOUT in newer Pythons
|
||||||
|
+ self.addCleanup(smtp.close)
|
||||||
|
+ with self.assertRaises(ValueError) as exc:
|
||||||
|
+ smtp.sendmail("hi@me.com", "you@me.com", m)
|
||||||
|
+ self.assertIn(
|
||||||
|
+ "prohibited newline characters: ehlo hi\\nX-INJECTED",
|
||||||
|
+ str(exc.exception),
|
||||||
|
+ )
|
||||||
|
+ # XXX (see comment in testSend)
|
||||||
|
+ time.sleep(0.01)
|
||||||
|
+ smtp.quit()
|
||||||
|
+
|
||||||
|
+ debugout = smtpd.DEBUGSTREAM.getvalue()
|
||||||
|
+ self.assertNotIn("X-INJECTED", debugout)
|
||||||
|
+
|
||||||
|
+ def test_issue43124_escape_options(self):
|
||||||
|
+ # see: https://bugs.python.org/issue43124
|
||||||
|
+ # connect and send mail
|
||||||
|
+ m = 'wazzuuup\nlinetwo'
|
||||||
|
+ smtp = smtplib.SMTP(
|
||||||
|
+ HOST, self.port, local_hostname='localhost',
|
||||||
|
+ timeout=10) # support.LOOPBACK_TIMEOUT in newer Pythons
|
||||||
|
+
|
||||||
|
+ self.addCleanup(smtp.close)
|
||||||
|
+ smtp.sendmail("hi@me.com", "you@me.com", m)
|
||||||
|
+ with self.assertRaises(ValueError) as exc:
|
||||||
|
+ smtp.mail("hi@me.com", ["X-OPTION\nX-INJECTED-1", "X-OPTION2\nX-INJECTED-2"])
|
||||||
|
+ msg = str(exc.exception)
|
||||||
|
+ self.assertIn("prohibited newline characters", msg)
|
||||||
|
+ self.assertIn("X-OPTION\\nX-INJECTED-1 X-OPTION2\\nX-INJECTED-2", msg)
|
||||||
|
+ # XXX (see comment in testSend)
|
||||||
|
+ time.sleep(0.01)
|
||||||
|
+ smtp.quit()
|
||||||
|
+
|
||||||
|
+ debugout = smtpd.DEBUGSTREAM.getvalue()
|
||||||
|
+ self.assertNotIn("X-OPTION", debugout)
|
||||||
|
+ self.assertNotIn("X-OPTION2", debugout)
|
||||||
|
+ self.assertNotIn("X-INJECTED-1", debugout)
|
||||||
|
+ self.assertNotIn("X-INJECTED-2", debugout)
|
||||||
|
+
|
||||||
|
def testSendNullSender(self):
|
||||||
|
m = 'A test message'
|
||||||
|
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
|
||||||
|
diff --git a/Misc/NEWS.d/next/Security/2021-05-08-11-50-46.bpo-43124.2CTM6M.rst b/Misc/NEWS.d/next/Security/2021-05-08-11-50-46.bpo-43124.2CTM6M.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..e897d6c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Security/2021-05-08-11-50-46.bpo-43124.2CTM6M.rst
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+Made the internal ``putcmd`` function in :mod:`smtplib` sanitize input for
|
||||||
|
+presence of ``\r`` and ``\n`` characters to avoid (unlikely) command injection.
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
59
backport-bpo-12800-tarfile-Restore-fix-from-011525ee9.patch
Normal file
59
backport-bpo-12800-tarfile-Restore-fix-from-011525ee9.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From 4fedd7123eaf147edd55eabbbd72e0bcc8368e47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Palard <julien@palard.fr>
|
||||||
|
Date: Wed, 25 Nov 2020 10:23:17 +0100
|
||||||
|
Subject: [PATCH] bpo-12800: tarfile: Restore fix from 011525ee9 (GH-21409)
|
||||||
|
|
||||||
|
Restore fix from 011525ee92eb1c13ad1a62d28725a840e28f8160.
|
||||||
|
---
|
||||||
|
Lib/tarfile.py | 3 +++
|
||||||
|
Lib/test/test_tarfile.py | 6 +++---
|
||||||
|
Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst | 4 ++++
|
||||||
|
3 files changed, 10 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
|
||||||
|
index 3be5188..6d743da 100755
|
||||||
|
--- a/Lib/tarfile.py
|
||||||
|
+++ b/Lib/tarfile.py
|
||||||
|
@@ -2201,6 +2201,9 @@ class TarFile(object):
|
||||||
|
try:
|
||||||
|
# For systems that support symbolic and hard links.
|
||||||
|
if tarinfo.issym():
|
||||||
|
+ if os.path.lexists(targetpath):
|
||||||
|
+ # Avoid FileExistsError on following os.symlink.
|
||||||
|
+ os.unlink(targetpath)
|
||||||
|
os.symlink(tarinfo.linkname, targetpath)
|
||||||
|
else:
|
||||||
|
# See extract().
|
||||||
|
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
|
||||||
|
index 9133d60..fe68c6f 100644
|
||||||
|
--- a/Lib/test/test_tarfile.py
|
||||||
|
+++ b/Lib/test/test_tarfile.py
|
||||||
|
@@ -1314,11 +1314,11 @@ class WriteTest(WriteTestBase, unittest.TestCase):
|
||||||
|
f.write('something\n')
|
||||||
|
os.symlink(source_file, target_file)
|
||||||
|
tar = tarfile.open(temparchive,'w')
|
||||||
|
- tar.add(source_file)
|
||||||
|
- tar.add(target_file)
|
||||||
|
+ tar.add(source_file, arcname="source")
|
||||||
|
+ tar.add(target_file, arcname="symlink")
|
||||||
|
tar.close()
|
||||||
|
# Let's extract it to the location which contains the symlink
|
||||||
|
- tar = tarfile.open(temparchive,'r')
|
||||||
|
+ tar = tarfile.open(temparchive,'r', errorlevel=2)
|
||||||
|
# this should not raise OSError: [Errno 17] File exists
|
||||||
|
try:
|
||||||
|
tar.extractall(path=tempdir)
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst b/Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..fdd7c5e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Library/2020-07-09-11-32-28.bpo-12800.fNgWwx.rst
|
||||||
|
@@ -0,0 +1,4 @@
|
||||||
|
+Extracting a symlink from a tarball should succeed and overwrite the symlink
|
||||||
|
+if it already exists. The fix is to remove the existing file or symlink
|
||||||
|
+before extraction. Based on patch by Chris AtLee, Jeffrey Kintscher, and
|
||||||
|
+Senthil Kumaran.
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
From bfee9fad84531a471fd7864e88947320669f68e2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter McCormick <peter@pdmccormick.com>
|
||||||
|
Date: Sat, 19 Sep 2020 23:40:46 -0400
|
||||||
|
Subject: [PATCH] bpo-41815: SQLite: segfault if backup called on closed
|
||||||
|
database (GH-22322)
|
||||||
|
|
||||||
|
# [bpo-41815](): SQLite: fix segfault if backup called on closed database
|
||||||
|
|
||||||
|
Attempting to backup a closed database will trigger segfault:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import sqlite3
|
||||||
|
target = sqlite3.connect(':memory:')
|
||||||
|
source = sqlite3.connect(':memory:')
|
||||||
|
source.close()
|
||||||
|
source.backup(target)
|
||||||
|
```
|
||||||
|
---
|
||||||
|
Lib/sqlite3/test/backup.py | 7 +++++++
|
||||||
|
Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst | 2 ++
|
||||||
|
Modules/_sqlite/connection.c | 4 ++++
|
||||||
|
3 files changed, 13 insertions(+)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/sqlite3/test/backup.py b/Lib/sqlite3/test/backup.py
|
||||||
|
index 903bacf..ad1da97 100644
|
||||||
|
--- a/Lib/sqlite3/test/backup.py
|
||||||
|
+++ b/Lib/sqlite3/test/backup.py
|
||||||
|
@@ -36,6 +36,13 @@ class BackupTests(unittest.TestCase):
|
||||||
|
with self.assertRaises(sqlite.ProgrammingError):
|
||||||
|
self.cx.backup(bck)
|
||||||
|
|
||||||
|
+ def test_bad_source_closed_connection(self):
|
||||||
|
+ bck = sqlite.connect(':memory:')
|
||||||
|
+ source = sqlite.connect(":memory:")
|
||||||
|
+ source.close()
|
||||||
|
+ with self.assertRaises(sqlite.ProgrammingError):
|
||||||
|
+ source.backup(bck)
|
||||||
|
+
|
||||||
|
def test_bad_target_in_transaction(self):
|
||||||
|
bck = sqlite.connect(':memory:')
|
||||||
|
bck.execute('CREATE TABLE bar (key INTEGER)')
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst b/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3560db9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Library/2020-09-19-23-14-54.bpo-41815.RNpuX3.rst
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+Fix SQLite3 segfault when backing up closed database. Patch contributed by
|
||||||
|
+Peter David McCormick.
|
||||||
|
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
|
||||||
|
index 9eb61c1..2d2f4fd 100644
|
||||||
|
--- a/Modules/_sqlite/connection.c
|
||||||
|
+++ b/Modules/_sqlite/connection.c
|
||||||
|
@@ -1489,6 +1489,10 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *
|
||||||
|
sleep_ms = (int)ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!pysqlite_check_connection((pysqlite_Connection *)target)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
From 42d873c63aa9d160c132be4a34599531574db12c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Svetlov <andrew.svetlov@gmail.com>
|
||||||
|
Date: Tue, 10 Nov 2020 15:58:31 +0200
|
||||||
|
Subject: [PATCH] bpo-42183: Fix a stack overflow error for asyncio Task or
|
||||||
|
Future repr() (GH-23020)
|
||||||
|
|
||||||
|
The overflow occurs under some circumstances when a task or future
|
||||||
|
recursively returns itself.
|
||||||
|
|
||||||
|
Co-authored-by: Kyle Stanley <aeros167@gmail.com>
|
||||||
|
---
|
||||||
|
Lib/asyncio/base_futures.py | 25 +++++++++++++++++++---
|
||||||
|
Lib/test/test_asyncio/test_futures2.py | 18 ++++++++++++++++
|
||||||
|
.../2020-10-29-11-17-35.bpo-42183.50ZcIi.rst | 4 ++++
|
||||||
|
3 files changed, 44 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 Lib/test/test_asyncio/test_futures2.py
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2020-10-29-11-17-35.bpo-42183.50ZcIi.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/asyncio/base_futures.py b/Lib/asyncio/base_futures.py
|
||||||
|
index 5182884..2646fde 100644
|
||||||
|
--- a/Lib/asyncio/base_futures.py
|
||||||
|
+++ b/Lib/asyncio/base_futures.py
|
||||||
|
@@ -2,6 +2,7 @@ __all__ = ()
|
||||||
|
|
||||||
|
import concurrent.futures._base
|
||||||
|
import reprlib
|
||||||
|
+from _thread import get_ident
|
||||||
|
|
||||||
|
from . import format_helpers
|
||||||
|
|
||||||
|
@@ -51,6 +52,16 @@ def _format_callbacks(cb):
|
||||||
|
return f'cb=[{cb}]'
|
||||||
|
|
||||||
|
|
||||||
|
+# bpo-42183: _repr_running is needed for repr protection
|
||||||
|
+# when a Future or Task result contains itself directly or indirectly.
|
||||||
|
+# The logic is borrowed from @reprlib.recursive_repr decorator.
|
||||||
|
+# Unfortunately, the direct decorator usage is impossible because of
|
||||||
|
+# AttributeError: '_asyncio.Task' object has no attribute '__module__' error.
|
||||||
|
+#
|
||||||
|
+# After fixing this thing we can return to the decorator based approach.
|
||||||
|
+_repr_running = set()
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def _future_repr_info(future):
|
||||||
|
# (Future) -> str
|
||||||
|
"""helper function for Future.__repr__"""
|
||||||
|
@@ -59,9 +70,17 @@ def _future_repr_info(future):
|
||||||
|
if future._exception is not None:
|
||||||
|
info.append(f'exception={future._exception!r}')
|
||||||
|
else:
|
||||||
|
- # use reprlib to limit the length of the output, especially
|
||||||
|
- # for very long strings
|
||||||
|
- result = reprlib.repr(future._result)
|
||||||
|
+ key = id(future), get_ident()
|
||||||
|
+ if key in _repr_running:
|
||||||
|
+ result = '...'
|
||||||
|
+ else:
|
||||||
|
+ _repr_running.add(key)
|
||||||
|
+ try:
|
||||||
|
+ # use reprlib to limit the length of the output, especially
|
||||||
|
+ # for very long strings
|
||||||
|
+ result = reprlib.repr(future._result)
|
||||||
|
+ finally:
|
||||||
|
+ _repr_running.discard(key)
|
||||||
|
info.append(f'result={result}')
|
||||||
|
if future._callbacks:
|
||||||
|
info.append(_format_callbacks(future._callbacks))
|
||||||
|
diff --git a/Lib/test/test_asyncio/test_futures2.py b/Lib/test/test_asyncio/test_futures2.py
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..c78b0cb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Lib/test/test_asyncio/test_futures2.py
|
||||||
|
@@ -0,0 +1,18 @@
|
||||||
|
+# IsolatedAsyncioTestCase based tests
|
||||||
|
+import asyncio
|
||||||
|
+import unittest
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+class FutureTests(unittest.TestCase):
|
||||||
|
+ async def test_recursive_repr_for_pending_tasks(self):
|
||||||
|
+ # The call crashes if the guard for recursive call
|
||||||
|
+ # in base_futures:_future_repr_info is absent
|
||||||
|
+ # See Also: https://bugs.python.org/issue42183
|
||||||
|
+
|
||||||
|
+ async def func():
|
||||||
|
+ return asyncio.all_tasks()
|
||||||
|
+
|
||||||
|
+ # The repr() call should not raise RecursiveError at first.
|
||||||
|
+ # The check for returned string is not very reliable but
|
||||||
|
+ # exact comparison for the whole string is even weaker.
|
||||||
|
+ self.assertIn('...', repr(await asyncio.wait_for(func(), timeout=10)))
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2020-10-29-11-17-35.bpo-42183.50ZcIi.rst b/Misc/NEWS.d/next/Library/2020-10-29-11-17-35.bpo-42183.50ZcIi.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..f6d7653
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Library/2020-10-29-11-17-35.bpo-42183.50ZcIi.rst
|
||||||
|
@@ -0,0 +1,4 @@
|
||||||
|
+Fix a stack overflow error for asyncio Task or Future repr().
|
||||||
|
+
|
||||||
|
+The overflow occurs under some circumstances when a Task or Future
|
||||||
|
+recursively returns itself.
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
From e9b85afd7dc004460f6d914375ab67d617a8a7ff Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Miss Islington (bot)"
|
||||||
|
<31488909+miss-islington@users.noreply.github.com>
|
||||||
|
Date: Mon, 30 Aug 2021 11:48:04 -0700
|
||||||
|
Subject: [PATCH] bpo-45001: Make email date parsing more robust against
|
||||||
|
malformed input (GH-27946) (GH-27975)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Various date parsing utilities in the email module, such as
|
||||||
|
email.utils.parsedate(), are supposed to gracefully handle invalid
|
||||||
|
input, typically by raising an appropriate exception or by returning
|
||||||
|
None.
|
||||||
|
|
||||||
|
The internal email._parseaddr._parsedate_tz() helper used by some of
|
||||||
|
these date parsing routines tries to be robust against malformed input,
|
||||||
|
but unfortunately it can still crash ungracefully when a non-empty but
|
||||||
|
whitespace-only input is passed. This manifests as an unexpected
|
||||||
|
IndexError.
|
||||||
|
|
||||||
|
In practice, this can happen when parsing an email with only a newline
|
||||||
|
inside a ‘Date:’ header, which unfortunately happens occasionally in the
|
||||||
|
real world.
|
||||||
|
|
||||||
|
Here's a minimal example:
|
||||||
|
|
||||||
|
$ python
|
||||||
|
Python 3.9.6 (default, Jun 30 2021, 10:22:16)
|
||||||
|
[GCC 11.1.0] on linux
|
||||||
|
Type "help", "copyright", "credits" or "license" for more information.
|
||||||
|
>>> import email.utils
|
||||||
|
>>> email.utils.parsedate('foo')
|
||||||
|
>>> email.utils.parsedate(' ')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
File "/usr/lib/python3.9/email/_parseaddr.py", line 176, in parsedate
|
||||||
|
t = parsedate_tz(data)
|
||||||
|
File "/usr/lib/python3.9/email/_parseaddr.py", line 50, in parsedate_tz
|
||||||
|
res = _parsedate_tz(data)
|
||||||
|
File "/usr/lib/python3.9/email/_parseaddr.py", line 72, in _parsedate_tz
|
||||||
|
if data[0].endswith(',') or data[0].lower() in _daynames:
|
||||||
|
IndexError: list index out of range
|
||||||
|
|
||||||
|
The fix is rather straight-forward: guard against empty lists, after
|
||||||
|
splitting on whitespace, but before accessing the first element.
|
||||||
|
(cherry picked from commit 989f6a3800f06b2bd31cfef7c3269a443ad94fac)
|
||||||
|
|
||||||
|
Co-authored-by: wouter bolsterlee <wouter@bolsterl.ee>
|
||||||
|
---
|
||||||
|
Lib/email/_parseaddr.py | 2 ++
|
||||||
|
Lib/test/test_email/test_email.py | 2 ++
|
||||||
|
Misc/NEWS.d/next/Library/2021-08-26-16-25-48.bpo-45001.tn_dKp.rst | 2 ++
|
||||||
|
3 files changed, 6 insertions(+)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2021-08-26-16-25-48.bpo-45001.tn_dKp.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/email/_parseaddr.py b/Lib/email/_parseaddr.py
|
||||||
|
index 41ff6f8..178329f 100644
|
||||||
|
--- a/Lib/email/_parseaddr.py
|
||||||
|
+++ b/Lib/email/_parseaddr.py
|
||||||
|
@@ -67,6 +67,8 @@ def _parsedate_tz(data):
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
data = data.split()
|
||||||
|
+ if not data: # This happens for whitespace-only input.
|
||||||
|
+ return None
|
||||||
|
# The FWS after the comma after the day-of-week is optional, so search and
|
||||||
|
# adjust for this.
|
||||||
|
if data[0].endswith(',') or data[0].lower() in _daynames:
|
||||||
|
diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py
|
||||||
|
index 9e5c6ad..64bcdcc 100644
|
||||||
|
--- a/Lib/test/test_email/test_email.py
|
||||||
|
+++ b/Lib/test/test_email/test_email.py
|
||||||
|
@@ -2967,6 +2967,8 @@ def test_formatdate_usegmt(self):
|
||||||
|
def test_parsedate_returns_None_for_invalid_strings(self):
|
||||||
|
self.assertIsNone(utils.parsedate(''))
|
||||||
|
self.assertIsNone(utils.parsedate_tz(''))
|
||||||
|
+ self.assertIsNone(utils.parsedate(' '))
|
||||||
|
+ self.assertIsNone(utils.parsedate_tz(' '))
|
||||||
|
self.assertIsNone(utils.parsedate('0'))
|
||||||
|
self.assertIsNone(utils.parsedate_tz('0'))
|
||||||
|
self.assertIsNone(utils.parsedate('A Complete Waste of Time'))
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2021-08-26-16-25-48.bpo-45001.tn_dKp.rst b/Misc/NEWS.d/next/Library/2021-08-26-16-25-48.bpo-45001.tn_dKp.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..55cc409
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Library/2021-08-26-16-25-48.bpo-45001.tn_dKp.rst
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+Made email date parsing more robust against malformed input, namely a
|
||||||
|
+whitespace-only ``Date:`` header. Patch by Wouter Bolsterlee.
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
22
python3.spec
22
python3.spec
@ -3,7 +3,7 @@ Summary: Interpreter of the Python3 programming language
|
|||||||
URL: https://www.python.org/
|
URL: https://www.python.org/
|
||||||
|
|
||||||
Version: 3.7.9
|
Version: 3.7.9
|
||||||
Release: 20
|
Release: 21
|
||||||
License: Python
|
License: Python
|
||||||
|
|
||||||
%global branchversion 3.7
|
%global branchversion 3.7
|
||||||
@ -154,6 +154,11 @@ Patch6044: backport-CVE-2021-3737.patch
|
|||||||
Patch6045: backport-bpo-44022-Improve-the-regression-test.patch
|
Patch6045: backport-bpo-44022-Improve-the-regression-test.patch
|
||||||
Patch6046: backport-CVE-2021-4189.patch
|
Patch6046: backport-CVE-2021-4189.patch
|
||||||
Patch6047: backport-CVE-2022-0391.patch
|
Patch6047: backport-CVE-2022-0391.patch
|
||||||
|
Patch6048: backport-bpo-12800-tarfile-Restore-fix-from-011525ee9.patch
|
||||||
|
Patch6049: backport-bpo-42183-Fix-a-stack-overflow-error-for-asyncio-Tas.patch
|
||||||
|
Patch6050: backport-bpo-41815-SQLite-segfault-if-backup-called-on-closed.patch
|
||||||
|
Patch6051: backport-bpo-45001-Make-email-date-parsing-more-robust-agains.patch
|
||||||
|
Patch6052: backport-3.7-bpo-43124-Fix-smtplib-multiple-CRLF-injection-GH.patch
|
||||||
|
|
||||||
patch9000: Don-t-override-PYTHONPATH-which-is-already-set.patch
|
patch9000: Don-t-override-PYTHONPATH-which-is-already-set.patch
|
||||||
patch9001: add-the-sm3-method-for-obtaining-the-salt-value.patch
|
patch9001: add-the-sm3-method-for-obtaining-the-salt-value.patch
|
||||||
@ -296,6 +301,11 @@ rm Lib/ensurepip/_bundled/*.whl
|
|||||||
%patch6045 -p1
|
%patch6045 -p1
|
||||||
%patch6046 -p1
|
%patch6046 -p1
|
||||||
%patch6047 -p1
|
%patch6047 -p1
|
||||||
|
%patch6048 -p1
|
||||||
|
%patch6049 -p1
|
||||||
|
%patch6050 -p1
|
||||||
|
%patch6051 -p1
|
||||||
|
%patch6052 -p1
|
||||||
|
|
||||||
%patch9000 -p1
|
%patch9000 -p1
|
||||||
%patch9001 -p1
|
%patch9001 -p1
|
||||||
@ -900,6 +910,16 @@ export BEP_GTDLIST="$BEP_GTDLIST_TMP"
|
|||||||
%{_mandir}/*/*
|
%{_mandir}/*/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Feb 19 2022 shixuantong <shixuantong@h-partners.com> - 3.7.9-21
|
||||||
|
- Type:bugfix
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:bpo-43124: Fix smtplib multiple CRLF injection
|
||||||
|
bpo-12800: tarfile: Restore fix from 011525ee9
|
||||||
|
bpo-41815: SQLite: segfault if backup called on closed database
|
||||||
|
bpo-42183: Fix a stack overflow error for asyncio Task or Future repr()
|
||||||
|
bpo-45001: Make email date parsing more robust against malformed input
|
||||||
|
|
||||||
* Thu Feb 17 2022 shixuantong <shixuantong@h-partners.com> - 3.7.9-20
|
* Thu Feb 17 2022 shixuantong <shixuantong@h-partners.com> - 3.7.9-20
|
||||||
- Type:CVE
|
- Type:CVE
|
||||||
- CVE:CVE-2021-4189 CVE-2022-0391
|
- CVE:CVE-2021-4189 CVE-2022-0391
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user