diff --git a/SOURCES/00221-pep466-backport-sslwrap-c-ssl.patch b/SOURCES/00221-pep466-backport-sslwrap-c-ssl.patch deleted file mode 100644 index 358b40a..0000000 --- a/SOURCES/00221-pep466-backport-sslwrap-c-ssl.patch +++ /dev/null @@ -1,384 +0,0 @@ -diff -up Python-2.7.5/Modules/_ssl.c.wrap Python-2.7.5/Modules/_ssl.c ---- Python-2.7.5/Modules/_ssl.c.wrap 2015-06-25 09:09:59.646325880 +0200 -+++ Python-2.7.5/Modules/_ssl.c 2015-06-25 10:33:20.349273370 +0200 -@@ -224,6 +224,19 @@ typedef struct { - enum py_ssl_server_or_client socket_type; - } PySSLSocket; - -+typedef struct { -+ PyObject_HEAD -+ PySocketSockObject *Socket; /* Socket on which we're layered */ -+ PySSLContext* ctx; -+ SSL* ssl; -+ X509* peer_cert; -+ char server[X509_NAME_MAXLEN]; -+ char issuer[X509_NAME_MAXLEN]; -+ int shutdown_seen_zero; -+ -+} PySSLObject; -+ -+static PyTypeObject PySSL_Type; - static PyTypeObject PySSLContext_Type; - static PyTypeObject PySSLSocket_Type; - -@@ -455,6 +468,138 @@ _setSSLError (char *errstr, int errcode, - * SSL objects - */ - -+static PyObject * -+context_new_args(PyTypeObject *type, int proto_version); -+ -+static PyObject * -+load_cert_chain_args(PySSLContext *self, char *certfile_bytes, char *keyfile_bytes, PyObject *password); -+ -+static PyObject * -+set_ciphers_args(PySSLContext *self, const char *cipherlist); -+ -+static PyObject * -+load_verify_locations_args(PySSLContext *self, PyObject *cafile, PyObject *capath, PyObject *cadata); -+ -+static int -+set_verify_mode_args(PySSLContext *self, int n); -+ -+static PySSLObject * -+newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file, -+ enum py_ssl_server_or_client socket_type, -+ enum py_ssl_cert_requirements certreq, -+ enum py_ssl_version proto_version, -+ PyObject *cacerts_file, const char *ciphers) -+{ -+ PySSLObject *self; -+ char *errstr = NULL; -+ SSL_CTX *ctx = NULL; -+ -+ -+ self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */ -+ if (self == NULL) -+ return NULL; -+ memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN); -+ memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN); -+ -+ self->peer_cert = NULL; -+ self->ssl = NULL; -+ self->ctx = NULL; -+ self->Socket = NULL; -+ self->shutdown_seen_zero = 0; -+ -+ /* Make sure the SSL error state is initialized */ -+ (void) ERR_get_state(); -+ ERR_clear_error(); -+ -+ if ((socket_type == PY_SSL_SERVER) && -+ ((key_file == NULL) || (cert_file == NULL))) { -+ errstr = ERRSTR("Both the key & certificate files " -+ "must be specified for server-side operation"); -+ goto fail; -+ } -+ -+ -+ if ((key_file && !cert_file) || (!key_file && cert_file)) { -+ errstr = ERRSTR("Both the key & certificate files " -+ "must be specified"); -+ goto fail; -+ } -+ -+ -+ PyObject *sslctx = context_new_args(&PySSLContext_Type, proto_version); -+ if ((sslctx != NULL) && (PyObject_TypeCheck(sslctx, &PySSLContext_Type))) { -+#if !HAVE_SNI -+ errstr = ERRSTR("setting a socket's " -+ "context is not supported by your OpenSSL library"); -+ goto fail; -+#else -+ self->ctx = (PySSLContext *) sslctx; -+ ctx = self->ctx->ctx; -+#endif -+ } else { -+ errstr = ERRSTR("The value must be a SSLContext"); -+ goto fail; -+ } -+ -+ if (key_file) { -+ load_cert_chain_args(self->ctx, cert_file, key_file, NULL); -+ } -+ -+ if (ciphers != NULL) { -+ set_ciphers_args(self->ctx, ciphers); -+ } -+ -+ -+ -+ if (certreq != PY_SSL_CERT_NONE) { -+ if (cacerts_file == Py_None) { -+ errstr = ERRSTR("No root certificates specified for " -+ "verification of other-side certificates."); -+ goto fail; -+ } else { -+ load_verify_locations_args(self->ctx, cacerts_file, NULL, NULL); -+ } -+ } -+ -+ /* ssl compatibility */ -+ SSL_CTX_set_options(ctx, -+ SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); -+ -+ set_verify_mode_args(self->ctx, certreq); -+ -+ PySSL_BEGIN_ALLOW_THREADS -+ self->ssl = SSL_new(ctx); /* New ssl struct */ -+ PySSL_END_ALLOW_THREADS -+ SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */ -+#ifdef SSL_MODE_AUTO_RETRY -+ SSL_set_mode(self->ssl, SSL_MODE_AUTO_RETRY); -+#endif -+ -+ /* If the socket is in non-blocking mode or timeout mode, set the BIO -+ * to non-blocking mode (blocking is the default) -+ */ -+ if (Sock->sock_timeout >= 0.0) { -+ /* Set both the read and write BIO's to non-blocking mode */ -+ BIO_set_nbio(SSL_get_rbio(self->ssl), 1); -+ BIO_set_nbio(SSL_get_wbio(self->ssl), 1); -+ } -+ PySSL_BEGIN_ALLOW_THREADS -+ if (socket_type == PY_SSL_CLIENT) -+ SSL_set_connect_state(self->ssl); -+ else -+ SSL_set_accept_state(self->ssl); -+ PySSL_END_ALLOW_THREADS -+ -+ self->Socket = Sock; -+ Py_INCREF(self->Socket); -+ return self; -+ fail: -+ if (errstr) -+ PyErr_SetString(PySSLErrorObject, errstr); -+ Py_DECREF(self); -+ return NULL; -+} -+ - static PySSLSocket * - newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, - enum py_ssl_server_or_client socket_type, -@@ -526,6 +671,47 @@ newPySSLSocket(PySSLContext *sslctx, PyS - } - - -+ -+ -+static PyObject * -+PySSL_sslwrap(PyObject *self, PyObject *args) -+{ -+ PySocketSockObject *Sock; -+ int server_side = 0; -+ int verification_mode = PY_SSL_CERT_NONE; -+ int protocol = PY_SSL_VERSION_SSL23; -+ char *key_file = NULL; -+ char *cert_file = NULL; -+ PyObject *cacerts_file; -+ const char *ciphers = NULL; -+ -+ if (!PyArg_ParseTuple(args, "O!i|zziizz:sslwrap", -+ PySocketModule.Sock_Type, -+ &Sock, -+ &server_side, -+ &key_file, &cert_file, -+ &verification_mode, &protocol, -+ &cacerts_file, &ciphers)) -+ return NULL; -+ -+ /* -+ fprintf(stderr, -+ "server_side is %d, keyfile %p, certfile %p, verify_mode %d, " -+ "protocol %d, certs %p\n", -+ server_side, key_file, cert_file, verification_mode, -+ protocol, cacerts_file); -+ */ -+ -+ return (PyObject *) newPySSLObject(Sock, key_file, cert_file, -+ server_side, verification_mode, -+ protocol, cacerts_file, -+ ciphers); -+} -+ -+PyDoc_STRVAR(ssl_doc, -+"sslwrap(socket, server_side, [keyfile, certfile, certs_mode, protocol,\n" -+" cacertsfile, ciphers]) -> sslobject"); -+ - /* SSL object methods */ - - static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) -@@ -1922,6 +2108,11 @@ static PyMethodDef PySSLMethods[] = { - {NULL, NULL} - }; - -+static PyObject *PySSL_getattr(PySSLObject *self, char *name) -+{ -+ return Py_FindMethod(PySSLMethods, (PyObject *)self, name); -+} -+ - static PyTypeObject PySSLSocket_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl._SSLSocket", /*tp_name*/ -@@ -1956,25 +2147,49 @@ static PyTypeObject PySSLSocket_Type = { - ssl_getsetlist, /*tp_getset*/ - }; - -+static PyTypeObject PySSL_Type = { -+ PyVarObject_HEAD_INIT(NULL, 0) -+ "ssl.SSLContext", /*tp_name*/ -+ sizeof(PySSLObject), /*tp_basicsize*/ -+ 0, /*tp_itemsize*/ -+ /* methods */ -+ (destructor)PySSL_dealloc, /*tp_dealloc*/ -+ 0, /*tp_print*/ -+ (getattrfunc)PySSL_getattr, /*tp_getattr*/ -+ 0, /*tp_setattr*/ -+ 0, /*tp_compare*/ -+ 0, /*tp_repr*/ -+ 0, /*tp_as_number*/ -+ 0, /*tp_as_sequence*/ -+ 0, /*tp_as_mapping*/ -+ 0, /*tp_hash*/ -+}; -+ - - /* - * _SSLContext objects - */ - -+ - static PyObject * - context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) - { - char *kwlist[] = {"protocol", NULL}; -- PySSLContext *self; - int proto_version = PY_SSL_VERSION_SSL23; -- long options; -- SSL_CTX *ctx = NULL; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "i:_SSLContext", kwlist, - &proto_version)) - return NULL; -+ return context_new_args(type, proto_version); -+} - -+static PyObject * -+context_new_args(PyTypeObject *type, int proto_version) -+{ -+ SSL_CTX *ctx = NULL; -+ PySSLContext *self; -+ long options; - PySSL_BEGIN_ALLOW_THREADS - if (proto_version == PY_SSL_VERSION_TLS1) - ctx = SSL_CTX_new(TLSv1_method()); -@@ -2082,11 +2297,16 @@ context_dealloc(PySSLContext *self) - static PyObject * - set_ciphers(PySSLContext *self, PyObject *args) - { -- int ret; - const char *cipherlist; - - if (!PyArg_ParseTuple(args, "s:set_ciphers", &cipherlist)) - return NULL; -+ return set_ciphers_args(self, cipherlist); -+ } -+ -+static PyObject * -+set_ciphers_args(PySSLContext *self, const char *cipherlist){ -+ int ret; - ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); - if (ret == 0) { - /* Clearing the error queue is necessary on some OpenSSL versions, -@@ -2204,9 +2424,17 @@ get_verify_mode(PySSLContext *self, void - static int - set_verify_mode(PySSLContext *self, PyObject *arg, void *c) - { -- int n, mode; -+ int n; - if (!PyArg_Parse(arg, "i", &n)) - return -1; -+ return set_verify_mode_args(self, n); -+ } -+ -+static int -+set_verify_mode_args(PySSLContext *self, int n) -+{ -+ int mode; -+ - if (n == PY_SSL_CERT_NONE) - mode = SSL_VERIFY_NONE; - else if (n == PY_SSL_CERT_OPTIONAL) -@@ -2434,10 +2662,6 @@ load_cert_chain(PySSLContext *self, PyOb - char *kwlist[] = {"certfile", "keyfile", "password", NULL}; - PyObject *password = NULL; - char *certfile_bytes = NULL, *keyfile_bytes = NULL; -- pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback; -- void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata; -- _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; -- int r; - - errno = 0; - ERR_clear_error(); -@@ -2447,6 +2671,17 @@ load_cert_chain(PySSLContext *self, PyOb - Py_FileSystemDefaultEncoding, &keyfile_bytes, - &password)) - return NULL; -+ return load_cert_chain_args(self, certfile_bytes, keyfile_bytes, password); -+ } -+ -+static PyObject * -+load_cert_chain_args(PySSLContext *self, char *certfile_bytes, char *keyfile_bytes ,PyObject *password){ -+ -+ pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback; -+ void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata; -+ _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; -+ int r; -+ - if (password && password != Py_None) { - if (PyCallable_Check(password)) { - pw_info.callable = password; -@@ -2598,22 +2833,27 @@ _add_ca_certs(PySSLContext *self, void * - return retval; - } - -- - static PyObject * - load_verify_locations(PySSLContext *self, PyObject *args, PyObject *kwds) - { - char *kwlist[] = {"cafile", "capath", "cadata", NULL}; - PyObject *cadata = NULL, *cafile = NULL, *capath = NULL; -- PyObject *cafile_bytes = NULL, *capath_bytes = NULL; -- const char *cafile_buf = NULL, *capath_buf = NULL; -- int r = 0, ok = 1; -- -- errno = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|OOO:load_verify_locations", kwlist, - &cafile, &capath, &cadata)) - return NULL; -+ return load_verify_locations_args(self, cafile, capath, cadata); -+ } -+ - -+static PyObject * -+load_verify_locations_args(PySSLContext *self, PyObject *cafile, PyObject *capath, PyObject *cadata) -+{ -+ PyObject *cafile_bytes = NULL, *capath_bytes = NULL; -+ const char *cafile_buf = NULL, *capath_buf = NULL; -+ int r = 0, ok = 1; -+ -+ errno = 0; - if (cafile == Py_None) - cafile = NULL; - if (capath == Py_None) -@@ -3688,6 +3928,8 @@ PySSL_enum_crls(PyObject *self, PyObject - /* List of functions exported by this module. */ - - static PyMethodDef PySSL_methods[] = { -+ {"sslwrap", PySSL_sslwrap, -+ METH_VARARGS, ssl_doc}, - {"_test_decode_cert", PySSL_test_decode_certificate, - METH_VARARGS}, - #ifdef HAVE_OPENSSL_RAND diff --git a/SOURCES/00227-accept-none-keyfile-loadcertchain.patch b/SOURCES/00227-accept-none-keyfile-loadcertchain.patch index 2946b81..39d9073 100644 --- a/SOURCES/00227-accept-none-keyfile-loadcertchain.patch +++ b/SOURCES/00227-accept-none-keyfile-loadcertchain.patch @@ -1,51 +1,29 @@ -diff -up Python-2.7.5/Modules/_ssl.c.none Python-2.7.5/Modules/_ssl.c ---- Python-2.7.5/Modules/_ssl.c.none 2015-08-06 10:41:14.091782344 +0200 -+++ Python-2.7.5/Modules/_ssl.c 2015-08-06 11:02:49.010193679 +0200 -@@ -472,7 +472,7 @@ static PyObject * - context_new_args(PyTypeObject *type, int proto_version); - - static PyObject * --load_cert_chain_args(PySSLContext *self, char *certfile_bytes, char *keyfile_bytes, PyObject *password); -+load_cert_chain_args(PySSLContext *self, char *certfile_bytes, PyObject *keyfile, PyObject *password); - - static PyObject * - set_ciphers_args(PySSLContext *self, const char *cipherlist); -@@ -484,7 +484,7 @@ static int - set_verify_mode_args(PySSLContext *self, int n); - - static PySSLObject * --newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file, -+newPySSLObject(PySocketSockObject *Sock, PyObject *key_file, char *cert_file, - enum py_ssl_server_or_client socket_type, - enum py_ssl_cert_requirements certreq, - enum py_ssl_version proto_version, -@@ -512,7 +512,7 @@ newPySSLObject(PySocketSockObject *Sock, - ERR_clear_error(); - - if ((socket_type == PY_SSL_SERVER) && -- ((key_file == NULL) || (cert_file == NULL))) { -+ ((key_file == Py_None) || (cert_file == NULL) || (key_file == NULL))) { - errstr = ERRSTR("Both the key & certificate files " - "must be specified for server-side operation"); - goto fail; -@@ -680,7 +680,7 @@ PySSL_sslwrap(PyObject *self, PyObject * - int server_side = 0; - int verification_mode = PY_SSL_CERT_NONE; - int protocol = PY_SSL_VERSION_SSL23; -- char *key_file = NULL; -+ PyObject *key_file = NULL; - char *cert_file = NULL; - PyObject *cacerts_file; - const char *ciphers = NULL; -@@ -2660,22 +2660,39 @@ static PyObject * +From c1f4979e7019f6c1ce9e5a02c2e3f8ca146645bc Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Mon, 11 Jul 2016 14:20:01 +0200 +Subject: [PATCH] Allow the keyfile argument of SSLContext.load_cert_chain to + be set to None + +--- + Modules/_ssl.c | 30 +++++++++++++++++++++++------- + 1 file changed, 23 insertions(+), 7 deletions(-) + +diff --git a/Modules/_ssl.c b/Modules/_ssl.c +index 38eba1d..1786afd 100644 +--- a/Modules/_ssl.c ++++ b/Modules/_ssl.c +@@ -2445,8 +2445,8 @@ static PyObject * load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"certfile", "keyfile", "password", NULL}; - PyObject *password = NULL; - char *certfile_bytes = NULL, *keyfile_bytes = NULL; -+ PyObject *password = NULL, *keyfile = NULL; ++ PyObject *keyfile = NULL, *keyfile_bytes = NULL, *password = NULL; + char *certfile_bytes = NULL; - + pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback; + void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata; + _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; +@@ -2455,11 +2455,27 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) errno = 0; ERR_clear_error(); if (!PyArg_ParseTupleAndKeywords(args, kwds, @@ -56,15 +34,6 @@ diff -up Python-2.7.5/Modules/_ssl.c.none Python-2.7.5/Modules/_ssl.c - &password)) + &keyfile, &password)) return NULL; -- return load_cert_chain_args(self, certfile_bytes, keyfile_bytes, password); -+ return load_cert_chain_args(self, certfile_bytes, keyfile, password); - } - - static PyObject * --load_cert_chain_args(PySSLContext *self, char *certfile_bytes, char *keyfile_bytes ,PyObject *password){ -+load_cert_chain_args(PySSLContext *self, char *certfile_bytes, PyObject *keyfile ,PyObject *password){ -+ -+ PyObject *keyfile_bytes = NULL; + + if (keyfile && keyfile != Py_None) { + if (PyString_Check(keyfile)) { @@ -81,10 +50,11 @@ diff -up Python-2.7.5/Modules/_ssl.c.none Python-2.7.5/Modules/_ssl.c + goto error; + } + } - - pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback; - void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata; -@@ -2711,7 +2728,7 @@ load_cert_chain_args(PySSLContext *self, ++ + if (password && password != Py_None) { + if (PyCallable_Check(password)) { + pw_info.callable = password; +@@ -2489,7 +2505,7 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) } PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state); r = SSL_CTX_use_PrivateKey_file(self->ctx, @@ -93,7 +63,7 @@ diff -up Python-2.7.5/Modules/_ssl.c.none Python-2.7.5/Modules/_ssl.c SSL_FILETYPE_PEM); PySSL_END_ALLOW_THREADS_S(pw_info.thread_state); if (r != 1) { -@@ -2743,8 +2760,8 @@ load_cert_chain_args(PySSLContext *self, +@@ -2521,8 +2537,8 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) error: SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata); @@ -103,3 +73,6 @@ diff -up Python-2.7.5/Modules/_ssl.c.none Python-2.7.5/Modules/_ssl.c PyMem_Free(certfile_bytes); return NULL; } +-- +2.7.4 + diff --git a/SOURCES/00232-man-page-date-macro-removal.patch b/SOURCES/00232-man-page-date-macro-removal.patch new file mode 100644 index 0000000..c79aed6 --- /dev/null +++ b/SOURCES/00232-man-page-date-macro-removal.patch @@ -0,0 +1,9 @@ +diff -r 62e3b7af0697 -r db8d7f376d24 Misc/python.man +--- a/Misc/python.man Mon Mar 21 10:38:58 2016 +0100 ++++ b/Misc/python.man Mon Mar 21 13:54:28 2016 +0100 +@@ -1,4 +1,4 @@ +-.TH PYTHON "1" "$Date$" ++.TH PYTHON "1" + + .\" To view this file while editing, run it through groff: + .\" groff -Tascii -man python.man | less diff --git a/SOURCES/00233-Computed-Goto-dispatch.patch b/SOURCES/00233-Computed-Goto-dispatch.patch new file mode 100644 index 0000000..7b4c5fe --- /dev/null +++ b/SOURCES/00233-Computed-Goto-dispatch.patch @@ -0,0 +1,2274 @@ +From 66818f47df1e37b105fd42d6cbaa756c4d72393c Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Wed, 30 Mar 2016 15:54:29 +0200 +Subject: [PATCH] Computed Goto dispatch for Python2 + +--- + Include/opcode.h | 9 + + Makefile.pre.in | 15 + + Python/ceval.c | 770 +++++++++++++++++++++++++++++++------------- + Python/makeopcodetargets.py | 45 +++ + Python/opcode_targets.h | 258 +++++++++++++++ + configure | 81 +++++ + configure.ac | 51 +++ + pyconfig.h.in | 6 + + 8 files changed, 1005 insertions(+), 230 deletions(-) + +diff --git a/Include/opcode.h b/Include/opcode.h +index 9764109..9ed5487 100644 +--- a/Include/opcode.h ++++ b/Include/opcode.h +@@ -37,12 +37,21 @@ extern "C" { + + #define SLICE 30 + /* Also uses 31-33 */ ++#define SLICE_1 31 ++#define SLICE_2 32 ++#define SLICE_3 33 + + #define STORE_SLICE 40 + /* Also uses 41-43 */ ++#define STORE_SLICE_1 41 ++#define STORE_SLICE_2 42 ++#define STORE_SLICE_3 43 + + #define DELETE_SLICE 50 + /* Also uses 51-53 */ ++#define DELETE_SLICE_1 51 ++#define DELETE_SLICE_2 52 ++#define DELETE_SLICE_3 53 + + #define STORE_MAP 54 + #define INPLACE_ADD 55 +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 4ee61f6..611f63a 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -299,6 +299,16 @@ ASDLGEN= $(srcdir)/Parser/asdl_c.py + + ########################################################################## + # Python ++ ++OPCODETARGETS_H= \ ++ $(srcdir)/Python/opcode_targets.h ++ ++OPCODETARGETGEN= \ ++ $(srcdir)/Python/makeopcodetargets.py ++ ++OPCODETARGETGEN_FILES= \ ++ $(OPCODETARGETGEN) $(srcdir)/Lib/opcode.py ++ + PYTHON_OBJS= \ + Python/_warnings.o \ + Python/Python-ast.o \ +@@ -648,6 +658,11 @@ Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c \ + Objects/stringobject.o: $(srcdir)/Objects/stringobject.c \ + $(STRINGLIB_HEADERS) + ++$(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) ++ $(OPCODETARGETGEN) $(OPCODETARGETS_H) ++ ++Python/ceval.o: $(OPCODETARGETS_H) ++ + Python/formatter_unicode.o: $(srcdir)/Python/formatter_unicode.c \ + $(STRINGLIB_HEADERS) + +diff --git a/Python/ceval.c b/Python/ceval.c +index 8c6f8d7..67d1576 100644 +--- a/Python/ceval.c ++++ b/Python/ceval.c +@@ -757,6 +757,99 @@ PyEval_EvalFrame(PyFrameObject *f) { + PyObject * + PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + { ++#ifdef DYNAMIC_EXECUTION_PROFILE ++ #undef USE_COMPUTED_GOTOS ++#endif ++#ifdef HAVE_COMPUTED_GOTOS ++ #ifndef USE_COMPUTED_GOTOS ++ #define USE_COMPUTED_GOTOS 1 ++ #endif ++#else ++ #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS ++ #error "Computed gotos are not supported on this compiler." ++ #endif ++ #undef USE_COMPUTED_GOTOS ++ #define USE_COMPUTED_GOTOS 0 ++#endif ++#if USE_COMPUTED_GOTOS ++/* Import the static jump table */ ++#include "opcode_targets.h" ++ ++ /* This macro is used when several opcodes defer to the same implementation ++ (e.g. SETUP_LOOP, SETUP_FINALLY) */ ++#define TARGET_WITH_IMPL(op, impl) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ oparg = NEXTARG(); \ ++ case op: \ ++ goto impl; \ ++ ++#define TARGET_WITH_IMPL_NOARG(op, impl) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ case op: \ ++ goto impl; \ ++ ++#define TARGET_NOARG(op) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ case op: \ ++ ++#define TARGET(op) \ ++ TARGET_##op: \ ++ opcode = op; \ ++ oparg = NEXTARG(); \ ++ case op:\ ++ ++#define DISPATCH() \ ++ { \ ++ int _tick = _Py_Ticker - 1; \ ++ _Py_Ticker = _tick; \ ++ if (_tick >= 0) { \ ++ FAST_DISPATCH(); \ ++ } \ ++ continue; \ ++ } ++ ++#ifdef LLTRACE ++#define FAST_DISPATCH() \ ++ { \ ++ if (!lltrace && !_Py_TracingPossible) { \ ++ f->f_lasti = INSTR_OFFSET(); \ ++ goto *opcode_targets[*next_instr++]; \ ++ } \ ++ goto fast_next_opcode; \ ++ } ++#else ++#define FAST_DISPATCH() { \ ++ if (!_Py_TracingPossible) { \ ++ f->f_lasti = INSTR_OFFSET(); \ ++ goto *opcode_targets[*next_instr++]; \ ++ } \ ++ goto fast_next_opcode;\ ++} ++#endif ++ ++#else ++#define TARGET(op) \ ++ case op: ++#define TARGET_WITH_IMPL(op, impl) \ ++ /* silence compiler warnings about `impl` unused */ \ ++ if (0) goto impl; ++ case op:\ ++ ++#define TARGET_NOARG(op) \ ++ case op:\ ++ ++#define TARGET_WITH_IMPL_NOARG(op, impl) \ ++ if (0) goto impl; \ ++ case op:\ ++ ++#define DISPATCH() continue ++#define FAST_DISPATCH() goto fast_next_opcode ++#endif ++ ++ + #ifdef DXPAIRS + int lastopcode = 0; + #endif +@@ -874,14 +967,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + counter updates for both opcodes. + */ + +-#ifdef DYNAMIC_EXECUTION_PROFILE ++// Next opcode prediction is also enabled for Computed Gotos as well. ++#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS + #define PREDICT(op) if (0) goto PRED_##op ++#define PREDICTED(op) PRED_##op: ++#define PREDICTED_WITH_ARG(op) PRED_##op: + #else + #define PREDICT(op) if (*next_instr == op) goto PRED_##op +-#endif +- + #define PREDICTED(op) PRED_##op: next_instr++ + #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = PEEKARG(); next_instr += 3 ++#endif ++ + + /* Stack manipulation macros */ + +@@ -1179,55 +1275,71 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + + /* case STOP_CODE: this is an error! */ + +- case NOP: +- goto fast_next_opcode; ++ TARGET_NOARG(NOP) ++ { ++ FAST_DISPATCH(); ++ } ++ TARGET(LOAD_FAST) ++ { + +- case LOAD_FAST: + x = GETLOCAL(oparg); + if (x != NULL) { + Py_INCREF(x); + PUSH(x); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + format_exc_check_arg(PyExc_UnboundLocalError, + UNBOUNDLOCAL_ERROR_MSG, + PyTuple_GetItem(co->co_varnames, oparg)); + break; + +- case LOAD_CONST: ++ } ++ ++ TARGET(LOAD_CONST) ++ { + x = GETITEM(consts, oparg); + Py_INCREF(x); + PUSH(x); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + + PREDICTED_WITH_ARG(STORE_FAST); +- case STORE_FAST: ++ TARGET(STORE_FAST) ++ { + v = POP(); + SETLOCAL(oparg, v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case POP_TOP: ++ TARGET_NOARG(POP_TOP) ++ { + v = POP(); + Py_DECREF(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case ROT_TWO: ++ TARGET_NOARG(ROT_TWO) ++ { + v = TOP(); + w = SECOND(); + SET_TOP(w); + SET_SECOND(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case ROT_THREE: ++ TARGET_NOARG(ROT_THREE) ++ { + v = TOP(); + w = SECOND(); + x = THIRD(); + SET_TOP(w); + SET_SECOND(x); + SET_THIRD(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case ROT_FOUR: ++ TARGET_NOARG(ROT_FOUR) ++ { + u = TOP(); + v = SECOND(); + w = THIRD(); +@@ -1236,15 +1348,19 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + SET_SECOND(w); + SET_THIRD(x); + SET_FOURTH(u); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case DUP_TOP: ++ TARGET_NOARG(DUP_TOP) ++ { + v = TOP(); + Py_INCREF(v); + PUSH(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + +- case DUP_TOPX: ++ TARGET(DUP_TOPX) ++ { + if (oparg == 2) { + x = TOP(); + Py_INCREF(x); +@@ -1253,7 +1369,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + STACKADJ(2); + SET_TOP(x); + SET_SECOND(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } else if (oparg == 3) { + x = TOP(); + Py_INCREF(x); +@@ -1265,84 +1381,100 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + SET_TOP(x); + SET_SECOND(w); + SET_THIRD(v); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + Py_FatalError("invalid argument to DUP_TOPX" + " (bytecode corruption?)"); + /* Never returns, so don't bother to set why. */ + break; ++ } + +- case UNARY_POSITIVE: ++ TARGET_NOARG(UNARY_POSITIVE) ++ { + v = TOP(); + x = PyNumber_Positive(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case UNARY_NEGATIVE: ++ TARGET_NOARG( UNARY_NEGATIVE) ++ { + v = TOP(); + x = PyNumber_Negative(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case UNARY_NOT: ++ TARGET_NOARG(UNARY_NOT) ++ { + v = TOP(); + err = PyObject_IsTrue(v); + Py_DECREF(v); + if (err == 0) { + Py_INCREF(Py_True); + SET_TOP(Py_True); +- continue; ++ DISPATCH(); + } + else if (err > 0) { + Py_INCREF(Py_False); + SET_TOP(Py_False); + err = 0; +- continue; ++ DISPATCH(); + } + STACKADJ(-1); + break; ++ } + +- case UNARY_CONVERT: ++ TARGET_NOARG(UNARY_CONVERT) ++ { + v = TOP(); + x = PyObject_Repr(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case UNARY_INVERT: ++ TARGET_NOARG(UNARY_INVERT) ++ { + v = TOP(); + x = PyNumber_Invert(v); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_POWER: ++ TARGET_NOARG(BINARY_POWER) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Power(v, w, Py_None); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_MULTIPLY: ++ TARGET_NOARG(BINARY_MULTIPLY) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Multiply(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if(x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_DIVIDE: ++ TARGET_NOARG(BINARY_DIVIDE) ++ { + if (!_Py_QnewFlag) { + w = POP(); + v = TOP(); +@@ -1350,32 +1482,37 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; + } +- /* -Qnew is in effect: fall through to +- BINARY_TRUE_DIVIDE */ +- case BINARY_TRUE_DIVIDE: ++ } ++ /* -Qnew is in effect: fall through to BINARY_TRUE_DIVIDE */ ++ TARGET_NOARG(BINARY_TRUE_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_TrueDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_FLOOR_DIVIDE: ++ TARGET_NOARG(BINARY_FLOOR_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_FloorDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_MODULO: ++ TARGET_NOARG(BINARY_MODULO) ++ { + w = POP(); + v = TOP(); + if (PyString_CheckExact(v)) +@@ -1385,10 +1522,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_ADD: ++ TARGET_NOARG(BINARY_ADD) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1417,10 +1556,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + skip_decref_vx: + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_SUBTRACT: ++ TARGET_NOARG(BINARY_SUBTRACT) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1442,10 +1583,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_SUBSCR: ++ TARGET_NOARG(BINARY_SUBSCR) ++ { + w = POP(); + v = TOP(); + if (PyList_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1466,102 +1609,122 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_LSHIFT: ++ TARGET_NOARG(BINARY_LSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Lshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_RSHIFT: ++ TARGET_NOARG(BINARY_RSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Rshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_AND: ++ TARGET_NOARG(BINARY_AND) ++ { + w = POP(); + v = TOP(); + x = PyNumber_And(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_XOR: ++ TARGET_NOARG(BINARY_XOR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Xor(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case BINARY_OR: ++ TARGET_NOARG(BINARY_OR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_Or(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case LIST_APPEND: ++ TARGET(LIST_APPEND) ++ { + w = POP(); + v = PEEK(oparg); + err = PyList_Append(v, w); + Py_DECREF(w); + if (err == 0) { + PREDICT(JUMP_ABSOLUTE); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case SET_ADD: ++ TARGET(SET_ADD) ++ { + w = POP(); + v = stack_pointer[-oparg]; + err = PySet_Add(v, w); + Py_DECREF(w); + if (err == 0) { + PREDICT(JUMP_ABSOLUTE); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case INPLACE_POWER: ++ TARGET_NOARG(INPLACE_POWER) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlacePower(v, w, Py_None); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_MULTIPLY: ++ TARGET_NOARG(INPLACE_MULTIPLY) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceMultiply(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_DIVIDE: ++ TARGET_NOARG(INPLACE_DIVIDE) ++ { + if (!_Py_QnewFlag) { + w = POP(); + v = TOP(); +@@ -1569,42 +1732,50 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; + } ++ } + /* -Qnew is in effect: fall through to + INPLACE_TRUE_DIVIDE */ +- case INPLACE_TRUE_DIVIDE: ++ TARGET_NOARG(INPLACE_TRUE_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceTrueDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_FLOOR_DIVIDE: ++ TARGET_NOARG(INPLACE_FLOOR_DIVIDE) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceFloorDivide(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_MODULO: ++ TARGET_NOARG(INPLACE_MODULO) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceRemainder(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_ADD: ++ TARGET_NOARG(INPLACE_ADD) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1631,10 +1802,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + skip_decref_v: + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_SUBTRACT: ++ TARGET_NOARG(INPLACE_SUBTRACT) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { +@@ -1654,63 +1827,78 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_LSHIFT: ++ TARGET_NOARG(INPLACE_LSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceLshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_RSHIFT: ++ TARGET_NOARG(INPLACE_RSHIFT) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceRshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_AND: ++ TARGET_NOARG(INPLACE_AND) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceAnd(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_XOR: ++ TARGET_NOARG(INPLACE_XOR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceXor(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case INPLACE_OR: ++ TARGET_NOARG(INPLACE_OR) ++ { + w = POP(); + v = TOP(); + x = PyNumber_InPlaceOr(v, w); + Py_DECREF(v); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } ++ + +- case SLICE+0: +- case SLICE+1: +- case SLICE+2: +- case SLICE+3: ++ ++ TARGET_WITH_IMPL_NOARG(SLICE, _slice) ++ TARGET_WITH_IMPL_NOARG(SLICE_1, _slice) ++ TARGET_WITH_IMPL_NOARG(SLICE_2, _slice) ++ TARGET_WITH_IMPL_NOARG(SLICE_3, _slice) ++ _slice: ++ { + if ((opcode-SLICE) & 2) + w = POP(); + else +@@ -1725,13 +1913,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_XDECREF(v); + Py_XDECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } ++ + +- case STORE_SLICE+0: +- case STORE_SLICE+1: +- case STORE_SLICE+2: +- case STORE_SLICE+3: ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE, _store_slice) ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE_1, _store_slice) ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE_2, _store_slice) ++ TARGET_WITH_IMPL_NOARG(STORE_SLICE_3, _store_slice) ++ _store_slice: ++ { + if ((opcode-STORE_SLICE) & 2) + w = POP(); + else +@@ -1747,13 +1939,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(u); + Py_XDECREF(v); + Py_XDECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } ++ + +- case DELETE_SLICE+0: +- case DELETE_SLICE+1: +- case DELETE_SLICE+2: +- case DELETE_SLICE+3: ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE, _delete_slice) ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE_1, _delete_slice) ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE_2, _delete_slice) ++ TARGET_WITH_IMPL_NOARG(DELETE_SLICE_3, _delete_slice) ++ _delete_slice: ++ { + if ((opcode-DELETE_SLICE) & 2) + w = POP(); + else +@@ -1768,10 +1964,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(u); + Py_XDECREF(v); + Py_XDECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case STORE_SUBSCR: ++ TARGET_NOARG(STORE_SUBSCR) ++ { + w = TOP(); + v = SECOND(); + u = THIRD(); +@@ -1781,10 +1979,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(u); + Py_DECREF(v); + Py_DECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case DELETE_SUBSCR: ++ TARGET_NOARG(DELETE_SUBSCR) ++ { + w = TOP(); + v = SECOND(); + STACKADJ(-2); +@@ -1792,10 +1992,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + err = PyObject_DelItem(v, w); + Py_DECREF(v); + Py_DECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case PRINT_EXPR: ++ TARGET_NOARG(PRINT_EXPR) ++ { + v = POP(); + w = PySys_GetObject("displayhook"); + if (w == NULL) { +@@ -1818,12 +2020,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_XDECREF(x); + break; ++ } + +- case PRINT_ITEM_TO: ++ TARGET_NOARG(PRINT_ITEM_TO) ++ { + w = stream = POP(); + /* fall through to PRINT_ITEM */ ++ } + +- case PRINT_ITEM: ++ TARGET_NOARG(PRINT_ITEM) ++ { + v = POP(); + if (stream == NULL || stream == Py_None) { + w = PySys_GetObject("stdout"); +@@ -1869,16 +2075,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_XDECREF(stream); + stream = NULL; +- if (err == 0) +- continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case PRINT_NEWLINE_TO: ++ TARGET_NOARG(PRINT_NEWLINE_TO) ++ { + w = stream = POP(); + /* fall through to PRINT_NEWLINE */ ++ } + +- case PRINT_NEWLINE: +- if (stream == NULL || stream == Py_None) { ++ TARGET_NOARG(PRINT_NEWLINE) ++ { ++ if (stream == NULL || stream == Py_None) ++ { + w = PySys_GetObject("stdout"); + if (w == NULL) { + PyErr_SetString(PyExc_RuntimeError, +@@ -1899,11 +2109,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + stream = NULL; + break; + +- ++ } + #ifdef CASE_TOO_BIG + default: switch (opcode) { + #endif +- case RAISE_VARARGS: ++ ++ TARGET(RAISE_VARARGS) ++ { + u = v = w = NULL; + switch (oparg) { + case 3: +@@ -1924,28 +2136,37 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + break; + } + break; ++ } + +- case LOAD_LOCALS: +- if ((x = f->f_locals) != NULL) { ++ TARGET_NOARG(LOAD_LOCALS) ++ { ++ if ((x = f->f_locals) != NULL) ++ { + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); + } + PyErr_SetString(PyExc_SystemError, "no locals"); + break; ++ } + +- case RETURN_VALUE: ++ TARGET_NOARG(RETURN_VALUE) ++ { + retval = POP(); + why = WHY_RETURN; + goto fast_block_end; ++ } + +- case YIELD_VALUE: ++ TARGET_NOARG(YIELD_VALUE) ++ { + retval = POP(); + f->f_stacktop = stack_pointer; + why = WHY_YIELD; + goto fast_yield; ++ } + +- case EXEC_STMT: ++ TARGET_NOARG(EXEC_STMT) ++ { + w = TOP(); + v = SECOND(); + u = THIRD(); +@@ -1957,8 +2178,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + break; ++ } + +- case POP_BLOCK: ++ TARGET_NOARG(POP_BLOCK) ++ { + { + PyTryBlock *b = PyFrame_BlockPop(f); + while (STACK_LEVEL() > b->b_level) { +@@ -1966,10 +2189,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + } + } +- continue; ++ DISPATCH(); ++ } + + PREDICTED(END_FINALLY); +- case END_FINALLY: ++ TARGET_NOARG(END_FINALLY) ++ { + v = POP(); + if (PyInt_Check(v)) { + why = (enum why_code) PyInt_AS_LONG(v); +@@ -1993,8 +2218,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + } + Py_DECREF(v); + break; ++ } + +- case BUILD_CLASS: ++ TARGET_NOARG(BUILD_CLASS) ++ { + u = TOP(); + v = SECOND(); + w = THIRD(); +@@ -2005,8 +2232,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_DECREF(w); + break; ++ } + +- case STORE_NAME: ++ TARGET(STORE_NAME) ++ { + w = GETITEM(names, oparg); + v = POP(); + if ((x = f->f_locals) != NULL) { +@@ -2015,15 +2244,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + else + err = PyObject_SetItem(x, w, v); + Py_DECREF(v); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; + } + PyErr_Format(PyExc_SystemError, + "no locals found when storing %s", + PyObject_REPR(w)); + break; ++ } + +- case DELETE_NAME: ++ TARGET(DELETE_NAME) ++ { + w = GETITEM(names, oparg); + if ((x = f->f_locals) != NULL) { + if ((err = PyObject_DelItem(x, w)) != 0) +@@ -2036,9 +2267,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + "no locals when deleting %s", + PyObject_REPR(w)); + break; ++ } + + PREDICTED_WITH_ARG(UNPACK_SEQUENCE); +- case UNPACK_SEQUENCE: ++ TARGET(UNPACK_SEQUENCE) ++ { + v = POP(); + if (PyTuple_CheckExact(v) && + PyTuple_GET_SIZE(v) == oparg) { +@@ -2050,7 +2283,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + PUSH(w); + } + Py_DECREF(v); +- continue; ++ DISPATCH(); + } else if (PyList_CheckExact(v) && + PyList_GET_SIZE(v) == oparg) { + PyObject **items = \ +@@ -2069,8 +2302,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + } + Py_DECREF(v); + break; ++ } + +- case STORE_ATTR: ++ TARGET(STORE_ATTR) ++ { + w = GETITEM(names, oparg); + v = TOP(); + u = SECOND(); +@@ -2078,33 +2313,41 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + err = PyObject_SetAttr(v, w, u); /* v.w = u */ + Py_DECREF(v); + Py_DECREF(u); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case DELETE_ATTR: ++ TARGET(DELETE_ATTR) ++ { + w = GETITEM(names, oparg); + v = POP(); + err = PyObject_SetAttr(v, w, (PyObject *)NULL); + /* del v.w */ + Py_DECREF(v); + break; ++ } + +- case STORE_GLOBAL: ++ TARGET(STORE_GLOBAL) ++ { + w = GETITEM(names, oparg); + v = POP(); + err = PyDict_SetItem(f->f_globals, w, v); + Py_DECREF(v); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case DELETE_GLOBAL: ++ TARGET(DELETE_GLOBAL) ++ { + w = GETITEM(names, oparg); + if ((err = PyDict_DelItem(f->f_globals, w)) != 0) + format_exc_check_arg( + PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w); + break; ++ } + +- case LOAD_NAME: ++ TARGET(LOAD_NAME) ++ { + w = GETITEM(names, oparg); + if ((v = f->f_locals) == NULL) { + PyErr_Format(PyExc_SystemError, +@@ -2140,9 +2383,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_INCREF(x); + } + PUSH(x); +- continue; ++ DISPATCH(); ++ } + +- case LOAD_GLOBAL: ++ TARGET(LOAD_GLOBAL) ++ { + w = GETITEM(names, oparg); + if (PyString_CheckExact(w)) { + /* Inline the PyDict_GetItem() calls. +@@ -2162,7 +2407,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + if (x != NULL) { + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); + } + d = (PyDictObject *)(f->f_builtins); + e = d->ma_lookup(d, w, hash); +@@ -2174,7 +2419,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + if (x != NULL) { + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); + } + goto load_global_error; + } +@@ -2193,13 +2438,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + } + Py_INCREF(x); + PUSH(x); +- continue; ++ DISPATCH(); ++ } + +- case DELETE_FAST: ++ TARGET(DELETE_FAST) ++ { + x = GETLOCAL(oparg); + if (x != NULL) { + SETLOCAL(oparg, NULL); +- continue; ++ DISPATCH(); + } + format_exc_check_arg( + PyExc_UnboundLocalError, +@@ -2207,20 +2454,24 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + PyTuple_GetItem(co->co_varnames, oparg) + ); + break; ++ } + +- case LOAD_CLOSURE: ++ TARGET(LOAD_CLOSURE) ++ { + x = freevars[oparg]; + Py_INCREF(x); + PUSH(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case LOAD_DEREF: ++ TARGET(LOAD_DEREF) ++ { + x = freevars[oparg]; + w = PyCell_Get(x); + if (w != NULL) { + PUSH(w); +- continue; ++ DISPATCH(); + } + err = -1; + /* Don't stomp existing exception */ +@@ -2240,15 +2491,19 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + UNBOUNDFREE_ERROR_MSG, v); + } + break; ++ } + +- case STORE_DEREF: ++ TARGET(STORE_DEREF) ++ { + w = POP(); + x = freevars[oparg]; + PyCell_Set(x, w); + Py_DECREF(w); +- continue; ++ DISPATCH(); ++ } + +- case BUILD_TUPLE: ++ TARGET(BUILD_TUPLE) ++ { + x = PyTuple_New(oparg); + if (x != NULL) { + for (; --oparg >= 0;) { +@@ -2256,11 +2511,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + PyTuple_SET_ITEM(x, oparg, w); + } + PUSH(x); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case BUILD_LIST: ++ TARGET(BUILD_LIST) ++ { + x = PyList_New(oparg); + if (x != NULL) { + for (; --oparg >= 0;) { +@@ -2268,11 +2525,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + PyList_SET_ITEM(x, oparg, w); + } + PUSH(x); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case BUILD_SET: ++ TARGET(BUILD_SET) ++ { + x = PySet_New(NULL); + if (x != NULL) { + for (; --oparg >= 0;) { +@@ -2286,18 +2545,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + break; + } + PUSH(x); +- continue; ++ DISPATCH(); + } + break; ++ } + +- +- case BUILD_MAP: ++ TARGET(BUILD_MAP) ++ { + x = _PyDict_NewPresized((Py_ssize_t)oparg); + PUSH(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case STORE_MAP: ++ TARGET_NOARG(STORE_MAP) ++ { + w = TOP(); /* key */ + u = SECOND(); /* value */ + v = THIRD(); /* dict */ +@@ -2306,10 +2568,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + err = PyDict_SetItem(v, w, u); /* v[w] = u */ + Py_DECREF(u); + Py_DECREF(w); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case MAP_ADD: ++ TARGET(MAP_ADD) ++ { + w = TOP(); /* key */ + u = SECOND(); /* value */ + STACKADJ(-2); +@@ -2320,20 +2584,24 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(w); + if (err == 0) { + PREDICT(JUMP_ABSOLUTE); +- continue; ++ DISPATCH(); + } + break; ++ } + +- case LOAD_ATTR: ++ TARGET(LOAD_ATTR) ++ { + w = GETITEM(names, oparg); + v = TOP(); + x = PyObject_GetAttr(v, w); + Py_DECREF(v); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case COMPARE_OP: ++ TARGET(COMPARE_OP) ++ { + w = POP(); + v = TOP(); + if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) { +@@ -2366,9 +2634,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + if (x == NULL) break; + PREDICT(POP_JUMP_IF_FALSE); + PREDICT(POP_JUMP_IF_TRUE); +- continue; ++ DISPATCH(); ++ } + +- case IMPORT_NAME: ++ TARGET(IMPORT_NAME) ++ { + w = GETITEM(names, oparg); + x = PyDict_GetItemString(f->f_builtins, "__import__"); + if (x == NULL) { +@@ -2409,10 +2679,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + READ_TIMESTAMP(intr1); + Py_DECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case IMPORT_STAR: ++ TARGET_NOARG(IMPORT_STAR) ++ { + v = POP(); + PyFrame_FastToLocals(f); + if ((x = f->f_locals) == NULL) { +@@ -2425,34 +2697,40 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + READ_TIMESTAMP(intr1); + PyFrame_LocalsToFast(f, 0); + Py_DECREF(v); +- if (err == 0) continue; ++ if (err == 0) DISPATCH(); + break; ++ } + +- case IMPORT_FROM: ++ TARGET(IMPORT_FROM) ++ { + w = GETITEM(names, oparg); + v = TOP(); + READ_TIMESTAMP(intr0); + x = import_from(v, w); + READ_TIMESTAMP(intr1); + PUSH(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case JUMP_FORWARD: ++ TARGET(JUMP_FORWARD) ++ { + JUMPBY(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); ++ } + + PREDICTED_WITH_ARG(POP_JUMP_IF_FALSE); +- case POP_JUMP_IF_FALSE: ++ TARGET(POP_JUMP_IF_FALSE) ++ { + w = POP(); + if (w == Py_True) { + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_False) { + Py_DECREF(w); + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + Py_DECREF(w); +@@ -2462,19 +2740,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + JUMPTO(oparg); + else + break; +- continue; +- ++ DISPATCH(); ++ } + PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE); +- case POP_JUMP_IF_TRUE: ++ TARGET(POP_JUMP_IF_TRUE) ++ { + w = POP(); + if (w == Py_False) { + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_True) { + Py_DECREF(w); + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + Py_DECREF(w); +@@ -2486,18 +2765,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + ; + else + break; +- continue; ++ DISPATCH(); ++ } + +- case JUMP_IF_FALSE_OR_POP: ++ TARGET(JUMP_IF_FALSE_OR_POP) ++ { + w = TOP(); + if (w == Py_True) { + STACKADJ(-1); + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_False) { + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + if (err > 0) { +@@ -2509,18 +2790,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + JUMPTO(oparg); + else + break; +- continue; ++ DISPATCH(); ++ } + +- case JUMP_IF_TRUE_OR_POP: ++ TARGET(JUMP_IF_TRUE_OR_POP) ++ { + w = TOP(); + if (w == Py_False) { + STACKADJ(-1); + Py_DECREF(w); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + if (w == Py_True) { + JUMPTO(oparg); +- goto fast_next_opcode; ++ FAST_DISPATCH(); + } + err = PyObject_IsTrue(w); + if (err > 0) { +@@ -2533,10 +2816,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + } + else + break; +- continue; ++ DISPATCH(); ++ } + + PREDICTED_WITH_ARG(JUMP_ABSOLUTE); +- case JUMP_ABSOLUTE: ++ TARGET(JUMP_ABSOLUTE) ++ { + JUMPTO(oparg); + #if FAST_LOOPS + /* Enabling this path speeds-up all while and for-loops by bypassing +@@ -2548,10 +2833,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + */ + goto fast_next_opcode; + #else +- continue; ++ DISPATCH(); + #endif ++ } + +- case GET_ITER: ++ TARGET_NOARG(GET_ITER) ++ { + /* before: [obj]; after [getiter(obj)] */ + v = TOP(); + x = PyObject_GetIter(v); +@@ -2559,13 +2846,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + if (x != NULL) { + SET_TOP(x); + PREDICT(FOR_ITER); +- continue; ++ DISPATCH(); + } + STACKADJ(-1); + break; ++ } + + PREDICTED_WITH_ARG(FOR_ITER); +- case FOR_ITER: ++ TARGET(FOR_ITER) ++ { + /* before: [iter]; after: [iter, iter()] *or* [] */ + v = TOP(); + x = (*v->ob_type->tp_iternext)(v); +@@ -2573,7 +2862,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + PUSH(x); + PREDICT(STORE_FAST); + PREDICT(UNPACK_SEQUENCE); +- continue; ++ DISPATCH(); + } + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches( +@@ -2585,13 +2874,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + x = v = POP(); + Py_DECREF(v); + JUMPBY(oparg); +- continue; ++ DISPATCH(); ++ } + +- case BREAK_LOOP: ++ TARGET_NOARG(BREAK_LOOP) ++ { + why = WHY_BREAK; + goto fast_block_end; ++ } + +- case CONTINUE_LOOP: ++ TARGET(CONTINUE_LOOP) ++ { + retval = PyInt_FromLong(oparg); + if (!retval) { + x = NULL; +@@ -2599,10 +2892,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + } + why = WHY_CONTINUE; + goto fast_block_end; ++ } + +- case SETUP_LOOP: +- case SETUP_EXCEPT: +- case SETUP_FINALLY: ++ TARGET_WITH_IMPL(SETUP_LOOP, _setup_finally) ++ TARGET_WITH_IMPL(SETUP_EXCEPT, _setup_finally) ++ TARGET(SETUP_FINALLY) ++ _setup_finally: ++ { + /* NOTE: If you add any new block-setup opcodes that + are not try/except/finally handlers, you may need + to update the PyGen_NeedsFinalizing() function. +@@ -2610,9 +2906,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + + PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, + STACK_LEVEL()); +- continue; ++ DISPATCH(); ++ } + +- case SETUP_WITH: ++ ++ TARGET(SETUP_WITH) ++ { + { + static PyObject *exit, *enter; + w = TOP(); +@@ -2638,10 +2937,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + STACK_LEVEL()); + + PUSH(x); +- continue; ++ DISPATCH(); ++ } + } + +- case WITH_CLEANUP: ++ TARGET_NOARG(WITH_CLEANUP) + { + /* At the top of the stack are 1-3 values indicating + how/why we entered the finally clause: +@@ -2729,7 +3029,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + break; + } + +- case CALL_FUNCTION: ++ TARGET(CALL_FUNCTION) + { + PyObject **sp; + PCALL(PCALL_ALL); +@@ -2741,14 +3041,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + #endif + stack_pointer = sp; + PUSH(x); +- if (x != NULL) +- continue; ++ if (x != NULL) DISPATCH(); + break; + } + +- case CALL_FUNCTION_VAR: +- case CALL_FUNCTION_KW: +- case CALL_FUNCTION_VAR_KW: ++ TARGET_WITH_IMPL(CALL_FUNCTION_VAR, _call_function_var_kw) ++ TARGET_WITH_IMPL(CALL_FUNCTION_KW, _call_function_var_kw) ++ TARGET(CALL_FUNCTION_VAR_KW) ++ _call_function_var_kw: + { + int na = oparg & 0xff; + int nk = (oparg>>8) & 0xff; +@@ -2786,12 +3086,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(w); + } + PUSH(x); +- if (x != NULL) +- continue; ++ if (x != NULL) DISPATCH(); + break; + } + +- case MAKE_FUNCTION: ++ TARGET(MAKE_FUNCTION) ++ { + v = POP(); /* code object */ + x = PyFunction_New(v, f->f_globals); + Py_DECREF(v); +@@ -2812,8 +3112,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + } + PUSH(x); + break; ++ } + +- case MAKE_CLOSURE: ++ TARGET(MAKE_CLOSURE) + { + v = POP(); /* code object */ + x = PyFunction_New(v, f->f_globals); +@@ -2848,7 +3149,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + break; + } + +- case BUILD_SLICE: ++ TARGET(BUILD_SLICE) ++ { + if (oparg == 3) + w = POP(); + else +@@ -2860,14 +3162,22 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) + Py_DECREF(v); + Py_XDECREF(w); + SET_TOP(x); +- if (x != NULL) continue; ++ if (x != NULL) DISPATCH(); + break; ++ } + +- case EXTENDED_ARG: ++ TARGET(EXTENDED_ARG) ++ { + opcode = NEXTOP(); + oparg = oparg<<16 | NEXTARG(); + goto dispatch_opcode; + ++ } ++ ++ ++#if USE_COMPUTED_GOTOS ++ _unknown_opcode: ++#endif + default: + fprintf(stderr, + "XXX lineno: %d, opcode: %d\n", +diff --git a/Python/makeopcodetargets.py b/Python/makeopcodetargets.py +index e69de29..703e5f2 100644 +--- a/Python/makeopcodetargets.py ++++ b/Python/makeopcodetargets.py +@@ -0,0 +1,45 @@ ++#! /usr/bin/env python ++"""Generate C code for the jump table of the threaded code interpreter ++(for compilers supporting computed gotos or "labels-as-values", such as gcc). ++""" ++ ++# This code should stay compatible with Python 2.3, at least while ++# some of the buildbots have Python 2.3 as their system Python. ++ ++import imp ++import os ++ ++ ++def find_module(modname): ++ """Finds and returns a module in the local dist/checkout. ++ """ ++ modpath = os.path.join( ++ os.path.dirname(os.path.dirname(__file__)), "Lib") ++ return imp.load_module(modname, *imp.find_module(modname, [modpath])) ++ ++def write_contents(f): ++ """Write C code contents to the target file object. ++ """ ++ opcode = find_module("opcode") ++ targets = ['_unknown_opcode'] * 256 ++ for opname, op in opcode.opmap.items(): ++ if opname == "STOP_CODE": ++ continue ++ targets[op] = "TARGET_%s" % opname.replace("+0", " ").replace("+", "_") ++ f.write("static void *opcode_targets[256] = {\n") ++ f.write(",\n".join([" &&%s" % s for s in targets])) ++ f.write("\n};\n") ++ ++ ++if __name__ == "__main__": ++ import sys ++ assert len(sys.argv) < 3, "Too many arguments" ++ if len(sys.argv) == 2: ++ target = sys.argv[1] ++ else: ++ target = "Python/opcode_targets.h" ++ f = open(target, "w") ++ try: ++ write_contents(f) ++ finally: ++ f.close() +\ No newline at end of file +diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h +index e69de29..2203566 100644 +--- a/Python/opcode_targets.h ++++ b/Python/opcode_targets.h +@@ -0,0 +1,258 @@ ++static void *opcode_targets[256] = { ++ &&_unknown_opcode, ++ &&TARGET_POP_TOP, ++ &&TARGET_ROT_TWO, ++ &&TARGET_ROT_THREE, ++ &&TARGET_DUP_TOP, ++ &&TARGET_ROT_FOUR, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_NOP, ++ &&TARGET_UNARY_POSITIVE, ++ &&TARGET_UNARY_NEGATIVE, ++ &&TARGET_UNARY_NOT, ++ &&TARGET_UNARY_CONVERT, ++ &&_unknown_opcode, ++ &&TARGET_UNARY_INVERT, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_BINARY_POWER, ++ &&TARGET_BINARY_MULTIPLY, ++ &&TARGET_BINARY_DIVIDE, ++ &&TARGET_BINARY_MODULO, ++ &&TARGET_BINARY_ADD, ++ &&TARGET_BINARY_SUBTRACT, ++ &&TARGET_BINARY_SUBSCR, ++ &&TARGET_BINARY_FLOOR_DIVIDE, ++ &&TARGET_BINARY_TRUE_DIVIDE, ++ &&TARGET_INPLACE_FLOOR_DIVIDE, ++ &&TARGET_INPLACE_TRUE_DIVIDE, ++ &&TARGET_SLICE , ++ &&TARGET_SLICE_1, ++ &&TARGET_SLICE_2, ++ &&TARGET_SLICE_3, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_STORE_SLICE , ++ &&TARGET_STORE_SLICE_1, ++ &&TARGET_STORE_SLICE_2, ++ &&TARGET_STORE_SLICE_3, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_DELETE_SLICE , ++ &&TARGET_DELETE_SLICE_1, ++ &&TARGET_DELETE_SLICE_2, ++ &&TARGET_DELETE_SLICE_3, ++ &&TARGET_STORE_MAP, ++ &&TARGET_INPLACE_ADD, ++ &&TARGET_INPLACE_SUBTRACT, ++ &&TARGET_INPLACE_MULTIPLY, ++ &&TARGET_INPLACE_DIVIDE, ++ &&TARGET_INPLACE_MODULO, ++ &&TARGET_STORE_SUBSCR, ++ &&TARGET_DELETE_SUBSCR, ++ &&TARGET_BINARY_LSHIFT, ++ &&TARGET_BINARY_RSHIFT, ++ &&TARGET_BINARY_AND, ++ &&TARGET_BINARY_XOR, ++ &&TARGET_BINARY_OR, ++ &&TARGET_INPLACE_POWER, ++ &&TARGET_GET_ITER, ++ &&_unknown_opcode, ++ &&TARGET_PRINT_EXPR, ++ &&TARGET_PRINT_ITEM, ++ &&TARGET_PRINT_NEWLINE, ++ &&TARGET_PRINT_ITEM_TO, ++ &&TARGET_PRINT_NEWLINE_TO, ++ &&TARGET_INPLACE_LSHIFT, ++ &&TARGET_INPLACE_RSHIFT, ++ &&TARGET_INPLACE_AND, ++ &&TARGET_INPLACE_XOR, ++ &&TARGET_INPLACE_OR, ++ &&TARGET_BREAK_LOOP, ++ &&TARGET_WITH_CLEANUP, ++ &&TARGET_LOAD_LOCALS, ++ &&TARGET_RETURN_VALUE, ++ &&TARGET_IMPORT_STAR, ++ &&TARGET_EXEC_STMT, ++ &&TARGET_YIELD_VALUE, ++ &&TARGET_POP_BLOCK, ++ &&TARGET_END_FINALLY, ++ &&TARGET_BUILD_CLASS, ++ &&TARGET_STORE_NAME, ++ &&TARGET_DELETE_NAME, ++ &&TARGET_UNPACK_SEQUENCE, ++ &&TARGET_FOR_ITER, ++ &&TARGET_LIST_APPEND, ++ &&TARGET_STORE_ATTR, ++ &&TARGET_DELETE_ATTR, ++ &&TARGET_STORE_GLOBAL, ++ &&TARGET_DELETE_GLOBAL, ++ &&TARGET_DUP_TOPX, ++ &&TARGET_LOAD_CONST, ++ &&TARGET_LOAD_NAME, ++ &&TARGET_BUILD_TUPLE, ++ &&TARGET_BUILD_LIST, ++ &&TARGET_BUILD_SET, ++ &&TARGET_BUILD_MAP, ++ &&TARGET_LOAD_ATTR, ++ &&TARGET_COMPARE_OP, ++ &&TARGET_IMPORT_NAME, ++ &&TARGET_IMPORT_FROM, ++ &&TARGET_JUMP_FORWARD, ++ &&TARGET_JUMP_IF_FALSE_OR_POP, ++ &&TARGET_JUMP_IF_TRUE_OR_POP, ++ &&TARGET_JUMP_ABSOLUTE, ++ &&TARGET_POP_JUMP_IF_FALSE, ++ &&TARGET_POP_JUMP_IF_TRUE, ++ &&TARGET_LOAD_GLOBAL, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_CONTINUE_LOOP, ++ &&TARGET_SETUP_LOOP, ++ &&TARGET_SETUP_EXCEPT, ++ &&TARGET_SETUP_FINALLY, ++ &&_unknown_opcode, ++ &&TARGET_LOAD_FAST, ++ &&TARGET_STORE_FAST, ++ &&TARGET_DELETE_FAST, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_RAISE_VARARGS, ++ &&TARGET_CALL_FUNCTION, ++ &&TARGET_MAKE_FUNCTION, ++ &&TARGET_BUILD_SLICE, ++ &&TARGET_MAKE_CLOSURE, ++ &&TARGET_LOAD_CLOSURE, ++ &&TARGET_LOAD_DEREF, ++ &&TARGET_STORE_DEREF, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&TARGET_CALL_FUNCTION_VAR, ++ &&TARGET_CALL_FUNCTION_KW, ++ &&TARGET_CALL_FUNCTION_VAR_KW, ++ &&TARGET_SETUP_WITH, ++ &&_unknown_opcode, ++ &&TARGET_EXTENDED_ARG, ++ &&TARGET_SET_ADD, ++ &&TARGET_MAP_ADD, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode, ++ &&_unknown_opcode ++}; +\ No newline at end of file +diff --git a/configure b/configure +index 6a47e1a..60a3335 100755 +--- a/configure ++++ b/configure +@@ -810,6 +810,7 @@ with_libm + with_libc + enable_big_digits + enable_unicode ++with_computed_gotos + ' + ac_precious_vars='build_alias + host_alias +@@ -1488,6 +1489,9 @@ Optional Packages: + --with-fpectl enable SIGFPE catching + --with-libm=STRING math library + --with-libc=STRING C library ++ --with(out)-computed-gotos ++ Use computed gotos in evaluation loop (enabled by ++ default on supported compilers) + + Some influential environment variables: + CC C compiler command +@@ -14608,6 +14612,83 @@ for dir in $SRCDIRS; do + mkdir $dir + fi + done ++ ++ BEGIN_COMPUTED_GOTO ++# Check for --with-computed-gotos ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-computed-gotos" >&5 ++$as_echo_n "checking for --with-computed-gotos... " >&6; } ++ ++# Check whether --with-computed-gotos was given. ++if test "${with_computed_gotos+set}" = set; then : ++ withval=$with_computed_gotos; ++if test "$withval" = yes ++then ++ ++$as_echo "#define USE_COMPUTED_GOTOS 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++fi ++if test "$withval" = no ++then ++ ++$as_echo "#define USE_COMPUTED_GOTOS 0" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 ++$as_echo "no value specified" >&6; } ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports computed gotos" >&5 ++$as_echo_n "checking whether $CC supports computed gotos... " >&6; } ++if ${ac_cv_computed_gotos+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test "$cross_compiling" = yes; then : ++ if test "${with_computed_gotos+set}" = set; then ++ ac_cv_computed_gotos="$with_computed_gotos -- configured --with(out)-computed-gotos" ++ else ++ ac_cv_computed_gotos=no ++ fi ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++int main(int argc, char **argv) ++{ ++ static void *targets[1] = { &&LABEL1 }; ++ goto LABEL2; ++LABEL1: ++ return 0; ++LABEL2: ++ goto *targets[0]; ++ return 1; ++} ++_ACEOF ++if ac_fn_c_try_run "$LINENO"; then : ++ ac_cv_computed_gotos=yes ++else ++ ac_cv_computed_gotos=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ ++ conftest.$ac_objext conftest.beam conftest.$ac_ext ++fi ++ ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_computed_gotos" >&5 ++$as_echo "$ac_cv_computed_gotos" >&6; } ++case "$ac_cv_computed_gotos" in yes*) ++ ++$as_echo "#define HAVE_COMPUTED_GOTOS 1" >>confdefs.h ++ ++esac ++# END_COMPUTED_GOTO ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 + $as_echo "done" >&6; } + +diff --git a/configure.ac b/configure.ac +index 48eccdd..74bb514 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -4561,6 +4561,57 @@ for dir in $SRCDIRS; do + mkdir $dir + fi + done ++ ++# BEGIN_COMPUTED_GOTO ++# Check for --with-computed-gotos ++AC_MSG_CHECKING(for --with-computed-gotos) ++AC_ARG_WITH(computed-gotos, ++ AS_HELP_STRING([--with(out)-computed-gotos], ++ [Use computed gotos in evaluation loop (enabled by default on supported compilers)]), ++[ ++if test "$withval" = yes ++then ++ AC_DEFINE(USE_COMPUTED_GOTOS, 1, ++ [Define if you want to use computed gotos in ceval.c.]) ++ AC_MSG_RESULT(yes) ++fi ++if test "$withval" = no ++then ++ AC_DEFINE(USE_COMPUTED_GOTOS, 0, ++ [Define if you want to use computed gotos in ceval.c.]) ++ AC_MSG_RESULT(no) ++fi ++], ++[AC_MSG_RESULT(no value specified)]) ++ ++AC_MSG_CHECKING(whether $CC supports computed gotos) ++AC_CACHE_VAL(ac_cv_computed_gotos, ++AC_RUN_IFELSE([AC_LANG_SOURCE([[[ ++int main(int argc, char **argv) ++{ ++ static void *targets[1] = { &&LABEL1 }; ++ goto LABEL2; ++LABEL1: ++ return 0; ++LABEL2: ++ goto *targets[0]; ++ return 1; ++} ++]]])], ++[ac_cv_computed_gotos=yes], ++[ac_cv_computed_gotos=no], ++[if test "${with_computed_gotos+set}" = set; then ++ ac_cv_computed_gotos="$with_computed_gotos -- configured --with(out)-computed-gotos" ++ else ++ ac_cv_computed_gotos=no ++ fi])) ++AC_MSG_RESULT($ac_cv_computed_gotos) ++case "$ac_cv_computed_gotos" in yes*) ++ AC_DEFINE(HAVE_COMPUTED_GOTOS, 1, ++ [Define if the C compiler supports computed gotos.]) ++esac ++# END_COMPUTED_GOTO ++ + AC_MSG_RESULT(done) + + # generate output files +diff --git a/pyconfig.h.in b/pyconfig.h.in +index eace285..ac85729 100644 +--- a/pyconfig.h.in ++++ b/pyconfig.h.in +@@ -121,6 +121,9 @@ + /* Define to 1 if you have the `clock' function. */ + #undef HAVE_CLOCK + ++/* Define if the C compiler supports computed gotos. */ ++#undef HAVE_COMPUTED_GOTOS ++ + /* Define to 1 if you have the `confstr' function. */ + #undef HAVE_CONFSTR + +@@ -1060,6 +1063,9 @@ + /* Define to 1 if your declares `struct tm'. */ + #undef TM_IN_SYS_TIME + ++/* Define if you want to use computed gotos in ceval.c. */ ++#undef USE_COMPUTED_GOTOS ++ + /* Enable extensions on AIX 3, Interix. */ + #ifndef _ALL_SOURCE + # undef _ALL_SOURCE +-- +2.5.5 + diff --git a/SOURCES/00234-PEP493-updated-implementation.patch b/SOURCES/00234-PEP493-updated-implementation.patch new file mode 100644 index 0000000..d6468bd --- /dev/null +++ b/SOURCES/00234-PEP493-updated-implementation.patch @@ -0,0 +1,132 @@ +@@ -, +, @@ +--- + Lib/ssl.py | 53 ++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 38 insertions(+), 15 deletions(-) +--- a/Lib/ssl.py ++++ a/Lib/ssl.py +@@ -466,24 +466,47 @@ def _create_unverified_context(protocol=PROTOCOL_SSLv23, cert_reqs=None, + + return context + ++_https_verify_envvar = 'PYTHONHTTPSVERIFY' + _cert_verification_config = '/etc/python/cert-verification.cfg' + +-def _get_verify_status(protocol): +- context_factory = { +- 'platform_default': _create_unverified_context, +- 'enable': create_default_context, +- 'disable': _create_unverified_context +- } +- import ConfigParser +- try: +- config = ConfigParser.RawConfigParser() +- config.read(_cert_verification_config) +- status = config.get(protocol, 'verify') +- except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): +- status = 'platform_default' +- default = context_factory.get('platform_default') +- return context_factory.get(status, default) ++# To provide same function name as specified in PEP493 with keeping ++# the old name as defined in our previous patch ++_get_https_context_factory = lambda: _get_verify_status('https') + ++def _get_verify_status(protocol): ++ # See https://www.python.org/dev/peps/pep-0493/#recommendation-for-combined-feature-backports ++ # Check for an environmental override of the default behaviour ++ if not sys.flags.ignore_environment: ++ config_setting = os.environ.get(_https_verify_envvar) ++ if config_setting is not None: ++ if config_setting == '0': ++ return _create_unverified_context ++ return create_default_context ++ ++ # Check for a system-wide override of the default behaviour ++ context_factory = { ++ 'platform_default': _create_unverified_context, ++ 'enable': create_default_context, ++ 'disable': _create_unverified_context ++ } ++ import ConfigParser ++ try: ++ config = ConfigParser.RawConfigParser() ++ config.read(_cert_verification_config) ++ status = config.get(protocol, 'verify') ++ except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): ++ status = 'platform_default' ++ default = context_factory.get('platform_default') ++ return context_factory.get(status, default) ++ ++# See https://www.python.org/dev/peps/pep-0493/#feature-configuration-api ++def _https_verify_certificates(enable=True): ++ """Verify server HTTPS certificates by default?""" ++ global _create_default_https_context ++ if enable: ++ _create_default_https_context = create_default_context ++ else: ++ _create_default_https_context = _create_unverified_context + + # Used by http.client if no context is explicitly passed. + _create_default_https_context = _get_verify_status('https') +--- a/Lib/test/test_ssl.py Thu Jan 14 21:57:57 2016 -0800 ++++ a/Lib/test/test_ssl.py Fri Jan 15 17:41:37 2016 +1000 +@@ -4,6 +4,7 @@ + import sys + import unittest + from test import test_support as support ++from test.script_helper import assert_python_ok + import asyncore + import socket + import select +@@ -1149,6 +1149,52 @@ + self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) + self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) + ++ def test__https_verify_certificates(self): ++ # Unit test to check the contect factory mapping ++ # The factories themselves are tested above ++ # This test will fail by design if run under PYTHONHTTPSVERIFY=0 ++ # (as will various test_httplib tests) ++ ++ # Uses a fresh SSL module to avoid affecting the real one ++ local_ssl = support.import_fresh_module("ssl") ++ # Certificate verification is enabled by default ++ self.assertIs(local_ssl._create_default_https_context, ++ local_ssl._create_unverified_context) ++ # Turn verification on ++ local_ssl._https_verify_certificates(enable=True) ++ self.assertIs(local_ssl._create_default_https_context, ++ local_ssl.create_default_context) ++ # Turn verification off ++ local_ssl._https_verify_certificates(enable=False) ++ self.assertIs(local_ssl._create_default_https_context, ++ local_ssl._create_unverified_context) ++ # The default behaviour is verification on ++ local_ssl._https_verify_certificates(enable=True) ++ local_ssl._https_verify_certificates() ++ self.assertIs(local_ssl._create_default_https_context, ++ local_ssl.create_default_context) ++ ++ def test__https_verify_envvar(self): ++ # Unit test to check the PYTHONHTTPSVERIFY handling ++ # Need to use a subprocess so it can still be run under -E ++ # Checks are inverted due to the 0 == success return code convention ++ https_is_verified = """import ssl, sys;\ ++ sys.exit(ssl._create_default_https_context is not ++ ssl.create_default_context)""" ++ https_is_not_verified = """import ssl, sys;\ ++ sys.exit(ssl._create_default_https_context is not ++ ssl._create_unverified_context)""" ++ extra_env = {} ++ # Omitting it leaves verification off ++ assert_python_ok("-c", https_is_not_verified, **extra_env) ++ # Setting it to zero turns verification off ++ extra_env[ssl._https_verify_envvar] = "0" ++ assert_python_ok("-c", https_is_not_verified, **extra_env) ++ # Any other value should also leave it on ++ for setting in ("", "1", "enabled", "foo"): ++ extra_env[ssl._https_verify_envvar] = setting ++ assert_python_ok("-c", https_is_verified, **extra_env) ++ + def test_check_hostname(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + self.assertFalse(ctx.check_hostname) diff --git a/SOURCES/00235-JSON-decoder-lone-surrogates-fix.patch b/SOURCES/00235-JSON-decoder-lone-surrogates-fix.patch new file mode 100644 index 0000000..d78e8e7 --- /dev/null +++ b/SOURCES/00235-JSON-decoder-lone-surrogates-fix.patch @@ -0,0 +1,226 @@ +From 90986ef48c0df602ab38aa831a24e99e9ed61e7e Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Mon, 4 Apr 2016 15:55:28 +0200 +Subject: [PATCH] JSON decoder now accepts lone surrogates + +--- + Lib/json/decoder.py | 35 ++++++++++++------------ + Lib/json/tests/test_scanstring.py | 56 ++++++++++++++++++++++++++++++++++++--- + Modules/_json.c | 49 +++++++++------------------------- + 3 files changed, 83 insertions(+), 57 deletions(-) + +diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py +index dfcc628..1b43238 100644 +--- a/Lib/json/decoder.py ++++ b/Lib/json/decoder.py +@@ -62,6 +62,16 @@ BACKSLASH = { + + DEFAULT_ENCODING = "utf-8" + ++def _decode_uXXXX(s, pos): ++ esc = s[pos + 1:pos + 5] ++ if len(esc) == 4 and esc[1] not in 'xX': ++ try: ++ return int(esc, 16) ++ except ValueError: ++ pass ++ msg = "Invalid \\uXXXX escape" ++ raise ValueError(errmsg(msg, s, pos)) ++ + def py_scanstring(s, end, encoding=None, strict=True, + _b=BACKSLASH, _m=STRINGCHUNK.match): + """Scan the string s for a JSON string. End is the index of the +@@ -116,25 +126,16 @@ def py_scanstring(s, end, encoding=None, strict=True, + end += 1 + else: + # Unicode escape sequence +- esc = s[end + 1:end + 5] +- next_end = end + 5 +- if len(esc) != 4: +- msg = "Invalid \\uXXXX escape" +- raise ValueError(errmsg(msg, s, end)) +- uni = int(esc, 16) ++ uni = _decode_uXXXX(s, end) ++ end += 5 + # Check for surrogate pair on UCS-4 systems +- if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535: +- msg = "Invalid \\uXXXX\\uXXXX surrogate pair" +- if not s[end + 5:end + 7] == '\\u': +- raise ValueError(errmsg(msg, s, end)) +- esc2 = s[end + 7:end + 11] +- if len(esc2) != 4: +- raise ValueError(errmsg(msg, s, end)) +- uni2 = int(esc2, 16) +- uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) +- next_end += 6 ++ if sys.maxunicode > 65535 and \ ++ 0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u': ++ uni2 = _decode_uXXXX(s, end + 1) ++ if 0xdc00 <= uni2 <= 0xdfff: ++ uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) ++ end += 6 + char = unichr(uni) +- end = next_end + # Append the unescaped character + _append(char) + return u''.join(chunks), end +diff --git a/Lib/json/tests/test_scanstring.py b/Lib/json/tests/test_scanstring.py +index 4fef8cb..ed80a41 100644 +--- a/Lib/json/tests/test_scanstring.py ++++ b/Lib/json/tests/test_scanstring.py +@@ -5,10 +5,6 @@ from json.tests import PyTest, CTest + class TestScanstring(object): + def test_scanstring(self): + scanstring = self.json.decoder.scanstring +- self.assertEqual( +- scanstring('"z\\ud834\\udd20x"', 1, None, True), +- (u'z\U0001d120x', 16)) +- + if sys.maxunicode == 65535: + self.assertEqual( + scanstring(u'"z\U0001d120x"', 1, None, True), +@@ -94,6 +90,58 @@ class TestScanstring(object): + scanstring('["Bad value", truth]', 2, None, True), + (u'Bad value', 12)) + ++ def test_surrogates(self): ++ scanstring = self.json.decoder.scanstring ++ def assertScan(given, expect): ++ self.assertEqual(scanstring(given, 1, None, True), ++ (expect, len(given))) ++ if not isinstance(given, unicode): ++ given = unicode(given) ++ self.assertEqual(scanstring(given, 1, None, True), ++ (expect, len(given))) ++ ++ surrogates = unichr(0xd834) + unichr(0xdd20) ++ assertScan('"z\\ud834\\u0079x"', u'z\ud834yx') ++ assertScan('"z\\ud834\\udd20x"', u'z\U0001d120x') ++ assertScan('"z\\ud834\\ud834\\udd20x"', u'z\ud834\U0001d120x') ++ assertScan('"z\\ud834x"', u'z\ud834x') ++ assertScan(u'"z\\ud834\udd20x12345"', u'z%sx12345' % surrogates) ++ assertScan('"z\\udd20x"', u'z\udd20x') ++ assertScan(u'"z\ud834\udd20x"', u'z\ud834\udd20x') ++ assertScan(u'"z\ud834\\udd20x"', u'z%sx' % surrogates) ++ assertScan(u'"z\ud834x"', u'z\ud834x') ++ ++ def test_bad_escapes(self): ++ scanstring = self.json.decoder.scanstring ++ bad_escapes = [ ++ '"\\"', ++ '"\\x"', ++ '"\\u"', ++ '"\\u0"', ++ '"\\u01"', ++ '"\\u012"', ++ '"\\uz012"', ++ '"\\u0z12"', ++ '"\\u01z2"', ++ '"\\u012z"', ++ '"\\u0x12"', ++ '"\\u0X12"', ++ '"\\ud834\\"', ++ '"\\ud834\\u"', ++ '"\\ud834\\ud"', ++ '"\\ud834\\udd"', ++ '"\\ud834\\udd2"', ++ '"\\ud834\\uzdd2"', ++ '"\\ud834\\udzd2"', ++ '"\\ud834\\uddz2"', ++ '"\\ud834\\udd2z"', ++ '"\\ud834\\u0x20"', ++ '"\\ud834\\u0X20"', ++ ] ++ for s in bad_escapes: ++ with self.assertRaises(ValueError): ++ scanstring(s, 1, None, True) ++ + def test_issue3623(self): + self.assertRaises(ValueError, self.json.decoder.scanstring, b"xxx", 1, + "xxx") +diff --git a/Modules/_json.c b/Modules/_json.c +index 7c925fd..56d9ee4 100644 +--- a/Modules/_json.c ++++ b/Modules/_json.c +@@ -524,16 +524,10 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_s + } + #ifdef Py_UNICODE_WIDE + /* Surrogate pair */ +- if ((c & 0xfc00) == 0xd800) { ++ if ((c & 0xfc00) == 0xd800 && end + 6 < len && ++ buf[next++] == '\\' && ++ buf[next++] == 'u') { + Py_UNICODE c2 = 0; +- if (end + 6 >= len) { +- raise_errmsg("Unpaired high surrogate", pystr, end - 5); +- goto bail; +- } +- if (buf[next++] != '\\' || buf[next++] != 'u') { +- raise_errmsg("Unpaired high surrogate", pystr, end - 5); +- goto bail; +- } + end += 6; + /* Decode 4 hex digits */ + for (; next < end; next++) { +@@ -554,15 +548,10 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_s + goto bail; + } + } +- if ((c2 & 0xfc00) != 0xdc00) { +- raise_errmsg("Unpaired high surrogate", pystr, end - 5); +- goto bail; +- } +- c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); +- } +- else if ((c & 0xfc00) == 0xdc00) { +- raise_errmsg("Unpaired low surrogate", pystr, end - 5); +- goto bail; ++ if ((c2 & 0xfc00) == 0xdc00) ++ c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); ++ else ++ end -= 6; + } + #endif + } +@@ -703,16 +692,9 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next + } + #ifdef Py_UNICODE_WIDE + /* Surrogate pair */ +- if ((c & 0xfc00) == 0xd800) { ++ if ((c & 0xfc00) == 0xd800 && end + 6 < len && ++ buf[next++] == '\\' && buf[next++] == 'u') { + Py_UNICODE c2 = 0; +- if (end + 6 >= len) { +- raise_errmsg("Unpaired high surrogate", pystr, end - 5); +- goto bail; +- } +- if (buf[next++] != '\\' || buf[next++] != 'u') { +- raise_errmsg("Unpaired high surrogate", pystr, end - 5); +- goto bail; +- } + end += 6; + /* Decode 4 hex digits */ + for (; next < end; next++) { +@@ -733,15 +715,10 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next + goto bail; + } + } +- if ((c2 & 0xfc00) != 0xdc00) { +- raise_errmsg("Unpaired high surrogate", pystr, end - 5); +- goto bail; +- } +- c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); +- } +- else if ((c & 0xfc00) == 0xdc00) { +- raise_errmsg("Unpaired low surrogate", pystr, end - 5); +- goto bail; ++ if ((c2 & 0xfc00) == 0xdc00) ++ c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); ++ else ++ end -= 6; + } + #endif + } +-- +2.5.5 + diff --git a/SOURCES/00236-use-Py_ssize_t-for-file-offset-and-length-computations-in-iteration.patch b/SOURCES/00236-use-Py_ssize_t-for-file-offset-and-length-computations-in-iteration.patch new file mode 100644 index 0000000..7522dd8 --- /dev/null +++ b/SOURCES/00236-use-Py_ssize_t-for-file-offset-and-length-computations-in-iteration.patch @@ -0,0 +1,101 @@ +From 6bebd55022c82829c0b15d24d2ca99edd22562df Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Wed, 4 May 2016 10:39:40 +0200 +Subject: [PATCH] use Py_ssize_t for file offset and length computations in + iteration + +--- + Lib/test/test_file2k.py | 16 +++++++++++++++- + Objects/fileobject.c | 15 +++++++-------- + 2 files changed, 22 insertions(+), 9 deletions(-) + +diff --git a/Lib/test/test_file2k.py b/Lib/test/test_file2k.py +index 5a3c354..8f94cee 100644 +--- a/Lib/test/test_file2k.py ++++ b/Lib/test/test_file2k.py +@@ -14,7 +14,7 @@ except ImportError: + threading = None + + from test import test_support +-from test.test_support import TESTFN, run_unittest ++from test.test_support import TESTFN, run_unittest, requires + from UserList import UserList + + class AutoFileTests(unittest.TestCase): +@@ -416,6 +416,20 @@ class OtherFileTests(unittest.TestCase): + finally: + os.unlink(TESTFN) + ++ @test_support.precisionbigmemtest(2**31, 2.5, dry_run=False) ++ def test_very_long_line(self, size): ++ # Issue #22526 ++ requires('largefile') ++ with open(TESTFN, "wb") as fp: ++ fp.seek(size - 1) ++ fp.write("\0") ++ with open(TESTFN, "rb") as fp: ++ for l in fp: ++ pass ++ self.assertEqual(len(l), size) ++ self.assertEqual(l.count("\0"), size) ++ l = None ++ + class FileSubclassTests(unittest.TestCase): + + def testExit(self): +diff --git a/Objects/fileobject.c b/Objects/fileobject.c +index 76cdf74..fabe207 100644 +--- a/Objects/fileobject.c ++++ b/Objects/fileobject.c +@@ -2230,7 +2230,7 @@ drop_readahead(PyFileObject *f) + (unless at EOF) and no more than bufsize. Returns negative value on + error, will set MemoryError if bufsize bytes cannot be allocated. */ + static int +-readahead(PyFileObject *f, int bufsize) ++readahead(PyFileObject *f, Py_ssize_t bufsize) + { + Py_ssize_t chunksize; + +@@ -2268,7 +2268,7 @@ readahead(PyFileObject *f, int bufsize) + logarithmic buffer growth to about 50 even when reading a 1gb line. */ + + static PyStringObject * +-readahead_get_line_skip(PyFileObject *f, int skip, int bufsize) ++readahead_get_line_skip(PyFileObject *f, Py_ssize_t skip, Py_ssize_t bufsize) + { + PyStringObject* s; + char *bufptr; +@@ -2288,10 +2288,10 @@ readahead_get_line_skip(PyFileObject *f, int skip, int bufsize) + bufptr++; /* Count the '\n' */ + len = bufptr - f->f_bufptr; + s = (PyStringObject *) +- PyString_FromStringAndSize(NULL, skip+len); ++ PyString_FromStringAndSize(NULL, skip + len); + if (s == NULL) + return NULL; +- memcpy(PyString_AS_STRING(s)+skip, f->f_bufptr, len); ++ memcpy(PyString_AS_STRING(s) + skip, f->f_bufptr, len); + f->f_bufptr = bufptr; + if (bufptr == f->f_bufend) + drop_readahead(f); +@@ -2299,14 +2299,13 @@ readahead_get_line_skip(PyFileObject *f, int skip, int bufsize) + bufptr = f->f_bufptr; + buf = f->f_buf; + f->f_buf = NULL; /* Force new readahead buffer */ +- assert(skip+len < INT_MAX); +- s = readahead_get_line_skip( +- f, (int)(skip+len), bufsize + (bufsize>>2) ); ++ assert(len <= PY_SSIZE_T_MAX - skip); ++ s = readahead_get_line_skip(f, skip + len, bufsize + (bufsize>>2)); + if (s == NULL) { + PyMem_Free(buf); + return NULL; + } +- memcpy(PyString_AS_STRING(s)+skip, bufptr, len); ++ memcpy(PyString_AS_STRING(s) + skip, bufptr, len); + PyMem_Free(buf); + } + return s; +-- +2.5.5 + diff --git a/SOURCES/00241-CVE-2016-5636-buffer-overflow-in-zipimport-module-fix.patch b/SOURCES/00241-CVE-2016-5636-buffer-overflow-in-zipimport-module-fix.patch new file mode 100644 index 0000000..f166d01 --- /dev/null +++ b/SOURCES/00241-CVE-2016-5636-buffer-overflow-in-zipimport-module-fix.patch @@ -0,0 +1,39 @@ +From 0f12cb75c708978f9201c1dd3464d2a8572b4544 Mon Sep 17 00:00:00 2001 +From: Charalampos Stratakis +Date: Fri, 8 Jul 2016 20:24:10 +0200 +Subject: [PATCH] CVE-2016-5636 fix + +--- + Modules/zipimport.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/Modules/zipimport.c b/Modules/zipimport.c +index 7240cb4..2e6a61f 100644 +--- a/Modules/zipimport.c ++++ b/Modules/zipimport.c +@@ -861,6 +861,10 @@ get_data(char *archive, PyObject *toc_entry) + &date, &crc)) { + return NULL; + } ++ if (data_size < 0) { ++ PyErr_Format(ZipImportError, "negative data size"); ++ return NULL; ++ } + + fp = fopen(archive, "rb"); + if (!fp) { +@@ -895,6 +899,11 @@ get_data(char *archive, PyObject *toc_entry) + PyMarshal_ReadShortFromFile(fp); /* local header size */ + file_offset += l; /* Start of file data */ + ++ if (data_size > LONG_MAX - 1) { ++ fclose(fp); ++ PyErr_NoMemory(); ++ return NULL; ++ } + raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ? + data_size : data_size + 1); + if (raw_data == NULL) { +-- +2.7.4 + diff --git a/SOURCES/cert-verification.cfg b/SOURCES/cert-verification.cfg index e653406..3583e46 100755 --- a/SOURCES/cert-verification.cfg +++ b/SOURCES/cert-verification.cfg @@ -1,5 +1,8 @@ -# Possible values are `disable` to disable certificate verifications -# `enable` to enable certificate verifications +# Possible values are: +# 'enable' to ensure HTTPS certificate verification is enabled by default +# 'disable' to ensure HTTPS certificate verification is disabled by default +# 'platform_default' to delegate the decision to the redistributor providing this particular Python version + # For more info refer to https://www.python.org/dev/peps/pep-0493/ [https] -verify=disable +verify=platform_default diff --git a/SPECS/python.spec b/SPECS/python.spec index 80ea0ee..8e64529 100644 --- a/SPECS/python.spec +++ b/SPECS/python.spec @@ -106,7 +106,7 @@ Summary: An interpreted, interactive, object-oriented programming language Name: %{python} # Remember to also rebase python-docs when changing this: Version: 2.7.5 -Release: 39%{?dist} +Release: 48%{?dist} License: Python Group: Development/Languages Requires: %{python}-libs%{?_isa} = %{version}-%{release} @@ -987,7 +987,8 @@ Patch219: 00219-pep466-fix-referenced-sslwrap.patch Patch220: 00220-pep466-allow-passing-ssl-urrlib-httplib.patch # 00221 # # Patch214 remove sslwrap from _ssl.c this so we have to reimplement it -Patch221: 00221-pep466-backport-sslwrap-c-ssl.patch +#Patch221: 00221-pep466-backport-sslwrap-c-ssl.patch +# Backporting sslwrap introduces regressions so patch 221 was dropped (rhbz#1331425) # 00222 # # test_ssl: fails on recent libressl version with BAD_DH_P_LENGTH # https://bugs.python.org/issue23844 @@ -1009,8 +1010,9 @@ Patch224: 00224-pep476-add-toggle-for-cert-verify.patch Patch225: 00225-cprofile-sort-option.patch # 00227 # -# Make load_cert_chain function of SSLContext accept -# keyfile which is set to None +# Make load_cert_chain function of SSLContext accept a +# keyfile argument set to None +# Upstream issue: http://bugs.python.org/issue22787 # Resolves: rhbz#1250611 Patch227: 00227-accept-none-keyfile-loadcertchain.patch @@ -1026,39 +1028,84 @@ Patch229: 00229-Expect-a-failure-when-trying-to-connect-with-SSLv2-c.patch # 00230 # # Force all child threads to terminate in TestForkInThread, so no zombie -# processes get left behind with stalled threads which hang Python builds. +# processes get left behind with stalled threads which hang Python builds # https://bugs.python.org/issue26456 -# Resolves: rhbz#1365200 +# Resolves: rhbz#1313259 Patch230: 00230-force-all-child-threads-to-terminate-in-TestForkInThread.patch # 00231 # # Fix hashlib algorithms breaking by initializing OpenSSL_add_all_digests # function in _hashlib library of _hashopenssl.c module -# Resolves: rhbz#1371132 +# Resolves: rhbz#1295459 Patch231: 00231-Initialize-OpenSSL_add_all_digests-in-_hashlib.patch +# 00232 # +# Removal of the '$Date$' placeholder on the python(1) man page footer, +# which does not expand during build +# http://bugs.python.org/issue17167 +# Resolves: rhbz#1268310 +Patch232: 00232-man-page-date-macro-removal.patch + +# 00233 # +# Backport of Computed Goto dispatch +# http://bugs.python.org/issue4753 +# https://lwn.net/Articles/646888/ +# Resolves: rhbz#1289277 +Patch233: 00233-Computed-Goto-dispatch.patch + +# 00234 # +# Updated implementation of PEP493 +# The following features were backported: +# https://www.python.org/dev/peps/pep-0493/#feature-configuration-api +# https://www.python.org/dev/peps/pep-0493/#feature-environment-based-configuration +# Combined usage explained: +# https://www.python.org/dev/peps/pep-0493/#recommendation-for-combined-feature-backports +# Resolves: rhbz#1315758 +Patch234: 00234-PEP493-updated-implementation.patch + +# 0235 # +# JSON decoder lone surrogates fix. +# https://bugs.python.org/issue11489 +# Resolves: rhbz#1301017 +Patch235: 00235-JSON-decoder-lone-surrogates-fix.patch + +# 0236 # +# Fix for iteration over files vith very long lines +# http://bugs.python.org/issue22526 +# Resolves: rhbz#1271760 +Patch236: 00236-use-Py_ssize_t-for-file-offset-and-length-computations-in-iteration.patch + # 00237 # # CVE-2016-0772 python: smtplib StartTLS stripping attack # https://bugzilla.redhat.com/show_bug.cgi?id=1303647 # FIXED UPSTREAM: https://hg.python.org/cpython/rev/b3ce713fb9be # Raise an error when STARTTLS fails -# Resolves: rhbz#1346356 +# Resolves: rhbz#1346357 Patch237: 00237-CVE-2016-0772-smtplib.patch # 00238 # # CVE-2016-5699 python: http protocol steam injection attack -# https://bugzilla.redhat.com/show_bug.cgi?id=1303699 -# FIXED UPSTREAM: https://hg.python.org/cpython/rev/1c45047c5102 +# https://bugzilla.redhat.com/show_bug.cgi?id=1303699 +# FIXED UPSTREAM: https://hg.python.org/cpython/rev/1c45047c5102 # Disabled HTTP header injections in httplib -# Resolves: rhbz#1346356 +# Resolves: rhbz#1346357 Patch238: 00238-CVE-2016-5699-httplib.patch +# 00241 # +# CVE-2016-5636: http://seclists.org/oss-sec/2016/q2/560 +# https://hg.python.org/cpython/rev/985fc64c60d6/ +# https://hg.python.org/cpython/rev/2edbdb79cd6d +# Fix possible integer overflow and heap corruption in zipimporter.get_data() +# FIXED UPSTREAM: https://bugs.python.org/issue26171 +# Resolves: rhbz#1356364 +Patch241: 00241-CVE-2016-5636-buffer-overflow-in-zipimport-module-fix.patch + # 00242 # # HTTPoxy attack (CVE-2016-1000110) # https://httpoxy.org/ # FIXED UPSTREAM: http://bugs.python.org/issue27568 # Based on a patch by RĂ©mi Rampin -# Resolves: rhbz#1359163 +# Resolves: rhbz#1359164 Patch242: 00242-CVE-2016-1000110-httpoxy.patch # (New patches go here ^^^) @@ -1445,7 +1492,7 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c %patch218 -p1 %patch219 -p1 %patch220 -p1 -%patch221 -p1 +# 00221: Dropped because of regressions %patch222 -p1 %patch223 -p1 %patch224 -p1 @@ -1455,8 +1502,14 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c %patch229 -p1 %patch230 -p1 %patch231 -p1 +%patch232 -p1 +%patch233 -p1 +%patch234 -p1 +%patch235 -p1 +%patch236 -p1 %patch237 -p1 %patch238 -p1 +%patch241 -p1 %patch242 -p1 @@ -1900,8 +1953,8 @@ sed -i "s|^#\!.\?/usr/bin.*$|#\! %{__python}|" \ /usr/bin/chmod 755 %{buildroot}%{_libdir}/libpython%{pybasever}.so.1.0 /usr/bin/chmod 755 %{buildroot}%{_libdir}/libpython%{pybasever}_d.so.1.0 -mkdir %{buildroot}%{_sysconfdir}/tmpfiles.d -cp %{SOURCE9} %{buildroot}%{_sysconfdir}/tmpfiles.d/python.conf +mkdir %{buildroot}%{_tmpfilesdir} +cp %{SOURCE9} %{buildroot}%{_tmpfilesdir}/python.conf # ====================================================== # Running the upstream test suite @@ -1998,7 +2051,7 @@ rm -fr %{buildroot} %dir %{pylibdir} %dir %{dynload_dir} %dir %{_sysconfdir}/python -%{_sysconfdir}/tmpfiles.d/python.conf +%{_tmpfilesdir}/python.conf %config(noreplace) %{_sysconfdir}/python/cert-verification.cfg %{dynload_dir}/Python-%{version}-py%{pybasever}.egg-info %{dynload_dir}/_bisectmodule.so @@ -2327,29 +2380,67 @@ rm -fr %{buildroot} # ====================================================== %changelog -* Mon Aug 29 2016 Charalampos Stratakis - 2.7.5-39 -- Fix hashlib algorithms breaking by initializing OpenSSL_add_all_digests -function in _hashlib library -Resolves: rhbz#1371132 - -* Tue Aug 09 2016 Charalampos Stratakis - 2.7.5-38 +* Mon Aug 01 2016 Charalampos Stratakis - 2.7.5-48 - Fix for CVE-2016-1000110 HTTPoxy attack -Resolves: rhbz#1359163 +Resolves: rhbz#1359164 -* Tue Aug 09 2016 Charalampos Stratakis - 2.7.5-37 -- Force all child threads to terminate in TestForkInThread -Resolves: rhbz#1365200 +* Mon Jul 11 2016 Charalampos Stratakis - 2.7.5-47 +- Fix for CVE-2016-5636: possible integer overflow and heap corruption in zipimporter.get_data() +Resolves: rhbz#1356364 + +* Mon Jul 11 2016 Charalampos Stratakis - 2.7.5-46 +- Drop patch 221 that backported sslwrap function since it was introducing regressions +- Refactor patch 227 +Resolves: rhbz#1331425 -* Tue Jun 21 2016 Tomas Orsava - 2.7.5-36 +* Tue Jun 21 2016 Tomas Orsava - 2.7.5-45 - Fix for CVE-2016-0772 python: smtplib StartTLS stripping attack (rhbz#1303647) Raise an error when STARTTLS fails (upstream patch) - Fix for CVE-2016-5699 python: http protocol steam injection attack (rhbz#1303699) Disabled HTTP header injections in httplib (upstream patch) -Resolves: rhbz#1346356 +Resolves: rhbz#1346357 + +* Wed May 4 2016 Charalampos Stratakis - 2.7.5-44 +- Fix iteration over files with very long lines +Resolves: rhbz#1271760 + +* Tue May 3 2016 Charalampos Stratakis - 2.7.5-43 +- Move python.conf from /etc/tmpfiles.d/ to /usr/lib/tmpfiles.d/ +Resolves: rhbz#1288426 + +* Mon Apr 4 2016 Charalampos Stratakis - 2.7.5-42 +- JSON decoder lone surrogates fix +Resolves: rhbz#1301017 + +* Mon Apr 4 2016 Charalampos Stratakis - 2.7.5-41 +- Updated PEP493 implementation +Resolves: rhbz#1315758 + +* Thu Mar 31 2016 Charalampos Stratakis - 2.7.5-40 +- Backport of Computed Goto dispatch +Resolves: rhbz#1289277 + +* Mon Mar 21 2016 Charalampos Stratakis - 2.7.5-39 +- Removal of the '$Date$' placeholder on the python(1) man page footer, +which does not expand during build +Resolves: rhbz#1268310 + +* Thu Mar 17 2016 Charalampos Stratakis - 2.7.5-38 +- Fix hashlib algorithms breaking by initializing OpenSSL_add_all_digests +function in _hashlib library +Resolves: rhbz#1295459 + +* Thu Mar 17 2016 Charalampos Stratakis - 2.7.5-37 +- Change HTTPS certificate verification to platform_default +Resolves: rhbz#1278429 + +* Wed Mar 16 2016 Charalampos Stratakis - 2.7.5-36 +- Force all child threads to terminate in TestForkInThread +Resolves: rhbz#1313259 * Thu Mar 10 2016 Charalampos Stratakis - 2.7.5-35 - Adjusted tests to acknowledge lack of SSLv2 support -Resolves: rhbz#1351584 +Resolves: rhbz#1315310 * Fri Oct 09 2015 Matej Stuchlik - 2.7.5-34 - Revert fix for rhbz#1117751 as it leads to regressions