Skip to content

Commit d6954b6

Browse files
authored
gh-124513: Check args in framelocalsproxy_new() (#124515)
Fix a crash in FrameLocalsProxy constructor: check the number of arguments.
1 parent 0d9d56c commit d6954b6

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

Lib/test/test_frame.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,27 @@ class ObjectSubclass:
494494
with self.assertRaises(TypeError):
495495
proxy[obj] = 0
496496

497+
def test_constructor(self):
498+
FrameLocalsProxy = type([sys._getframe().f_locals
499+
for x in range(1)][0])
500+
self.assertEqual(FrameLocalsProxy.__name__, 'FrameLocalsProxy')
501+
502+
def make_frame():
503+
x = 1
504+
y = 2
505+
return sys._getframe()
506+
507+
proxy = FrameLocalsProxy(make_frame())
508+
self.assertEqual(proxy, {'x': 1, 'y': 2})
509+
510+
# constructor expects 1 frame argument
511+
with self.assertRaises(TypeError):
512+
FrameLocalsProxy() # no arguments
513+
with self.assertRaises(TypeError):
514+
FrameLocalsProxy(123) # wrong type
515+
with self.assertRaises(TypeError):
516+
FrameLocalsProxy(frame=sys._getframe()) # no keyword arguments
517+
497518

498519
class FrameLocalsProxyMappingTests(mapping_tests.TestHashMappingProtocol):
499520
"""Test that FrameLocalsProxy behaves like a Mapping (with exceptions)"""
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash in FrameLocalsProxy constructor: check the number of arguments.
2+
Patch by Victor Stinner.

Objects/frameobject.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,31 @@ framelocalsproxy_dealloc(PyObject *self)
310310
static PyObject *
311311
framelocalsproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
312312
{
313+
if (PyTuple_GET_SIZE(args) != 1) {
314+
PyErr_Format(PyExc_TypeError,
315+
"FrameLocalsProxy expected 1 argument, got %zd",
316+
PyTuple_GET_SIZE(args));
317+
return NULL;
318+
}
319+
PyObject *item = PyTuple_GET_ITEM(args, 0);
320+
321+
if (!PyFrame_Check(item)) {
322+
PyErr_Format(PyExc_TypeError, "expect frame, not %T", item);
323+
return NULL;
324+
}
325+
PyFrameObject *frame = (PyFrameObject*)item;
326+
327+
if (kwds != NULL && PyDict_Size(kwds) != 0) {
328+
PyErr_SetString(PyExc_TypeError,
329+
"FrameLocalsProxy takes no keyword arguments");
330+
return 0;
331+
}
332+
313333
PyFrameLocalsProxyObject *self = (PyFrameLocalsProxyObject *)type->tp_alloc(type, 0);
314334
if (self == NULL) {
315335
return NULL;
316336
}
317337

318-
PyFrameObject *frame = (PyFrameObject*)PyTuple_GET_ITEM(args, 0);
319-
assert(PyFrame_Check(frame));
320-
321338
((PyFrameLocalsProxyObject*)self)->frame = (PyFrameObject*)Py_NewRef(frame);
322339

323340
return (PyObject *)self;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy