https://github.com/python/cpython/commit/d6954b6421aa34afd280df9c44ded21a2348a6ea
commit: d6954b6421aa34afd280df9c44ded21a2348a6ea
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2024-09-25T21:41:09+02:00
summary:
gh-124513: Check args in framelocalsproxy_new() (#124515)
Fix a crash in FrameLocalsProxy constructor: check the number of
arguments.
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst
M Lib/test/test_frame.py
M Objects/frameobject.c
diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py
index ca88e657367d9a..32de8ed9a13f80 100644
--- a/Lib/test/test_frame.py
+++ b/Lib/test/test_frame.py
@@ -494,6 +494,27 @@ class ObjectSubclass:
with self.assertRaises(TypeError):
proxy[obj] = 0
+ def test_constructor(self):
+ FrameLocalsProxy = type([sys._getframe().f_locals
+ for x in range(1)][0])
+ self.assertEqual(FrameLocalsProxy.__name__, 'FrameLocalsProxy')
+
+ def make_frame():
+ x = 1
+ y = 2
+ return sys._getframe()
+
+ proxy = FrameLocalsProxy(make_frame())
+ self.assertEqual(proxy, {'x': 1, 'y': 2})
+
+ # constructor expects 1 frame argument
+ with self.assertRaises(TypeError):
+ FrameLocalsProxy() # no arguments
+ with self.assertRaises(TypeError):
+ FrameLocalsProxy(123) # wrong type
+ with self.assertRaises(TypeError):
+ FrameLocalsProxy(frame=sys._getframe()) # no keyword arguments
+
class FrameLocalsProxyMappingTests(mapping_tests.TestHashMappingProtocol):
"""Test that FrameLocalsProxy behaves like a Mapping (with exceptions)"""
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst
new file mode 100644
index 00000000000000..691e03b3b98e7a
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-14-45-56.gh-issue-124513.ywiXtr.rst
@@ -0,0 +1,2 @@
+Fix a crash in FrameLocalsProxy constructor: check the number of arguments.
+Patch by Victor Stinner.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 9f1c031dcb9a9d..f3a66ffc9aac8f 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -310,14 +310,31 @@ framelocalsproxy_dealloc(PyObject *self)
static PyObject *
framelocalsproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
+ if (PyTuple_GET_SIZE(args) != 1) {
+ PyErr_Format(PyExc_TypeError,
+ "FrameLocalsProxy expected 1 argument, got %zd",
+ PyTuple_GET_SIZE(args));
+ return NULL;
+ }
+ PyObject *item = PyTuple_GET_ITEM(args, 0);
+
+ if (!PyFrame_Check(item)) {
+ PyErr_Format(PyExc_TypeError, "expect frame, not %T", item);
+ return NULL;
+ }
+ PyFrameObject *frame = (PyFrameObject*)item;
+
+ if (kwds != NULL && PyDict_Size(kwds) != 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "FrameLocalsProxy takes no keyword arguments");
+ return 0;
+ }
+
PyFrameLocalsProxyObject *self = (PyFrameLocalsProxyObject
*)type->tp_alloc(type, 0);
if (self == NULL) {
return NULL;
}
- PyFrameObject *frame = (PyFrameObject*)PyTuple_GET_ITEM(args, 0);
- assert(PyFrame_Check(frame));
-
((PyFrameLocalsProxyObject*)self)->frame =
(PyFrameObject*)Py_NewRef(frame);
return (PyObject *)self;
_______________________________________________
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]