Skip to content

Commit

Permalink
[3.13] gh-124513: Check args in framelocalsproxy_new() (GH-124515) (#…
Browse files Browse the repository at this point in the history
…124539)

gh-124513: Check args in framelocalsproxy_new() (GH-124515)

Fix a crash in FrameLocalsProxy constructor: check the number of
arguments.
(cherry picked from commit d6954b6)

Co-authored-by: Victor Stinner <[email protected]>
  • Loading branch information
miss-islington and vstinner authored Sep 30, 2024
1 parent c7f9332 commit 62f691f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
21 changes: 21 additions & 0 deletions Lib/test/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,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)"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a crash in FrameLocalsProxy constructor: check the number of arguments.
Patch by Victor Stinner.
23 changes: 20 additions & 3 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,14 +308,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;
Expand Down

0 comments on commit 62f691f

Please sign in to comment.