From: JinWang An Date: Wed, 18 Jan 2023 06:01:31 +0000 (+0900) Subject: Imported Upstream version 3.9.15 X-Git-Tag: upstream/3.9.15^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=677f4979b2845bf194f0dc32174765ce440e89e5;p=platform%2Fupstream%2Fpython3.git Imported Upstream version 3.9.15 --- diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index c7fbcb2..9756481 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -845,6 +845,8 @@ ABC hierarchy:: Read contents of self as text. + Note: In Python 3.11 and later, this class is found in ``importlib.resources.abc``. + .. class:: TraversableResources @@ -856,6 +858,8 @@ ABC hierarchy:: .. versionadded:: 3.9 + Note: In Python 3.11 and later, this class is found in ``importlib.resources.abc``. + :mod:`importlib.resources` -- Resources --------------------------------------- @@ -918,7 +922,7 @@ The following functions are available. .. function:: files(package) - Returns an :class:`importlib.resources.abc.Traversable` object + Returns an :class:`importlib.abc.Traversable` object representing the resource container for the package (think directory) and its resources (think files). A Traversable may contain other containers (think subdirectories). @@ -930,7 +934,7 @@ The following functions are available. .. function:: as_file(traversable) - Given a :class:`importlib.resources.abc.Traversable` object representing + Given a :class:`importlib.abc.Traversable` object representing a file, typically from :func:`importlib.resources.files`, return a context manager for use in a :keyword:`with` statement. The context manager provides a :class:`pathlib.Path` object. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 6eef564..d6b270d 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -5277,7 +5277,7 @@ When an operation would exceed the limit, a :exc:`ValueError` is raised: >>> _ = int('2' * 5432) Traceback (most recent call last): ... - ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits. + ValueError: Exceeds the limit (4300) for integer string conversion: value has 5432 digits; use sys.set_int_max_str_digits() to increase the limit. >>> i = int('2' * 4300) >>> len(str(i)) 4300 @@ -5285,7 +5285,7 @@ When an operation would exceed the limit, a :exc:`ValueError` is raised: >>> len(str(i_squared)) Traceback (most recent call last): ... - ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits. + ValueError: Exceeds the limit (4300) for integer string conversion: value has 8599 digits; use sys.set_int_max_str_digits() to increase the limit. >>> len(hex(i_squared)) 7144 >>> assert int(hex(i_squared), base=16) == i*i # Hexadecimal is unlimited. diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 45eff7f..10e4063 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -195,7 +195,10 @@ compatibility with older versions, see the :ref:`call-function-trio` section. .. attribute:: output Output of the child process if it was captured by :func:`run` or - :func:`check_output`. Otherwise, ``None``. + :func:`check_output`. Otherwise, ``None``. This is always + :class:`bytes` when any output was captured regardless of the + ``text=True`` setting. It may remain ``None`` instead of ``b''`` + when no output was observed. .. attribute:: stdout @@ -204,7 +207,9 @@ compatibility with older versions, see the :ref:`call-function-trio` section. .. attribute:: stderr Stderr output of the child process if it was captured by :func:`run`. - Otherwise, ``None``. + Otherwise, ``None``. This is always :class:`bytes` when stderr output + was captured regardless of the ``text=True`` setting. It may remain + ``None`` instead of ``b''`` when no stderr output was observed. .. versionadded:: 3.3 diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index b7430e9..f0f8605 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -113,7 +113,8 @@ or on combining URL components into a URL string. +------------------+-------+-------------------------+------------------------+ | :attr:`path` | 2 | Hierarchical path | empty string | +------------------+-------+-------------------------+------------------------+ - | :attr:`params` | 3 | No longer used | always an empty string | + | :attr:`params` | 3 | Parameters for last | empty string | + | | | path element | | +------------------+-------+-------------------------+------------------------+ | :attr:`query` | 4 | Query component | empty string | +------------------+-------+-------------------------+------------------------+ diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 3d48e97..a30fa4a 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 9 -#define PY_MICRO_VERSION 14 +#define PY_MICRO_VERSION 15 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.9.14" +#define PY_VERSION "3.9.15" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index bfb5db0..c06cf32 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Sep 6 19:25:22 2022 +# Autogenerated by Sphinx on Tue Oct 11 16:45:32 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index e38fc69..9fb48c5 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -821,6 +821,8 @@ class CmdLineTest(unittest.TestCase): assert_python_failure('-X', 'int_max_str_digits', '-c', code) assert_python_failure('-X', 'int_max_str_digits=foo', '-c', code) assert_python_failure('-X', 'int_max_str_digits=100', '-c', code) + assert_python_failure('-X', 'int_max_str_digits', '-c', code, + PYTHONINTMAXSTRDIGITS='4000') assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='foo') assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='100') diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index 3c8d829..85bbf51 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -68,6 +68,19 @@ class ListTest(list_tests.CommonTest): self.assertRaises((MemoryError, OverflowError), mul, lst, n) self.assertRaises((MemoryError, OverflowError), imul, lst, n) + def test_list_resize_overflow(self): + # gh-97616: test new_allocated * sizeof(PyObject*) overflow + # check in list_resize() + lst = [0] * 65 + del lst[1:] + self.assertEqual(len(lst), 1) + + size = ((2 ** (tuple.__itemsize__ * 8) - 1) // 2) + with self.assertRaises((MemoryError, OverflowError)): + lst * size + with self.assertRaises((MemoryError, OverflowError)): + lst *= size + def test_repr_large(self): # Check the repr of large list objects def check(n): diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 6ba1454..3c0ddeb 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -2040,6 +2040,28 @@ class TestPosixWeaklinking(unittest.TestCase): with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): os.mkdir("dir", dir_fd=0) + def test_mkfifo(self): + self._verify_available("HAVE_MKFIFOAT") + if self.mac_ver >= (13, 0): + self.assertIn("HAVE_MKFIFOAT", posix._have_functions) + + else: + self.assertNotIn("HAVE_MKFIFOAT", posix._have_functions) + + with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): + os.mkfifo("path", dir_fd=0) + + def test_mknod(self): + self._verify_available("HAVE_MKNODAT") + if self.mac_ver >= (13, 0): + self.assertIn("HAVE_MKNODAT", posix._have_functions) + + else: + self.assertNotIn("HAVE_MKNODAT", posix._have_functions) + + with self.assertRaisesRegex(NotImplementedError, "dir_fd unavailable"): + os.mknod("path", dir_fd=0) + def test_rename_replace(self): self._verify_available("HAVE_RENAMEAT") if self.mac_ver >= (10, 10): diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 6faa2ee..e270f44 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -1141,8 +1141,10 @@ class ContextTests(unittest.TestCase): def test_protocol(self): for proto in PROTOCOLS: - ctx = ssl.SSLContext(proto) - self.assertEqual(ctx.protocol, proto) + if has_tls_protocol(proto): + with warnings_helper.check_warnings(): + ctx = ssl.SSLContext(proto) + self.assertEqual(ctx.protocol, proto) def test_ciphers(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -1524,7 +1526,10 @@ class ContextTests(unittest.TestCase): def test_session_stats(self): for proto in PROTOCOLS: - ctx = ssl.SSLContext(proto) + if not has_tls_protocol(proto): + continue + with warnings_helper.check_warnings(): + ctx = ssl.SSLContext(proto) self.assertEqual(ctx.session_stats(), { 'number': 0, 'connect': 0, @@ -1715,13 +1720,14 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) self._assert_context_options(ctx) - ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1, - cert_reqs=ssl.CERT_REQUIRED, - check_hostname=True) - self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) - self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) - self.assertTrue(ctx.check_hostname) - self._assert_context_options(ctx) + with warnings_helper.check_warnings(): + ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1, + cert_reqs=ssl.CERT_REQUIRED, + check_hostname=True) + self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) + self.assertTrue(ctx.check_hostname) + self._assert_context_options(ctx) ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH) self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS) diff --git a/Misc/NEWS b/Misc/NEWS index 1ac3ba1..ee0452b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,56 @@ Python News +++++++++++ +What's New in Python 3.9.15 final? +================================== + +*Release date: 2022-10-11* + +Security +-------- + +- gh-issue-97616: Fix multiplying a list by an integer (``list *= int``): + detect the integer overflow when the new allocated length is close to the + maximum size. Issue reported by Jordan Limor. Patch by Victor Stinner. + +- gh-issue-97612: Fix a shell code injection vulnerability in the + ``get-remote-certificate.py`` example script. The script no longer uses a + shell to run ``openssl`` commands. Issue reported and initial fix by Caleb + Shortt. Patch by Victor Stinner. + +Core and Builtins +----------------- + +- gh-issue-96848: Fix command line parsing: reject :option:`-X + int_max_str_digits <-X>` option with no value (invalid) when the + :envvar:`PYTHONINTMAXSTRDIGITS` environment variable is set to a valid + limit. Patch by Victor Stinner. + +- gh-issue-95778: When :exc:`ValueError` is raised if an integer is larger + than the limit, mention the :func:`sys.set_int_max_str_digits` function in + the error message. Patch by Victor Stinner. + +Library +------- + +- gh-issue-97005: Update bundled libexpat to 2.4.9 + +Windows +------- + +- gh-issue-96577: Fixes a potential buffer overrun in :mod:`msilib`. + +macOS +----- + +- gh-issue-97897: The macOS 13 SDK includes support for the ``mkfifoat`` and + ``mknodat`` system calls. Using the ``dir_fd`` option with either + :func:`os.mkfifo` or :func:`os.mknod` could result in a segfault if + cpython is built with the macOS 13 SDK but run on an earlier version of + macOS. Prevent this by adding runtime support for detection of these + system calls ("weaklinking") as is done for other newer syscalls on macOS. + + What's New in Python 3.9.14 final? ================================== diff --git a/Modules/expat/COPYING b/Modules/expat/COPYING index 3c0142e..ce9e593 100644 --- a/Modules/expat/COPYING +++ b/Modules/expat/COPYING @@ -1,5 +1,5 @@ Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper -Copyright (c) 2001-2019 Expat maintainers +Copyright (c) 2001-2022 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index c9214f6..2b47ce2 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -1055,7 +1055,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 7 +#define XML_MICRO_VERSION 9 #ifdef __cplusplus } diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h index 444eba0..e09f533 100644 --- a/Modules/expat/internal.h +++ b/Modules/expat/internal.h @@ -28,7 +28,7 @@ Copyright (c) 2002-2003 Fred L. Drake, Jr. Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2003 Greg Stein - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2018 Yury Gribov Copyright (c) 2019 David Loffredo Licensed under the MIT license: @@ -107,7 +107,9 @@ #include // ULONG_MAX -#if defined(_WIN32) && ! defined(__USE_MINGW_ANSI_STDIO) +#if defined(_WIN32) \ + && (! defined(__USE_MINGW_ANSI_STDIO) \ + || (1 - __USE_MINGW_ANSI_STDIO - 1 == 0)) # define EXPAT_FMT_ULL(midpart) "%" midpart "I64u" # if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW # define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d" diff --git a/Modules/expat/siphash.h b/Modules/expat/siphash.h index e5406d7..303283a 100644 --- a/Modules/expat/siphash.h +++ b/Modules/expat/siphash.h @@ -106,7 +106,7 @@ * if this code is included and compiled as C++; related GCC warning is: * warning: use of C++11 long long integer constant [-Wlong-long] */ -#define _SIP_ULL(high, low) (((uint64_t)high << 32) | low) +#define _SIP_ULL(high, low) ((((uint64_t)high) << 32) | (low)) #define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 05216d9..c0bece5 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* fcb1a62fefa945567301146eb98e3ad3413e823a41c4378e84e8b6b6f308d824 (2.4.7+) +/* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065e42784e001db4f23de324 (2.4.9+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -19,7 +19,7 @@ Copyright (c) 2016 Gustavo Grieco Copyright (c) 2016 Pascal Cuoq Copyright (c) 2016 Ed Schouten - Copyright (c) 2017-2018 Rhodri James + Copyright (c) 2017-2022 Rhodri James Copyright (c) 2017 Václav Slavík Copyright (c) 2017 Viktor Szakats Copyright (c) 2017 Chanho Park @@ -4271,7 +4271,7 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, const XML_Char *storedEncName = NULL; const ENCODING *newEncoding = NULL; const char *version = NULL; - const char *versionend; + const char *versionend = NULL; const XML_Char *storedversion = NULL; int standalone = -1; @@ -5826,10 +5826,15 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end, { parser->m_processor = contentProcessor; /* see externalEntityContentProcessor vs contentProcessor */ - return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, - s, end, nextPtr, - (XML_Bool)! parser->m_parsingStatus.finalBuffer, - XML_ACCOUNT_DIRECT); + result = doContent(parser, parser->m_parentParser ? 1 : 0, + parser->m_encoding, s, end, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, + XML_ACCOUNT_DIRECT); + if (result == XML_ERROR_NONE) { + if (! storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } + return result; } } diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index c659983..2b7012a 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -21,6 +21,7 @@ Copyright (c) 2017 José Gutiérrez de la Concha Copyright (c) 2019 David Loffredo Copyright (c) 2021 Dong-hee Na + Copyright (c) 2022 Martin Ettl Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -296,7 +297,7 @@ sb_charMatches(const ENCODING *enc, const char *p, int c) { } #else /* c is an ASCII character */ -# define CHAR_MATCHES(enc, p, c) (*(p) == c) +# define CHAR_MATCHES(enc, p, c) (*(p) == (c)) #endif #define PREFIX(ident) normal_##ident @@ -740,7 +741,7 @@ DEFINE_UTF16_TO_UTF16(big2_) ((p)[1] == 0 ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ : unicode_byte_type((p)[1], (p)[0])) #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) -#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == c) +#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c)) #define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ @@ -875,7 +876,7 @@ static const struct normal_encoding internal_little2_encoding ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ : unicode_byte_type((p)[0], (p)[1])) #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) -#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == c) +#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c)) #define BIG2_IS_NAME_CHAR_MINBPC(p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) #define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ diff --git a/Modules/expat/xmltok_impl.c b/Modules/expat/xmltok_impl.c index 4072b06..1971d74 100644 --- a/Modules/expat/xmltok_impl.c +++ b/Modules/expat/xmltok_impl.c @@ -16,6 +16,7 @@ Copyright (c) 2018 Anton Maklakov Copyright (c) 2019 David Loffredo Copyright (c) 2020 Boris Kolpackov + Copyright (c) 2022 Martin Ettl Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -96,7 +97,7 @@ # define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD##n: \ - if (end - ptr < n) \ + if ((end) - (ptr) < (n)) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ @@ -124,7 +125,8 @@ # define PREFIX(ident) ident # endif -# define HAS_CHARS(enc, ptr, end, count) (end - ptr >= count * MINBPC(enc)) +# define HAS_CHARS(enc, ptr, end, count) \ + ((end) - (ptr) >= ((count)*MINBPC(enc))) # define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1270af7..bf4e648 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -79,6 +79,8 @@ # define HAVE_FUTIMENS_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) # define HAVE_UTIMENSAT_RUNTIME __builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) # define HAVE_PWRITEV_RUNTIME __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +# define HAVE_MKFIFOAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) +# define HAVE_MKNODAT_RUNTIME __builtin_available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) # define HAVE_POSIX_SPAWN_SETSID_RUNTIME __builtin_available(macOS 10.15, *) @@ -163,6 +165,8 @@ # define HAVE_FUTIMENS_RUNTIME 1 # define HAVE_UTIMENSAT_RUNTIME 1 # define HAVE_PWRITEV_RUNTIME 1 +# define HAVE_MKFIFOAT_RUNTIME 1 +# define HAVE_MKNODAT_RUNTIME 1 #endif @@ -10482,18 +10486,35 @@ os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd) { int result; int async_err = 0; +#ifdef HAVE_MKFIFOAT + int mkfifoat_unavailable = 0; +#endif do { Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKFIFOAT - if (dir_fd != DEFAULT_DIR_FD) - result = mkfifoat(dir_fd, path->narrow, mode); - else + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_MKFIFOAT_RUNTIME) { + result = mkfifoat(dir_fd, path->narrow, mode); + + } else { + mkfifoat_unavailable = 1; + result = 0; + } + } else #endif result = mkfifo(path->narrow, mode); Py_END_ALLOW_THREADS } while (result != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + +#ifdef HAVE_MKFIFOAT + if (mkfifoat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif + if (result != 0) return (!async_err) ? posix_error() : NULL; @@ -10534,18 +10555,33 @@ os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, { int result; int async_err = 0; +#ifdef HAVE_MKNODAT + int mknodat_unavailable = 0; +#endif do { Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKNODAT - if (dir_fd != DEFAULT_DIR_FD) - result = mknodat(dir_fd, path->narrow, mode, device); - else + if (dir_fd != DEFAULT_DIR_FD) { + if (HAVE_MKNODAT_RUNTIME) { + result = mknodat(dir_fd, path->narrow, mode, device); + + } else { + mknodat_unavailable = 1; + result = 0; + } + } else #endif result = mknod(path->narrow, mode, device); Py_END_ALLOW_THREADS } while (result != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); +#ifdef HAVE_MKNODAT + if (mknodat_unavailable) { + argument_unavailable_error(NULL, "dir_fd"); + return NULL; + } +#endif if (result != 0) return (!async_err) ? posix_error() : NULL; @@ -15265,6 +15301,14 @@ PROBE(probe_fdopendir, HAVE_FDOPENDIR_RUNTIME) PROBE(probe_mkdirat, HAVE_MKDIRAT_RUNTIME) #endif +#ifdef HAVE_MKFIFOAT +PROBE(probe_mkfifoat, HAVE_MKFIFOAT_RUNTIME) +#endif + +#ifdef HAVE_MKNODAT +PROBE(probe_mknodat, HAVE_MKNODAT_RUNTIME) +#endif + #ifdef HAVE_RENAMEAT PROBE(probe_renameat, HAVE_RENAMEAT_RUNTIME) #endif @@ -15394,11 +15438,11 @@ static const struct have_function { #endif #ifdef HAVE_MKFIFOAT - { "HAVE_MKFIFOAT", NULL }, + { "HAVE_MKFIFOAT", probe_mkfifoat }, #endif #ifdef HAVE_MKNODAT - { "HAVE_MKNODAT", NULL }, + { "HAVE_MKNODAT", probe_mknodat }, #endif #ifdef HAVE_OPENAT diff --git a/Objects/listobject.c b/Objects/listobject.c index 1e868b4..c12c02c 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -68,8 +68,14 @@ list_resize(PyListObject *self, Py_ssize_t newsize) if (newsize == 0) new_allocated = 0; - num_allocated_bytes = new_allocated * sizeof(PyObject *); - items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes); + if (new_allocated <= (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) { + num_allocated_bytes = new_allocated * sizeof(PyObject *); + items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes); + } + else { + // integer overflow + items = NULL; + } if (items == NULL) { PyErr_NoMemory(); return -1; diff --git a/Objects/longobject.c b/Objects/longobject.c index ec18ec3..2a9178a 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -38,8 +38,8 @@ PyObject *_PyLong_One = NULL; #define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS) #define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS) -#define _MAX_STR_DIGITS_ERROR_FMT_TO_INT "Exceeds the limit (%d) for integer string conversion: value has %zd digits" -#define _MAX_STR_DIGITS_ERROR_FMT_TO_STR "Exceeds the limit (%d) for integer string conversion" +#define _MAX_STR_DIGITS_ERROR_FMT_TO_INT "Exceeds the limit (%d) for integer string conversion: value has %zd digits; use sys.set_int_max_str_digits() to increase the limit" +#define _MAX_STR_DIGITS_ERROR_FMT_TO_STR "Exceeds the limit (%d) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit" static PyObject * get_small_int(sdigit ival) diff --git a/PC/_msi.c b/PC/_msi.c index 913d3b8..fd68e1d 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -292,7 +292,7 @@ msierror(int status) int code; char buf[2000]; char *res = buf; - DWORD size = sizeof(buf); + DWORD size = Py_ARRAY_LENGTH(buf); MSIHANDLE err = MsiGetLastErrorRecord(); if (err == 0) { @@ -386,7 +386,7 @@ record_getstring(msiobj* record, PyObject* args) unsigned int status; WCHAR buf[2000]; WCHAR *res = buf; - DWORD size = sizeof(buf); + DWORD size = Py_ARRAY_LENGTH(buf); PyObject* string; if (!PyArg_ParseTuple(args, "I:GetString", &field)) diff --git a/Python/initconfig.c b/Python/initconfig.c index a2c435f..7ab52fb 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -1426,10 +1426,10 @@ static PyStatus config_init_int_max_str_digits(PyConfig *config) { int maxdigits; - int valid = 0; const char *env = config_get_env(config, "PYTHONINTMAXSTRDIGITS"); if (env) { + int valid = 0; if (!_Py_str_to_int(env, &maxdigits)) { valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)); } @@ -1447,6 +1447,7 @@ config_init_int_max_str_digits(PyConfig *config) const wchar_t *xoption = config_get_xoption(config, L"int_max_str_digits"); if (xoption) { const wchar_t *sep = wcschr(xoption, L'='); + int valid = 0; if (sep) { if (!config_wstr_to_int(sep + 1, &maxdigits)) { valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)); diff --git a/README.rst b/README.rst index ae3e983..d78b6bc 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.9.14 +This is Python version 3.9.15 ============================= .. image:: https://travis-ci.org/python/cpython.svg?branch=3.9 diff --git a/Tools/scripts/get-remote-certificate.py b/Tools/scripts/get-remote-certificate.py index 3890128..68272fc 100755 --- a/Tools/scripts/get-remote-certificate.py +++ b/Tools/scripts/get-remote-certificate.py @@ -15,8 +15,8 @@ import tempfile def fetch_server_certificate (host, port): def subproc(cmd): - from subprocess import Popen, PIPE, STDOUT - proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True) + from subprocess import Popen, PIPE, STDOUT, DEVNULL + proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, stdin=DEVNULL) status = proc.wait() output = proc.stdout.read() return status, output @@ -33,8 +33,8 @@ def fetch_server_certificate (host, port): fp.write(m.group(1) + b"\n") try: tn2 = (outfile or tempfile.mktemp()) - status, output = subproc(r'openssl x509 -in "%s" -out "%s"' % - (tn, tn2)) + cmd = ['openssl', 'x509', '-in', tn, '-out', tn2] + status, output = subproc(cmd) if status != 0: raise RuntimeError('OpenSSL x509 failed with status %s and ' 'output: %r' % (status, output)) @@ -45,20 +45,9 @@ def fetch_server_certificate (host, port): finally: os.unlink(tn) - if sys.platform.startswith("win"): - tfile = tempfile.mktemp() - with open(tfile, "w") as fp: - fp.write("quit\n") - try: - status, output = subproc( - 'openssl s_client -connect "%s:%s" -showcerts < "%s"' % - (host, port, tfile)) - finally: - os.unlink(tfile) - else: - status, output = subproc( - 'openssl s_client -connect "%s:%s" -showcerts < /dev/null' % - (host, port)) + cmd = ['openssl', 's_client', '-connect', '%s:%s' % (host, port), '-showcerts'] + status, output = subproc(cmd) + if status != 0: raise RuntimeError('OpenSSL connect failed with status %s and ' 'output: %r' % (status, output))