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

gh-132775: Use _PyFunction_VerifyStateless() and _PyCode_VerifyStateless()#134439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletionsInclude/internal/pycore_pyerrors.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,13 +94,13 @@ extern void _PyErr_Fetch(
PyObject **value,
PyObject **traceback);

externPyObject* _PyErr_GetRaisedException(PyThreadState *tstate);
PyAPI_FUNC(PyObject*) _PyErr_GetRaisedException(PyThreadState *tstate);

PyAPI_FUNC(int) _PyErr_ExceptionMatches(
PyThreadState *tstate,
PyObject *exc);

externvoid _PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc);
PyAPI_FUNC(void) _PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc);

extern void _PyErr_Restore(
PyThreadState *tstate,
Expand Down
3 changes: 2 additions & 1 deletionLib/test/test__interpreters.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1054,7 +1054,7 @@ def test_closure(self):
def script():
assert spam

with self.assertRaises(ValueError):
with self.assertRaises(TypeError):
_interpreters.run_func(self.id, script)

# XXX This hasn't been fixed yet.
Expand All@@ -1065,6 +1065,7 @@ def script():
with self.assertRaises(ValueError):
_interpreters.run_func(self.id, script)

@unittest.skip("we're not quite there yet")
def test_args(self):
with self.subTest('args'):
def script(a, b=0):
Expand Down
139 changes: 66 additions & 73 deletionsModules/_interpretersmodule.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,6 +8,8 @@
#include "Python.h"
#include "pycore_code.h" // _PyCode_HAS_EXECUTORS()
#include "pycore_crossinterp.h" // _PyXIData_t
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_function.h" // _PyFunction_VerifyStateless()
#include "pycore_interp.h" // _PyInterpreterState_IDIncref()
#include "pycore_modsupport.h" // _PyArg_BadArgument()
#include "pycore_namespace.h" // _PyNamespace_New()
Expand DownExpand Up@@ -374,34 +376,17 @@ check_code_str(PyUnicodeObject *text)
return NULL;
}

static const char *
check_code_object(PyCodeObject *code)
#ifndef NDEBUG
static int
code_has_args(PyCodeObject *code)
{
assert(code != NULL);
if (code->co_argcount > 0
return (code->co_argcount > 0
|| code->co_posonlyargcount > 0
|| code->co_kwonlyargcount > 0
|| code->co_flags & (CO_VARARGS | CO_VARKEYWORDS))
{
return "arguments not supported";
}
if (code->co_ncellvars > 0) {
return "closures not supported";
}
// We trust that no code objects under co_consts have unbound cell vars.

if (_PyCode_HAS_EXECUTORS(code) || _PyCode_HAS_INSTRUMENTATION(code)) {
return "only basic functions are supported";
}
if (code->_co_monitoring != NULL) {
return "only basic functions are supported";
}
if (code->co_extra != NULL) {
return "only basic functions are supported";
}

return NULL;
|| code->co_flags & (CO_VARARGS | CO_VARKEYWORDS));
}
#endif

#define RUN_TEXT 1
#define RUN_CODE 2
Expand DownExpand Up@@ -429,8 +414,10 @@ get_code_str(PyObject *arg, Py_ssize_t *len_p, PyObject **bytes_p, int *flags_p)
flags = RUN_TEXT;
}
else {
assert(PyCode_Check(arg)
&& (check_code_object((PyCodeObject *)arg) == NULL));
assert(PyCode_Check(arg));
assert(_PyCode_VerifyStateless(
PyThreadState_Get(), (PyCodeObject *)arg, NULL, NULL, NULL) == 0);
assert(!code_has_args((PyCodeObject *)arg));
flags = RUN_CODE;

// Serialize the code object.
Expand DownExpand Up@@ -949,7 +936,8 @@ Bind the given attributes in the interpreter's __main__ module.");


static PyUnicodeObject *
convert_script_arg(PyObject *arg, const char *fname, const char *displayname,
convert_script_arg(PyThreadState *tstate,
PyObject *arg, const char *fname, const char *displayname,
const char *expected)
{
PyUnicodeObject *str = NULL;
Expand All@@ -968,60 +956,53 @@ convert_script_arg(PyObject *arg, const char *fname, const char *displayname,
const char *err = check_code_str(str);
if (err != NULL) {
Py_DECREF(str);
PyErr_Format(PyExc_ValueError,
"%.200s(): bad script text (%s)", fname, err);
_PyErr_Format(tstate,PyExc_ValueError,
"%.200s(): bad script text (%s)", fname, err);
return NULL;
}

return str;
}

static PyCodeObject *
convert_code_arg(PyObject *arg, const char *fname, const char *displayname,
convert_code_arg(PyThreadState *tstate,
PyObject *arg, const char *fname, const char *displayname,
const char *expected)
{
const char *kind = NULL;
PyObject *cause;
PyCodeObject *code = NULL;
if (PyFunction_Check(arg)) {
if (PyFunction_GetClosure(arg) != NULL) {
PyErr_Format(PyExc_ValueError,
"%.200s(): closures not supported", fname);
return NULL;
}
code = (PyCodeObject *)PyFunction_GetCode(arg);
if (code == NULL) {
if (PyErr_Occurred()) {
// This chains.
PyErr_Format(PyExc_ValueError,
"%.200s(): bad func", fname);
}
else {
PyErr_Format(PyExc_ValueError,
"%.200s(): func.__code__ missing", fname);
}
return NULL;
// For now we allow globals, so we can't use
// _PyFunction_VerifyStateless().
PyObject *codeobj = PyFunction_GetCode(arg);
if (_PyCode_VerifyStateless(
tstate, (PyCodeObject *)codeobj, NULL, NULL, NULL) < 0) {
goto chained;
}
Py_INCREF(code);
kind = "func";
code = (PyCodeObject *)Py_NewRef(codeobj);
}
else if (PyCode_Check(arg)) {
if (_PyCode_VerifyStateless(
tstate, (PyCodeObject *)arg, NULL, NULL, NULL) < 0) {
goto chained;
}
code = (PyCodeObject *)Py_NewRef(arg);
kind = "code object";
}
else {
_PyArg_BadArgument(fname, displayname, expected, arg);
return NULL;
}

const char *err = check_code_object(code);
if (err != NULL) {
Py_DECREF(code);
PyErr_Format(PyExc_ValueError,
"%.200s(): bad %s (%s)", fname, kind, err);
return NULL;
}

return code;

chained:
cause = _PyErr_GetRaisedException(tstate);
assert(cause != NULL);
_PyArg_BadArgument(fname, displayname, expected, arg);
PyObject *exc = _PyErr_GetRaisedException(tstate);
PyException_SetCause(exc, cause);
_PyErr_SetRaisedException(tstate, exc);
return NULL;
}

static int
Expand DownExpand Up@@ -1057,12 +1038,14 @@ _interp_exec(PyObject *self, PyInterpreterState *interp,
static PyObject *
interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
{
#define FUNCNAME MODULE_NAME_STR ".exec"
PyThreadState *tstate = _PyThreadState_GET();
static char *kwlist[] = {"id", "code", "shared", "restrict", NULL};
PyObject *id, *code;
PyObject *shared = NULL;
int restricted = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"OO|O$p:"MODULE_NAME_STR ".exec", kwlist,
"OO|O$p:"FUNCNAME, kwlist,
&id, &code, &shared, &restricted))
{
return NULL;
Expand All@@ -1077,12 +1060,12 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)

const char *expected = "a string, a function, or a code object";
if (PyUnicode_Check(code)) {
code = (PyObject *)convert_script_arg(code,MODULE_NAME_STR ".exec",
"argument 2", expected);
code = (PyObject *)convert_script_arg(tstate,code,FUNCNAME,
"argument 2", expected);
}
else {
code = (PyObject *)convert_code_arg(code,MODULE_NAME_STR ".exec",
"argument 2", expected);
code = (PyObject *)convert_code_arg(tstate,code,FUNCNAME,
"argument 2", expected);
}
if (code == NULL) {
return NULL;
Expand All@@ -1096,6 +1079,7 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
return excinfo;
}
Py_RETURN_NONE;
#undef FUNCNAME
}

PyDoc_STRVAR(exec_doc,
Expand All@@ -1118,13 +1102,15 @@ is ignored, including its __globals__ dict.");
static PyObject *
interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
{
#define FUNCNAME MODULE_NAME_STR ".run_string"
PyThreadState *tstate = _PyThreadState_GET();
static char *kwlist[] = {"id", "script", "shared", "restrict", NULL};
PyObject *id, *script;
PyObject *shared = NULL;
int restricted = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"OU|O$p:"MODULE_NAME_STR ".run_string",
kwlist,&id, &script, &shared, &restricted))
"OU|O$p:"FUNCNAME, kwlist,
&id, &script, &shared, &restricted))
{
return NULL;
}
Expand All@@ -1136,7 +1122,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
}

script = (PyObject *)convert_script_arg(script,MODULE_NAME_STR ".run_string",
script = (PyObject *)convert_script_arg(tstate,script,FUNCNAME,
"argument 2", "a string");
if (script == NULL) {
return NULL;
Expand All@@ -1150,6 +1136,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
return excinfo;
}
Py_RETURN_NONE;
#undef FUNCNAME
}

PyDoc_STRVAR(run_string_doc,
Expand All@@ -1162,13 +1149,15 @@ Execute the provided string in the identified interpreter.\n\
static PyObject *
interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
{
#define FUNCNAME MODULE_NAME_STR ".run_func"
PyThreadState *tstate = _PyThreadState_GET();
static char *kwlist[] = {"id", "func", "shared", "restrict", NULL};
PyObject *id, *func;
PyObject *shared = NULL;
int restricted = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"OO|O$p:"MODULE_NAME_STR ".run_func",
kwlist,&id, &func, &shared, &restricted))
"OO|O$p:"FUNCNAME, kwlist,
&id, &func, &shared, &restricted))
{
return NULL;
}
Expand All@@ -1180,7 +1169,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
}

PyCodeObject *code = convert_code_arg(func,MODULE_NAME_STR ".exec",
PyCodeObject *code = convert_code_arg(tstate,func,FUNCNAME,
"argument 2",
"a function or a code object");
if (code == NULL) {
Expand All@@ -1195,6 +1184,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
return excinfo;
}
Py_RETURN_NONE;
#undef FUNCNAME
}

PyDoc_STRVAR(run_func_doc,
Expand All@@ -1209,14 +1199,16 @@ are not supported. Methods and other callables are not supported either.\n\
static PyObject *
interp_call(PyObject *self, PyObject *args, PyObject *kwds)
{
#define FUNCNAME MODULE_NAME_STR ".call"
PyThreadState *tstate = _PyThreadState_GET();
static char *kwlist[] = {"id", "callable", "args", "kwargs",
"restrict", NULL};
PyObject *id, *callable;
PyObject *args_obj = NULL;
PyObject *kwargs_obj = NULL;
int restricted = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"OO|OO$p:"MODULE_NAME_STR ".call", kwlist,
"OO|OO$p:"FUNCNAME, kwlist,
&id, &callable, &args_obj, &kwargs_obj,
&restricted))
{
Expand All@@ -1231,15 +1223,15 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
}

if (args_obj != NULL) {
PyErr_SetString(PyExc_ValueError, "got unexpected args");
_PyErr_SetString(tstate,PyExc_ValueError, "got unexpected args");
return NULL;
}
if (kwargs_obj != NULL) {
PyErr_SetString(PyExc_ValueError, "got unexpected kwargs");
_PyErr_SetString(tstate,PyExc_ValueError, "got unexpected kwargs");
return NULL;
}

PyObject *code = (PyObject *)convert_code_arg(callable,MODULE_NAME_STR ".call",
PyObject *code = (PyObject *)convert_code_arg(tstate,callable,FUNCNAME,
"argument 2", "a function");
if (code == NULL) {
return NULL;
Expand All@@ -1253,6 +1245,7 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
return excinfo;
}
Py_RETURN_NONE;
#undef FUNCNAME
}

PyDoc_STRVAR(call_doc,
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp