Merge pull request #114537 from FRidh/python-20.09

[20.09] backport Python version updates
This commit is contained in:
Robert Hensing
2021-02-28 09:44:54 +01:00
committed by GitHub
7 changed files with 344 additions and 38 deletions

View File

@@ -0,0 +1,181 @@
From fab838b2ee7cfb9037c24f0f18dfe01aa379b3f7 Mon Sep 17 00:00:00 2001
From: Benjamin Peterson <benjamin@python.org>
Date: Mon, 18 Jan 2021 15:11:46 -0600
Subject: [3.6] closes bpo-42938: Replace snprintf with Python unicode
formatting in ctypes param reprs. (GH-24250)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry picked from commit 916610ef90a0d0761f08747f7b0905541f0977c7)
Co-authored-by: Benjamin Peterson <benjamin@python.org>
Rebased for Python 2.7 by Michał Górny <mgorny@gentoo.org>
---
Lib/ctypes/test/test_parameters.py | 43 +++++++++++++++++++
.../2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst | 2 +
Modules/_ctypes/callproc.c | 49 +++++++++++-----------
3 files changed, 69 insertions(+), 25 deletions(-)
create mode 100644 Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst
diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py
index 23c1b6e225..3456882ccb 100644
--- a/Lib/ctypes/test/test_parameters.py
+++ b/Lib/ctypes/test/test_parameters.py
@@ -206,6 +206,49 @@ class SimpleTypesTestCase(unittest.TestCase):
with self.assertRaises(ZeroDivisionError):
WorseStruct().__setstate__({}, b'foo')
+ def test_parameter_repr(self):
+ from ctypes import (
+ c_bool,
+ c_char,
+ c_wchar,
+ c_byte,
+ c_ubyte,
+ c_short,
+ c_ushort,
+ c_int,
+ c_uint,
+ c_long,
+ c_ulong,
+ c_longlong,
+ c_ulonglong,
+ c_float,
+ c_double,
+ c_longdouble,
+ c_char_p,
+ c_wchar_p,
+ c_void_p,
+ )
+ self.assertRegexpMatches(repr(c_bool.from_param(True)), r"^<cparam '\?' at 0x[A-Fa-f0-9]+>$")
+ self.assertEqual(repr(c_char.from_param('a')), "<cparam 'c' (a)>")
+ self.assertRegexpMatches(repr(c_wchar.from_param('a')), r"^<cparam 'u' at 0x[A-Fa-f0-9]+>$")
+ self.assertEqual(repr(c_byte.from_param(98)), "<cparam 'b' (98)>")
+ self.assertEqual(repr(c_ubyte.from_param(98)), "<cparam 'B' (98)>")
+ self.assertEqual(repr(c_short.from_param(511)), "<cparam 'h' (511)>")
+ self.assertEqual(repr(c_ushort.from_param(511)), "<cparam 'H' (511)>")
+ self.assertRegexpMatches(repr(c_int.from_param(20000)), r"^<cparam '[li]' \(20000\)>$")
+ self.assertRegexpMatches(repr(c_uint.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$")
+ self.assertRegexpMatches(repr(c_long.from_param(20000)), r"^<cparam '[li]' \(20000\)>$")
+ self.assertRegexpMatches(repr(c_ulong.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$")
+ self.assertRegexpMatches(repr(c_longlong.from_param(20000)), r"^<cparam '[liq]' \(20000\)>$")
+ self.assertRegexpMatches(repr(c_ulonglong.from_param(20000)), r"^<cparam '[LIQ]' \(20000\)>$")
+ self.assertEqual(repr(c_float.from_param(1.5)), "<cparam 'f' (1.5)>")
+ self.assertEqual(repr(c_double.from_param(1.5)), "<cparam 'd' (1.5)>")
+ self.assertEqual(repr(c_double.from_param(1e300)), "<cparam 'd' (1e+300)>")
+ self.assertRegexpMatches(repr(c_longdouble.from_param(1.5)), r"^<cparam ('d' \(1.5\)|'g' at 0x[A-Fa-f0-9]+)>$")
+ self.assertRegexpMatches(repr(c_char_p.from_param(b'hihi')), "^<cparam 'z' \(0x[A-Fa-f0-9]+\)>$")
+ self.assertRegexpMatches(repr(c_wchar_p.from_param('hihi')), "^<cparam 'Z' \(0x[A-Fa-f0-9]+\)>$")
+ self.assertRegexpMatches(repr(c_void_p.from_param(0x12)), r"^<cparam 'P' \(0x0*12\)>$")
+
################################################################
if __name__ == '__main__':
diff --git a/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst b/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst
new file mode 100644
index 0000000000..7df65a156f
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2021-01-18-09-27-31.bpo-42938.4Zn4Mp.rst
@@ -0,0 +1,2 @@
+Avoid static buffers when computing the repr of :class:`ctypes.c_double` and
+:class:`ctypes.c_longdouble` values.
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 066fefc0cc..421addf353 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -460,50 +460,51 @@ PyCArg_dealloc(PyCArgObject *self)
static PyObject *
PyCArg_repr(PyCArgObject *self)
{
- char buffer[256];
switch(self->tag) {
case 'b':
case 'B':
- sprintf(buffer, "<cparam '%c' (%d)>",
+ return PyString_FromFormat("<cparam '%c' (%d)>",
self->tag, self->value.b);
- break;
case 'h':
case 'H':
- sprintf(buffer, "<cparam '%c' (%d)>",
+ return PyString_FromFormat("<cparam '%c' (%d)>",
self->tag, self->value.h);
- break;
case 'i':
case 'I':
- sprintf(buffer, "<cparam '%c' (%d)>",
+ return PyString_FromFormat("<cparam '%c' (%d)>",
self->tag, self->value.i);
- break;
case 'l':
case 'L':
- sprintf(buffer, "<cparam '%c' (%ld)>",
+ return PyString_FromFormat("<cparam '%c' (%ld)>",
self->tag, self->value.l);
- break;
#ifdef HAVE_LONG_LONG
case 'q':
case 'Q':
- sprintf(buffer,
+ return PyString_FromFormat(
"<cparam '%c' (%" PY_FORMAT_LONG_LONG "d)>",
self->tag, self->value.q);
- break;
#endif
case 'd':
- sprintf(buffer, "<cparam '%c' (%f)>",
- self->tag, self->value.d);
- break;
- case 'f':
- sprintf(buffer, "<cparam '%c' (%f)>",
- self->tag, self->value.f);
- break;
-
+ case 'f': {
+ PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : self->value.d);
+ if (f == NULL) {
+ return NULL;
+ }
+ PyObject *r = PyObject_Repr(f);
+ if (r == NULL) {
+ Py_DECREF(f);
+ return NULL;
+ }
+ PyObject *result = PyString_FromFormat(
+ "<cparam '%c' (%s)>", self->tag, PyString_AsString(r));
+ Py_DECREF(r);
+ Py_DECREF(f);
+ return result;
+ }
case 'c':
- sprintf(buffer, "<cparam '%c' (%c)>",
+ return PyString_FromFormat("<cparam '%c' (%c)>",
self->tag, self->value.c);
- break;
/* Hm, are these 'z' and 'Z' codes useful at all?
Shouldn't they be replaced by the functionality of c_string
@@ -512,16 +513,14 @@ PyCArg_repr(PyCArgObject *self)
case 'z':
case 'Z':
case 'P':
- sprintf(buffer, "<cparam '%c' (%p)>",
+ return PyString_FromFormat("<cparam '%c' (%p)>",
self->tag, self->value.p);
break;
default:
- sprintf(buffer, "<cparam '%c' at %p>",
+ return PyString_FromFormat("<cparam '%c' at %p>",
self->tag, self);
- break;
}
- return PyString_FromString(buffer);
}
static PyMemberDef PyCArgType_members[] = {
--
cgit v1.2.3

View File

@@ -93,6 +93,9 @@ let
# Patch is likely to go away in the next release (if there is any)
./CVE-2019-20907.patch
./CVE-2021-3177.patch
] ++ optionals (x11Support && stdenv.isDarwin) [
./use-correct-tcl-tk-on-darwin.patch
] ++ optionals stdenv.isLinux [

View File

@@ -0,0 +1,105 @@
From 9b5a023a5dc3127da15253f7acad71019395ebe1 Mon Sep 17 00:00:00 2001
From: Pablo Galindo <Pablogsal@gmail.com>
Date: Thu, 8 Oct 2020 19:50:37 +0100
Subject: [PATCH] [3.7] bpo-41976: Fix the fallback to gcc of
ctypes.util.find_library when using gcc>9 (GH-22598). (GH-22601)
(cherry picked from commit 27ac19cca2c639caaf6fedf3632fe6beb265f24f)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
---
Lib/ctypes/test/test_find.py | 12 ++++++-
Lib/ctypes/util.py | 32 +++++++++++++++----
.../2020-10-08-18-22-28.bpo-41976.Svm0wb.rst | 3 ++
3 files changed, 39 insertions(+), 8 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst
diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py
index b99fdcba7b28f..92ac1840ad7d4 100644
--- a/Lib/ctypes/test/test_find.py
+++ b/Lib/ctypes/test/test_find.py
@@ -1,4 +1,5 @@
import unittest
+import unittest.mock
import os.path
import sys
import test.support
@@ -72,7 +73,7 @@ def test_shell_injection(self):
@unittest.skipUnless(sys.platform.startswith('linux'),
'Test only valid for Linux')
-class LibPathFindTest(unittest.TestCase):
+class FindLibraryLinux(unittest.TestCase):
def test_find_on_libpath(self):
import subprocess
import tempfile
@@ -111,6 +112,15 @@ def test_find_on_libpath(self):
# LD_LIBRARY_PATH)
self.assertEqual(find_library(libname), 'lib%s.so' % libname)
+ def test_find_library_with_gcc(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
+ def test_find_library_with_ld(self):
+ with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \
+ unittest.mock.patch("ctypes.util._findLib_gcc", lambda *args: None):
+ self.assertNotEqual(find_library('c'), None)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index 97973bce001d9..0c2510e1619c8 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -93,6 +93,12 @@ def find_library(name):
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
import re, tempfile
+ def _is_elf(filename):
+ "Return True if the given file is an ELF file"
+ elf_header = b'\x7fELF'
+ with open(filename, 'br') as thefile:
+ return thefile.read(4) == elf_header
+
def _findLib_gcc(name):
# Run GCC's linker with the -t (aka --trace) option and examine the
# library name it prints out. The GCC command will fail because we
@@ -299,17 +312,22 @@ def _findLib_ld(name):
stderr=subprocess.PIPE,
universal_newlines=True)
out, _ = p.communicate()
- res = re.search(expr, os.fsdecode(out))
- if res:
- result = res.group(0)
- except Exception as e:
+ res = re.findall(expr, os.fsdecode(out))
+ for file in res:
+ # Check if the given file is an elf file: gcc can report
+ # some files that are linker scripts and not actual
+ # shared objects. See bpo-41976 for more details
+ if not _is_elf(file):
+ continue
+ return os.fsdecode(file)
+ except Exception:
pass # result will be None
return result
def find_library(name):
# See issue #9998
return _findSoname_ldconfig(name) or \
- _get_soname(_findLib_gcc(name) or _findLib_ld(name))
+ _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name))
################################################################
# test code
diff --git a/Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst b/Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst
new file mode 100644
index 0000000000000..c8b3fc771845e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-10-08-18-22-28.bpo-41976.Svm0wb.rst
@@ -0,0 +1,3 @@
+Fixed a bug that was causing :func:`ctypes.util.find_library` to return
+``None`` when triying to locate a library in an environment when gcc>=9 is
+available and ``ldconfig`` is not. Patch by Pablo Galindo

View File

@@ -1,18 +1,18 @@
From 597e73f2a4b2f0b508127931b36d5540d6941823 Mon Sep 17 00:00:00 2001
From ba458f33f335b217d078fdce56e9c6f9f93adb49 Mon Sep 17 00:00:00 2001
From: Frederik Rietdijk <fridh@fridh.nl>
Date: Mon, 28 Aug 2017 09:24:06 +0200
Subject: [PATCH] Don't use ldconfig
---
Lib/ctypes/util.py | 70 ++----------------------------------------------------
1 file changed, 2 insertions(+), 68 deletions(-)
Lib/ctypes/util.py | 78 ++--------------------------------------------
1 file changed, 2 insertions(+), 76 deletions(-)
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index 5e8b31a854..7b45ce6c15 100644
index 0c2510e..79635a8 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -94,46 +94,7 @@ elif os.name == "posix":
import re, tempfile
@@ -100,54 +100,7 @@ elif os.name == "posix":
return thefile.read(4) == elf_header
def _findLib_gcc(name):
- # Run GCC's linker with the -t (aka --trace) option and examine the
@@ -51,15 +51,23 @@ index 5e8b31a854..7b45ce6c15 100644
- # Raised if the file was already removed, which is the normal
- # behaviour of GCC if linking fails
- pass
- res = re.search(expr, trace)
- res = re.findall(expr, trace)
- if not res:
- return None
- return os.fsdecode(res.group(0))
-
- for file in res:
- # Check if the given file is an elf file: gcc can report
- # some files that are linker scripts and not actual
- # shared objects. See bpo-41976 for more details
- if not _is_elf(file):
- continue
- return os.fsdecode(file)
-
+ return None
if sys.platform == "sunos5":
@@ -255,34 +216,7 @@ elif os.name == "posix":
# use /usr/ccs/bin/dump on solaris
@@ -268,34 +221,7 @@ elif os.name == "posix":
else:
def _findSoname_ldconfig(name):
@@ -96,5 +104,5 @@ index 5e8b31a854..7b45ce6c15 100644
def _findLib_ld(name):
# See issue #9998 for why this is needed
--
2.15.0
2.30.0

View File

@@ -1,19 +1,19 @@
From 597e73f2a4b2f0b508127931b36d5540d6941823 Mon Sep 17 00:00:00 2001
From: Frederik Rietdijk <fridh@fridh.nl>
Date: Mon, 28 Aug 2017 09:24:06 +0200
From 66f492d2eda94bd64db833839a325caf6ba0fed5 Mon Sep 17 00:00:00 2001
From: Greg Roodt <greg@canva.com>
Date: Wed, 9 Dec 2020 17:59:24 +1100
Subject: [PATCH] Don't use ldconfig
---
Lib/ctypes/util.py | 70 ++----------------------------------------------------
1 file changed, 2 insertions(+), 68 deletions(-)
Lib/ctypes/util.py | 77 ++--------------------------------------------
1 file changed, 2 insertions(+), 75 deletions(-)
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index 5e8b31a854..7b45ce6c15 100644
index 0c2510e161..7fb98af308 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -94,46 +94,7 @@ elif os.name == "posix":
import re, tempfile
@@ -100,53 +100,7 @@ elif os.name == "posix":
return thefile.read(4) == elf_header
def _findLib_gcc(name):
- # Run GCC's linker with the -t (aka --trace) option and examine the
- # library name it prints out. The GCC command will fail because we
@@ -51,17 +51,24 @@ index 5e8b31a854..7b45ce6c15 100644
- # Raised if the file was already removed, which is the normal
- # behaviour of GCC if linking fails
- pass
- res = re.search(expr, trace)
- res = re.findall(expr, trace)
- if not res:
- return None
- return os.fsdecode(res.group(0))
-
- for file in res:
- # Check if the given file is an elf file: gcc can report
- # some files that are linker scripts and not actual
- # shared objects. See bpo-41976 for more details
- if not _is_elf(file):
- continue
- return os.fsdecode(file)
+ return None
if sys.platform == "sunos5":
@@ -255,34 +216,7 @@ elif os.name == "posix":
@@ -268,34 +222,7 @@ elif os.name == "posix":
else:
def _findSoname_ldconfig(name):
- import struct
- if struct.calcsize('l') == 4:
@@ -92,9 +99,8 @@ index 5e8b31a854..7b45ce6c15 100644
- except OSError:
- pass
+ return None
def _findLib_ld(name):
# See issue #9998 for why this is needed
--
2.15.0
--
2.24.3 (Apple Git-128)

View File

@@ -153,6 +153,9 @@ in with passthru; stdenv.mkDerivation {
] ++ [
# LDSHARED now uses $CC instead of gcc. Fixes cross-compilation of extension modules.
./3.8/0001-On-all-posix-systems-not-just-Darwin-set-LDSHARED-if.patch
] ++ optionals (isPy36) [
# Backport a fix for ctypes.util.find_library.
./3.6/find_library.patch
];
postPatch = ''

View File

@@ -68,10 +68,10 @@ in {
sourceVersion = {
major = "3";
minor = "6";
patch = "12";
patch = "13";
suffix = "";
};
sha256 = "cJU6m11okdkuZdGEw1EhJqFYFL7hXh7/LdzOBDNOmpk=";
sha256 = "pHpDpTq7QihqLBGWU0P/VnEbnmTo0RvyxnAaT7jOGg8=";
inherit (darwin) configd;
inherit passthruFun;
};
@@ -81,10 +81,10 @@ in {
sourceVersion = {
major = "3";
minor = "7";
patch = "9";
patch = "10";
suffix = "";
};
sha256 = "008v6g1jkrjrdmiqlgjlq6msbbj848bvkws6ppwva1ahn03k14li";
sha256 = "+NgudXLIbsnVXIYnquUEAST9IgOvQAw4PIIbmAMG7ms=";
inherit (darwin) configd;
inherit passthruFun;
};
@@ -94,10 +94,10 @@ in {
sourceVersion = {
major = "3";
minor = "8";
patch = "5";
patch = "8";
suffix = "";
};
sha256 = "1c43dbv9lvlp3ynqmgdi4rh8q94swanhqarqrdx62zmigpakw073";
sha256 = "fGZCSf935EPW6g5M8OWH6ukYyjxI0IHRkV/iofG8xcw=";
inherit (darwin) configd;
inherit passthruFun;
};
@@ -107,10 +107,10 @@ in {
sourceVersion = {
major = "3";
minor = "9";
patch = "1";
patch = "2";
suffix = "";
};
sha256 = "1zq3k4ymify5ig739zyvx9s2ainvchxb1zpy139z74krr653y74r";
sha256 = "PCA0xU+BFEj1FmaNzgnSQAigcWw6eU3YY5tTiMveJH0=";
inherit (darwin) configd;
inherit passthruFun;
};