python3: Update to 3.7.9, refresh/remove backported patches 13687/head
authorJeffery To <jeffery.to@gmail.com>
Fri, 16 Oct 2020 17:35:19 +0000 (01:35 +0800)
committerJeffery To <jeffery.to@gmail.com>
Fri, 16 Oct 2020 17:35:19 +0000 (01:35 +0800)
Signed-off-by: Jeffery To <jeffery.to@gmail.com>
lang/python/python3-version.mk
lang/python/python3/Makefile
lang/python/python3/patches/014-remove-platform-so-suffix.patch
lang/python/python3/patches/016-adjust-config-paths.patch
lang/python/python3/patches/025-bpo-34585-Dont-do-runtime-test-to-get-float-byte-order-GH-9085.patch
lang/python/python3/patches/026-bpo-34585-run-autoconf-GH-9411.patch
lang/python/python3/patches/027-bpo-41004-Resolve-hash-collisions-for-IPv4Interface-and-IPv6Interface-GH-21033-GH-21231.patch [deleted file]
lang/python/python3/patches/028-closes-bpo-41235-Fix-the-error-handling-in-SSLContext.load_dh_params-GH-21389.patch [deleted file]
lang/python/python3/patches/029-bpo-41288-Fix-a-crash-in-unpickling-invalid-NEWOBJ_EX-GH-21458-GH-21461.patch [deleted file]
lang/python/python3/patches/030-bpo-39017-Avoid-infinite-loop-in-the-tarfile-module-GH-21454-GH-21484.patch [deleted file]
lang/python/python3/patches/031-bpo-39603-Prevent-header-injection-in-http-methods-GH-18485-GH-21538.patch [deleted file]

index a047f4c69873b2029630733c17c9bccbeb8d7f0c..bc60c42e9a2afa6e65fab6a222da238b52f8300e 100644 (file)
@@ -8,7 +8,7 @@
 # Note: keep in sync with setuptools & pip
 PYTHON3_VERSION_MAJOR:=3
 PYTHON3_VERSION_MINOR:=7
-PYTHON3_VERSION_MICRO:=8
+PYTHON3_VERSION_MICRO:=9
 
 PYTHON3_VERSION:=$(PYTHON3_VERSION_MAJOR).$(PYTHON3_VERSION_MINOR)
 
index 12ac49fe184e74c50f3e3dfd4e5aa3da9b03fd80..294a63668f354330512f76bfddb908cd18ef1bd1 100644 (file)
@@ -14,12 +14,12 @@ PYTHON_VERSION:=$(PYTHON3_VERSION)
 PYTHON_VERSION_MICRO:=$(PYTHON3_VERSION_MICRO)
 
 PKG_NAME:=python3
-PKG_RELEASE:=4
+PKG_RELEASE:=1
 PKG_VERSION:=$(PYTHON_VERSION).$(PYTHON_VERSION_MICRO)
 
 PKG_SOURCE:=Python-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=https://www.python.org/ftp/python/$(PKG_VERSION)
-PKG_HASH:=43a543404b363f0037f89df8478f19db2dbc0d6f3ffee310bc2997fa71854a63
+PKG_HASH:=91923007b05005b5f9bd46f3b9172248aea5abc1543e8a636d59e629c3331b01
 
 PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>, Jeffery To <jeffery.to@gmail.com>
 PKG_LICENSE:=Python/2.0
index 488ce4990d0d2419b06599b8f2362e37d7d00e0c..7d48bd2919c5cba0191c9e96d53afaed33b39357 100644 (file)
@@ -1,6 +1,6 @@
 --- a/configure
 +++ b/configure
-@@ -15272,7 +15272,7 @@ $as_echo_n "checking ABIFLAGS... " >&6;
+@@ -15275,7 +15275,7 @@ $as_echo_n "checking ABIFLAGS... " >&6;
  $as_echo "$ABIFLAGS" >&6; }
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5
  $as_echo_n "checking SOABI... " >&6; }
@@ -11,7 +11,7 @@
  
 --- a/configure.ac
 +++ b/configure.ac
