From b439f1c411a9479ccc03c16465cdff50fede79d3 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 10 Jun 2021 15:45:03 +0200 Subject: [PATCH 1/7] Use Py_CompileString rather than PyParser_SimpleParseFile/PyNode_Compile --- src/server/mod_wsgi.c | 68 +++++++++++++++++++++++++++++++--------- src/server/wsgi_python.h | 1 - 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/server/mod_wsgi.c b/src/server/mod_wsgi.c index b657a748..4f1d8765 100644 --- a/src/server/mod_wsgi.c +++ b/src/server/mod_wsgi.c @@ -3645,7 +3645,10 @@ static PyObject *wsgi_load_source(apr_pool_t *pool, request_rec *r, FILE *fp = NULL; PyObject *m = NULL; PyObject *co = NULL; - struct _node *n = NULL; + char *source; + size_t pos = 0; + size_t allocated = 1024; + size_t nread; #if defined(WIN32) && defined(APR_HAS_UNICODE_FS) apr_wchar_t wfilename[APR_PATH_MAX]; @@ -3730,36 +3733,71 @@ static PyObject *wsgi_load_source(apr_pool_t *pool, request_rec *r, return NULL; } - n = PyParser_SimpleParseFile(fp, filename, Py_file_input); - + source = malloc(allocated); + if (source != NULL) { + do { + nread = fread(source + pos, 1, allocated - pos, fp); + pos += nread; + if (nread == 0) { + if (ferror(fp)) { + free(source); + source = NULL; + } + break; + } + if (pos == allocated) { + allocated *= 2; + char *reallocated_source = realloc(source, allocated); + if (reallocated_source == NULL) { + free(source); + source = NULL; + break; + } + source = reallocated_source; + } + } while (!feof(fp)); + } fclose(fp); - - if (!n) { + if (source == NULL) { Py_BEGIN_ALLOW_THREADS if (r) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Failed to parse Python script file '%s'.", getpid(), + "Could not read source file '%s'.", getpid(), process_group, application_group, filename); } else { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server, + ap_log_error(APLOG_MARK, APLOG_ERR, errno, wsgi_server, "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Failed to parse Python script file '%s'.", getpid(), + "Could not read source file '%s'.", getpid(), process_group, application_group, filename); } Py_END_ALLOW_THREADS + return NULL; + } - wsgi_log_python_error(r, NULL, filename, 0); + co = Py_CompileString(filename, source, 0); + free(source); + if (!co) { + Py_BEGIN_ALLOW_THREADS + if (r) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, + "mod_wsgi (pid=%d, process='%s', application='%s'): " + "Could not compile source file '%s'.", getpid(), + process_group, application_group, filename); + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, errno, wsgi_server, + "mod_wsgi (pid=%d, process='%s', application='%s'): " + "Could not compile source file '%s'.", getpid(), + process_group, application_group, filename); + } + Py_END_ALLOW_THREADS return NULL; } - co = (PyObject *)PyNode_Compile(n, filename); - PyNode_Free(n); - - if (co) - m = PyImport_ExecCodeModuleEx((char *)name, co, (char *)filename); + m = PyImport_ExecCodeModuleEx((char *)name, co, (char *)filename); Py_XDECREF(co); diff --git a/src/server/wsgi_python.h b/src/server/wsgi_python.h index fa06e2cb..3b34b731 100644 --- a/src/server/wsgi_python.h +++ b/src/server/wsgi_python.h @@ -43,7 +43,6 @@ #include "structmember.h" #include "compile.h" -#include "node.h" #include "osdefs.h" #include "frameobject.h" From a73166e01394bbbbaad7cda18418dd7cb37fd45e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 10 Jun 2021 15:55:50 +0200 Subject: [PATCH 2/7] Don't call PyEval_InitThreads on Python 3.9+ --- src/server/wsgi_interp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/wsgi_interp.c b/src/server/wsgi_interp.c index bb91b69c..5fc38d1a 100644 --- a/src/server/wsgi_interp.c +++ b/src/server/wsgi_interp.c @@ -2433,10 +2433,10 @@ void wsgi_python_init(apr_pool_t *p) Py_Initialize(); +#if PY_VERSION_HEX < 0x03090000 /* Initialise threading. */ - PyEval_InitThreads(); - +#endif /* * Remove the environment variable we set for the hash * seed. This has to be done in os.environ, which will From 8dbf81e0280c902cd6af6b254d233ecead10b56c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 10 Jun 2021 15:58:25 +0200 Subject: [PATCH 3/7] Replace undocumented PyEval_CallObject with PyObject_CallObject --- src/server/mod_wsgi.c | 44 +++++++++++++++++---------------------- src/server/wsgi_interp.c | 24 ++++++++++----------- src/server/wsgi_logger.c | 4 ++-- src/server/wsgi_metrics.c | 2 +- src/server/wsgi_stream.c | 4 ++-- 5 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/server/mod_wsgi.c b/src/server/mod_wsgi.c index 4f1d8765..903d8572 100644 --- a/src/server/mod_wsgi.c +++ b/src/server/mod_wsgi.c @@ -2897,7 +2897,7 @@ static int Adapter_process_file_wrapper(AdapterObject *self) if (!method) return 0; - object = PyEval_CallObject(method, NULL); + object = PyObject_CallObject(method, NULL); Py_DECREF(method); if (!object) { @@ -3179,7 +3179,7 @@ static int Adapter_run(AdapterObject *self, PyObject *object) args = Py_BuildValue("(OO)", vars, start); - self->sequence = PyEval_CallObject(object, args); + self->sequence = PyObject_CallObject(object, args); if (self->sequence != NULL) { if (!Adapter_process_file_wrapper(self)) { @@ -3301,7 +3301,7 @@ static int Adapter_run(AdapterObject *self, PyObject *object) close = PyObject_GetAttrString(self->sequence, "close"); args = Py_BuildValue("()"); - data = PyEval_CallObject(close, args); + data = PyObject_CallObject(close, args); Py_DECREF(args); Py_XDECREF(data); @@ -3910,7 +3910,7 @@ static int wsgi_reload_required(apr_pool_t *pool, request_rec *r, Py_INCREF(object); args = Py_BuildValue("(s)", resource); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); @@ -4283,7 +4283,7 @@ static int wsgi_execute_script(request_rec *r) } else { args = PyTuple_New(0); - object = PyEval_CallObject(method, args); + object = PyObject_CallObject(method, args); Py_DECREF(args); } @@ -6892,7 +6892,7 @@ static int wsgi_execute_dispatch(request_rec *r) if (adapter) { Py_INCREF(object); args = Py_BuildValue("(O)", vars); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); @@ -6974,7 +6974,7 @@ static int wsgi_execute_dispatch(request_rec *r) if (adapter) { Py_INCREF(object); args = Py_BuildValue("(O)", vars); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); @@ -7056,7 +7056,7 @@ static int wsgi_execute_dispatch(request_rec *r) if (adapter) { Py_INCREF(object); args = Py_BuildValue("(O)", vars); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); @@ -7147,9 +7147,7 @@ static int wsgi_execute_dispatch(request_rec *r) adapter->log->ob_type->tp_name); } else { - args = PyTuple_New(0); - object = PyEval_CallObject(method, args); - Py_DECREF(args); + object = PyObject_CallObject(method, NULL); } Py_XDECREF(object); @@ -14841,7 +14839,7 @@ static authn_status wsgi_check_password(request_rec *r, const char *user, Py_INCREF(object); args = Py_BuildValue("(Oss)", vars, user, password); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); @@ -14911,10 +14909,8 @@ static authn_status wsgi_check_password(request_rec *r, const char *user, adapter->log->ob_type->tp_name); } else { - args = PyTuple_New(0); - result = PyEval_CallObject(method, args); + result = PyObject_CallObject(method, NULL); Py_XDECREF(result); - Py_DECREF(args); } /* Log any details of exceptions if execution failed. */ @@ -15086,7 +15082,7 @@ static authn_status wsgi_get_realm_hash(request_rec *r, const char *user, Py_INCREF(object); args = Py_BuildValue("(Oss)", vars, user, realm); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); @@ -15158,7 +15154,7 @@ static authn_status wsgi_get_realm_hash(request_rec *r, const char *user, } else { args = PyTuple_New(0); - result = PyEval_CallObject(method, args); + result = PyObject_CallObject(method, args); Py_XDECREF(result); Py_DECREF(args); } @@ -15337,7 +15333,7 @@ static int wsgi_groups_for_user(request_rec *r, WSGIRequestConfig *config, Py_INCREF(object); args = Py_BuildValue("(Os)", vars, r->user); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); @@ -15450,7 +15446,7 @@ static int wsgi_groups_for_user(request_rec *r, WSGIRequestConfig *config, } else { args = PyTuple_New(0); - result = PyEval_CallObject(method, args); + result = PyObject_CallObject(method, args); Py_XDECREF(result); Py_DECREF(args); } @@ -15623,7 +15619,7 @@ static int wsgi_allow_access(request_rec *r, WSGIRequestConfig *config, Py_INCREF(object); args = Py_BuildValue("(Oz)", vars, host); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); @@ -15675,7 +15671,7 @@ static int wsgi_allow_access(request_rec *r, WSGIRequestConfig *config, } else { args = PyTuple_New(0); - result = PyEval_CallObject(method, args); + result = PyObject_CallObject(method, args); Py_XDECREF(result); Py_DECREF(args); } @@ -15888,7 +15884,7 @@ static int wsgi_hook_check_user_id(request_rec *r) Py_INCREF(object); args = Py_BuildValue("(Oss)", vars, r->user, password); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); Py_DECREF(vars); @@ -15956,10 +15952,8 @@ static int wsgi_hook_check_user_id(request_rec *r) adapter->log->ob_type->tp_name); } else { - args = PyTuple_New(0); - result = PyEval_CallObject(method, args); + result = PyObject_CallObject(method, NULL); Py_XDECREF(result); - Py_DECREF(args); } /* Log any details of exceptions if execution failed. */ diff --git a/src/server/wsgi_interp.c b/src/server/wsgi_interp.c index 5fc38d1a..027325fd 100644 --- a/src/server/wsgi_interp.c +++ b/src/server/wsgi_interp.c @@ -100,7 +100,7 @@ static PyObject *SignalIntercept_call( Py_INCREF(o); log = newLogObject(NULL, APLOG_WARNING, NULL, 0); args = Py_BuildValue("(OOO)", Py_None, Py_None, log); - result = PyEval_CallObject(o, args); + result = PyObject_CallObject(o, args); Py_XDECREF(result); Py_DECREF(args); Py_DECREF(log); @@ -238,7 +238,7 @@ static PyObject *ShutdownInterpreter_call( PyObject *res = NULL; Py_INCREF(exitfunc); PySys_SetObject("exitfunc", (PyObject *)NULL); - res = PyEval_CallObject(exitfunc, (PyObject *)NULL); + res = PyObject_CallObject(exitfunc, (PyObject *)NULL); if (res == NULL) { PyObject *m = NULL; @@ -290,7 +290,7 @@ static PyObject *ShutdownInterpreter_call( log = newLogObject(NULL, APLOG_ERR, NULL, 0); args = Py_BuildValue("(OOOOO)", type, value, traceback, Py_None, log); - result = PyEval_CallObject(o, args); + result = PyObject_CallObject(o, args); Py_DECREF(args); Py_DECREF(log); Py_DECREF(o); @@ -639,7 +639,7 @@ InterpreterObject *newInterpreterObject(const char *name) callback = PyCFunction_New(&wsgi_system_exit_method[0], NULL); args = Py_BuildValue("(iO)", SIGTERM, callback); - res = PyEval_CallObject(func, args); + res = PyObject_CallObject(func, args); if (!res) { Py_BEGIN_ALLOW_THREADS @@ -984,7 +984,7 @@ InterpreterObject *newInterpreterObject(const char *name) Py_END_ALLOW_THREADS args = Py_BuildValue("(O)", item); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); if (!result) { Py_BEGIN_ALLOW_THREADS @@ -1019,7 +1019,7 @@ InterpreterObject *newInterpreterObject(const char *name) Py_END_ALLOW_THREADS args = Py_BuildValue("(O)", item); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); if (!result) { Py_BEGIN_ALLOW_THREADS @@ -1054,7 +1054,7 @@ InterpreterObject *newInterpreterObject(const char *name) Py_END_ALLOW_THREADS args = Py_BuildValue("(O)", item); - result = PyEval_CallObject(object, args); + result = PyObject_CallObject(object, args); if (!result) { Py_BEGIN_ALLOW_THREADS @@ -1672,7 +1672,7 @@ static void Interpreter_dealloc(InterpreterObject *self) if (func) { PyObject *res = NULL; Py_INCREF(func); - res = PyEval_CallObject(func, (PyObject *)NULL); + res = PyObject_CallObject(func, (PyObject *)NULL); if (!res) { PyErr_Clear(); } @@ -1699,7 +1699,7 @@ static void Interpreter_dealloc(InterpreterObject *self) if (func) { PyObject *res = NULL; Py_INCREF(func); - res = PyEval_CallObject(func, (PyObject *)NULL); + res = PyObject_CallObject(func, (PyObject *)NULL); if (res == NULL) { PyObject *m = NULL; @@ -1742,7 +1742,7 @@ static void Interpreter_dealloc(InterpreterObject *self) log = newLogObject(NULL, APLOG_ERR, NULL, 0); args = Py_BuildValue("(OOOOO)", type, value, traceback, Py_None, log); - result = PyEval_CallObject(o, args); + result = PyObject_CallObject(o, args); Py_DECREF(args); Py_DECREF(log); Py_DECREF(o); @@ -1823,7 +1823,7 @@ static void Interpreter_dealloc(InterpreterObject *self) PyObject *res = NULL; Py_INCREF(exitfunc); PySys_SetObject("exitfunc", (PyObject *)NULL); - res = PyEval_CallObject(exitfunc, (PyObject *)NULL); + res = PyObject_CallObject(exitfunc, (PyObject *)NULL); if (res == NULL) { PyObject *m = NULL; @@ -1875,7 +1875,7 @@ static void Interpreter_dealloc(InterpreterObject *self) log = newLogObject(NULL, APLOG_ERR, NULL, 0); args = Py_BuildValue("(OOOOO)", type, value, traceback, Py_None, log); - result = PyEval_CallObject(o, args); + result = PyObject_CallObject(o, args); Py_DECREF(args); Py_DECREF(log); Py_DECREF(o); diff --git a/src/server/wsgi_logger.c b/src/server/wsgi_logger.c index f47a720f..c7470a53 100644 --- a/src/server/wsgi_logger.c +++ b/src/server/wsgi_logger.c @@ -96,7 +96,7 @@ PyObject *newLogWrapperObject(PyObject *buffer) args = Py_BuildValue("(OssOOO)", buffer, "utf-8", "replace", Py_None, Py_True, Py_True); - wrapper = PyEval_CallObject(object, args); + wrapper = PyObject_CallObject(object, args); Py_DECREF(args); Py_DECREF(object); @@ -662,7 +662,7 @@ void wsgi_log_python_error(request_rec *r, PyObject *log, Py_INCREF(o); args = Py_BuildValue("(OOOOO)", type, value, traceback, Py_None, log); - result = PyEval_CallObject(o, args); + result = PyObject_CallObject(o, args); Py_DECREF(args); Py_DECREF(o); } diff --git a/src/server/wsgi_metrics.c b/src/server/wsgi_metrics.c index 29ee7e69..7b628596 100644 --- a/src/server/wsgi_metrics.c +++ b/src/server/wsgi_metrics.c @@ -1269,7 +1269,7 @@ void wsgi_call_callbacks(const char *name, PyObject *callbacks, log = newLogObject(NULL, APLOG_ERR, NULL, 0); args = Py_BuildValue("(OOOOO)", type, value, traceback, Py_None, log); - result = PyEval_CallObject(o, args); + result = PyObject_CallObject(o, args); Py_DECREF(args); Py_DECREF(log); Py_DECREF(o); diff --git a/src/server/wsgi_stream.c b/src/server/wsgi_stream.c index e40c8049..39d58428 100644 --- a/src/server/wsgi_stream.c +++ b/src/server/wsgi_stream.c @@ -124,7 +124,7 @@ static PyObject *Stream_iternext(StreamObject *self) } args = Py_BuildValue("(O)", attribute); - result = PyEval_CallObject(method, args); + result = PyObject_CallObject(method, args); Py_DECREF(args); Py_DECREF(method); @@ -164,7 +164,7 @@ static PyObject *Stream_close(StreamObject *self, PyObject *args) method = PyObject_GetAttrString(self->filelike, "close"); if (method) { - result = PyEval_CallObject(method, (PyObject *)NULL); + result = PyObject_CallObject(method, (PyObject *)NULL); if (!result) PyErr_Clear(); Py_DECREF(method); From 744558fff7130229a50ac89a35038ccde0c94b70 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 10 Jun 2021 16:01:28 +0200 Subject: [PATCH 4/7] Remove unused variable --- src/server/wsgi_metrics.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/server/wsgi_metrics.c b/src/server/wsgi_metrics.c index 7b628596..5c6d8762 100644 --- a/src/server/wsgi_metrics.c +++ b/src/server/wsgi_metrics.c @@ -420,7 +420,6 @@ static PyObject *wsgi_request_metrics(void) double application_time_total = 0; double application_time_avg = 0; - WSGIThreadInfo **thread_info = NULL; int request_threads_active = 0; int i; @@ -583,8 +582,6 @@ static PyObject *wsgi_request_metrics(void) WSGI_INTERNED_STRING(request_threads_started), object); Py_DECREF(object); - thread_info = (WSGIThreadInfo **)wsgi_thread_details->elts; - request_busy_time = stop_request_busy_time - start_request_busy_time; capacity_utilization = (request_busy_time / sample_period / From e3c31e518e6d02bab293b2394d1e8ece8a8de444 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 11 Jun 2021 12:59:08 +0200 Subject: [PATCH 5/7] Correct Py_CompileString usage --- src/server/mod_wsgi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/mod_wsgi.c b/src/server/mod_wsgi.c index 903d8572..705c470f 100644 --- a/src/server/mod_wsgi.c +++ b/src/server/mod_wsgi.c @@ -3776,7 +3776,7 @@ static PyObject *wsgi_load_source(apr_pool_t *pool, request_rec *r, return NULL; } - co = Py_CompileString(filename, source, 0); + co = Py_CompileString(source, filename, Py_file_input); free(source); if (!co) { From 715a1327ad19658ee9b8a3233ae150875a10334e Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 11 Jun 2021 13:00:09 +0200 Subject: [PATCH 6/7] Use Python API to read source files --- src/server/mod_wsgi.c | 155 ++++++++---------------------------------- 1 file changed, 29 insertions(+), 126 deletions(-) diff --git a/src/server/mod_wsgi.c b/src/server/mod_wsgi.c index 705c470f..9ebd6856 100644 --- a/src/server/mod_wsgi.c +++ b/src/server/mod_wsgi.c @@ -3642,155 +3642,58 @@ static PyObject *wsgi_load_source(apr_pool_t *pool, request_rec *r, const char *application_group, int ignore_system_exit) { - FILE *fp = NULL; PyObject *m = NULL; PyObject *co = NULL; - char *source; - size_t pos = 0; - size_t allocated = 1024; - size_t nread; - -#if defined(WIN32) && defined(APR_HAS_UNICODE_FS) - apr_wchar_t wfilename[APR_PATH_MAX]; -#endif + PyObject *io_module = NULL; + PyObject *fileobject = NULL; + PyObject *source_bytes_object = NULL; + PyObject *result = NULL; + char *source_buf = NULL; - if (exists) { - Py_BEGIN_ALLOW_THREADS - if (r) { - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Reloading WSGI script '%s'.", getpid(), - process_group, application_group, filename); - } - else { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Reloading WSGI script '%s'.", getpid(), - process_group, application_group, filename); - } - Py_END_ALLOW_THREADS + io_module = PyImport_AddModule("io"); + if (!io_module) { + goto load_source_finally; } - else { - Py_BEGIN_ALLOW_THREADS - if (r) { - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Loading Python script file '%s'.", getpid(), - process_group, application_group, filename); - } - else { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, wsgi_server, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Loading Python script file '%s'.", getpid(), - process_group, application_group, filename); - } - Py_END_ALLOW_THREADS - } - -#if defined(WIN32) && defined(APR_HAS_UNICODE_FS) - if (wsgi_utf8_to_unicode_path(wfilename, sizeof(wfilename) / - sizeof(apr_wchar_t), filename)) { - Py_BEGIN_ALLOW_THREADS - if (r) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "mod_wsgi (pid=%d, process='%s', " - "application='%s'): Failed to convert '%s' " - "to UCS2 filename.", getpid(), - process_group, application_group, filename); - } - else { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, wsgi_server, - "mod_wsgi (pid=%d, process='%s', " - "application='%s'): Failed to convert '%s' " - "to UCS2 filename.", getpid(), - process_group, application_group, filename); - } - Py_END_ALLOW_THREADS - return NULL; + fileobject = PyObject_CallMethod(io_module, "open", "ss", filename, "rb"); + if (!fileobject) { + goto load_source_finally; } - fp = _wfopen(wfilename, L"r"); -#else - fp = fopen(filename, "r"); -#endif - - if (!fp) { - Py_BEGIN_ALLOW_THREADS - if (r) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Call to fopen() failed for '%s'.", getpid(), - process_group, application_group, filename); - } - else { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, wsgi_server, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Call to fopen() failed for '%s'.", getpid(), - process_group, application_group, filename); - } - Py_END_ALLOW_THREADS - return NULL; + source_bytes_object = PyObject_CallMethod(fileobject, "read", ""); + if (!source_bytes_object) { + goto load_source_finally; } - source = malloc(allocated); - if (source != NULL) { - do { - nread = fread(source + pos, 1, allocated - pos, fp); - pos += nread; - if (nread == 0) { - if (ferror(fp)) { - free(source); - source = NULL; - } - break; - } - if (pos == allocated) { - allocated *= 2; - char *reallocated_source = realloc(source, allocated); - if (reallocated_source == NULL) { - free(source); - source = NULL; - break; - } - source = reallocated_source; - } - } while (!feof(fp)); + result = PyObject_CallMethod(fileobject, "close", ""); + if (!result) { + goto load_source_finally; } - fclose(fp); - if (source == NULL) { - Py_BEGIN_ALLOW_THREADS - if (r) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Could not read source file '%s'.", getpid(), - process_group, application_group, filename); - } - else { - ap_log_error(APLOG_MARK, APLOG_ERR, errno, wsgi_server, - "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Could not read source file '%s'.", getpid(), - process_group, application_group, filename); - } - Py_END_ALLOW_THREADS - return NULL; + + source_buf = PyBytes_AsString(source_bytes_object); + if (!source_buf) { + goto load_source_finally; } - co = Py_CompileString(source, filename, Py_file_input); - free(source); + co = Py_CompileString(source_buf, filename, Py_file_input); +load_source_finally: + Py_XDECREF(io_module); + Py_XDECREF(fileobject); + Py_XDECREF(source_bytes_object); + Py_XDECREF(result); if (!co) { Py_BEGIN_ALLOW_THREADS if (r) { ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r, "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Could not compile source file '%s'.", getpid(), + "Could not read/compile source file '%s'.", getpid(), process_group, application_group, filename); } else { ap_log_error(APLOG_MARK, APLOG_ERR, errno, wsgi_server, "mod_wsgi (pid=%d, process='%s', application='%s'): " - "Could not compile source file '%s'.", getpid(), + "Could not read/compile source file '%s'.", getpid(), process_group, application_group, filename); } Py_END_ALLOW_THREADS From ad1bd9f00eaf0ffa04df62914c1bd7e9f00d1b09 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 11 Jun 2021 13:00:34 +0200 Subject: [PATCH 7/7] configure: Use sysconfig rather than the deprecated distutils.sysconfig --- configure.ac | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 0db345f4..9d4f779e 100644 --- a/configure.ac +++ b/configure.ac @@ -106,11 +106,11 @@ fi AC_SUBST(PYTHON) PYTHON_VERSION=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("VERSION"))'` PYTHON_LDVERSION=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("LDVERSION") or "")'` if test x"${PYTHON_LDVERSION}" = x""; then @@ -118,11 +118,11 @@ if test x"${PYTHON_LDVERSION}" = x""; then fi CPPFLAGS1=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write("-I" + sysconfig.get_config_var("INCLUDEPY"))'` CPPFLAGS2=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(" ".join(filter(lambda x: x.startswith("-D"), \ sysconfig.get_config_var("CFLAGS").split())))'` @@ -137,20 +137,20 @@ CPPFLAGS="${CPPFLAGS} ${CPPFLAGS1} ${CPPFLAGS2} ${CPPFLAGS3}" AC_SUBST(CPPFLAGS) PYTHONLIBDIR=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("LIBDIR"))'` PYTHONCFGDIR=`${PYTHON} -c 'from sys import stdout; \ import distutils.sysconfig; \ stdout.write(distutils.sysconfig.get_python_lib(plat_specific=1, \ standard_lib=1) +"/config")'` PYTHONFRAMEWORKDIR=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("PYTHONFRAMEWORKDIR"))'` PYTHONFRAMEWORKPREFIX=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("PYTHONFRAMEWORKPREFIX"))'` PYTHONFRAMEWORK=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("PYTHONFRAMEWORK"))'` if test "${PYTHON_LDVERSION}" != "${PYTHON_VERSION}"; then @@ -176,10 +176,10 @@ if test "${PYTHONFRAMEWORKDIR}" = "no-framework" -o \ fi LDLIBS2=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("LIBS"))'` LDLIBS3=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("SYSLIBS"))'` else LDFLAGS1="-Wl,-F${PYTHONFRAMEWORKPREFIX} -framework ${PYTHONFRAMEWORK}" @@ -187,13 +187,13 @@ else VERSION="${PYTHON_VERSION}" STRING="${PYTHONFRAMEWORKDIR}/Versions/${VERSION}/${PYTHONFRAMEWORK}" LDFLAGS2=`${PYTHON} -c "from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var( \"LINKFORSHARED\").replace(\"${STRING}\", ''))" | \ sed -e 's/-Wl,-stack_size,[[0-9]]*//'` LDLIBS1=`${PYTHON} -c 'from sys import stdout; \ - from distutils import sysconfig; \ + import sysconfig; \ stdout.write(sysconfig.get_config_var("LIBS"))'` fi