Imported Upstream version 3.9.15 upstream/3.9.15
authorJinWang An <jinwang.an@samsung.com>
Wed, 18 Jan 2023 06:01:31 +0000 (15:01 +0900)
committerJinWang An <jinwang.an@samsung.com>
Wed, 18 Jan 2023 06:01:31 +0000 (15:01 +0900)
25 files changed:
Doc/library/importlib.rst
Doc/library/stdtypes.rst
Doc/library/subprocess.rst
Doc/library/urllib.parse.rst
Include/patchlevel.h
Lib/pydoc_data/topics.py
Lib/test/test_cmd_line.py
Lib/test/test_list.py
Lib/test/test_posix.py
Lib/test/test_ssl.py
Misc/NEWS
Modules/expat/COPYING
Modules/expat/expat.h
Modules/expat/internal.h
Modules/expat/siphash.h
Modules/expat/xmlparse.c
Modules/expat/xmltok.c
Modules/expat/xmltok_impl.c
Modules/posixmodule.c
Objects/listobject.c
Objects/longobject.c
PC/_msi.c
Python/initconfig.c
README.rst
Tools/scripts/get-remote-certificate.py

index c7fbcb2..9756481 100644 (file)
@@ -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.
index 6eef564..d6b270d 100644 (file)
@@ -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.
index 45eff7f..10e4063 100644 (file)
@@ -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
 
index b7430e9..f0f8605 100644 (file)
@@ -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           |
    +------------------+-------+-------------------------+------------------------+
index 3d48e97..a30fa4a 100644 (file)
 /*--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.
index bfb5db0..c06cf32 100644 (file)
@@ -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'
index e38fc69..9fb48c5 100644 (file)
@@ -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')
index 3c8d829..85bbf51 100644 (file)
@@ -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):
index 6ba1454..3c0ddeb 100644 (file)
@@ -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):
index 6faa2ee..e270f44 100644 (file)
@@ -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)
index 1ac3ba1..ee0452b 100644 (file)
--- 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?
 ==================================
 
index 3c0142e..ce9e593 100644 (file)
@@ -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
index c9214f6..2b47ce2 100644 (file)
@@ -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
 }
index 444eba0..e09f533 100644 (file)
@@ -28,7 +28,7 @@
    Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
    Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
    Copyright (c) 2003      Greg Stein <gstein@users.sourceforge.net>
-   Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
+   Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
    Copyright (c) 2018      Yury Gribov <tetra2005@gmail.com>
    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
    Licensed under the MIT license:
 
 #include <limits.h> // 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"
index e5406d7..303283a 100644 (file)
  * 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))))
 
index 05216d9..c0bece5 100644 (file)
@@ -1,4 +1,4 @@
-/* fcb1a62fefa945567301146eb98e3ad3413e823a41c4378e84e8b6b6f308d824 (2.4.7+)
+/* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065e42784e001db4f23de324 (2.4.9+)
                             __  __            _
                          ___\ \/ /_ __   __ _| |_
                         / _ \\  /| '_ \ / _` | __|
@@ -19,7 +19,7 @@
    Copyright (c) 2016      Gustavo Grieco <gustavo.grieco@imag.fr>
    Copyright (c) 2016      Pascal Cuoq <cuoq@trust-in-soft.com>
    Copyright (c) 2016      Ed Schouten <ed@nuxi.nl>
-   Copyright (c) 2017-2018 Rhodri James <rhodri@wildebeest.org.uk>
+   Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
    Copyright (c) 2017      Václav Slavík <vaclav@slavik.io>
    Copyright (c) 2017      Viktor Szakats <commit@vsz.me>
    Copyright (c) 2017      Chanho Park <chanho61.park@samsung.com>
@@ -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;
   }
 }
 
index c659983..2b7012a 100644 (file)
@@ -21,6 +21,7 @@
    Copyright (c) 2017      José Gutiérrez de la Concha <jose@zeroc.com>
    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
    Copyright (c) 2021      Dong-hee Na <donghee.na@python.org>
+   Copyright (c) 2022      Martin Ettl <ettl.martin78@googlemail.com>
    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)                                          \
index 4072b06..1971d74 100644 (file)
@@ -16,6 +16,7 @@
    Copyright (c) 2018      Anton Maklakov <antmak.pub@gmail.com>
    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
    Copyright (c) 2020      Boris Kolpackov <boris@codesynthesis.com>
+   Copyright (c) 2022      Martin Ettl <ettl.martin78@googlemail.com>
    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;                                                       \
 #    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)
 
index 1270af7..bf4e648 100644 (file)
@@ -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, *)
 
 #  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
index 1e868b4..c12c02c 100644 (file)
@@ -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;
index ec18ec3..2a9178a 100644 (file)
@@ -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)
index 913d3b8..fd68e1d 100644 (file)
--- 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))
index a2c435f..7ab52fb 100644 (file)
@@ -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));
index ae3e983..d78b6bc 100644 (file)
@@ -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
index 3890128..68272fc 100755 (executable)
@@ -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))