-@@ -4754,7 +4754,7 @@ AC_SUBST(SOABI)
+@@ -4757,7 +4757,7 @@ AC_SUBST(SOABI)
  AC_MSG_CHECKING(ABIFLAGS)
  AC_MSG_RESULT($ABIFLAGS)
  AC_MSG_CHECKING(SOABI)
index f6d3be84d64e3d139cf5f3ef1257cdf97cc45c99..3cd76fbe27bb782674249f4a04470f3f39c93db8 100644 (file)
@@ -49,7 +49,7 @@
      fi
  elif test "$cross_compiling" = maybe; then
      as_fn_error $? "Cross compiling required --host=HOST-TUPLE and --build=ARCH" "$LINENO" 5
-@@ -15291,7 +15291,7 @@ LDVERSION='$(VERSION)$(ABIFLAGS)'
+@@ -15294,7 +15294,7 @@ LDVERSION='$(VERSION)$(ABIFLAGS)'
  $as_echo "$LDVERSION" >&6; }
  
  
@@ -69,7 +69,7 @@
      fi
  elif test "$cross_compiling" = maybe; then
      AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH])
-@@ -4771,7 +4771,7 @@ AC_MSG_RESULT($LDVERSION)
+@@ -4774,7 +4774,7 @@ AC_MSG_RESULT($LDVERSION)
  
  dnl define LIBPL after ABIFLAGS and LDVERSION is defined.
  AC_SUBST(PY_ENABLE_SHARED)
index 3a03372b31e5a12e22853ede5fd675c5d3985e08..b2deb679c6025a66e120a64864ea466c8c00cd96 100644 (file)
@@ -25,7 +25,7 @@ RFC because this doesn't yet handle the weird ancient ARMv4 OABI 'mixed-endian'
 +builds.
 --- a/configure.ac
 +++ b/configure.ac
-@@ -4362,74 +4362,24 @@ fi
+@@ -4365,74 +4365,24 @@ fi
  # * Check for various properties of floating point *
  # **************************************************
  
index 6a79ff5a73396d7633ab0d8c0a23214ede54ad72..2a2d7aef5d162cd2b43745d2bd66ba275257d147 100644 (file)
@@ -20,7 +20,7 @@ Follow up to 2a9c3805ddedf282881ef7811a561c70b74f80b1 (bpo-34585).
  m4_include([m4/ax_check_openssl.m4])
 --- a/configure
 +++ b/configure
-@@ -14232,131 +14232,77 @@ fi
+@@ -14235,131 +14235,77 @@ fi
  # * Check for various properties of floating point *
  # **************************************************
  
