mirror of https://github.com/python/cpython
gh-126220: Fix crash on calls to `_lsprof.Profiler` methods with 0 args (backportable) (#126271)
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
This commit is contained in:
parent
72dd4714f9
commit
28b148fb32
|
@ -30,6 +30,22 @@ class CProfileTest(ProfileTest):
|
||||||
|
|
||||||
self.assertEqual(cm.unraisable.exc_type, TypeError)
|
self.assertEqual(cm.unraisable.exc_type, TypeError)
|
||||||
|
|
||||||
|
def test_crash_with_not_enough_args(self):
|
||||||
|
# gh-126220
|
||||||
|
import _lsprof
|
||||||
|
|
||||||
|
for profile in [_lsprof.Profiler(), cProfile.Profile()]:
|
||||||
|
for method in [
|
||||||
|
"_pystart_callback",
|
||||||
|
"_pyreturn_callback",
|
||||||
|
"_ccall_callback",
|
||||||
|
"_creturn_callback",
|
||||||
|
]:
|
||||||
|
with self.subTest(profile=profile, method=method):
|
||||||
|
method_obj = getattr(profile, method)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
method_obj() # should not crash
|
||||||
|
|
||||||
def test_evil_external_timer(self):
|
def test_evil_external_timer(self):
|
||||||
# gh-120289
|
# gh-120289
|
||||||
# Disabling profiler in external timer should not crash
|
# Disabling profiler in external timer should not crash
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix crash in :class:`!cProfile.Profile` and :class:`!_lsprof.Profiler` when their
|
||||||
|
callbacks were directly called with 0 arguments.
|
|
@ -608,6 +608,12 @@ setBuiltins(ProfilerObject *pObj, int nvalue)
|
||||||
|
|
||||||
PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
||||||
{
|
{
|
||||||
|
if (size < 2) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"_pystart_callback expected 2 arguments, got %zd",
|
||||||
|
size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
PyObject* code = args[0];
|
PyObject* code = args[0];
|
||||||
ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code);
|
ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code);
|
||||||
|
|
||||||
|
@ -616,6 +622,12 @@ PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize
|
||||||
|
|
||||||
PyObject* pyreturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
PyObject* pyreturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
||||||
{
|
{
|
||||||
|
if (size < 3) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"_pyreturn_callback expected 3 arguments, got %zd",
|
||||||
|
size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
PyObject* code = args[0];
|
PyObject* code = args[0];
|
||||||
ptrace_leave_call((PyObject*)self, (void *)code);
|
ptrace_leave_call((PyObject*)self, (void *)code);
|
||||||
|
|
||||||
|
@ -651,6 +663,12 @@ PyObject* get_cfunc_from_callable(PyObject* callable, PyObject* self_arg, PyObje
|
||||||
|
|
||||||
PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
||||||
{
|
{
|
||||||
|
if (size < 4) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"_ccall_callback expected 4 arguments, got %zd",
|
||||||
|
size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (self->flags & POF_BUILTINS) {
|
if (self->flags & POF_BUILTINS) {
|
||||||
PyObject* callable = args[2];
|
PyObject* callable = args[2];
|
||||||
PyObject* self_arg = args[3];
|
PyObject* self_arg = args[3];
|
||||||
|
@ -669,6 +687,12 @@ PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t
|
||||||
|
|
||||||
PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
|
||||||
{
|
{
|
||||||
|
if (size < 4) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"_creturn_callback expected 4 arguments, got %zd",
|
||||||
|
size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (self->flags & POF_BUILTINS) {
|
if (self->flags & POF_BUILTINS) {
|
||||||
PyObject* callable = args[2];
|
PyObject* callable = args[2];
|
||||||
PyObject* self_arg = args[3];
|
PyObject* self_arg = args[3];
|
||||||
|
|
Loading…
Reference in New Issue