Python: fixing incorrect function object dereference.
The __call__ method can be native and not be a PyFunction type. A type check is thus required before accessing op_code and other fields. Reproduced on Ubuntu 21.04, Python 3.9.4 and Falcon framework: here, the App.__call__ method is compiled with Cython, so accessing op_code->co_flags is invalid; accidentally, the COROUTINE bit is set which forces the Python module into the ASGI mode. The workaround is explicit protocol specification. Note: it is impossible to specify the legacy mode for ASGI.
This commit is contained in:
@@ -43,6 +43,13 @@ some Spring Boot applications failed to start, notably with Grails.
|
|||||||
</para>
|
</para>
|
||||||
</change>
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para>
|
||||||
|
incorrect Python protocol auto detection (ASGI or WSGI) for native callable
|
||||||
|
object, notably with Falcon.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
</changes>
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -117,15 +117,20 @@ nxt_python_asgi_get_func(PyObject *obj)
|
|||||||
if (PyMethod_Check(call)) {
|
if (PyMethod_Check(call)) {
|
||||||
obj = PyMethod_GET_FUNCTION(call);
|
obj = PyMethod_GET_FUNCTION(call);
|
||||||
|
|
||||||
Py_INCREF(obj);
|
if (PyFunction_Check(obj)) {
|
||||||
Py_DECREF(call);
|
Py_INCREF(obj);
|
||||||
|
|
||||||
return obj;
|
} else {
|
||||||
|
obj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
obj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(call);
|
Py_DECREF(call);
|
||||||
|
|
||||||
return NULL;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -161,8 +166,9 @@ nxt_python_asgi_init(nxt_unit_init_t *init, nxt_python_proto_t *proto)
|
|||||||
for (i = 0; i < nxt_py_targets->count; i++) {
|
for (i = 0; i < nxt_py_targets->count; i++) {
|
||||||
func = nxt_python_asgi_get_func(nxt_py_targets->target[i].application);
|
func = nxt_python_asgi_get_func(nxt_py_targets->target[i].application);
|
||||||
if (nxt_slow_path(func == NULL)) {
|
if (nxt_slow_path(func == NULL)) {
|
||||||
nxt_unit_alert(NULL, "Python cannot find function for callable");
|
nxt_unit_debug(NULL, "asgi: cannot find function for callable, "
|
||||||
return NXT_UNIT_ERROR;
|
"unable to check for legacy mode (#%d)", i);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = (PyCodeObject *) PyFunction_GET_CODE(func);
|
code = (PyCodeObject *) PyFunction_GET_CODE(func);
|
||||||
|
|||||||
Reference in New Issue
Block a user