diff --git a/lang/python/python3/patches/027-bpo-41004-Resolve-hash-collisions-for-IPv4Interface-and-IPv6Interface-GH-21033-GH-21231.patch b/lang/python/python3/patches/027-bpo-41004-Resolve-hash-collisions-for-IPv4Interface-and-IPv6Interface-GH-21033-GH-21231.patch
deleted file mode 100644 (file)
index 9042f83..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-From b98e7790c77a4378ec4b1c71b84138cb930b69b7 Mon Sep 17 00:00:00 2001
-From: Tapas Kundu <39723251+tapakund@users.noreply.github.com>
-Date: Wed, 1 Jul 2020 00:50:21 +0530
-Subject: [PATCH] [3.7] bpo-41004: Resolve hash collisions for IPv4Interface
- and IPv6Interface (GH-21033) (GH-21231)
-
-CVE-2020-14422
-The __hash__() methods of classes IPv4Interface and IPv6Interface had issue
-of generating constant hash values of 32 and 128 respectively causing hash collisions.
-The fix uses the hash() function to generate hash values for the objects
-instead of XOR operation
-(cherry picked from commit b30ee26e366bf509b7538d79bfec6c6d38d53f28)
-
-Co-authored-by: Ravi Teja P <rvteja92@gmail.com>
-
-Signed-off-by: Tapas Kundu <tkundu@vmware.com>
----
- Lib/ipaddress.py                                      |  4 ++--
- Lib/test/test_ipaddress.py                            | 11 +++++++++++
- .../Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst |  1 +
- 3 files changed, 14 insertions(+), 2 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
-
-diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
-index 80249288d73ab..54882934c3dc1 100644
---- a/Lib/ipaddress.py
-+++ b/Lib/ipaddress.py
-@@ -1442,7 +1442,7 @@ def __lt__(self, other):
-             return False
-     def __hash__(self):
--        return self._ip ^ self._prefixlen ^ int(self.network.network_address)
-+        return hash((self._ip, self._prefixlen, int(self.network.network_address)))
-     __reduce__ = _IPAddressBase.__reduce__
-@@ -2088,7 +2088,7 @@ def __lt__(self, other):
-             return False
-     def __hash__(self):
--        return self._ip ^ self._prefixlen ^ int(self.network.network_address)
-+        return hash((self._ip, self._prefixlen, int(self.network.network_address)))
-     __reduce__ = _IPAddressBase.__reduce__
-diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py
-index 455b893fb126f..1fb6a929dc2d9 100644
---- a/Lib/test/test_ipaddress.py
-+++ b/Lib/test/test_ipaddress.py
-@@ -2091,6 +2091,17 @@ def testsixtofour(self):
-                          sixtofouraddr.sixtofour)
-         self.assertFalse(bad_addr.sixtofour)
-+    # issue41004 Hash collisions in IPv4Interface and IPv6Interface
-+    def testV4HashIsNotConstant(self):
-+        ipv4_address1 = ipaddress.IPv4Interface("1.2.3.4")
-+        ipv4_address2 = ipaddress.IPv4Interface("2.3.4.5")
-+        self.assertNotEqual(ipv4_address1.__hash__(), ipv4_address2.__hash__())
-+
-+    # issue41004 Hash collisions in IPv4Interface and IPv6Interface
-+    def testV6HashIsNotConstant(self):
-+        ipv6_address1 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:1")
-+        ipv6_address2 = ipaddress.IPv6Interface("2001:658:22a:cafe:200:0:0:2")
-+        self.assertNotEqual(ipv6_address1.__hash__(), ipv6_address2.__hash__())
- if __name__ == '__main__':
-     unittest.main()
-diff --git a/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst b/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
-new file mode 100644
-index 0000000000000..f5a9db52fff52
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2020-06-29-16-02-29.bpo-41004.ovF0KZ.rst
-@@ -0,0 +1 @@
-+CVE-2020-14422: The __hash__() methods of  ipaddress.IPv4Interface and ipaddress.IPv6Interface incorrectly generated constant hash values of 32 and 128 respectively. This resulted in always causing hash collisions. The fix uses hash() to generate hash values for the tuple of (address, mask length, network address).
diff --git a/lang/python/python3/patches/028-closes-bpo-41235-Fix-the-error-handling-in-SSLContext.load_dh_params-GH-21389.patch b/lang/python/python3/patches/028-closes-bpo-41235-Fix-the-error-handling-in-SSLContext.load_dh_params-GH-21389.patch
deleted file mode 100644 (file)
index 90d87b3..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From c8c818b0d73680516d5841597b705a1feeb42113 Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Tue, 7 Jul 2020 21:55:36 -0700
-Subject: [PATCH] closes bpo-41235: Fix the error handling in
- SSLContext.load_dh_params() (GH-21389)
-
-(cherry picked from commit aebc0495572c5bb85d2bd97d27cf93ab038b5a6a)
-
-Co-authored-by: Zackery Spytz <zspytz@gmail.com>
----
- .../next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst   | 1 +
- Modules/_ssl.c                                              | 6 ++++--
- 2 files changed, 5 insertions(+), 2 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst
-
-diff --git a/Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst b/Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst
-new file mode 100644
-index 0000000000000..c55275bb1c622
---- /dev/null
-+++ b/Misc/NEWS.d/next/Library/2020-07-07-21-56-26.bpo-41235.H2csMU.rst
-@@ -0,0 +1 @@
-+Fix the error handling in :meth:`ssl.SSLContext.load_dh_params`.
-diff --git a/Modules/_ssl.c b/Modules/_ssl.c
-index 93cc529e796a0..719f8e8ca308d 100644
---- a/Modules/_ssl.c
-+++ b/Modules/_ssl.c
-@@ -4189,8 +4189,10 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath)
-         }
-         return NULL;
-     }
--    if (SSL_CTX_set_tmp_dh(self->ctx, dh) == 0)
--        _setSSLError(NULL, 0, __FILE__, __LINE__);
-+    if (!SSL_CTX_set_tmp_dh(self->ctx, dh)) {
-+        DH_free(dh);
-+        return _setSSLError(NULL, 0, __FILE__, __LINE__);
-+    }
-     DH_free(dh);
-     Py_RETURN_NONE;
- }
diff --git a/lang/python/python3/patches/029-bpo-41288-Fix-a-crash-in-unpickling-invalid-NEWOBJ_EX-GH-21458-GH-21461.patch b/lang/python/python3/patches/029-bpo-41288-Fix-a-crash-in-unpickling-invalid-NEWOBJ_EX-GH-21458-GH-21461.patch
deleted file mode 100644 (file)
index f36a7a1..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-From 620e276a8c1d53332fbf08d369be87f862b6949d Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Mon, 13 Jul 2020 11:17:01 -0700
-Subject: [PATCH] bpo-41288: Fix a crash in unpickling invalid NEWOBJ_EX.
- (GH-21458) (GH-21461)
-
-Automerge-Triggered-By: @tiran
-(cherry picked from commit 4f309abf55f0e6f8950ac13d6ec83c22b8d47bf8)
-
-Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
----
- Lib/test/pickletester.py                      | 18 ++++++++++++
- .../2020-07-13-15-06-35.bpo-41288.8mn5P-.rst  |  2 ++
- Modules/_pickle.c                             | 29 ++++++++++++++-----
- 3 files changed, 41 insertions(+), 8 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst
-
-diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
-index 1d88fcb859af8..c576d73349af8 100644
---- a/Lib/test/pickletester.py
-+++ b/Lib/test/pickletester.py
-@@ -998,6 +998,24 @@ def test_compat_unpickle(self):
-             self.assertIs(type(unpickled), collections.UserDict)
-             self.assertEqual(unpickled, collections.UserDict({1: 2}))
-+    def test_bad_reduce(self):
-+        self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0)
-+        self.check_unpickling_error(TypeError, b'N)R.')
-+        self.check_unpickling_error(TypeError, b'cbuiltins\nint\nNR.')
-+
-+    def test_bad_newobj(self):
-+        error = (pickle.UnpicklingError, TypeError)
-+        self.assertEqual(self.loads(b'cbuiltins\nint\n)\x81.'), 0)
-+        self.check_unpickling_error(error, b'cbuiltins\nlen\n)\x81.')
-+        self.check_unpickling_error(error, b'cbuiltins\nint\nN\x81.')
-+
-+    def test_bad_newobj_ex(self):
-+        error = (pickle.UnpicklingError, TypeError)
-+        self.assertEqual(self.loads(b'cbuiltins\nint\n)}\x92.'), 0)
-+        self.check_unpickling_error(error, b'cbuiltins\nlen\n)}\x92.')
-+        self.check_unpickling_error(error, b'cbuiltins\nint\nN}\x92.')
-+        self.check_unpickling_error(error, b'cbuiltins\nint\n)N\x92.')
-+
-     def test_bad_stack(self):
-         badpickles = [
-             b'.',                       # STOP
-diff --git a/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst b/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst
-new file mode 100644
-index 0000000000000..3c3adbabf16ff
---- /dev/null
-+++ b/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst
-@@ -0,0 +1,2 @@
-+Unpickling invalid NEWOBJ_EX opcode with the C implementation raises now
-+UnpicklingError instead of crashing.
-diff --git a/Modules/_pickle.c b/Modules/_pickle.c
-index ef83da02e2e41..329631d7e3b98 100644
---- a/Modules/_pickle.c
-+++ b/Modules/_pickle.c
-@@ -5515,23 +5515,30 @@ load_newobj_ex(UnpicklerObject *self)
-     }
-     if (!PyType_Check(cls)) {
--        Py_DECREF(kwargs);
--        Py_DECREF(args);
-         PyErr_Format(st->UnpicklingError,
-                      "NEWOBJ_EX class argument must be a type, not %.200s",
-                      Py_TYPE(cls)->tp_name);
--        Py_DECREF(cls);
--        return -1;
-+        goto error;
-     }
-     if (((PyTypeObject *)cls)->tp_new == NULL) {
--        Py_DECREF(kwargs);
--        Py_DECREF(args);
--        Py_DECREF(cls);
-         PyErr_SetString(st->UnpicklingError,
-                         "NEWOBJ_EX class argument doesn't have __new__");
--        return -1;
-+        goto error;
-+    }
-+    if (!PyTuple_Check(args)) {
-+        PyErr_Format(st->UnpicklingError,
-+                     "NEWOBJ_EX args argument must be a tuple, not %.200s",
-+                     Py_TYPE(args)->tp_name);
-+        goto error;
-+    }
-+    if (!PyDict_Check(kwargs)) {
-+        PyErr_Format(st->UnpicklingError,
-+                     "NEWOBJ_EX kwargs argument must be a dict, not %.200s",
-+                     Py_TYPE(kwargs)->tp_name);
-+        goto error;
-     }
-+
-     obj = ((PyTypeObject *)cls)->tp_new((PyTypeObject *)cls, args, kwargs);
-     Py_DECREF(kwargs);
-     Py_DECREF(args);
-@@ -5541,6 +5548,12 @@ load_newobj_ex(UnpicklerObject *self)
-     }
-     PDATA_PUSH(self->stack, obj, -1);
-     return 0;
-+
-+error:
-+    Py_DECREF(kwargs);
-+    Py_DECREF(args);
-+    Py_DECREF(cls);
-+    return -1;
- }
- static int
diff --git a/lang/python/python3/patches/030-bpo-39017-Avoid-infinite-loop-in-the-tarfile-module-GH-21454-GH-21484.patch b/lang/python/python3/patches/030-bpo-39017-Avoid-infinite-loop-in-the-tarfile-module-GH-21454-GH-21484.patch
deleted file mode 100644 (file)
index c851555..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-From 79c6b602efc9a906c8496f3d5f4d54c54b48fa06 Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Wed, 15 Jul 2020 05:35:08 -0700
-Subject: [PATCH] bpo-39017: Avoid infinite loop in the tarfile module
- (GH-21454) (GH-21484)
-
-Avoid infinite loop when reading specially crafted TAR files using the tarfile module
-(CVE-2019-20907).
-(cherry picked from commit 5a8d121a1f3ef5ad7c105ee378cc79a3eac0c7d4)
-
-Co-authored-by: Rishi <rishi_devan@mail.com>
----
- Lib/tarfile.py                                    |   2 ++
- Lib/test/recursion.tar                            | Bin 0 -> 516 bytes
- Lib/test/test_tarfile.py                          |   7 +++++++
- .../2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst      |   1 +
- 4 files changed, 10 insertions(+)
- create mode 100644 Lib/test/recursion.tar
- create mode 100644 Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst
-
-diff --git a/Lib/tarfile.py b/Lib/tarfile.py
-index 3b596cbf49d27..3be5188c8b0a2 100755
---- a/Lib/tarfile.py
-+++ b/Lib/tarfile.py
-@@ -1233,6 +1233,8 @@ def _proc_pax(self, tarfile):
-             length, keyword = match.groups()
-             length = int(length)
-+            if length == 0:
-+                raise InvalidHeaderError("invalid header")
-             value = buf[match.end(2) + 1:match.start(1) + length - 1]
-             # Normally, we could just use "utf-8" as the encoding and "strict"
-diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
-index 5e4d75ecfce1a..9133d60e49be1 100644
---- a/Lib/test/test_tarfile.py
-+++ b/Lib/test/test_tarfile.py
-@@ -395,6 +395,13 @@ def test_premature_end_of_archive(self):
-                 with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"):
-                     tar.extractfile(t).read()
-+    def test_length_zero_header(self):
-+        # bpo-39017 (CVE-2019-20907): reading a zero-length header should fail
-+        # with an exception
-+        with self.assertRaisesRegex(tarfile.ReadError, "file could not be opened successfully"):
-+            with tarfile.open(support.findfile('recursion.tar')) as tar:
-+                pass
-+
- class MiscReadTestBase(CommonReadTest):
-     def requires_name_attribute(self):
-         pass
-diff --git a/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst
-new file mode 100644
-index 0000000000000..ad26676f8b856
---- /dev/null
-+++ b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst
-@@ -0,0 +1 @@
-+Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907).
diff --git a/lang/python/python3/patches/031-bpo-39603-Prevent-header-injection-in-http-methods-GH-18485-GH-21538.patch b/lang/python/python3/patches/031-bpo-39603-Prevent-header-injection-in-http-methods-GH-18485-GH-21538.patch
deleted file mode 100644 (file)
index 67d9040..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-From ca75fec1ed358f7324272608ca952b2d8226d11a Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Sun, 19 Jul 2020 02:27:35 -0700
-Subject: [PATCH] bpo-39603: Prevent header injection in http methods
- (GH-18485) (GH-21538)
-
-reject control chars in http method in http.client.putrequest to prevent http header injection
-(cherry picked from commit 8ca8a2e8fb068863c1138f07e3098478ef8be12e)
-
-Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
----
- Lib/http/client.py                            | 15 +++++++++++++
- Lib/test/test_httplib.py                      | 22 +++++++++++++++++++
- .../2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst  |  2 ++
- 3 files changed, 39 insertions(+)
- create mode 100644 Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst
-
-diff --git a/Lib/http/client.py b/Lib/http/client.py
-index 09c57af865ee0..04cd8f7d84986 100644
---- a/Lib/http/client.py
-+++ b/Lib/http/client.py
-@@ -150,6 +150,10 @@
- #  _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$")
- # We are more lenient for assumed real world compatibility purposes.
-+# These characters are not allowed within HTTP method names
-+# to prevent http header injection.
-+_contains_disallowed_method_pchar_re = re.compile('[\x00-\x1f]')
-+
- # We always set the Content-Length header for these methods because some
- # servers will otherwise respond with a 411
- _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}
-@@ -1109,6 +1113,8 @@ def putrequest(self, method, url, skip_host=False,
-         else:
-             raise CannotSendRequest(self.__state)
-+        self._validate_method(method)
-+
-         # Save the method for use later in the response phase
-         self._method = method
-@@ -1199,6 +1205,15 @@ def _encode_request(self, request):
-         # ASCII also helps prevent CVE-2019-9740.
-         return request.encode('ascii')
-+    def _validate_method(self, method):
-+        """Validate a method name for putrequest."""
-+        # prevent http header injection
-+        match = _contains_disallowed_method_pchar_re.search(method)
-+        if match:
-+            raise ValueError(
-+                    f"method can't contain control characters. {method!r} "
-+                    f"(found at least {match.group()!r})")
-+
-     def _validate_path(self, url):
-         """Validate a url for putrequest."""
-         # Prevent CVE-2019-9740.
-diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
-index 891393ab869e6..3fa0691d3ad8f 100644
---- a/Lib/test/test_httplib.py
-+++ b/Lib/test/test_httplib.py
-@@ -363,6 +363,28 @@ def test_headers_debuglevel(self):
-         self.assertEqual(lines[3], "header: Second: val2")
-+class HttpMethodTests(TestCase):
-+    def test_invalid_method_names(self):
-+        methods = (
-+            'GET\r',
-+            'POST\n',
-+            'PUT\n\r',
-+            'POST\nValue',
-+            'POST\nHOST:abc',
-+            'GET\nrHost:abc\n',
-+            'POST\rRemainder:\r',
-+            'GET\rHOST:\n',
-+            '\nPUT'
-+        )
-+
-+        for method in methods:
-+            with self.assertRaisesRegex(
-+                    ValueError, "method can't contain control characters"):
-+                conn = client.HTTPConnection('example.com')
-+                conn.sock = FakeSocket(None)
-+                conn.request(method=method, url="/")
-+
-+
- class TransferEncodingTest(TestCase):
-     expected_body = b"It's just a flesh wound"
-diff --git a/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst b/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst
-new file mode 100644
-index 0000000000000..990affc3edd9d
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst
-@@ -0,0 +1,2 @@
-+Prevent http header injection by rejecting control characters in
-+http.client.putrequest(...).