From 5fa2eaddddb212ba8c03589ca74a9e8b545d783e Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Tue, 8 Dec 2020 10:59:51 +0900 Subject: [PATCH] Imported Upstream version 2.7.18 --- Doc/README.txt | 7 ++++ Doc/c-api/iter.rst | 2 +- Doc/c-api/list.rst | 12 +++---- Doc/c-api/tuple.rst | 18 ++++++---- Doc/conf.py | 4 +++ Doc/copyright.rst | 2 +- Doc/library/threading.rst | 4 +++ Doc/license.rst | 4 +-- Doc/tools/susp-ignored.csv | 1 + Doc/tools/templates/indexsidebar.html | 2 +- Doc/tools/templates/layout.html | 10 ++++++ Include/patchlevel.h | 4 +-- LICENSE | 2 +- Lib/cookielib.py | 20 +++++++---- Lib/encodings/uu_codec.py | 4 +++ Lib/httplib.py | 13 +++++++ Lib/test/test_ast.py | 9 +++++ Lib/test/test_cookielib.py | 15 +++++++- Lib/test/test_httplib.py | 13 ++++++- Lib/test/test_posix.py | 6 +++- Lib/test/test_py_compile.py | 2 +- Lib/test/test_urllib2.py | 32 +++++++++++++---- Lib/test/test_urllibnet.py | 39 +++++++++++++++++++- Lib/test/test_uu.py | 10 ++++++ Lib/urllib.py | 6 ++++ Lib/uu.py | 7 ++++ Mac/BuildScript/build-installer.py | 22 ++++++------ Mac/BuildScript/resources/License.rtf | 8 ++--- Mac/BuildScript/resources/ReadMe.rtf | 20 +++++------ Mac/BuildScript/resources/Welcome.rtf | 6 ++-- Mac/PythonLauncher/Info.plist.in | 2 +- Mac/Resources/app/Info.plist.in | 2 +- Misc/ACKS | 1 + Misc/NEWS | 67 +++++++++++++++++++++++++++++++++++ Modules/expat/xmlparse.c | 12 +++---- Modules/expat/xmltok.c | 16 ++++----- Modules/getpath.c | 2 +- Modules/parsermodule.c | 11 +++--- Modules/readline.c | 2 +- Modules/signalmodule.c | 6 ++-- Modules/zipimport.c | 6 ++-- Objects/structseq.c | 8 +++-- PC/dl_nt.c | 15 +++++--- Python/ast.c | 5 +-- Python/compile.c | 4 +-- Python/getargs.c | 14 +++++++- Python/getcopyright.c | 2 +- Python/import.c | 6 ++-- README | 4 +-- Tools/nuget/make_zip.py | 2 +- Tools/ssl/multissltests.py | 6 ++-- 51 files changed, 377 insertions(+), 120 deletions(-) diff --git a/Doc/README.txt b/Doc/README.txt index a362ecc..625efd4 100644 --- a/Doc/README.txt +++ b/Doc/README.txt @@ -104,6 +104,13 @@ Then, from the ``Doc`` directory, run :: where ```` 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 ============ diff --git a/Doc/c-api/iter.rst b/Doc/c-api/iter.rst index fb2a71c..4f70882 100644 --- a/Doc/c-api/iter.rst +++ b/Doc/c-api/iter.rst @@ -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 */ diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index a5e4a45..c28d6b0 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -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 diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 16de45f..fd85663 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -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 diff --git a/Doc/conf.py b/Doc/conf.py index 393018d..29927c3 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -80,6 +80,10 @@ htmlhelp_basename = 'python' + release.replace('.', '') # Split the index html_split_index = True +html_context = { + 'outdated': True +} + # Options for LaTeX output # ------------------------ diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 393a1f0..1b90d9f 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -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. diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index e16f78c..9228e11 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -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: diff --git a/Doc/license.rst b/Doc/license.rst index eded4a9..c347cf5 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -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. diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index f7d23e2..0efbbab 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -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""))" diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html index e5748f2..36f94ee 100644 --- a/Doc/tools/templates/indexsidebar.html +++ b/Doc/tools/templates/indexsidebar.html @@ -7,7 +7,7 @@
  • {% trans %}Python 3.7 (stable){% endtrans %}
  • {% trans %}Python 3.6 (security-fixes){% endtrans %}
  • {% trans %}Python 3.5 (security-fixes){% endtrans %}
  • -
  • {% trans %}Python 2.7 (stable){% endtrans %}
  • +
  • {% trans %}Python 2.7 (EOL){% endtrans %}
  • {% trans %}All versions{% endtrans %}
  • diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index 8d6d3e5..34a87ae 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -1,4 +1,14 @@ {% extends "!layout.html" %} +{% block header %} +{%- if outdated %} +
    + {% trans %}This document is for an old version of Python that is {% endtrans %}{% trans %}no longer supported{% endtrans %}. + {% trans %}You should upgrade and read the {% endtrans %} + {% trans %} Python documentation for the current stable release{% endtrans %}. +
    +{%- endif %} +{% endblock %} + {% block rootrellink %}
  • diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 4bfcdaf..0ce6313 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -22,12 +22,12 @@ /*--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 9dc010d..66a3ac8 100644 --- 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. diff --git a/Lib/cookielib.py b/Lib/cookielib.py index 1d56d3f..e76d09d 100644 --- a/Lib/cookielib.py +++ b/Lib/cookielib.py @@ -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: diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py index 5cb0d2b..fcd5aa4 100644 --- a/Lib/encodings/uu_codec.py +++ b/Lib/encodings/uu_codec.py @@ -31,6 +31,10 @@ def uu_encode(input,errors='strict',filename='',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) diff --git a/Lib/httplib.py b/Lib/httplib.py index 79532b9..fcc4152 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -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. diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 0a1ca41..3cfe618 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -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)))]), diff --git a/Lib/test/test_cookielib.py b/Lib/test/test_cookielib.py index a93bbfb..f3711b9 100644 --- a/Lib/test/test_cookielib.py +++ b/Lib/test/test_cookielib.py @@ -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): diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 5462fdd..d8a57f7 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -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): diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index c4283b6..ae636e5 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -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) diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 5ec523a..9586308 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -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] diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 9531818..20a0f58 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -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): diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index 3f2d8dc..ef33e3a 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -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() diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py index df41cbc..f016bb2 100644 --- a/Lib/test/test_uu.py +++ b/Lib/test/test_uu.py @@ -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): diff --git a/Lib/urllib.py b/Lib/urllib.py index 156879d..87bcd94 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -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 diff --git a/Lib/uu.py b/Lib/uu.py index f8fa4c4..8eaea59 100755 --- 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 # diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 3edd947..4bb942a 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -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 ' diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf index 86e54f6..25d5338 100644 --- a/Mac/BuildScript/resources/License.rtf +++ b/Mac/BuildScript/resources/License.rtf @@ -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.\ \ diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index a4c351a..d49bab5 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -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 \ \ diff --git a/Mac/BuildScript/resources/Welcome.rtf b/Mac/BuildScript/resources/Welcome.rtf index 2786a74..fa398ac 100644 --- a/Mac/BuildScript/resources/Welcome.rtf +++ b/Mac/BuildScript/resources/Welcome.rtf @@ -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}}.\ diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index 77dbb0f..dba6454 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -40,7 +40,7 @@ CFBundleExecutable PythonLauncher CFBundleGetInfoString - %VERSION%, © 2001-2019 Python Software Foundation + %VERSION%, © 2001-2020 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index b758198..66b5e76 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2001-2019 Python Software Foundation. + %version%, (c) 2001-2020 Python Software Foundation. CFBundleName Python CFBundlePackageType diff --git a/Misc/ACKS b/Misc/ACKS index eba64ae..fd28ce7 100644 --- 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 diff --git a/Misc/NEWS b/Misc/NEWS index f265105..63b3fa8 100644 --- 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? ================================== diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index e740f0e..09ccacb 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -39,6 +39,12 @@ # define _CRT_RAND_S #endif +#ifdef _WIN32 +# include "winconfig.h" +#elif defined(HAVE_EXPAT_CONFIG_H) +# include +#endif /* ndef _WIN32 */ + #include #include /* memset(), memcpy() */ #include @@ -58,12 +64,6 @@ #define XML_BUILDING_EXPAT 1 -#ifdef _WIN32 -# include "winconfig.h" -#elif defined(HAVE_EXPAT_CONFIG_H) -# include -#endif /* ndef _WIN32 */ - #include "ascii.h" #include "expat.h" #include "siphash.h" diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index 11e9d1c..54cfedb 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -30,6 +30,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef _WIN32 +# include "winconfig.h" +#else +# ifdef HAVE_EXPAT_CONFIG_H +# include +# endif +#endif /* ndef _WIN32 */ + #include #include /* memcpy */ @@ -42,14 +50,6 @@ # include #endif -#ifdef _WIN32 -# include "winconfig.h" -#else -# ifdef HAVE_EXPAT_CONFIG_H -# include -# endif -#endif /* ndef _WIN32 */ - #include "expat_external.h" #include "internal.h" #include "xmltok.h" diff --git a/Modules/getpath.c b/Modules/getpath.c index c42ce31..092ccc7 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -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); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index fcc618d..759f0ff 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -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; } diff --git a/Modules/readline.c b/Modules/readline.c index 0262135..64bb19a 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -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'; } diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 8628f7a..88b4711 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -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 diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 1691773..8ec2475 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -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); diff --git a/Objects/structseq.c b/Objects/structseq.c index aee9528..82df926 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -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++ = '('; diff --git a/PC/dl_nt.c b/PC/dl_nt.c index ef1ce09..3e58bac 100644 --- a/PC/dl_nt.c +++ b/PC/dl_nt.c @@ -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: diff --git a/Python/ast.c b/Python/ast.c index 9460325..10571a3 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -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; diff --git a/Python/compile.c b/Python/compile.c index 4fe69e1..6386a40 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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; } diff --git a/Python/getargs.c b/Python/getargs.c index cc1ddde..12ee248 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -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: diff --git a/Python/getcopyright.c b/Python/getcopyright.c index 0ef16d0..3362ed5 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -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\ diff --git a/Python/import.c b/Python/import.c index ccbd949..b79354b 100644 --- a/Python/import.c +++ b/Python/import.c @@ -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 a2b0543..4afaac0 100644 --- 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. diff --git a/Tools/nuget/make_zip.py b/Tools/nuget/make_zip.py index 8844cac..efc06bc 100644 --- a/Tools/nuget/make_zip.py +++ b/Tools/nuget/make_zip.py @@ -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 = [ diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 78b068a..d351804 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -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 = [ -- 2.7.4