diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2012-04-18 22:57:45 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2012-04-18 22:57:45 (GMT) |
commit | b0b224233e481d979430a54d257d871424ff19fb (patch) | |
tree | 86be7f1a45404ec56003f36f5f76dd82c85c6ca8 /Python/ceval.c | |
parent | 05fac022eca4604275e16c62136ca02aaea879e1 (diff) | |
download | cpython-b0b224233e481d979430a54d257d871424ff19fb.zip cpython-b0b224233e481d979430a54d257d871424ff19fb.tar.gz cpython-b0b224233e481d979430a54d257d871424ff19fb.tar.bz2 |
Issue #14385: Support other types than dict for __builtins__
It is now possible to use a custom type for the __builtins__ namespace, instead
of a dict. It can be used for sandboxing for example. Raise also a NameError
instead of ImportError if __build_class__ name if not found in __builtins__.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 142 |
1 files changed, 94 insertions, 48 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 7908d44..a32d685 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1932,11 +1932,26 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) TARGET(LOAD_BUILD_CLASS) { _Py_IDENTIFIER(__build_class__); - x = _PyDict_GetItemId(f->f_builtins, &PyId___build_class__); - if (x == NULL) { - PyErr_SetString(PyExc_ImportError, - "__build_class__ not found"); - break; + + if (PyDict_CheckExact(f->f_builtins)) { + x = _PyDict_GetItemId(f->f_builtins, &PyId___build_class__); + if (x == NULL) { + PyErr_SetString(PyExc_NameError, + "__build_class__ not found"); + break; + } + } + else { + PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__); + if (build_class_str == NULL) + break; + x = PyObject_GetItem(f->f_builtins, build_class_str); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_SetString(PyExc_NameError, + "__build_class__ not found"); + break; + } } Py_INCREF(x); PUSH(x); @@ -2078,12 +2093,24 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (x == NULL) { x = PyDict_GetItem(f->f_globals, w); if (x == NULL) { - x = PyDict_GetItem(f->f_builtins, w); - if (x == NULL) { - format_exc_check_arg( - PyExc_NameError, - NAME_ERROR_MSG, w); - break; + if (PyDict_CheckExact(f->f_builtins)) { + x = PyDict_GetItem(f->f_builtins, w); + if (x == NULL) { + format_exc_check_arg( + PyExc_NameError, + NAME_ERROR_MSG, w); + break; + } + } + else { + x = PyObject_GetItem(f->f_builtins, w); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) + format_exc_check_arg( + PyExc_NameError, + NAME_ERROR_MSG, w); + break; + } } } Py_INCREF(x); @@ -2093,50 +2120,69 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) TARGET(LOAD_GLOBAL) w = GETITEM(names, oparg); - if (PyUnicode_CheckExact(w)) { - /* Inline the PyDict_GetItem() calls. - WARNING: this is an extreme speed hack. - Do not try this at home. */ - Py_hash_t hash = ((PyASCIIObject *)w)->hash; - if (hash != -1) { - PyDictObject *d; - PyDictEntry *e; - d = (PyDictObject *)(f->f_globals); - e = d->ma_lookup(d, w, hash); - if (e == NULL) { - x = NULL; - break; - } - x = e->me_value; - if (x != NULL) { - Py_INCREF(x); - PUSH(x); - DISPATCH(); + if (PyDict_CheckExact(f->f_globals) + && PyDict_CheckExact(f->f_builtins)) { + if (PyUnicode_CheckExact(w)) { + /* Inline the PyDict_GetItem() calls. + WARNING: this is an extreme speed hack. + Do not try this at home. */ + Py_hash_t hash = ((PyASCIIObject *)w)->hash; + if (hash != -1) { + PyDictObject *d; + PyDictEntry *e; + d = (PyDictObject *)(f->f_globals); + e = d->ma_lookup(d, w, hash); + if (e == NULL) { + x = NULL; + break; + } + x = e->me_value; + if (x != NULL) { + Py_INCREF(x); + PUSH(x); + DISPATCH(); + } + d = (PyDictObject *)(f->f_builtins); + e = d->ma_lookup(d, w, hash); + if (e == NULL) { + x = NULL; + break; + } + x = e->me_value; + if (x != NULL) { + Py_INCREF(x); + PUSH(x); + DISPATCH(); + } + goto load_global_error; } - d = (PyDictObject *)(f->f_builtins); - e = d->ma_lookup(d, w, hash); - if (e == NULL) { - x = NULL; + } + /* This is the un-inlined version of the code above */ + x = PyDict_GetItem(f->f_globals, w); + if (x == NULL) { + x = PyDict_GetItem(f->f_builtins, w); + if (x == NULL) { + load_global_error: + format_exc_check_arg( + PyExc_NameError, + GLOBAL_NAME_ERROR_MSG, w); break; } - x = e->me_value; - if (x != NULL) { - Py_INCREF(x); - PUSH(x); - DISPATCH(); - } - goto load_global_error; } + Py_INCREF(x); + PUSH(x); + DISPATCH(); } - /* This is the un-inlined version of the code above */ - x = PyDict_GetItem(f->f_globals, w); + + /* Slow-path if globals or builtins is not a dict */ + x = PyObject_GetItem(f->f_globals, w); if (x == NULL) { - x = PyDict_GetItem(f->f_builtins, w); + x = PyObject_GetItem(f->f_builtins, w); if (x == NULL) { - load_global_error: - format_exc_check_arg( - PyExc_NameError, - GLOBAL_NAME_ERROR_MSG, w); + if (PyErr_ExceptionMatches(PyExc_KeyError)) + format_exc_check_arg( + PyExc_NameError, + GLOBAL_NAME_ERROR_MSG, w); break; } } |