Imported Upstream version 2.7.18 upstream submit/tizen_base/20201208.051231 upstream/2.7.18
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 8 Dec 2020 01:59:51 +0000 (10:59 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 8 Dec 2020 01:59:51 +0000 (10:59 +0900)
51 files changed:
Doc/README.txt
Doc/c-api/iter.rst
Doc/c-api/list.rst
Doc/c-api/tuple.rst
Doc/conf.py
Doc/copyright.rst
Doc/library/threading.rst
Doc/license.rst
Doc/tools/susp-ignored.csv
Doc/tools/templates/indexsidebar.html
Doc/tools/templates/layout.html
Include/patchlevel.h
LICENSE
Lib/cookielib.py
Lib/encodings/uu_codec.py
Lib/httplib.py
Lib/test/test_ast.py
Lib/test/test_cookielib.py
Lib/test/test_httplib.py
Lib/test/test_posix.py
Lib/test/test_py_compile.py
Lib/test/test_urllib2.py
Lib/test/test_urllibnet.py
Lib/test/test_uu.py
Lib/urllib.py
Lib/uu.py
Mac/BuildScript/build-installer.py
Mac/BuildScript/resources/License.rtf
Mac/BuildScript/resources/ReadMe.rtf
Mac/BuildScript/resources/Welcome.rtf
Mac/PythonLauncher/Info.plist.in
Mac/Resources/app/Info.plist.in
Misc/ACKS
Misc/NEWS
Modules/expat/xmlparse.c
Modules/expat/xmltok.c
Modules/getpath.c
Modules/parsermodule.c
Modules/readline.c
Modules/signalmodule.c
Modules/zipimport.c
Objects/structseq.c
PC/dl_nt.c
Python/ast.c
Python/compile.c
Python/getargs.c
Python/getcopyright.c
Python/import.c
README
Tools/nuget/make_zip.py
Tools/ssl/multissltests.py

index a362ecca942731cb228bf54db3c67ae44335ae20..625efd47532b5e7ffea3970abbd57d9cec37e1d2 100644 (file)
@@ -104,6 +104,13 @@ Then, from the ``Doc`` directory, run ::
 where ``<builder>`` is one of html, text, latex, or htmlhelp (for explanations
 see the make targets above).
 
+Deprecation header
+==================
+
+Following the sunsetting of Python 2.7, a red banner displays at the
+top of each page redirecting to the corresponding page on
+``https://docs.python.org/3/``.
+
 
 Contributing
 ============
index fb2a71cf1a825a85205c09b2d04abfc57d9b7530..4f708829a89e40dcb35c841454493be9a47a636c 100644 (file)
@@ -36,7 +36,7 @@ something like this::
        /* propagate error */
    }
 
-   while (item = PyIter_Next(iterator)) {
+   while ((item = PyIter_Next(iterator))) {
        /* do something with item */
        ...
        /* release reference when done */
index a5e4a45492b69321b9a31969002429fceb333a7d..c28d6b0c9305563c4344470c7e14b7f13a9384e1 100644 (file)
@@ -96,8 +96,9 @@ List Objects
 
 .. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
 
-   Set the item at index *index* in list to *item*.  Return ``0`` on success
-   or ``-1`` on failure.
+   Set the item at index *index* in list to *item*.  Return ``0`` on success.
+   If *index* is out of bounds, return ``-1`` and set an :exc:`IndexError`
+   exception.
 
    .. note::
 
@@ -148,8 +149,7 @@ List Objects
 
    Return a list of the objects in *list* containing the objects *between* *low*
    and *high*.  Return *NULL* and set an exception if unsuccessful.  Analogous
-   to ``list[low:high]``.  Negative indices, as when slicing from Python, are not
-   supported.
+   to ``list[low:high]``.  Indexing from the end of the list is not supported.
 
    .. versionchanged:: 2.5
       This function used an :c:type:`int` for *low* and *high*. This might
@@ -161,8 +161,8 @@ List Objects
    Set the slice of *list* between *low* and *high* to the contents of
    *itemlist*.  Analogous to ``list[low:high] = itemlist``. The *itemlist* may
    be *NULL*, indicating the assignment of an empty list (slice deletion).
-   Return ``0`` on success, ``-1`` on failure.  Negative indices, as when
-   slicing from Python, are not supported.
+   Return ``0`` on success, ``-1`` on failure.  Indexing from the end of the
+   list is not supported.
 
    .. versionchanged:: 2.5
       This function used an :c:type:`int` for *low* and *high*. This might
index 16de45fb31c4316067f2ddbdbea0db88b1225bb7..fd85663a21cff92fd1ba3df911922d06b121222a 100644 (file)
@@ -82,7 +82,7 @@ Tuple Objects
 .. c:function:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos)
 
    Return the object at position *pos* in the tuple pointed to by *p*.  If *pos* is
-   out of bounds, return *NULL* and sets an :exc:`IndexError` exception.
+   out of bounds, return *NULL* and set an :exc:`IndexError` exception.
 
    .. versionchanged:: 2.5
       This function used an :c:type:`int` type for *pos*. This might require
@@ -100,8 +100,9 @@ Tuple Objects
 
 .. c:function:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high)
 
-   Take a slice of the tuple pointed to by *p* from *low* to *high* and return it
-   as a new tuple.
+   Return the slice of the tuple pointed to by *p* between *low* and *high*,
+   or *NULL* on failure.  This is the equivalent of the Python expression
+   ``p[low:high]``.  Indexing from the end of the list is not supported.
 
    .. versionchanged:: 2.5
       This function used an :c:type:`int` type for *low* and *high*. This might
@@ -111,11 +112,13 @@ Tuple Objects
 .. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)
 
    Insert a reference to object *o* at position *pos* of the tuple pointed to by
-   *p*. Return ``0`` on success.
+   *p*.  Return ``0`` on success.  If *pos* is out of bounds, return ``-1``
+   and set an :exc:`IndexError` exception.
 
    .. note::
 
-      This function "steals" a reference to *o*.
+      This function "steals" a reference to *o* and discards a reference to
+      an item already in the tuple at the affected position.
 
    .. versionchanged:: 2.5
       This function used an :c:type:`int` type for *pos*. This might require
@@ -129,7 +132,10 @@ Tuple Objects
 
    .. note::
 
-      This function "steals" a reference to *o*.
+      This macro "steals" a reference to *o*, and, unlike
+      :c:func:`PyTuple_SetItem`, does *not* discard a reference to any item that
+      is being replaced; any reference in the tuple at position *pos* will be
+      leaked.
 
    .. versionchanged:: 2.5
       This function used an :c:type:`int` type for *pos*. This might require
index 393018d08f51d2039fefc596fe7157fcb84b8089..29927c3bbbb820d8c1bcae82702b2eeeaec36961 100644 (file)
@@ -80,6 +80,10 @@ htmlhelp_basename = 'python' + release.replace('.', '')
 # Split the index
 html_split_index = True
 
+html_context = {
+    'outdated': True
+}
+
 
 # Options for LaTeX output
 # ------------------------
index 393a1f03751f823fdc370686ebaf3aa6fb848099..1b90d9f172c992e852a95fd128f92e06dd776cc4 100644 (file)
@@ -4,7 +4,7 @@ Copyright
 
 Python and this documentation is:
 
-Copyright © 2001-2019 Python Software Foundation. All rights reserved.
+Copyright © 2001-2020 Python Software Foundation. All rights reserved.
 
 Copyright © 2000 BeOpen.com. All rights reserved.
 
index e16f78c2047711685388fc5d7698dd7009902470..9228e1144237417de606d63a370d364b5a9eae96 100644 (file)
@@ -448,6 +448,10 @@ All methods are executed atomically.
 
    There is no return value.
 
+   .. method:: locked()
+      Return true if the lock is acquired.
+
+
 
 .. _rlock-objects:
 
index eded4a935ddfc122fd10c33fedcf3ebffa44f2c7..c347cf52f884c5f017cf468bb293f7ce6aec84fd 100644 (file)
@@ -22,7 +22,7 @@ Virginia where he released several versions of the software.
 In May 2000, Guido and the Python core development team moved to BeOpen.com to
 form the BeOpen PythonLabs team.  In October of the same year, the PythonLabs
 team moved to Digital Creations (now Zope Corporation; see
-http://www.zope.com/).  In 2001, the Python Software Foundation (PSF, see
+https://www.zope.org/).  In 2001, the Python Software Foundation (PSF, see
 https://www.python.org/psf/) was formed, a non-profit organization created
 specifically to own Python-related Intellectual Property.  Zope Corporation is a
 sponsoring member of the PSF.
@@ -87,7 +87,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release|
       analyze, test, perform and/or display publicly, prepare derivative works,
       distribute, and otherwise use Python |release| alone or in any derivative
       version, provided, however, that PSF's License Agreement and PSF's notice of
-      copyright, i.e., "Copyright © 2001-2019 Python Software Foundation; All Rights
+      copyright, i.e., "Copyright © 2001-2020 Python Software Foundation; All Rights
       Reserved" are retained in Python |release| alone or in any derivative version
       prepared by Licensee.
 
index f7d23e22baeacf24bf6ecc644a01a038489a3b14..0efbbabebfe4046b7c578960aafcb49b799ad3ab 100644 (file)
@@ -1,6 +1,7 @@
 c-api/arg,,:ref,"PyArg_ParseTuple(args, ""O|O:ref"", &object, &callback)"
 c-api/list,,:high,list[low:high]
 c-api/sequence,,:i2,o[i1:i2]
+c-api/tuple,,:high,p[low:high]
 c-api/unicode,,:end,str[start:end]
 distutils/setupscript,,::,
 extending/embedding,,:numargs,"if(!PyArg_ParseTuple(args, "":numargs""))"
index e5748f2ab0fc6e981ffb8ef988c32c3fb910648a..36f94ee03837e89cf1bd7b60b2bde8fc02ff9075 100644 (file)
@@ -7,7 +7,7 @@
   <li><a href="https://docs.python.org/3.7/">{% trans %}Python 3.7 (stable){% endtrans %}</a></li>
   <li><a href="https://docs.python.org/3.6/">{% trans %}Python 3.6 (security-fixes){% endtrans %}</a></li>
   <li><a href="https://docs.python.org/3.5/">{% trans %}Python 3.5 (security-fixes){% endtrans %}</a></li>
-  <li><a href="https://docs.python.org/2.7/">{% trans %}Python 2.7 (stable){% endtrans %}</a></li>
+  <li><a href="https://docs.python.org/2.7/">{% trans %}Python 2.7 (EOL){% endtrans %}</a></li>
   <li><a href="https://www.python.org/doc/versions/">{% trans %}All versions{% endtrans %}</a></li>
 </ul>
 
index 8d6d3e5bd1193b1eed3d4ba79341e655c75df735..34a87ae42d867461350205c102908efb69f78a53 100644 (file)
@@ -1,4 +1,14 @@
 {% extends "!layout.html" %}
+{% block header %}
+{%- if outdated %}
+<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
+    {% trans %}This document is for an old version of Python that is {% endtrans %}<a href="https://devguide.python.org/devcycle/#end-of-life-branches">{% trans %}no longer supported{% endtrans %}</a>.
+    {% trans %}You should upgrade and read the {% endtrans %}
+    <a href="https://docs.python.org/{{ language + '/' if language and language != 'en' else '' }}3/{{ pagename }}{{ file_suffix }}">{% trans %} Python documentation for the current stable release{% endtrans %}</a>.
+</div>
+{%- endif %}
+{% endblock %}
+
 {% block rootrellink %}
         <li><img src="{{ pathto('_static/py.png', 1) }}" alt=""
                  style="vertical-align: middle; margin-top: -1px"/></li>
index 4bfcdafcd2590143d4a8f127d260121cb70a2ffb..0ce6313fa94131ee9ba8cf96569dc40904bd0f5a 100644 (file)
 /*--start constants--*/
 #define PY_MAJOR_VERSION       2
 #define PY_MINOR_VERSION       7
-#define PY_MICRO_VERSION       17
+#define PY_MICRO_VERSION       18
 #define PY_RELEASE_LEVEL       PY_RELEASE_LEVEL_FINAL
 #define PY_RELEASE_SERIAL      0
 
 /* Version as a string */
-#define PY_VERSION             "2.7.17"
+#define PY_VERSION             "2.7.18"
 /*--end constants--*/
 
 /* Subversion Revision number of this file (not of the repository). Empty
diff --git a/LICENSE b/LICENSE
index 9dc010d80348fcce0c7ec1a57da2123e79412566..66a3ac80d729a3a5bdfd22002d34be59a6daf222 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -73,7 +73,7 @@ analyze, test, perform and/or display publicly, prepare derivative works,
 distribute, and otherwise use Python alone or in any derivative version,
 provided, however, that PSF's License Agreement and PSF's notice of copyright,
 i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation;
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation;
 All Rights Reserved" are retained in Python alone or in any derivative version
 prepared by Licensee.
 
index 1d56d3fe4c0a2e514ba023079006115efcfd1c83..e76d09d8a500d4baaa3971a9dac25b37edf6a26a 100644 (file)
@@ -205,10 +205,14 @@ LOOSE_HTTP_DATE_RE = re.compile(
        (?::(\d\d))?    # optional seconds
     )?                 # optional clock
        \s*
-    ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone
+    (?:
+       ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone
+       \s*
+    )?
+    (?:
+       \(\w+\)         # ASCII representation of timezone in parens.
        \s*
-    (?:\(\w+\))?       # ASCII representation of timezone in parens.
-       \s*$""", re.X)
+    )?$""", re.X)
 def http2time(text):
     """Returns time in seconds since epoch of time represented by a string.
 
@@ -266,7 +270,7 @@ def http2time(text):
     return _str2time(day, mon, yr, hr, min, sec, tz)
 
 ISO_DATE_RE = re.compile(
-    """^
+    r"""^
     (\d{4})              # year
        [-\/]?
     (\d\d?)              # numerical month
@@ -278,9 +282,11 @@ ISO_DATE_RE = re.compile(
       (?::?(\d\d(?:\.\d*)?))?  # optional seconds (and fractional)
    )?                    # optional clock
       \s*
-   ([-+]?\d\d?:?(:?\d\d)?
-    |Z|z)?               # timezone  (Z is "zero meridian", i.e. GMT)
-      \s*$""", re.X)
+   (?:
+      ([-+]?\d\d?:?(:?\d\d)?
+       |Z|z)             # timezone  (Z is "zero meridian", i.e. GMT)
+      \s*
+   )?$""", re.X)
 def iso2time(text):
     """
     As for http2time, but parses the ISO 8601 formats:
index 5cb0d2b13e07127532dd47d755f0a1d187de917a..fcd5aa45a9708c6872005cb9f63c63c44dbf881e 100644 (file)
@@ -31,6 +31,10 @@ def uu_encode(input,errors='strict',filename='<data>',mode=0666):
     read = infile.read
     write = outfile.write
 
+    # Remove newline chars from filename
+    filename = filename.replace('\n','\\n')
+    filename = filename.replace('\r','\\r')
+
     # Encode
     write('begin %o %s\n' % (mode & 0777, filename))
     chunk = read(45)
index 79532b91149b17e53a54153552f70e7f3aeceace..fcc4152aaf268dcb001af9af69856c5bd4de62e9 100644 (file)
@@ -745,6 +745,8 @@ class HTTPConnection:
 
         (self.host, self.port) = self._get_hostport(host, port)
 
+        self._validate_host(self.host)
+
         # This is stored as an instance variable to allow unittests
         # to replace with a suitable mock
         self._create_connection = socket.create_connection
@@ -1029,6 +1031,17 @@ class HTTPConnection:
             ).format(matched=match.group(), url=url)
             raise InvalidURL(msg)
 
+    def _validate_host(self, host):
+        """Validate a host so it doesn't contain control characters."""
+        # Prevent CVE-2019-18348.
+        match = _contains_disallowed_url_pchar_re.search(host)
+        if match:
+            msg = (
+                "URL can't contain control characters. {host!r} "
+                "(found at least {matched!r})"
+            ).format(matched=match.group(), host=host)
+            raise InvalidURL(msg)
+
     def putheader(self, header, *values):
         """Send a request header line to the server.
 
index 0a1ca4168a590856a801173c9cde9bc81d11c2ed..3cfe6188ac13422a74335aac2c6eb9697f7a5ff3 100644 (file)
@@ -103,6 +103,12 @@ exec_tests = [
     "{r for l in x if g}",
     # setcomp with naked tuple
     "{r for l,m in x}",
+    # Decorated FunctionDef
+    "@deco1\n@deco2()\n@deco3(1)\ndef f(): pass",
+    # Decorated ClassDef
+    "@deco1\n@deco2()\n@deco3(1)\nclass C: pass",
+    # Decorator with generator argument
+    "@deco(a for a in b)\ndef f(): pass",
 ]
 
 # These are compiled through "single"
@@ -546,6 +552,9 @@ exec_results = [
 ('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]),
 ('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]),
 ('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], [], None, None), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Num', (3, 7), 1)], [], None, None)])]),
+('Module', [('ClassDef', (1, 0), 'C', [], [('Pass', (4, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 1), ('Name', (2, 1), 'deco2', ('Load',)), [], [], None, None), ('Call', (3, 1), ('Name', (3, 1), 'deco3', ('Load',)), [('Num', (3, 7), 1)], [], None, None)])]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 6), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [])])], [], None, None)])]),
 ]
 single_results = [
 ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]),
index a93bbfb640b6a953c734b447be10bd87d8ba2c3b..f3711b966e572273bef5dc2ff767a68524063fe6 100644 (file)
@@ -6,7 +6,7 @@ import os
 import re
 import time
 
-from cookielib import http2time, time2isoz, time2netscape
+from cookielib import http2time, time2isoz, iso2time, time2netscape
 from unittest import TestCase
 
 from test import test_support
@@ -117,6 +117,19 @@ class DateTimeTests(TestCase):
                          "http2time(test) %s" % (test, http2time(test))
                          )
 
+    def test_http2time_redos_regression_actually_completes(self):
+        # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS).
+        # If we regress to cubic complexity, this test will take a very long time to succeed.
+        # If fixed, it should complete within a fraction of a second.
+        http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5))
+        http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5))
+
+    def test_iso2time_performance_regression(self):
+        # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed.
+        # If fixed, it should complete within a fraction of a second.
+        iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6))
+        iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6))
+
 
 class HeaderTests(TestCase):
 
index 5462fdd503c831177e70b0561f95cd306b755654..d8a57f73530da6a93d2918b2e4bf61e60854e147 100644 (file)
@@ -702,7 +702,7 @@ class BasicTest(TestCase):
         with self.assertRaisesRegexp(socket.error, "Invalid response"):
             conn._tunnel()
 
-    def test_putrequest_override_validation(self):
+    def test_putrequest_override_domain_validation(self):
         """
         It should be possible to override the default validation
         behavior in putrequest (bpo-38216).
@@ -715,6 +715,17 @@ class BasicTest(TestCase):
         conn.sock = FakeSocket('')
         conn.putrequest('GET', '/\x00')
 
+    def test_putrequest_override_host_validation(self):
+        class UnsafeHTTPConnection(httplib.HTTPConnection):
+            def _validate_host(self, url):
+                pass
+
+        conn = UnsafeHTTPConnection('example.com\r\n')
+        conn.sock = FakeSocket('')
+        # set skip_host so a ValueError is not raised upon adding the
+        # invalid URL as the value of the "Host:" header
+        conn.putrequest('GET', '/', skip_host=1)
+
 
 class OfflineTest(TestCase):
     def test_responses(self):
index c4283b604b96ab4fba05291413a956dea36de17a..ae636e591a9ef7338eeafc34bdcfd1009c029892 100644 (file)
@@ -556,7 +556,11 @@ class PosixTester(unittest.TestCase):
                     )
                     if quirky_platform:
                         expected_errno = errno.ERANGE
-                    self.assertEqual(e.errno, expected_errno)
+                    if 'darwin' in sys.platform:
+                        # macOS 10.15 may return errno.ENOENT instead
+                        self.assertIn(e.errno, (errno.ENOENT, errno.ENAMETOOLONG))
+                    else:
+                        self.assertEqual(e.errno, expected_errno)
                 finally:
                     os.chdir('..')
                     os.rmdir(dirname)
index 5ec523abe25889753fc6a9057f8afc3d317f424f..95863088b48cb4e35340fe4cfcea274c8543a1be 100644 (file)
@@ -10,7 +10,7 @@ from test import test_support as support
 class PyCompileTests(unittest.TestCase):
 
     def setUp(self):
-        self.directory = tempfile.mkdtemp()
+        self.directory = tempfile.mkdtemp(dir=os.getcwd())
         self.source_path = os.path.join(self.directory, '_test.py')
         self.pyc_path = self.source_path + 'c'
         self.cwd_drive = os.path.splitdrive(os.getcwd())[0]
index 9531818e16b25d945c059716235ea878d87490fe..20a0f581436d64030d088b90fb3974162770ca93 100644 (file)
@@ -1321,7 +1321,7 @@ class MiscTests(unittest.TestCase, FakeHTTPMixin):
         )
 
     @unittest.skipUnless(ssl, "ssl module required")
-    def test_url_with_control_char_rejected(self):
+    def test_url_path_with_control_char_rejected(self):
         for char_no in range(0, 0x21) + range(0x7f, 0x100):
             char = chr(char_no)
             schemeless_url = "//localhost:7777/test%s/" % char
@@ -1345,7 +1345,7 @@ class MiscTests(unittest.TestCase, FakeHTTPMixin):
                 self.unfakehttp()
 
     @unittest.skipUnless(ssl, "ssl module required")
-    def test_url_with_newline_header_injection_rejected(self):
+    def test_url_path_with_newline_header_injection_rejected(self):
         self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.")
         host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123"
         schemeless_url = "//" + host + ":8080/test/?test=a"
@@ -1357,14 +1357,32 @@ class MiscTests(unittest.TestCase, FakeHTTPMixin):
             # calls urllib.parse.quote() on the URL which makes all of the
             # above attempts at injection within the url _path_ safe.
             InvalidURL = httplib.InvalidURL
-            with self.assertRaisesRegexp(
-                InvalidURL, r"contain control.*\\r.*(found at least . .)"):
-                urllib2.urlopen("http:" + schemeless_url)
-            with self.assertRaisesRegexp(InvalidURL, r"contain control.*\\n"):
-                urllib2.urlopen("https:" + schemeless_url)
+            with self.assertRaisesRegexp(InvalidURL,
+                    r"contain control.*\\r.*(found at least . .)"):
+                urllib2.urlopen("http:{}".format(schemeless_url))
+            with self.assertRaisesRegexp(InvalidURL,
+                    r"contain control.*\\n"):
+                urllib2.urlopen("https:{}".format(schemeless_url))
         finally:
             self.unfakehttp()
 
+    @unittest.skipUnless(ssl, "ssl module required")
+    def test_url_host_with_control_char_rejected(self):
+        for char_no in list(range(0, 0x21)) + [0x7f]:
+            char = chr(char_no)
+            schemeless_url = "//localhost{}/test/".format(char)
+            self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.")
+            try:
+                escaped_char_repr = repr(char).replace('\\', r'\\')
+                InvalidURL = httplib.InvalidURL
+                with self.assertRaisesRegexp(InvalidURL,
+                    "contain control.*{}".format(escaped_char_repr)):
+                        urllib2.urlopen("http:{}".format(schemeless_url))
+                with self.assertRaisesRegexp(InvalidURL,
+                    "contain control.*{}".format(escaped_char_repr)):
+                        urllib2.urlopen("https:{}".format(schemeless_url))
+            finally:
+                self.unfakehttp()
 
 
 class RequestTests(unittest.TestCase):
index 3f2d8dcd43b0c714e971214d934bcc1e717a2df3..ef33e3a0ea6173310bd19a309e14731dfee058c4 100644 (file)
@@ -1,5 +1,6 @@
 import unittest
 from test import test_support
+from test.test_urllib2net import skip_ftp_test_on_travis
 
 import socket
 import urllib
@@ -213,6 +214,41 @@ class urlopen_HttpsTests(unittest.TestCase):
         self.assertIn("Python", response.read())
 
 
+class urlopen_FTPTest(unittest.TestCase):
+    FTP_TEST_FILE = 'ftp://www.pythontest.net/README'
+    NUM_FTP_RETRIEVES = 3
+
+    @skip_ftp_test_on_travis
+    def test_multiple_ftp_retrieves(self):
+
+        with test_support.transient_internet(self.FTP_TEST_FILE):
+            try:
+                for file_num in range(self.NUM_FTP_RETRIEVES):
+                    with test_support.temp_dir() as td:
+                        urllib.FancyURLopener().retrieve(self.FTP_TEST_FILE,
+                                                         os.path.join(td, str(file_num)))
+            except IOError as e:
+                self.fail("Failed FTP retrieve while accessing ftp url "
+                          "multiple times.\n Error message was : %s" % e)
+
+    @skip_ftp_test_on_travis
+    def test_multiple_ftp_urlopen_same_host(self):
+        with test_support.transient_internet(self.FTP_TEST_FILE):
+            ftp_fds_to_close = []
+            try:
+                for _ in range(self.NUM_FTP_RETRIEVES):
+                    fd = urllib.urlopen(self.FTP_TEST_FILE)
+                    # test ftp open without closing fd as a supported scenario.
+                    ftp_fds_to_close.append(fd)
+            except IOError as e:
+                self.fail("Failed FTP binary file open. "
+                          "Error message was: %s" % e)
+            finally:
+                # close the open fds
+                for fd in ftp_fds_to_close:
+                    fd.close()
+
+
 def test_main():
     test_support.requires('network')
     with test_support.check_py3k_warnings(
@@ -220,7 +256,8 @@ def test_main():
         test_support.run_unittest(URLTimeoutTest,
                                   urlopenNetworkTests,
                                   urlretrieveNetworkTests,
-                                  urlopen_HttpsTests)
+                                  urlopen_HttpsTests,
+                                  urlopen_FTPTest)
 
 if __name__ == "__main__":
     test_main()
index df41cbc12d40d086ae718a856ee0de360c57040a..f016bb2c67ea2f2e4e4f971b14b07d86400380f9 100644 (file)
@@ -9,6 +9,7 @@ from test import test_support as support
 import cStringIO
 import sys
 import uu
+import io
 
 plaintext = "The smooth-scaled python crept over the sleeping dog\n"
 
@@ -82,6 +83,15 @@ class UUTest(unittest.TestCase):
         decoded = codecs.decode(encodedtext, "uu_codec")
         self.assertEqual(decoded, plaintext)
 
+    def test_newlines_escaped(self):
+        # Test newlines are escaped with uu.encode
+        inp = io.BytesIO(plaintext)
+        out = io.BytesIO()
+        filename = "test.txt\n\roverflow.txt"
+        safefilename = b"test.txt\\n\\roverflow.txt"
+        uu.encode(inp, out, filename)
+        self.assertIn(safefilename, out.getvalue())
+
 class UUStdIOTest(unittest.TestCase):
 
     def setUp(self):
index 156879dd0a140b638f9545eeb098b3bd71d266a8..87bcd94db5f058fa0412f40036cd8938171ffe91 100644 (file)
@@ -934,7 +934,13 @@ class ftpwrapper:
         return (ftpobj, retrlen)
 
     def endtransfer(self):
+        if not self.busy:
+            return
         self.busy = 0
+        try:
+            self.ftp.voidresp()
+        except ftperrors():
+            pass
 
     def close(self):
         self.keepalive = False
index f8fa4c4757661b1af3b32166ed3ff17ccde2b3ad..8eaea5960dffe14461ccb4c07ecb2f8f6c255a2a 100755 (executable)
--- a/Lib/uu.py
+++ b/Lib/uu.py
@@ -73,6 +73,13 @@ def encode(in_file, out_file, name=None, mode=None):
             name = '-'
         if mode is None:
             mode = 0666
+
+        #
+        # Remove newline chars from name
+        #
+        name = name.replace('\n','\\n')
+        name = name.replace('\r','\\r')
+
         #
         # Write the data
         #
index 3edd947f0df14f967ad1f8ea31ccbfe2cfe822ac..4bb942a733b86fa63b62487fe39e6b6376b8011b 100755 (executable)
@@ -25,11 +25,11 @@ Sphinx, build-installer.py should also be converted to use python3!
 For 10.6 or greater deployment targets, build-installer builds and links
 with its own copy of Tcl/Tk 8.6 and the rest of this paragraph does not
 apply.  Otherwise, build-installer requires an installed third-party version
-of Tcl/Tk 8.4 (for OS X 10.4 and 10.5 deployment targets) or Tcl/TK 8.5
-(for 10.6 or later) installed in /Library/Frameworks.  When installed,
-the Python built by this script will attempt to dynamically link first to
-Tcl and Tk frameworks in /Library/Frameworks if available otherwise fall
-back to the ones in /System/Library/Framework.  For the build, we recommend
+of Tcl/Tk 8.4 (for OS X 10.4 and 10.5 deployment targets) installed in
+/Library/Frameworks.  For 10.4 or 10.5, the Python built by this script
+when installed will attempt to dynamically link first to Tcl and Tk frameworks
+in /Library/Frameworks if available otherwise fall back to the ones in
+/System/Library/Framework.  For 10.4 or 10.5, we recommend
 installing the most recent ActiveTcl 8.5 or 8.4 version, depending
 on the deployment target.  The actual version linked to depends on the
 path of /Library/Frameworks/{Tcl,Tk}.framework/Versions/Current.
@@ -213,9 +213,9 @@ def library_recipes():
 
     result.extend([
           dict(
-              name="OpenSSL 1.0.2t",
-              url="https://www.openssl.org/source/openssl-1.0.2t.tar.gz",
-              checksum='ef66581b80f06eae42f5268bc0b50c6d',
+              name="OpenSSL 1.0.2u",
+              url="https://www.openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz",
+              checksum='cdc2638f789ecc2db2c91488265686c1',
               buildrecipe=build_universal_openssl,
               configure=None,
               install=None,
@@ -311,9 +311,9 @@ def library_recipes():
                   ),
           ),
           dict(
-              name="SQLite 3.28.0",
-              url="https://www.sqlite.org/2019/sqlite-autoconf-3280000.tar.gz",
-              checksum='3c68eb400f8354605736cd55400e1572',
+              name="SQLite 3.31.1",
+              url="https://sqlite.org/2020/sqlite-autoconf-3310100.tar.gz",
+              checksum='2d0a553534c521504e3ac3ad3b90f125',
               extra_cflags=('-Os '
                             '-DSQLITE_ENABLE_FTS5 '
                             '-DSQLITE_ENABLE_FTS4 '
index 86e54f6662a201e00d6851c508b994c57b97e0c7..25d53386da01a5671921a50604b7fbd464d73866 100644 (file)
@@ -1,5 +1,5 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
-{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fmodern\fcharset0 CourierNewPS-BoldMT;
+{\rtf1\ansi\ansicpg1252\cocoartf2511
+\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fmodern\fcharset0 CourierNewPS-BoldMT;
 \f3\fmodern\fcharset0 CourierNewPSMT;}
 {\colortbl;\red255\green255\blue255;}
 {\*\expandedcolortbl;;}
@@ -16,7 +16,7 @@ Python was created in the early 1990s by Guido van Rossum at Stichting Mathemati
 \
 In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software.\
 \
-In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.com). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF.\
+In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.org). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF.\
 \
 All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases.\
 \
@@ -55,7 +55,7 @@ Thanks to the many outside volunteers who have worked under Guido's direction to
 \f1\b0 \
 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation.\
 \
-2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\
+2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright \'a9 2001-2020 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\
 \
 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python.\
 \
index a4c351a7ff78a595a3a5964208db71fe9596c492..d49bab5c3f1aeb8c33fdafa65d3e75e34483a796 100644 (file)
@@ -1,5 +1,5 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
-{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique;
+{\rtf1\ansi\ansicpg1252\cocoartf2512
+\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique;
 \f3\fmodern\fcharset0 CourierNewPSMT;}
 {\colortbl;\red255\green255\blue255;}
 {\*\expandedcolortbl;;}
@@ -9,8 +9,8 @@
 \f0\fs24 \cf0 This package will install Python $FULL_VERSION for macOS $MACOSX_DEPLOYMENT_TARGET for the following architecture(s): $ARCHITECTURES.\
 \
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
-\cf0 NOTE: 
-\f1\b \ul Python 2 reaches end-of-life in 2020 and will no longer be supported or updated thereafter\ulnone .
+
+\f1\b \cf0 NOTE: \ul Python 2.7,x has now reached end-of-life.  This release, Python 2.7.18, is the FINAL RELEASE of Python 2.7.x.  It will no longer be supported or updated\ulnone .
 \f0\b0   You should 
 \f1\b upgrade to Python 3 
 \f0\b0 as soon as you can.  {\field{\*\fldinst{HYPERLINK "https://www.python.org/doc/sunset-python-2/"}}{\fldrslt Read more here}}.\
@@ -44,18 +44,14 @@ The bundled
 \f0\b0 \ulnone \
 \
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
-\cf0 In almost all cases, you should use the 
+\cf0 Use the 
 \f1\b macOS 64-bit installer for OS X 10.9 and later
-\f0\b0 .\
-\
-The legacy 
+\f0\b0 . As of 2.7.18, the deprecated 
 \f1\b macOS 64-bit/32-bit installer for Mac OS X 10.6 and later 
-\f0\b0 variant  is now deprecated.  macOS 10.6 Snow Leopard was released in 2009 and has not been supported by Apple for many years including lack of security updates.  It is becoming increasingly difficult to ensure new Python features and bug fixes are compatible with such old systems.  Note that, due to recent Apple installer packaging changes, the 10.6+ installer pkg we provide can no longer be opened by the Apple system installer application on 10.6;  10.7 and 10.8 are not affected.  We believe that there is now very little usage of this installer variant and so we would like to focus our resources on supporting newer systems.  We do not plan to intentionally break Python support on 10.6 through 10.8 and we will consider bug fixes for problems found when building from source on those systems through the support window of Python 2.7.  
-\f1\b macOS 10.15 Catalina
-\f0\b0  removes support for running 32-bit architecture programs; we do not recommend trying to use the 10.6+ variant on it and it may not install on 10.15 systems without intervention. \
+\f0\b0 variant  is no longer provided.   \
 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
 
-\f1\b \cf0 \ul \
+\f1\b \cf0 \ul \ulc0 \
 Using IDLE or other Tk applications 
 \f0\b0 \ulnone \
 \
index 2786a749854880ca523d4e693fa49e07c5286020..fa398acfc9e3b9fd16a79868d1a461fc960c805c 100644 (file)
@@ -1,5 +1,5 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
-\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT;
+{\rtf1\ansi\ansicpg1252\cocoartf2512
+\cocoascreenfonts1\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT;
 }
 {\colortbl;\red255\green255\blue255;}
 {\*\expandedcolortbl;;}
@@ -26,7 +26,7 @@ At the end of this install, click on
 \f0  to install a set of current SSL root certificates.\
 \
 
-\f1\b NOTE: \ul Python 2 reaches end-of-life in 2020 and will no longer be supported or updated thereafter\ulnone .
+\f1\b NOTE: \ul Python 2.7,x has now reached end-of-life.  This release, Python 2.7.18, is the FINAL RELEASE of Python 2.7.x.  It will no longer be supported or updated\ulnone .
 \f0\b0   You should 
 \f1\b upgrade to Python 3 
 \f0\b0 as soon as you can.  {\field{\*\fldinst{HYPERLINK "https://www.python.org/doc/sunset-python-2/"}}{\fldrslt Read more here}}.\
index 77dbb0fe84e46ed81a9f34eda045d3b6bc1bf37e..dba64546b8232370ddc8d339d3287c78635ff54f 100644 (file)
@@ -40,7 +40,7 @@
        <key>CFBundleExecutable</key>
        <string>PythonLauncher</string>
        <key>CFBundleGetInfoString</key>
-       <string>%VERSION%, © 2001-2019 Python Software Foundation</string>
+       <string>%VERSION%, © 2001-2020 Python Software Foundation</string>
        <key>CFBundleIconFile</key>
        <string>PythonLauncher.icns</string>
        <key>CFBundleIdentifier</key>
index b7581984dd6764e5a86eb324d652ed185244de5c..66b5e764c54b0b21e3c7ffe3953cb35dca83c42e 100644 (file)
@@ -37,7 +37,7 @@
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleLongVersionString</key>
-       <string>%version%, (c) 2001-2019 Python Software Foundation.</string>
+       <string>%version%, (c) 2001-2020 Python Software Foundation.</string>
        <key>CFBundleName</key>
        <string>Python</string>
        <key>CFBundlePackageType</key>
index eba64ae02586cea678f3211a3eb318913b1ca339..fd28ce7fe23ec007cb13950ddc0cf1642a66afdb 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -210,6 +210,7 @@ Ralph Butler
 Zach Byrne
 Nicolas Cadou
 Jp Calderone
+Ben Caller
 Arnaud Calmettes
 Daniel Calvelo
 Tony Campbell
index f265105a13eeb439aa3b7e165b38a6f76f018b80..63b3fa88c01e5a172d1a100b48e7400cfa3200e8 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,73 @@
 Python News
 +++++++++++
 
+What's New in Python 2.7.18 final?
+==================================
+
+*Release date: 2020-04-19*
+
+There were no new changes in version 2.7.18.
+
+
+
+What's New in Python 2.7.18 release candidate 1?
+================================================
+
+*Release date: 2020-04-04*
+
+Security
+--------
+
+- bpo-38945: Newline characters have been escaped when performing uu
+  encoding to prevent them from overflowing into to content section of the
+  encoded file. This prevents malicious or accidental modification of data
+  during the decoding process.
+
+- bpo-38804: Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by
+  Ben Caller.
+
+Core and Builtins
+-----------------
+
+- bpo-38535: Fixed line numbers and column offsets for AST nodes for calls
+  without arguments in decorators.
+
+Library
+-------
+
+- bpo-38576: Disallow control characters in hostnames in http.client,
+  addressing CVE-2019-18348. Such potentially malicious header injection
+  URLs now cause a InvalidURL to be raised.
+
+- bpo-27973: Fix urllib.urlretrieve failing on subsequent ftp transfers from
+  the same host.
+
+Build
+-----
+
+- bpo-38730: Fix problems identified by GCC's ``-Wstringop-truncation``
+  warning.
+
+Windows
+-------
+
+- bpo-37025: ``AddRefActCtx()`` was needlessly being checked for failure in
+  ``PC/dl_nt.c``.
+
+macOS
+-----
+
+- bpo-38295: Prevent failure of test_relative_path in test_py_compile on
+  macOS Catalina.
+
+C API
+-----
+
+- bpo-38540: Fixed possible leak in :c:func:`PyArg_Parse` and similar
+  functions for format units ``"es#"`` and ``"et#"`` when the macro
+  :c:macro:`PY_SSIZE_T_CLEAN` is not defined.
+
+
 What's New in Python 2.7.17 final?
 ==================================
 
index e740f0e19c7d4a1b7a36b46491a2157da334f408..09ccacb5aae596635b5233819357c8c066741b03 100644 (file)
 #  define _CRT_RAND_S
 #endif
 
+#ifdef _WIN32
+#  include "winconfig.h"
+#elif defined(HAVE_EXPAT_CONFIG_H)
+#  include <expat_config.h>
+#endif /* ndef _WIN32 */
+
 #include <stddef.h>
 #include <string.h> /* memset(), memcpy() */
 #include <assert.h>
 
 #define XML_BUILDING_EXPAT 1
 
-#ifdef _WIN32
-#  include "winconfig.h"
-#elif defined(HAVE_EXPAT_CONFIG_H)
-#  include <expat_config.h>
-#endif /* ndef _WIN32 */
-
 #include "ascii.h"
 #include "expat.h"
 #include "siphash.h"
index 11e9d1ccdad423e1845dc8d0e23da877c784a6fa..54cfedb85c28c441d7d6809635faf201d427f413 100644 (file)
    USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
+#ifdef _WIN32
+#  include "winconfig.h"
+#else
+#  ifdef HAVE_EXPAT_CONFIG_H
+#    include <expat_config.h>
+#  endif
+#endif /* ndef _WIN32 */
+
 #include <stddef.h>
 #include <string.h> /* memcpy */
 
 #  include <stdbool.h>
 #endif
 
-#ifdef _WIN32
-#  include "winconfig.h"
-#else
-#  ifdef HAVE_EXPAT_CONFIG_H
-#    include <expat_config.h>
-#  endif
-#endif /* ndef _WIN32 */
-
 #include "expat_external.h"
 #include "internal.h"
 #include "xmltok.h"
index c42ce31178593fa3308cec74aa364320e0d566e9..092ccc712f9d08446c3cbe74b543310368f66a93 100644 (file)
@@ -486,7 +486,7 @@ calculate_path(void)
             if (tmpbuffer[0] == SEP)
                 /* tmpbuffer should never be longer than MAXPATHLEN,
                    but extra check does not hurt */
-                strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
+                strncpy(argv0_path, tmpbuffer, MAXPATHLEN + 1);
             else {
                 /* Interpret relative to progpath */
                 reduce(argv0_path);
index fcc618d5d90a6f25d12be6260cc99e22c8155984..759f0ff4f6f85063d7e5957d1849d80ade43ce32 100644 (file)
@@ -1055,14 +1055,15 @@ validate_numnodes(node *n, int num, const char *const name)
 static int
 validate_terminal(node *terminal, int type, char *string)
 {
-    int res = (validate_ntype(terminal, type)
-               && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
-
-    if (!res && !PyErr_Occurred()) {
+    if (!validate_ntype(terminal, type)) {
+        return 0;
+    }
+    if (string != NULL && strcmp(string, STR(terminal)) != 0) {
         PyErr_Format(parser_error,
                      "Illegal terminal: expected \"%s\"", string);
+        return 0;
     }
-    return (res);
+    return 1;
 }
 
 
index 02621358238ea76343a8ec84eb0fd08370f81922..64bb19ae3fa37fdc3b2b0660b1567fcd79dc3ad6 100644 (file)
@@ -1180,7 +1180,7 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
     q = p;
     p = PyMem_Malloc(n+2);
     if (p != NULL) {
-        strncpy(p, q, n);
+        memcpy(p, q, n);
         p[n] = '\n';
         p[n+1] = '\0';
     }
index 8628f7a8005ff7d305de58014fb914fce714af51..88b471193214d59160d9afc7940f86409c30b61c 100644 (file)
@@ -173,8 +173,10 @@ trip_signal(int sig_num)
        cleared in PyErr_CheckSignals() before .tripped. */
     is_tripped = 1;
     Py_AddPendingCall(checksignals_witharg, NULL);
-    if (wakeup_fd != -1)
-        write(wakeup_fd, "\0", 1);
+    if (wakeup_fd != -1) {
+        int rc = write(wakeup_fd, "\0", 1);
+        (void)rc;
+    }
 }
 
 static void
index 1691773ec10f2dd274eca9e27094725c4ca0d734..8ec2475571ca6190ddcaac97473990d953e45d27 100644 (file)
@@ -714,8 +714,8 @@ read_directory(const char *archive)
     unsigned int count, i;
     unsigned char buffer[46];
     size_t length;
-    char path[MAXPATHLEN + 5];
-    char name[MAXPATHLEN + 5];
+    char name[MAXPATHLEN + 1];
+    char path[2*MAXPATHLEN + 2]; /* archive + SEP + name + '\0' */
     const char *errmsg = NULL;
 
     if (strlen(archive) > MAXPATHLEN) {
@@ -838,7 +838,7 @@ read_directory(const char *archive)
             }
         }
 
-        strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
+        memcpy(path + length + 1, name, name_size + 1);
 
         t = Py_BuildValue("sHIIkHHI", path, compress, data_size,
                           file_size, file_offset, time, date, crc);
index aee95286f78bcf88173ab756d6b81fe3221be7ae..82df926f2860425597dd1d1add83c24443e48511 100644 (file)
@@ -252,9 +252,11 @@ structseq_repr(PyStructSequence *obj)
     }
 
     /* "typename(", limited to  TYPE_MAXSIZE */
-    len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE :
-                            strlen(typ->tp_name);
-    strncpy(pbuf, typ->tp_name, len);
+    len = strlen(typ->tp_name);
+    if (len > TYPE_MAXSIZE) {
+        len = TYPE_MAXSIZE;
+    }
+    pbuf = memcpy(pbuf, typ->tp_name, len);
     pbuf += len;
     *pbuf++ = '(';
 
index ef1ce0934c18644f9b2bb7178298ba4dc369ad11..3e58bacb55ff2cc0b253ef753b644264a92936ca 100644 (file)
@@ -33,8 +33,8 @@ const char *PyWin_DLLVersionString = dllVersionBuffer;
 typedef BOOL (WINAPI * PFN_GETCURRENTACTCTX)(HANDLE *);
 typedef BOOL (WINAPI * PFN_ACTIVATEACTCTX)(HANDLE, ULONG_PTR *);
 typedef BOOL (WINAPI * PFN_DEACTIVATEACTCTX)(DWORD, ULONG_PTR);
-typedef BOOL (WINAPI * PFN_ADDREFACTCTX)(HANDLE);
-typedef BOOL (WINAPI * PFN_RELEASEACTCTX)(HANDLE);
+typedef void (WINAPI * PFN_ADDREFACTCTX)(HANDLE);
+typedef void (WINAPI * PFN_RELEASEACTCTX)(HANDLE);
 
 // locals and function pointers for this activation context magic.
 static HANDLE PyWin_DLLhActivationContext = NULL; // one day it might be public
@@ -90,9 +90,14 @@ BOOL    WINAPI  DllMain (HANDLE hInst,
             // and capture our activation context for use when loading extensions.
             _LoadActCtxPointers();
             if (pfnGetCurrentActCtx && pfnAddRefActCtx)
-                if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext))
-                    if (!(*pfnAddRefActCtx)(PyWin_DLLhActivationContext))
-                        OutputDebugString("Python failed to load the default activation context\n");
+                if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext)) {
+                    (*pfnAddRefActCtx)(PyWin_DLLhActivationContext);
+                }
+                else {
+                    OutputDebugString("Python failed to load the default "
+                                      "activation context\n");
+                    return FALSE;
+                }
             break;
 
         case DLL_PROCESS_DETACH:
index 946032589f4b003b4dce257c6dd3f81cc2733022..10571a3ec2428fdfa35313196bed6ed6a4bfa787 100644 (file)
@@ -852,8 +852,9 @@ ast_for_decorator(struct compiling *c, const node *n)
         name_expr = NULL;
     }
     else if (NCH(n) == 5) { /* Call with no arguments */
-        d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n),
-                 n->n_col_offset, c->c_arena);
+        d = Call(name_expr, NULL, NULL, NULL, NULL,
+                 name_expr->lineno, name_expr->col_offset,
+                 c->c_arena);
         if (!d)
             return NULL;
         name_expr = NULL;
index 4fe69e12bf84840e3ad0d041c77110537d9d0ba0..6386a40731ed68e13af94b001592f8207b6438c4 100644 (file)
@@ -221,7 +221,7 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident)
     }
     plen = strlen(p);
 
-    if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
+    if (nlen >= PY_SSIZE_T_MAX - 1 - plen) {
         PyErr_SetString(PyExc_OverflowError,
                         "private identifier too large to be mangled");
         return NULL;
@@ -233,7 +233,7 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident)
     /* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */
     buffer = PyString_AS_STRING(ident);
     buffer[0] = '_';
-    strncpy(buffer+1, p, plen);
+    memcpy(buffer+1, p, plen);
     strcpy(buffer+1+plen, name);
     return ident;
 }
index cc1ddde977f555914b5a38b39ea8afb07d651a7b..12ee2486377f6db728113b2c1804a065cf5b03ec 100644 (file)
@@ -1156,7 +1156,19 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
             memcpy(*buffer,
                    PyString_AS_STRING(s),
                    size + 1);
-            STORE_SIZE(size);
+
+            if (flags & FLAG_SIZE_T) {
+                *q2 = size;
+            }
+            else {
+                if (INT_MAX < size) {
+                    Py_DECREF(s);
+                    PyErr_SetString(PyExc_OverflowError,
+                                    "size does not fit in an int");
+                    return converterr("", arg, msgbuf, bufsize);
+                }
+                *q = (int)size;
+            }
         } else {
             /* Using a 0-terminated buffer:
 
index 0ef16d09238106f9bd53ecd44348d7427c215b56..3362ed59842aedb70328cd1a4e6efd9ae2a8f674 100644 (file)
@@ -4,7 +4,7 @@
 
 static char cprt[] = 
 "\
-Copyright (c) 2001-2019 Python Software Foundation.\n\
+Copyright (c) 2001-2020 Python Software Foundation.\n\
 All Rights Reserved.\n\
 \n\
 Copyright (c) 2000 BeOpen.com.\n\
index ccbd949e624f149fbb5aadbf568b5727ef0e4fad..b79354b37a406450d475cd6566dae0644d68af2f 100644 (file)
@@ -2456,7 +2456,7 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
                                 "Module name too long");
                 return NULL;
             }
-            strncpy(buf, start, len);
+            memcpy(buf, start, len);
             buf[len] = '\0';
             pkgname = PyString_FromString(buf);
             if (pkgname == NULL) {
@@ -2554,7 +2554,7 @@ load_next(PyObject *mod, PyObject *altmod, char **p_name, char *buf,
                         "Module name too long");
         return NULL;
     }
-    strncpy(p, name, len);
+    memcpy(p, name, len);
     p[len] = '\0';
     *p_buflen = p+len-buf;
 
@@ -2568,7 +2568,7 @@ load_next(PyObject *mod, PyObject *altmod, char **p_name, char *buf,
                 Py_DECREF(result);
                 return NULL;
             }
-            strncpy(buf, name, len);
+            memcpy(buf, name, len);
             buf[len] = '\0';
             *p_buflen = len;
         }
diff --git a/README b/README
index a2b0543dcdc5a9c183ae3c7660997204278834f0..4afaac0105419c3475dfe3b26b82c849670de004 100644 (file)
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
-This is Python version 2.7.17
+This is Python version 2.7.18
 =============================
 
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
-2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation.  All
+2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation.  All
 rights reserved.
 
 Copyright (c) 2000 BeOpen.com.
index 8844cacb096e9c20778cfb80e28bc2a8fff94d8b..efc06bc30652813b2e1514735366af7688b528a7 100644 (file)
@@ -103,7 +103,7 @@ FULL_LAYOUT = [
     ('Lib/', 'Lib', '**/*', include_in_lib),
     ('libs/', 'PCBuild/$arch', '*.lib', include_in_libs),
     ('Tools/', 'Tools', '**/*', include_in_tools),
-    ('/', '', 'LICENSE', None),
+    ('/', '', 'LICENSE*', None),
 ]
 
 EMBED_LAYOUT = [
index 78b068a46a50c4cfd6e50499e56d0d0fe7af9efb..d351804a92110510b744c75bfc29d88f02b1e6ce 100755 (executable)
@@ -46,9 +46,9 @@ OPENSSL_OLD_VERSIONS = [
 ]
 
 OPENSSL_RECENT_VERSIONS = [
-     "1.0.2p",
-     "1.1.0i",
-     "1.1.1",
+    "1.0.2t",
+    "1.1.0l",
+    "1.1.1f",
 ]
 
 LIBRESSL_OLD_VERSIONS = [