diff --git a/.gitignore b/.gitignore index 94e7946..3cb4f28 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/Python-3.6.3.tar.xz +SOURCES/Python-3.6.9.tar.xz diff --git a/.rh-python36-python.metadata b/.rh-python36-python.metadata index 55a6788..2bf5897 100644 --- a/.rh-python36-python.metadata +++ b/.rh-python36-python.metadata @@ -1 +1 @@ -6c71b14bdbc4d8aa0cfd59d4b6dc356d46abfdf5 SOURCES/Python-3.6.3.tar.xz +3cd8b0e814b753fcce4fdf7edc823d8fb0da9208 SOURCES/Python-3.6.9.tar.xz diff --git a/SOURCES/00102-lib64.patch b/SOURCES/00102-lib64.patch index 8e9ae4e..44e718c 100644 --- a/SOURCES/00102-lib64.patch +++ b/SOURCES/00102-lib64.patch @@ -1,5 +1,5 @@ diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py -index 9474e9c..c0ce4c6 100644 +index 0258d3d..4b969bf 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py @@ -30,14 +30,14 @@ WINDOWS_SCHEME = { @@ -20,10 +20,10 @@ index 9474e9c..c0ce4c6 100644 'scripts': '$base/bin', 'data' : '$base', diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py -index 026cca7..6d3e077 100644 +index 5c2670f..2013efa 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py -@@ -132,8 +132,12 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): +@@ -129,8 +129,12 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): prefix = plat_specific and EXEC_PREFIX or PREFIX if os.name == "posix": @@ -38,10 +38,10 @@ index 026cca7..6d3e077 100644 return libpython else: diff --git a/Lib/site.py b/Lib/site.py -index a84e3bb..ba0d3ea 100644 +index 86ca2db..58115f1 100644 --- a/Lib/site.py +++ b/Lib/site.py -@@ -303,11 +303,15 @@ def getsitepackages(prefixes=None): +@@ -304,11 +304,15 @@ def getsitepackages(prefixes=None): seen.add(prefix) if os.sep == '/': @@ -58,7 +58,7 @@ index a84e3bb..ba0d3ea 100644 if sys.platform == "darwin": # for framework builds *only* we add the standard Apple diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py -index b9bbfe5..2a5f29c 100644 +index d35b5eb..240bb66 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -20,10 +20,10 @@ __all__ = [ @@ -90,13 +90,13 @@ index b9bbfe5..2a5f29c 100644 'scripts': '{userbase}/bin', 'data': '{userbase}', diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py -index f698927..bc977b5 100644 +index 6964a84..d0cd84f 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py -@@ -248,8 +248,8 @@ class HelperFunctionsTests(unittest.TestCase): +@@ -264,8 +264,8 @@ class HelperFunctionsTests(unittest.TestCase): self.assertEqual(dirs[1], wanted) elif os.sep == '/': - # OS X non-framwework builds, Linux, FreeBSD, etc + # OS X non-framework builds, Linux, FreeBSD, etc - self.assertEqual(len(dirs), 1) - wanted = os.path.join('xoxo', 'lib', + self.assertEqual(len(dirs), 2) @@ -105,10 +105,10 @@ index f698927..bc977b5 100644 'site-packages') self.assertEqual(dirs[0], wanted) diff --git a/Makefile.pre.in b/Makefile.pre.in -index 8fa7934..a693917 100644 +index f380399..a545318 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in -@@ -126,7 +126,7 @@ LIBDIR= @libdir@ +@@ -139,7 +139,7 @@ LIBDIR= @libdir@ MANDIR= @mandir@ INCLUDEDIR= @includedir@ CONFINCLUDEDIR= $(exec_prefix)/include @@ -118,7 +118,7 @@ index 8fa7934..a693917 100644 # Detailed destination directories diff --git a/Modules/getpath.c b/Modules/getpath.c -index 65b47a3..eaa756c 100644 +index dd3387a..1258fcd 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -494,7 +494,7 @@ calculate_path(void) @@ -149,10 +149,10 @@ index 65b47a3..eaa756c 100644 /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ diff --git a/setup.py b/setup.py -index 0f2dfc4..da37896 100644 +index e2c1898..64d948d 100644 --- a/setup.py +++ b/setup.py -@@ -492,7 +492,7 @@ class PyBuildExt(build_ext): +@@ -521,7 +521,7 @@ class PyBuildExt(build_ext): # directories (i.e. '.' and 'Include') must be first. See issue # 10520. if not cross_compiling: @@ -161,7 +161,7 @@ index 0f2dfc4..da37896 100644 add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') # only change this for cross builds for 3.3, issues on Mageia if cross_compiling: -@@ -780,11 +780,11 @@ class PyBuildExt(build_ext): +@@ -818,11 +818,11 @@ class PyBuildExt(build_ext): elif curses_library: readline_libs.append(curses_library) elif self.compiler.find_library_file(lib_dirs + @@ -175,7 +175,7 @@ index 0f2dfc4..da37896 100644 extra_link_args=readline_extra_link_args, libraries=readline_libs) ) else: -@@ -821,8 +821,8 @@ class PyBuildExt(build_ext): +@@ -859,8 +859,8 @@ class PyBuildExt(build_ext): if krb5_h: ssl_incs += krb5_h ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs, diff --git a/SOURCES/00111-no-static-lib.patch b/SOURCES/00111-no-static-lib.patch index 6929fda..ddf4689 100644 --- a/SOURCES/00111-no-static-lib.patch +++ b/SOURCES/00111-no-static-lib.patch @@ -1,45 +1,39 @@ diff --git a/Makefile.pre.in b/Makefile.pre.in -index 70e5927..04c8e3d 100644 +index a545318..0848e14 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in -@@ -556,7 +556,7 @@ clinic: $(BUILDPYTHON) $(srcdir)/Modules/_blake2/blake2s_impl.c - $(RUNSHARED) $(PYTHON_FOR_BUILD) ./Tools/clinic/clinic.py --make +@@ -549,7 +549,7 @@ clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c + $(PYTHON_FOR_REGEN) ./Tools/clinic/clinic.py --make # Build the interpreter -$(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) +$(BUILDPYTHON): Programs/python.o $(LDLIBRARY) $(PY3LIBRARY) - $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) + $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) platform: $(BUILDPYTHON) pybuilddir.txt -@@ -601,18 +601,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o +@@ -597,12 +597,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o + _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - +- -# Build static library --# avoid long command lines, same as LIBRARY_OBJS -$(LIBRARY): $(LIBRARY_OBJS) - -rm -f $@ -- $(AR) $(ARFLAGS) $@ Modules/getbuildinfo.o -- $(AR) $(ARFLAGS) $@ $(PARSER_OBJS) -- $(AR) $(ARFLAGS) $@ $(OBJECT_OBJS) -- $(AR) $(ARFLAGS) $@ $(PYTHON_OBJS) Python/frozen.o -- $(AR) $(ARFLAGS) $@ $(MODULE_OBJS) -- $(AR) $(ARFLAGS) $@ $(MODOBJS) -- $(RANLIB) $@ +- $(AR) $(ARFLAGS) $@ $(LIBRARY_OBJS) - libpython$(LDVERSION).so: $(LIBRARY_OBJS) if test $(INSTSONAME) != $(LDLIBRARY); then \ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ -@@ -702,7 +690,7 @@ Modules/Setup: $(srcdir)/Modules/Setup.dist +@@ -692,7 +686,7 @@ Modules/Setup: $(srcdir)/Modules/Setup.dist echo "-----------------------------------------------"; \ fi -Programs/_testembed: Programs/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) +Programs/_testembed: Programs/_testembed.o $(LDLIBRARY) $(PY3LIBRARY) - $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) + $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) ############################################################################ -@@ -1382,18 +1370,6 @@ libainstall: all python-config +@@ -1428,17 +1422,6 @@ libainstall: @DEF_MAKE_RULE@ python-config else true; \ fi; \ done @@ -49,7 +43,6 @@ index 70e5927..04c8e3d 100644 - $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \ - else \ - $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ -- $(RANLIB) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ - fi; \ - else \ - echo Skip install of $(LIBRARY) - use make frameworkinstall; \ diff --git a/SOURCES/00146-hashlib-fips.patch b/SOURCES/00146-hashlib-fips.patch index 32fe26e..a4a8bb0 100644 --- a/SOURCES/00146-hashlib-fips.patch +++ b/SOURCES/00146-hashlib-fips.patch @@ -1,5 +1,5 @@ diff --git a/Lib/hashlib.py b/Lib/hashlib.py -index 053a7ad..fadd8fa 100644 +index 98d2d79..fa6cdbc 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -24,6 +24,16 @@ the zlib module. @@ -17,8 +17,8 @@ index 053a7ad..fadd8fa 100644 +usable even in FIPS mode. + Hash objects have these methods: - - update(arg): Update the hash object with the bytes in arg. Repeated calls - are equivalent to a single call with the concatenation of all + - update(data): Update the hash object with the bytes in data. Repeated calls + are equivalent to a single call with the concatenation of all @@ -67,6 +77,19 @@ algorithms_available = set(__always_supported) __all__ = __always_supported + ('new', 'algorithms_guaranteed', 'algorithms_available', 'pbkdf2_hmac') @@ -39,7 +39,7 @@ index 053a7ad..fadd8fa 100644 __builtin_constructor_cache = {} -@@ -121,23 +144,33 @@ def __get_openssl_constructor(name): +@@ -121,24 +144,33 @@ def __get_openssl_constructor(name): f = getattr(_hashlib, 'openssl_' + name) # Allow the C module to raise ValueError. The function will be # defined but the hash not actually available thanks to OpenSSL. @@ -58,7 +58,8 @@ index 053a7ad..fadd8fa 100644 -def __py_new(name, data=b'', **kwargs): - """new(name, data=b'', **kwargs) - Return a new hashing object using the -- named algorithm; optionally initialized with data (which must be bytes). +- named algorithm; optionally initialized with data (which must be +- a bytes-like object). +def __py_new(name, data=b'', *, usedforsecurity=True, **kwargs): + """new(name, data=b'', usedforsecurity=True) - Return a new hashing object using + the named algorithm; optionally initialized with data (which must be bytes). @@ -70,7 +71,7 @@ index 053a7ad..fadd8fa 100644 -def __hash_new(name, data=b'', **kwargs): - """new(name, data=b'') - Return a new hashing object using the named algorithm; -- optionally initialized with data (which must be bytes). +- optionally initialized with data (which must be a bytes-like object). +def __hash_new(name, data=b'', *, usedforsecurity=True, **kwargs): + """new(name, data=b'', usedforsecurity=True) - Return a new hashing object using + the named algorithm; optionally initialized with data (which must be bytes). @@ -80,7 +81,7 @@ index 053a7ad..fadd8fa 100644 """ if name in {'blake2b', 'blake2s'}: # Prefer our blake2 implementation. -@@ -146,12 +179,10 @@ def __hash_new(name, data=b'', **kwargs): +@@ -147,12 +179,10 @@ def __hash_new(name, data=b'', **kwargs): # salt, personal, tree hashing or SSE. return __get_builtin_constructor(name)(data, **kwargs) try: @@ -96,7 +97,7 @@ index 053a7ad..fadd8fa 100644 return __get_builtin_constructor(name)(data) -@@ -162,8 +193,8 @@ try: +@@ -163,8 +193,8 @@ try: algorithms_available = algorithms_available.union( _hashlib.openssl_md_meth_names) except ImportError: @@ -107,7 +108,7 @@ index 053a7ad..fadd8fa 100644 try: # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA -@@ -240,7 +271,10 @@ for __func_name in __always_supported: +@@ -241,7 +271,10 @@ for __func_name in __always_supported: # try them all, some may not work due to the OpenSSL # version not supporting that algorithm. try: @@ -119,7 +120,7 @@ index 053a7ad..fadd8fa 100644 except ValueError: import logging logging.exception('code for hash %s was not found.', __func_name) -@@ -248,4 +282,5 @@ for __func_name in __always_supported: +@@ -249,4 +282,5 @@ for __func_name in __always_supported: # Cleanup locals() del __always_supported, __func_name, __get_hash @@ -127,10 +128,10 @@ index 053a7ad..fadd8fa 100644 +del __hash_new, __get_openssl_constructor +del __ignore_usedforsecurity diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py -index 647719e..fce4c3a 100644 +index 9711856..254dbd3 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py -@@ -26,7 +26,22 @@ from http.client import HTTPException +@@ -27,7 +27,22 @@ from http.client import HTTPException COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') c_hashlib = import_fresh_module('hashlib', fresh=['_hashlib']) @@ -154,7 +155,7 @@ index 647719e..fce4c3a 100644 try: import _blake2 -@@ -70,6 +85,17 @@ def read_vectors(hash_name): +@@ -71,6 +86,17 @@ def read_vectors(hash_name): yield parts @@ -172,7 +173,7 @@ index 647719e..fce4c3a 100644 class HashLibTestCase(unittest.TestCase): supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1', 'sha224', 'SHA224', 'sha256', 'SHA256', -@@ -108,11 +134,11 @@ class HashLibTestCase(unittest.TestCase): +@@ -109,11 +135,11 @@ class HashLibTestCase(unittest.TestCase): # For each algorithm, test the direct constructor and the use # of hashlib.new given the algorithm name. for algorithm, constructors in self.constructors_to_test.items(): @@ -183,12 +184,12 @@ index 647719e..fce4c3a 100644 if data is None: - return hashlib.new(_alg, **kwargs) - return hashlib.new(_alg, data, **kwargs) -+ return suppress_fips(hashlib.new)(_alg) -+ return suppress_fips(hashlib.new)(_alg, data) ++ return suppress_fips(hashlib.new)(_alg, **kwargs) ++ return suppress_fips(hashlib.new)(_alg, data, **kwargs) constructors.add(_test_algorithm_via_hashlib_new) _hashlib = self._conditional_import_module('_hashlib') -@@ -124,26 +150,12 @@ class HashLibTestCase(unittest.TestCase): +@@ -125,26 +151,12 @@ class HashLibTestCase(unittest.TestCase): for algorithm, constructors in self.constructors_to_test.items(): constructor = getattr(_hashlib, 'openssl_'+algorithm, None) if constructor: @@ -216,7 +217,7 @@ index 647719e..fce4c3a 100644 if _blake2: add_builtin_constructor('blake2s') add_builtin_constructor('blake2b') -@@ -208,9 +220,6 @@ class HashLibTestCase(unittest.TestCase): +@@ -219,9 +231,6 @@ class HashLibTestCase(unittest.TestCase): else: del sys.modules['_md5'] self.assertRaises(TypeError, get_builtin_constructor, 3) @@ -226,7 +227,7 @@ index 647719e..fce4c3a 100644 def test_hexdigest(self): for cons in self.hash_constructors: -@@ -775,6 +784,65 @@ class HashLibTestCase(unittest.TestCase): +@@ -840,6 +849,65 @@ class HashLibTestCase(unittest.TestCase): self.assertEqual(expected_hash, hasher.hexdigest()) @@ -292,7 +293,7 @@ index 647719e..fce4c3a 100644 class KDFTests(unittest.TestCase): -@@ -865,6 +933,7 @@ class KDFTests(unittest.TestCase): +@@ -930,6 +998,7 @@ class KDFTests(unittest.TestCase): iterations=1, dklen=None) self.assertEqual(out, self.pbkdf2_results['sha1'][0][0]) @@ -301,7 +302,7 @@ index 647719e..fce4c3a 100644 self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac) diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c -index 5a86376..f5e688d 100644 +index 84edd72..cc602c4 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -20,6 +20,7 @@ @@ -454,7 +455,7 @@ index 5a86376..f5e688d 100644 + Py_RETURN_NONE; } - self->name = name_obj; + Py_INCREF(name_obj); @@ -460,7 +504,8 @@ static PyTypeObject EVPtype = { static PyObject * EVPnew(PyObject *name_obj, @@ -521,14 +522,14 @@ index 5a86376..f5e688d 100644 if (data_obj) PyBuffer_Release(&view); -@@ -915,66 +970,116 @@ generate_hash_name_list(void) +@@ -919,66 +974,116 @@ generate_hash_name_list(void) /* - * This macro generates constructor function definitions for specific - * hash algorithms. These constructors are much faster than calling - * the generic one passing it a python string and are noticeably -- * faster than calling a python new() wrapper. Thats important for +- * faster than calling a python new() wrapper. That is important for + * This macro and function generates a family of constructor function + * definitions for specific hash algorithms. These constructors are much + * faster than calling the generic one passing it a python string and are @@ -682,7 +683,7 @@ index 5a86376..f5e688d 100644 GEN_CONSTRUCTOR(md5) GEN_CONSTRUCTOR(sha1) -@@ -1022,16 +1127,10 @@ PyInit__hashlib(void) +@@ -1026,16 +1131,10 @@ PyInit__hashlib(void) { PyObject *m, *openssl_md_meth_names; diff --git a/SOURCES/00170-gc-assertions.patch b/SOURCES/00170-gc-assertions.patch index f491733..3385a35 100644 --- a/SOURCES/00170-gc-assertions.patch +++ b/SOURCES/00170-gc-assertions.patch @@ -1,8 +1,8 @@ diff --git a/Include/object.h b/Include/object.h -index 0c88603..e3413e8 100644 +index deac940..fe7469b 100644 --- a/Include/object.h +++ b/Include/object.h -@@ -1059,6 +1059,49 @@ PyAPI_FUNC(void) +@@ -1072,6 +1072,49 @@ PyAPI_FUNC(void) _PyObject_DebugTypeStats(FILE *out); #endif /* ifndef Py_LIMITED_API */ @@ -53,15 +53,16 @@ index 0c88603..e3413e8 100644 } #endif diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py -index e727499..6efcafb 100644 +index 7e82b24..346114f 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py -@@ -1,10 +1,11 @@ +@@ -1,10 +1,12 @@ import unittest from test.support import (verbose, refcount_test, run_unittest, strip_python_stderr, cpython_only, start_threads, -- temp_dir, requires_type_collecting) -+ temp_dir, import_module, requires_type_collecting) +- temp_dir, requires_type_collecting, TESTFN, unlink) ++ temp_dir, import_module, requires_type_collecting, ++ TESTFN, unlink) from test.support.script_helper import assert_python_ok, make_script import sys @@ -69,7 +70,7 @@ index e727499..6efcafb 100644 import time import gc import weakref -@@ -50,6 +51,8 @@ class GC_Detector(object): +@@ -50,6 +52,8 @@ class GC_Detector(object): # gc collects it. self.wr = weakref.ref(C1055820(666), it_happened) @@ -78,7 +79,7 @@ index e727499..6efcafb 100644 @with_tp_del class Uncollectable(object): """Create a reference cycle with multiple __del__ methods. -@@ -862,6 +865,50 @@ class GCCallbackTests(unittest.TestCase): +@@ -877,6 +881,50 @@ class GCCallbackTests(unittest.TestCase): self.assertEqual(len(gc.garbage), 0) @@ -130,10 +131,10 @@ index e727499..6efcafb 100644 def setUp(self): gc.enable() diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c -index 0c6f444..87edd5a 100644 +index 3bddc40..0cc24f7 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c -@@ -341,7 +341,8 @@ update_refs(PyGC_Head *containers) +@@ -342,7 +342,8 @@ update_refs(PyGC_Head *containers) { PyGC_Head *gc = containers->gc.gc_next; for (; gc != containers; gc = gc->gc.gc_next) { @@ -143,7 +144,7 @@ index 0c6f444..87edd5a 100644 _PyGCHead_SET_REFS(gc, Py_REFCNT(FROM_GC(gc))); /* Python's cyclic gc should never see an incoming refcount * of 0: if something decref'ed to 0, it should have been -@@ -361,7 +362,8 @@ update_refs(PyGC_Head *containers) +@@ -362,7 +363,8 @@ update_refs(PyGC_Head *containers) * so serious that maybe this should be a release-build * check instead of an assert? */ @@ -153,7 +154,7 @@ index 0c6f444..87edd5a 100644 } } -@@ -376,7 +378,9 @@ visit_decref(PyObject *op, void *data) +@@ -377,7 +379,9 @@ visit_decref(PyObject *op, void *data) * generation being collected, which can be recognized * because only they have positive gc_refs. */ @@ -164,7 +165,7 @@ index 0c6f444..87edd5a 100644 if (_PyGCHead_REFS(gc) > 0) _PyGCHead_DECREF(gc); } -@@ -436,9 +440,10 @@ visit_reachable(PyObject *op, PyGC_Head *reachable) +@@ -437,9 +441,10 @@ visit_reachable(PyObject *op, PyGC_Head *reachable) * If gc_refs == GC_UNTRACKED, it must be ignored. */ else { @@ -178,7 +179,7 @@ index 0c6f444..87edd5a 100644 } } return 0; -@@ -480,7 +485,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) +@@ -481,7 +486,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) */ PyObject *op = FROM_GC(gc); traverseproc traverse = Py_TYPE(op)->tp_traverse; @@ -187,7 +188,7 @@ index 0c6f444..87edd5a 100644 _PyGCHead_SET_REFS(gc, GC_REACHABLE); (void) traverse(op, (visitproc)visit_reachable, -@@ -543,7 +548,7 @@ move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) +@@ -544,7 +549,7 @@ move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) { PyObject *op = FROM_GC(gc); @@ -196,7 +197,7 @@ index 0c6f444..87edd5a 100644 next = gc->gc.gc_next; if (has_legacy_finalizer(op)) { -@@ -619,7 +624,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) +@@ -620,7 +625,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) PyWeakReference **wrlist; op = FROM_GC(gc); @@ -205,7 +206,7 @@ index 0c6f444..87edd5a 100644 next = gc->gc.gc_next; if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) -@@ -640,9 +645,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) +@@ -641,9 +646,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) * the callback pointer intact. Obscure: it also * changes *wrlist. */ @@ -217,7 +218,7 @@ index 0c6f444..87edd5a 100644 if (wr->wr_callback == NULL) continue; /* no callback */ -@@ -676,7 +681,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) +@@ -677,7 +682,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) */ if (IS_TENTATIVELY_UNREACHABLE(wr)) continue; @@ -226,7 +227,7 @@ index 0c6f444..87edd5a 100644 /* Create a new reference so that wr can't go away * before we can process it again. -@@ -685,7 +690,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) +@@ -686,7 +691,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) /* Move wr to wrcb_to_call, for the next pass. */ wrasgc = AS_GC(wr); @@ -236,7 +237,7 @@ index 0c6f444..87edd5a 100644 next isn't, so they can't be the same */ gc_list_move(wrasgc, &wrcb_to_call); -@@ -701,11 +707,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) +@@ -702,11 +708,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) gc = wrcb_to_call.gc.gc_next; op = FROM_GC(gc); @@ -251,7 +252,7 @@ index 0c6f444..87edd5a 100644 /* copy-paste of weakrefobject.c's handle_callback() */ temp = PyObject_CallFunctionObjArgs(callback, wr, NULL); -@@ -822,12 +828,14 @@ check_garbage(PyGC_Head *collectable) +@@ -820,12 +826,14 @@ check_garbage(PyGC_Head *collectable) for (gc = collectable->gc.gc_next; gc != collectable; gc = gc->gc.gc_next) { _PyGCHead_SET_REFS(gc, Py_REFCNT(FROM_GC(gc))); @@ -269,10 +270,10 @@ index 0c6f444..87edd5a 100644 return -1; } diff --git a/Objects/object.c b/Objects/object.c -index 559794f..a47d47f 100644 +index e1a0569..9a28521 100644 --- a/Objects/object.c +++ b/Objects/object.c -@@ -2022,6 +2022,35 @@ _PyTrash_thread_destroy_chain(void) +@@ -2062,6 +2062,35 @@ _PyTrash_thread_destroy_chain(void) } } diff --git a/SOURCES/00189-add-rewheel-module.patch b/SOURCES/00189-add-rewheel-module.patch index 53a26ca..bc77465 100644 --- a/SOURCES/00189-add-rewheel-module.patch +++ b/SOURCES/00189-add-rewheel-module.patch @@ -1,6 +1,7 @@ -diff -Nur Python-3.4.1/Lib/ensurepip/__init__.py Python-3.4.1-rewheel/Lib/ensurepip/__init__.py ---- Python-3.4.1/Lib/ensurepip/__init__.py 2014-08-21 10:49:30.792695824 +0200 -+++ Python-3.4.1-rewheel/Lib/ensurepip/__init__.py 2014-08-21 10:10:41.958341726 +0200 +diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py +index 83dbe70..440b96b 100644 +--- a/Lib/ensurepip/__init__.py ++++ b/Lib/ensurepip/__init__.py @@ -1,8 +1,10 @@ import os import os.path @@ -12,16 +13,26 @@ diff -Nur Python-3.4.1/Lib/ensurepip/__init__.py Python-3.4.1-rewheel/Lib/ensure __all__ = ["version", "bootstrap"] -@@ -38,6 +40,8 @@ +@@ -24,9 +26,15 @@ def _run_pip(args, additional_paths=None): + sys.path = additional_paths + sys.path # Install the bundled software - import pip +- import pip._internal +- return pip._internal.main(args) +- ++ try: ++ # pip 10 ++ from pip._internal import main ++ except ImportError: ++ # pip 9 ++ from pip import main + if args[0] in ["install", "list", "wheel"]: + args.append('--pre') - pip.main(args) - ++ return main(args) -@@ -87,20 +91,39 @@ + def version(): + """ +@@ -88,20 +96,39 @@ def _bootstrap(*, root=None, upgrade=False, user=False, # omit pip and easy_install os.environ["ENSUREPIP_OPTIONS"] = "install" @@ -71,9 +82,11 @@ diff -Nur Python-3.4.1/Lib/ensurepip/__init__.py Python-3.4.1-rewheel/Lib/ensure # Construct the arguments to be passed to the pip command args = ["install", "--no-index", "--find-links", tmpdir] -diff -Nur Python-3.4.1/Lib/ensurepip/rewheel/__init__.py Python-3.4.1-rewheel/Lib/ensurepip/rewheel/__init__.py ---- Python-3.4.1/Lib/ensurepip/rewheel/__init__.py 1970-01-01 01:00:00.000000000 +0100 -+++ Python-3.4.1-rewheel/Lib/ensurepip/rewheel/__init__.py 2014-08-21 10:11:22.560320121 +0200 +diff --git a/Lib/ensurepip/rewheel/__init__.py b/Lib/ensurepip/rewheel/__init__.py +new file mode 100644 +index 0000000..753c764 +--- /dev/null ++++ b/Lib/ensurepip/rewheel/__init__.py @@ -0,0 +1,143 @@ +import argparse +import codecs @@ -218,10 +231,11 @@ diff -Nur Python-3.4.1/Lib/ensurepip/rewheel/__init__.py Python-3.4.1-rewheel/Li + else: + pass # bad RECORD or empty line + return to_write, to_omit -diff -Nur Python-3.4.1/Makefile.pre.in Python-3.4.1-rewheel/Makefile.pre.in ---- Python-3.4.1/Makefile.pre.in 2014-08-21 10:49:31.512695040 +0200 -+++ Python-3.4.1-rewheel/Makefile.pre.in 2014-08-21 10:10:41.961341722 +0200 -@@ -1145,7 +1145,7 @@ +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 0848e14..48839c1 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -1261,7 +1261,7 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ test/test_asyncio \ collections concurrent concurrent/futures encodings \ email email/mime test/test_email test/test_email/data \ diff --git a/SOURCES/00231-cprofile-sort-option.patch b/SOURCES/00231-cprofile-sort-option.patch deleted file mode 100644 index 92e0150..0000000 --- a/SOURCES/00231-cprofile-sort-option.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0fba878e37390b581b95b31ff7d42041c9a3a370 Mon Sep 17 00:00:00 2001 -From: Charalampos Stratakis -Date: Tue, 12 Apr 2016 14:17:32 +0200 -Subject: [PATCH] add choices for sort option of cProfile for better output - message - ---- - Lib/cProfile.py | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/Lib/cProfile.py b/Lib/cProfile.py -index b2efd04..02acd4e 100755 ---- a/Lib/cProfile.py -+++ b/Lib/cProfile.py -@@ -161,7 +161,7 @@ def label(code): - # ____________________________________________________________ - - def main(): -- import os, sys -+ import os, pstats, sys - from optparse import OptionParser - usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..." - parser = OptionParser(usage=usage) -@@ -170,7 +170,8 @@ def main(): - help="Save stats to ", default=None) - parser.add_option('-s', '--sort', dest="sort", - help="Sort order when printing to stdout, based on pstats.Stats class", -- default=-1) -+ default=-1, -+ choices=list(pstats.Stats.sort_arg_dict_default.keys())) - - if not sys.argv[1:]: - parser.print_usage() --- -2.5.5 - diff --git a/SOURCES/00264-fix-pass-by-value-for-structs-on-aarch64.patch b/SOURCES/00264-fix-pass-by-value-for-structs-on-aarch64.patch deleted file mode 100644 index bbf431f..0000000 --- a/SOURCES/00264-fix-pass-by-value-for-structs-on-aarch64.patch +++ /dev/null @@ -1,118 +0,0 @@ -diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/ctypes/test/test_as_parameter.py -index 2a3484b..a264057 100644 ---- a/Lib/ctypes/test/test_as_parameter.py -+++ b/Lib/ctypes/test/test_as_parameter.py -@@ -169,6 +169,10 @@ class BasicWrapTestCase(unittest.TestCase): - s2h = dll.ret_2h_func(self.wrap(inp)) - self.assertEqual((s2h.x, s2h.y), (99*2, 88*3)) - -+ # Test also that the original struct was unmodified (i.e. was passed by -+ # value) -+ self.assertEqual((inp.x, inp.y), (99, 88)) -+ - def test_struct_return_8H(self): - class S8I(Structure): - _fields_ = [("a", c_int), -diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py -index 3eded77..3265996 100644 ---- a/Lib/ctypes/test/test_structures.py -+++ b/Lib/ctypes/test/test_structures.py -@@ -414,6 +414,28 @@ class StructureTestCase(unittest.TestCase): - self.assertEqual(s.second, 0xcafebabe) - self.assertEqual(s.third, 0x0bad1dea) - -+ def test_pass_by_value_in_register(self): -+ class X(Structure): -+ _fields_ = [ -+ ('first', c_uint), -+ ('second', c_uint) -+ ] -+ -+ s = X() -+ s.first = 0xdeadbeef -+ s.second = 0xcafebabe -+ dll = CDLL(_ctypes_test.__file__) -+ func = dll._testfunc_reg_struct_update_value -+ func.argtypes = (X,) -+ func.restype = None -+ func(s) -+ self.assertEqual(s.first, 0xdeadbeef) -+ self.assertEqual(s.second, 0xcafebabe) -+ got = X.in_dll(dll, "last_tfrsuv_arg") -+ self.assertEqual(s.first, got.first) -+ self.assertEqual(s.second, got.second) -+ -+ - class PointerMemberTestCase(unittest.TestCase): - - def test(self): -diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c -index 59d56d0..1963f57 100644 ---- a/Modules/_ctypes/_ctypes_test.c -+++ b/Modules/_ctypes/_ctypes_test.c -@@ -57,6 +57,24 @@ _testfunc_large_struct_update_value(Test in) - ((volatile Test *)&in)->third = 0x0badf00d; - } - -+typedef struct { -+ unsigned int first; -+ unsigned int second; -+} TestReg; -+ -+ -+EXPORT(TestReg) last_tfrsuv_arg; -+ -+ -+EXPORT(void) -+_testfunc_reg_struct_update_value(TestReg in) -+{ -+ last_tfrsuv_arg = in; -+ ((volatile TestReg *)&in)->first = 0x0badf00d; -+ ((volatile TestReg *)&in)->second = 0x0badf00d; -+} -+ -+ - EXPORT(void)testfunc_array(int values[4]) - { - printf("testfunc_array %d %d %d %d\n", -diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c -index 7d542fb..bc41433 100644 ---- a/Modules/_ctypes/callproc.c -+++ b/Modules/_ctypes/callproc.c -@@ -1040,6 +1040,13 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) - } - #endif - -+#if (defined(__x86_64__) && (defined(__MINGW64__) || defined(__CYGWIN__))) || \ -+ defined(__aarch64__) -+#define CTYPES_PASS_BY_REF_HACK -+#define POW2(x) (((x & ~(x - 1)) == x) ? x : 0) -+#define IS_PASS_BY_REF(x) (x > 8 || !POW2(x)) -+#endif -+ - /* - * Requirements, must be ensured by the caller: - * - argtuple is tuple of arguments -@@ -1137,8 +1144,20 @@ PyObject *_ctypes_callproc(PPROC pProc, - } - for (i = 0; i < argcount; ++i) { - atypes[i] = args[i].ffi_type; -- if (atypes[i]->type == FFI_TYPE_STRUCT -- ) -+#ifdef CTYPES_PASS_BY_REF_HACK -+ size_t size = atypes[i]->size; -+ if (IS_PASS_BY_REF(size)) { -+ void *tmp = alloca(size); -+ if (atypes[i]->type == FFI_TYPE_STRUCT) -+ memcpy(tmp, args[i].value.p, size); -+ else -+ memcpy(tmp, (void*)&args[i].value, size); -+ -+ avalues[i] = tmp; -+ } -+ else -+#endif -+ if (atypes[i]->type == FFI_TYPE_STRUCT) - avalues[i] = (void *)args[i].value.p; - else - avalues[i] = (void *)&args[i].value; diff --git a/SOURCES/00277-fix-test-subprocess-hanging-tests.patch b/SOURCES/00277-fix-test-subprocess-hanging-tests.patch deleted file mode 100644 index c9b54e2..0000000 --- a/SOURCES/00277-fix-test-subprocess-hanging-tests.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 54849962eacc38f4e6c6f8a72ae258b3e7c2ecd5 Mon Sep 17 00:00:00 2001 -From: Victor Stinner -Date: Thu, 5 Oct 2017 15:05:30 +0200 -Subject: [PATCH] bpo-31178: Mock os.waitpid() in test_subprocess - -Fix test_exception_errpipe_bad_data() and -test_exception_errpipe_normal() of test_subprocess: mock os.waitpid() -to avoid calling the real os.waitpid(0, 0) which is an unexpected -side effect of the test. ---- - Lib/test/test_subprocess.py | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py -index 00dc37bc2c7..3ba5c028517 100644 ---- a/Lib/test/test_subprocess.py -+++ b/Lib/test/test_subprocess.py -@@ -1559,8 +1559,10 @@ def proper_error(*args): - - fork_exec.side_effect = proper_error - -- with self.assertRaises(IsADirectoryError): -- self.PopenNoDestructor(["non_existent_command"]) -+ with mock.patch("subprocess.os.waitpid", -+ side_effect=ChildProcessError): -+ with self.assertRaises(IsADirectoryError): -+ self.PopenNoDestructor(["non_existent_command"]) - - @mock.patch("subprocess._posixsubprocess.fork_exec") - def test_exception_errpipe_bad_data(self, fork_exec): -@@ -1577,8 +1579,10 @@ def bad_error(*args): - - fork_exec.side_effect = bad_error - -- with self.assertRaises(subprocess.SubprocessError) as e: -- self.PopenNoDestructor(["non_existent_command"]) -+ with mock.patch("subprocess.os.waitpid", -+ side_effect=ChildProcessError): -+ with self.assertRaises(subprocess.SubprocessError) as e: -+ self.PopenNoDestructor(["non_existent_command"]) - - self.assertIn(repr(error_data), str(e.exception)) - diff --git a/SOURCES/00278-skip-test-sha256.patch b/SOURCES/00278-skip-test-sha256.patch deleted file mode 100644 index 9178c43..0000000 --- a/SOURCES/00278-skip-test-sha256.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py -index b2178ba..d53a5bb 100644 ---- a/Lib/test/test_socket.py -+++ b/Lib/test/test_socket.py -@@ -5415,7 +5415,7 @@ class LinuxKernelCryptoAPI(unittest.TestCase): - raise unittest.SkipTest(str(e), typ, name) - else: - return sock -- -+ @unittest.skip("Skip on ppc64le") - def test_sha256(self): - expected = bytes.fromhex("ba7816bf8f01cfea414140de5dae2223b00361a396" - "177a9cb410ff61f20015ad") diff --git a/SOURCES/00320-CVE-2019-9636.patch b/SOURCES/00320-CVE-2019-9636.patch deleted file mode 100644 index 2d7ac26..0000000 --- a/SOURCES/00320-CVE-2019-9636.patch +++ /dev/null @@ -1,153 +0,0 @@ -From c503f6d00aa4d1a75045999dee854b25fa746418 Mon Sep 17 00:00:00 2001 -From: Steve Dower -Date: Mon, 11 Mar 2019 21:34:03 -0700 -Subject: [PATCH] bpo-36216: Add check for characters in netloc that normalize - to separators (GH-12201) (GH-12215) - ---- - Doc/library/urllib.parse.rst | 18 +++++++++++++++ - Lib/test/test_urlparse.py | 23 +++++++++++++++++++ - Lib/urllib/parse.py | 17 ++++++++++++++ - .../2019-03-06-09-38-40.bpo-36216.6q1m4a.rst | 3 +++ - 4 files changed, 61 insertions(+) - create mode 100644 Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst - -diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst -index 1cc69e6..94407fa 100644 ---- a/Doc/library/urllib.parse.rst -+++ b/Doc/library/urllib.parse.rst -@@ -121,6 +121,11 @@ or on combining URL components into a URL string. - Unmatched square brackets in the :attr:`netloc` attribute will raise a - :exc:`ValueError`. - -+ Characters in the :attr:`netloc` attribute that decompose under NFKC -+ normalization (as used by the IDNA encoding) into any of ``/``, ``?``, -+ ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is -+ decomposed before parsing, no error will be raised. -+ - .. versionchanged:: 3.2 - Added IPv6 URL parsing capabilities. - -@@ -133,6 +138,10 @@ or on combining URL components into a URL string. - Out-of-range port numbers now raise :exc:`ValueError`, instead of - returning :const:`None`. - -+ .. versionchanged:: 3.6.9 -+ Characters that affect netloc parsing under NFKC normalization will -+ now raise :exc:`ValueError`. -+ - - .. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace') - -@@ -242,10 +251,19 @@ or on combining URL components into a URL string. - Unmatched square brackets in the :attr:`netloc` attribute will raise a - :exc:`ValueError`. - -+ Characters in the :attr:`netloc` attribute that decompose under NFKC -+ normalization (as used by the IDNA encoding) into any of ``/``, ``?``, -+ ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is -+ decomposed before parsing, no error will be raised. -+ - .. versionchanged:: 3.6 - Out-of-range port numbers now raise :exc:`ValueError`, instead of - returning :const:`None`. - -+ .. versionchanged:: 3.6.9 -+ Characters that affect netloc parsing under NFKC normalization will -+ now raise :exc:`ValueError`. -+ - - .. function:: urlunsplit(parts) - -diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py -index e5f6130..16f40f2 100644 ---- a/Lib/test/test_urlparse.py -+++ b/Lib/test/test_urlparse.py -@@ -1,3 +1,5 @@ -+import sys -+import unicodedata - import unittest - import urllib.parse - -@@ -968,6 +970,27 @@ class UrlParseTestCase(unittest.TestCase): - expected.append(name) - self.assertCountEqual(urllib.parse.__all__, expected) - -+ def test_urlsplit_normalization(self): -+ # Certain characters should never occur in the netloc, -+ # including under normalization. -+ # Ensure that ALL of them are detected and cause an error -+ illegal_chars = '/:#?@' -+ hex_chars = {'{:04X}'.format(ord(c)) for c in illegal_chars} -+ denorm_chars = [ -+ c for c in map(chr, range(128, sys.maxunicode)) -+ if (hex_chars & set(unicodedata.decomposition(c).split())) -+ and c not in illegal_chars -+ ] -+ # Sanity check that we found at least one such character -+ self.assertIn('\u2100', denorm_chars) -+ self.assertIn('\uFF03', denorm_chars) -+ -+ for scheme in ["http", "https", "ftp"]: -+ for c in denorm_chars: -+ url = "{}://netloc{}false.netloc/path".format(scheme, c) -+ with self.subTest(url=url, char='{:04X}'.format(ord(c))): -+ with self.assertRaises(ValueError): -+ urllib.parse.urlsplit(url) - - class Utility_Tests(unittest.TestCase): - """Testcase to test the various utility functions in the urllib.""" -diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py -index 3cab2d1..539987b 100644 ---- a/Lib/urllib/parse.py -+++ b/Lib/urllib/parse.py -@@ -389,6 +389,21 @@ def _splitnetloc(url, start=0): - delim = min(delim, wdelim) # use earliest delim position - return url[start:delim], url[delim:] # return (domain, rest) - -+def _checknetloc(netloc): -+ if not netloc or not any(ord(c) > 127 for c in netloc): -+ return -+ # looking for characters like \u2100 that expand to 'a/c' -+ # IDNA uses NFKC equivalence, so normalize for this check -+ import unicodedata -+ netloc2 = unicodedata.normalize('NFKC', netloc) -+ if netloc == netloc2: -+ return -+ _, _, netloc = netloc.rpartition('@') # anything to the left of '@' is okay -+ for c in '/?#@:': -+ if c in netloc2: -+ raise ValueError("netloc '" + netloc2 + "' contains invalid " + -+ "characters under NFKC normalization") -+ - def urlsplit(url, scheme='', allow_fragments=True): - """Parse a URL into 5 components: - :///?# -@@ -418,6 +433,7 @@ def urlsplit(url, scheme='', allow_fragments=True): - url, fragment = url.split('#', 1) - if '?' in url: - url, query = url.split('?', 1) -+ _checknetloc(netloc) - v = SplitResult(scheme, netloc, url, query, fragment) - _parse_cache[key] = v - return _coerce_result(v) -@@ -441,6 +457,7 @@ def urlsplit(url, scheme='', allow_fragments=True): - url, fragment = url.split('#', 1) - if '?' in url: - url, query = url.split('?', 1) -+ _checknetloc(netloc) - v = SplitResult(scheme, netloc, url, query, fragment) - _parse_cache[key] = v - return _coerce_result(v) -diff --git a/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst b/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst -new file mode 100644 -index 0000000..5546394 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst -@@ -0,0 +1,3 @@ -+Changes urlsplit() to raise ValueError when the URL contains characters that -+decompose under IDNA encoding (NFKC-normalization) into characters that -+affect how the URL is parsed. --- -2.20.1 - diff --git a/SOURCES/00332-CVE-2019-16056.patch b/SOURCES/00332-CVE-2019-16056.patch new file mode 100644 index 0000000..ca2e3d4 --- /dev/null +++ b/SOURCES/00332-CVE-2019-16056.patch @@ -0,0 +1,95 @@ +diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py +index 737951e4b1b1..bc9c9b6241d4 100644 +--- a/Lib/email/_header_value_parser.py ++++ b/Lib/email/_header_value_parser.py +@@ -1561,6 +1561,8 @@ def get_domain(value): + token, value = get_dot_atom(value) + except errors.HeaderParseError: + token, value = get_atom(value) ++ if value and value[0] == '@': ++ raise errors.HeaderParseError('Invalid Domain') + if leader is not None: + token[:0] = [leader] + domain.append(token) +diff --git a/Lib/email/_parseaddr.py b/Lib/email/_parseaddr.py +index cdfa3729adc7..41ff6f8c000d 100644 +--- a/Lib/email/_parseaddr.py ++++ b/Lib/email/_parseaddr.py +@@ -379,7 +379,12 @@ def getaddrspec(self): + aslist.append('@') + self.pos += 1 + self.gotonext() +- return EMPTYSTRING.join(aslist) + self.getdomain() ++ domain = self.getdomain() ++ if not domain: ++ # Invalid domain, return an empty address instead of returning a ++ # local part to denote failed parsing. ++ return EMPTYSTRING ++ return EMPTYSTRING.join(aslist) + domain + + def getdomain(self): + """Get the complete domain name from an address.""" +@@ -394,6 +399,10 @@ def getdomain(self): + elif self.field[self.pos] == '.': + self.pos += 1 + sdlist.append('.') ++ elif self.field[self.pos] == '@': ++ # bpo-34155: Don't parse domains with two `@` like ++ # `a@malicious.org@important.com`. ++ return EMPTYSTRING + elif self.field[self.pos] in self.atomends: + break + else: +diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py +index a2c900fa7fd2..02ef3e1006c6 100644 +--- a/Lib/test/test_email/test__header_value_parser.py ++++ b/Lib/test/test_email/test__header_value_parser.py +@@ -1418,6 +1418,16 @@ def test_get_addr_spec_dot_atom(self): + self.assertEqual(addr_spec.domain, 'example.com') + self.assertEqual(addr_spec.addr_spec, 'star.a.star@example.com') + ++ def test_get_addr_spec_multiple_domains(self): ++ with self.assertRaises(errors.HeaderParseError): ++ parser.get_addr_spec('star@a.star@example.com') ++ ++ with self.assertRaises(errors.HeaderParseError): ++ parser.get_addr_spec('star@a@example.com') ++ ++ with self.assertRaises(errors.HeaderParseError): ++ parser.get_addr_spec('star@172.17.0.1@example.com') ++ + # get_obs_route + + def test_get_obs_route_simple(self): +diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py +index f97ccc6711cc..68d052279987 100644 +--- a/Lib/test/test_email/test_email.py ++++ b/Lib/test/test_email/test_email.py +@@ -3035,6 +3035,20 @@ def test_parseaddr_empty(self): + self.assertEqual(utils.parseaddr('<>'), ('', '')) + self.assertEqual(utils.formataddr(utils.parseaddr('<>')), '') + ++ def test_parseaddr_multiple_domains(self): ++ self.assertEqual( ++ utils.parseaddr('a@b@c'), ++ ('', '') ++ ) ++ self.assertEqual( ++ utils.parseaddr('a@b.c@c'), ++ ('', '') ++ ) ++ self.assertEqual( ++ utils.parseaddr('a@172.17.0.1@c'), ++ ('', '') ++ ) ++ + def test_noquote_dump(self): + self.assertEqual( + utils.formataddr(('A Silly Person', 'person@dom.ain')), +diff --git a/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst b/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst +new file mode 100644 +index 000000000000..50292e29ed1d +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst +@@ -0,0 +1 @@ ++Fix parsing of invalid email addresses with more than one ``@`` (e.g. a@b@c.com.) to not return the part before 2nd ``@`` as valid email address. Patch by maxking & jpic. diff --git a/SPECS/python.spec b/SPECS/python.spec index 5c8e43e..fb733b8 100644 --- a/SPECS/python.spec +++ b/SPECS/python.spec @@ -130,8 +130,8 @@ # ================== Summary: Version 3 of the Python programming language aka Python 3000 Name: %{?scl_prefix}python -Version: %{pybasever}.3 -Release: 7%{?dist} +Version: %{pybasever}.9 +Release: 2%{?dist} License: Python Group: Development/Languages @@ -410,12 +410,6 @@ Patch205: 00205-make-libpl-respect-lib64.patch # by debian but fedora infra uses only eabi without hf Patch206: 00206-remove-hf-from-arm-triplet.patch -# 00231 # -# Add choices for sort option of cProfile for better output message -# http://bugs.python.org/issue23420 -# Resolves: rhbz#1326287 -Patch231: 00231-cprofile-sort-option.patch - # 00243 # # Fix the triplet used on 64-bit MIPS # rhbz#1322526: https://bugzilla.redhat.com/show_bug.cgi?id=1322526 @@ -423,33 +417,15 @@ Patch231: 00231-cprofile-sort-option.patch # Fedora needs the default mips64-linux-gnu Patch243: 00243-fix-mips64-triplet.patch -# 00264 # -# Fix pass by value for structs on 64-bit Cygwin/MinGW/aarch64 -# Fixed upstream: http://bugs.python.org/issue29804 -Patch264: 00264-fix-pass-by-value-for-structs-on-aarch64.patch - -# 00277 # -# Fix test_exception_errpipe_bad_data() and -# test_exception_errpipe_normal() of test_subprocess: mock os.waitpid() -# to avoid calling the real os.waitpid(0, 0) which is an unexpected -# side effect of the test, which makes the brew builds hang. -Patch277: 00277-fix-test-subprocess-hanging-tests.patch - -# 00278 # -# skip test_sha256 from test_socket, as it relies on the implementation -# of kernel's crypto API and the behaviour is not consistent for powerpc -# architectures, making the test fail. -# Reported upstream: https://bugs.python.org/issue31705 -Patch278: 00278-skip-test-sha256.patch +# 00332 # +# Fix CVE-2019-16056: Don't parse email addresses containing +# multiple '@' characters. +# Fixed upstream: https://bugs.python.org/issue34155 +# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1750829 +Patch332: 00332-CVE-2019-16056.patch Patch300: 00300-change-so-version-scl.patch -# 00320 # -# Security fix for CVE-2019-9636: Information Disclosure due to urlsplit improper NFKC normalization -# FIXED UPSTREAM: https://bugs.python.org/issue36216 -# Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689322 -Patch320: 00320-CVE-2019-9636.patch - # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -660,16 +636,8 @@ sed -r -i s/'_PIP_VERSION = "[0-9.]+"'/'_PIP_VERSION = "%{pip_version}"'/ Lib/en %patch205 -p1 %patch206 -p1 -%patch231 -p1 %patch243 -p1 -%patch264 -p1 -%patch277 -p1 - -%ifarch %{power64} -%patch278 -p1 -%endif - -%patch320 -p1 +%patch332 -p1 cat %{PATCH300} | sed -e "s/__SCL_NAME__/%{?scl}/" \ | patch -p1 @@ -1637,9 +1605,17 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Wed Sep 11 2019 Charalampos Stratakis - 3.6.9-2 +- Security fix for CVE-2019-16056 +Resolves: rhbz#1750829 + +* Fri Aug 02 2019 Charalampos Stratakis - 3.6.9-1 +- Update to version 3.6.9 +Resolves: rhbz#1709344 + * Tue Apr 09 2019 Tomas Orsava - 3.6.3-7 - Security fix for CVE-2019-9636 -Resolves: rhbz#1689322 +Resolves: rhbz#1689323 * Thu May 31 2018 Kalev Lember - 3.6.3-6 - Rebuild with tests and rewheel.