https://github.com/python/cpython/commit/b5c19bdba8f58cba80a1101ce8aad90be3486571
commit: b5c19bdba8f58cba80a1101ce8aad90be3486571
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: sobolevn <[email protected]>
date: 2024-11-01T22:18:50Z
summary:

[3.12] gh-126220: Fix crash on calls to `_lsprof.Profiler` methods with 0 args 
(backportable) (GH-126271) (#126311)

gh-126220: Fix crash on calls to `_lsprof.Profiler` methods with 0 args 
(backportable) (GH-126271)
(cherry picked from commit 28b148fb32e4548b461137d18d1ab6d366395d36)

Co-authored-by: sobolevn <[email protected]>
Co-authored-by: Erlend E. Aasland <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-10-31-14-06-28.gh-issue-126220.uJAJCU.rst
M Lib/test/test_cprofile.py
M Modules/_lsprof.c

diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index 14d69b6f5f3f15..3b7fd034276a22 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -30,6 +30,22 @@ def test_bad_counter_during_dealloc(self):
 
             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):
         # gh-120289
         # Disabling profiler in external timer should not crash
diff --git 
a/Misc/NEWS.d/next/Library/2024-10-31-14-06-28.gh-issue-126220.uJAJCU.rst 
b/Misc/NEWS.d/next/Library/2024-10-31-14-06-28.gh-issue-126220.uJAJCU.rst
new file mode 100644
index 00000000000000..555f2f3bafbf33
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-31-14-06-28.gh-issue-126220.uJAJCU.rst
@@ -0,0 +1,2 @@
+Fix crash in :class:`!cProfile.Profile` and :class:`!_lsprof.Profiler` when 
their
+callbacks were directly called with 0 arguments.
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c
index 2c82b18c0e18d7..d11689906e574d 100644
--- a/Modules/_lsprof.c
+++ b/Modules/_lsprof.c
@@ -604,6 +604,12 @@ setBuiltins(ProfilerObject *pObj, int nvalue)
 
 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];
     ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code);
 
@@ -612,6 +618,12 @@ PyObject* pystart_callback(ProfilerObject* self, PyObject 
*const *args, Py_ssize
 
 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];
     ptrace_leave_call((PyObject*)self, (void *)code);
 
@@ -647,6 +659,12 @@ PyObject* get_cfunc_from_callable(PyObject* callable, 
PyObject* self_arg, PyObje
 
 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) {
         PyObject* callable = args[2];
         PyObject* self_arg = args[3];
@@ -665,6 +683,12 @@ PyObject* ccall_callback(ProfilerObject* self, PyObject 
*const *args, Py_ssize_t
 
 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) {
         PyObject* callable = args[2];
         PyObject* self_arg = args[3];

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to