Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit57e727a

Browse files
authored
[3.11]gh-99110: Initialize frame->previous in init_frame to fix segmentation fault (GH-100182) (#100478)
(cherry picked from commit88d565f)Co-authored-by: Bill Fisher <william.w.fisher@gmail.com>
1 parentb914054 commit57e727a

File tree

5 files changed

+35
-1
lines changed

5 files changed

+35
-1
lines changed

‎Include/internal/pycore_frame.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@ static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) {
9494

9595
void_PyFrame_Copy(_PyInterpreterFrame*src,_PyInterpreterFrame*dest);
9696

97-
/* Consumes reference to func */
97+
/* Consumes reference to func and locals.
98+
Does not initialize frame->previous, which happens
99+
when frame is linked into the frame stack.
100+
*/
98101
staticinlinevoid
99102
_PyFrame_InitializeSpecials(
100103
_PyInterpreterFrame*frame,PyFunctionObject*func,

‎Lib/test/test_capi/test_misc.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,16 @@ def test_frame_get_generator(self):
13351335
frame=next(gen)
13361336
self.assertIs(gen,_testcapi.frame_getgenerator(frame))
13371337

1338+
deftest_frame_fback_api(self):
1339+
"""Test that accessing `f_back` does not cause a segmentation fault on
1340+
a frame created with `PyFrame_New` (GH-99110)."""
1341+
defdummy():
1342+
pass
1343+
1344+
frame=_testcapi.frame_new(dummy.__code__,globals(),locals())
1345+
# The following line should not cause a segmentation fault.
1346+
self.assertIsNone(frame.f_back)
1347+
13381348

13391349
SUFFICIENT_TO_DEOPT_AND_SPECIALIZE=100
13401350

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Initialize frame->previous in frameobject.c to fix a segmentation fault when
2+
accessing frames created by:c:func:`PyFrame_New`.

‎Modules/_testcapimodule.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include"Python.h"
2424
#include"datetime.h"// PyDateTimeAPI
25+
#include"frameobject.h"// PyFrame_New
2526
#include"marshal.h"// PyMarshal_WriteLongToFile
2627
#include"structmember.h"// PyMemberDef
2728
#include<float.h>// FLT_MAX
@@ -6000,6 +6001,22 @@ frame_getlasti(PyObject *self, PyObject *frame)
60006001
returnPyLong_FromLong(lasti);
60016002
}
60026003

6004+
staticPyObject*
6005+
frame_new(PyObject*self,PyObject*args)
6006+
{
6007+
PyObject*code,*globals,*locals;
6008+
if (!PyArg_ParseTuple(args,"OOO",&code,&globals,&locals)) {
6009+
returnNULL;
6010+
}
6011+
if (!PyCode_Check(code)) {
6012+
PyErr_SetString(PyExc_TypeError,"argument must be a code object");
6013+
returnNULL;
6014+
}
6015+
PyThreadState*tstate=PyThreadState_Get();
6016+
6017+
return (PyObject*)PyFrame_New(tstate, (PyCodeObject*)code,globals,locals);
6018+
}
6019+
60036020
staticPyObject*
60046021
eval_get_func_name(PyObject*self,PyObject*func)
60056022
{
@@ -6492,6 +6509,7 @@ static PyMethodDef TestMethods[] = {
64926509
{"frame_getgenerator",frame_getgenerator,METH_O,NULL},
64936510
{"frame_getbuiltins",frame_getbuiltins,METH_O,NULL},
64946511
{"frame_getlasti",frame_getlasti,METH_O,NULL},
6512+
{"frame_new",frame_new,METH_VARARGS,NULL},
64956513
{"eval_get_func_name",eval_get_func_name,METH_O,NULL},
64966514
{"eval_get_func_desc",eval_get_func_desc,METH_O,NULL},
64976515
{"get_feature_macros",get_feature_macros,METH_NOARGS,NULL},

‎Objects/frameobject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,7 @@ init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals)
10101010
Py_INCREF(func);
10111011
PyCodeObject*code= (PyCodeObject*)func->func_code;
10121012
_PyFrame_InitializeSpecials(frame,func,locals,code->co_nlocalsplus);
1013+
frame->previous=NULL;
10131014
for (Py_ssize_ti=0;i<code->co_nlocalsplus;i++) {
10141015
frame->localsplus[i]=NULL;
10151016
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp