mirror of https://github.com/python/cpython
gh-116180: Check the globals argument in PyRun_* C API (GH-116637)
It used to crash when passing NULL or non-dict as globals. Now it sets a SystemError.
This commit is contained in:
parent
7c97dc8c95
commit
7d2ffada0a
|
@ -11,6 +11,10 @@ Py_file_input = _testcapi.Py_file_input
|
||||||
Py_eval_input = _testcapi.Py_eval_input
|
Py_eval_input = _testcapi.Py_eval_input
|
||||||
|
|
||||||
|
|
||||||
|
class DictSubclass(dict):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CAPITest(unittest.TestCase):
|
class CAPITest(unittest.TestCase):
|
||||||
# TODO: Test the following functions:
|
# TODO: Test the following functions:
|
||||||
#
|
#
|
||||||
|
@ -50,15 +54,19 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, run, b'a\n', dict(a=1), [])
|
self.assertRaises(TypeError, run, b'a\n', dict(a=1), [])
|
||||||
self.assertRaises(TypeError, run, b'a\n', dict(a=1), 1)
|
self.assertRaises(TypeError, run, b'a\n', dict(a=1), 1)
|
||||||
|
|
||||||
|
self.assertIsNone(run(b'a\n', DictSubclass(a=1)))
|
||||||
|
self.assertIsNone(run(b'a\n', DictSubclass(), dict(a=1)))
|
||||||
|
self.assertRaises(NameError, run, b'a\n', DictSubclass())
|
||||||
|
|
||||||
self.assertIsNone(run(b'\xc3\xa4\n', {'\xe4': 1}))
|
self.assertIsNone(run(b'\xc3\xa4\n', {'\xe4': 1}))
|
||||||
self.assertRaises(SyntaxError, run, b'\xe4\n', {})
|
self.assertRaises(SyntaxError, run, b'\xe4\n', {})
|
||||||
|
|
||||||
# CRASHES run(b'a\n', NULL)
|
self.assertRaises(SystemError, run, b'a\n', NULL)
|
||||||
# CRASHES run(b'a\n', NULL, {})
|
self.assertRaises(SystemError, run, b'a\n', NULL, {})
|
||||||
# CRASHES run(b'a\n', NULL, dict(a=1))
|
self.assertRaises(SystemError, run, b'a\n', NULL, dict(a=1))
|
||||||
# CRASHES run(b'a\n', UserDict())
|
self.assertRaises(SystemError, run, b'a\n', UserDict())
|
||||||
# CRASHES run(b'a\n', UserDict(), {})
|
self.assertRaises(SystemError, run, b'a\n', UserDict(), {})
|
||||||
# CRASHES run(b'a\n', UserDict(), dict(a=1))
|
self.assertRaises(SystemError, run, b'a\n', UserDict(), dict(a=1))
|
||||||
|
|
||||||
# CRASHES run(NULL, {})
|
# CRASHES run(NULL, {})
|
||||||
|
|
||||||
|
@ -82,12 +90,16 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, run, dict(a=1), [])
|
self.assertRaises(TypeError, run, dict(a=1), [])
|
||||||
self.assertRaises(TypeError, run, dict(a=1), 1)
|
self.assertRaises(TypeError, run, dict(a=1), 1)
|
||||||
|
|
||||||
# CRASHES run(NULL)
|
self.assertIsNone(run(DictSubclass(a=1)))
|
||||||
# CRASHES run(NULL, {})
|
self.assertIsNone(run(DictSubclass(), dict(a=1)))
|
||||||
# CRASHES run(NULL, dict(a=1))
|
self.assertRaises(NameError, run, DictSubclass())
|
||||||
# CRASHES run(UserDict())
|
|
||||||
# CRASHES run(UserDict(), {})
|
self.assertRaises(SystemError, run, NULL)
|
||||||
# CRASHES run(UserDict(), dict(a=1))
|
self.assertRaises(SystemError, run, NULL, {})
|
||||||
|
self.assertRaises(SystemError, run, NULL, dict(a=1))
|
||||||
|
self.assertRaises(SystemError, run, UserDict())
|
||||||
|
self.assertRaises(SystemError, run, UserDict(), {})
|
||||||
|
self.assertRaises(SystemError, run, UserDict(), dict(a=1))
|
||||||
|
|
||||||
@unittest.skipUnless(TESTFN_UNDECODABLE, 'only works if there are undecodable paths')
|
@unittest.skipUnless(TESTFN_UNDECODABLE, 'only works if there are undecodable paths')
|
||||||
@unittest.skipIf(os.name == 'nt', 'does not work on Windows')
|
@unittest.skipIf(os.name == 'nt', 'does not work on Windows')
|
||||||
|
|
|
@ -1275,17 +1275,20 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py
|
||||||
_PyRuntime.signals.unhandled_keyboard_interrupt = 0;
|
_PyRuntime.signals.unhandled_keyboard_interrupt = 0;
|
||||||
|
|
||||||
/* Set globals['__builtins__'] if it doesn't exist */
|
/* Set globals['__builtins__'] if it doesn't exist */
|
||||||
if (globals != NULL) {
|
if (!globals || !PyDict_Check(globals)) {
|
||||||
int has_builtins = PyDict_ContainsString(globals, "__builtins__");
|
PyErr_SetString(PyExc_SystemError, "globals must be a real dict");
|
||||||
if (has_builtins < 0) {
|
return NULL;
|
||||||
|
}
|
||||||
|
int has_builtins = PyDict_ContainsString(globals, "__builtins__");
|
||||||
|
if (has_builtins < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!has_builtins) {
|
||||||
|
if (PyDict_SetItemString(globals, "__builtins__",
|
||||||
|
tstate->interp->builtins) < 0)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!has_builtins) {
|
|
||||||
if (PyDict_SetItemString(globals, "__builtins__",
|
|
||||||
tstate->interp->builtins) < 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v = PyEval_EvalCode((PyObject*)co, globals, locals);
|
v = PyEval_EvalCode((PyObject*)co, globals, locals);
|
||||||
|
|
Loading…
Reference in New Issue