Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-07-12 09:05:15 +0300
committerCampbell Barton <campbell@blender.org>2022-07-12 09:11:19 +0300
commitae6a4fcc7a707e419463c47e191afe54def26764 (patch)
tree35733066bddf441c945c3961ece4075b4b24229e /source/blender
parent00c7e760b323e5fa46703d0e4769c8f1d9c35f2e (diff)
Tests: add test to ensure restricted py-driver execution is working
Add internal function (only used for testing at the moment) `_bpy._driver_secure_code_test`. Add test `script_pyapi_bpy_driver_secure_eval` to serves two purposes: - Ensure expressions that should be insecure remain so when upgrading Python or making any changes in this area. - Ensure new versions of Python don't introduce new byte-codes that prevent existing expressions from being executed (happened when upgrading from 3.7, see [0]). [0]: dfa52017638abdf59791e5588c439d3a558a191d
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/python/intern/bpy.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 2e97ae0fc1d..d1e8b894ac0 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -32,6 +32,7 @@
#include "bpy.h"
#include "bpy_app.h"
#include "bpy_capi_utils.h"
+#include "bpy_driver.h"
#include "bpy_library.h"
#include "bpy_operator.h"
#include "bpy_props.h"
@@ -326,6 +327,49 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return PyC_UnicodeFromByte(path ? path : "");
}
+/* This is only exposed for tests, see: `tests/python/bl_pyapi_bpy_driver_secure_eval.py`. */
+PyDoc_STRVAR(bpy_driver_secure_code_test_doc,
+ ".. function:: _driver_secure_code_test(code)\n"
+ "\n"
+ " Test if the script should be considered trusted.\n"
+ "\n"
+ " :arg code: The code to test.\n"
+ " :type code: code\n"
+ " :arg namespace: The namespace of values which are allowed.\n"
+ " :type namespace: dict\n"
+ " :arg verbose: Print the reason for considering insecure to the ``stderr``.\n"
+ " :type verbose: bool\n"
+ " :return: True when the script is considered trusted.\n"
+ " :rtype: bool\n");
+static PyObject *bpy_driver_secure_code_test(PyObject *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ PyObject *py_code;
+ PyObject *py_namespace = NULL;
+ const bool verbose = false;
+ static const char *_keywords[] = {"code", "namespace", "verbose", NULL};
+ static _PyArg_Parser _parser = {
+ "O!" /* `expression` */
+ "|$" /* Optional keyword only arguments. */
+ "O!" /* `namespace` */
+ "O&" /* `verbose` */
+ ":driver_secure_code_test",
+ _keywords,
+ 0,
+ };
+ if (!_PyArg_ParseTupleAndKeywordsFast(args,
+ kw,
+ &_parser,
+ &PyCode_Type,
+ &py_code,
+ &PyDict_Type,
+ &py_namespace,
+ PyC_ParseBool,
+ &verbose)) {
+ return NULL;
+ }
+ return PyBool_FromLong(BPY_driver_secure_bytecode_test(py_code, py_namespace, verbose));
+}
+
PyDoc_STRVAR(bpy_escape_identifier_doc,
".. function:: escape_identifier(string)\n"
"\n"
@@ -528,6 +572,12 @@ static PyMethodDef meth_bpy_resource_path = {
METH_VARARGS | METH_KEYWORDS,
bpy_resource_path_doc,
};
+static PyMethodDef meth_bpy_driver_secure_code_test = {
+ "_driver_secure_code_test",
+ (PyCFunction)bpy_driver_secure_code_test,
+ METH_VARARGS | METH_KEYWORDS,
+ bpy_driver_secure_code_test_doc,
+};
static PyMethodDef meth_bpy_escape_identifier = {
"escape_identifier",
(PyCFunction)bpy_escape_identifier,
@@ -648,6 +698,9 @@ void BPy_init_modules(struct bContext *C)
meth_bpy_resource_path.ml_name,
(PyObject *)PyCFunction_New(&meth_bpy_resource_path, NULL));
PyModule_AddObject(mod,
+ meth_bpy_driver_secure_code_test.ml_name,
+ (PyObject *)PyCFunction_New(&meth_bpy_driver_secure_code_test, NULL));
+ PyModule_AddObject(mod,
meth_bpy_escape_identifier.ml_name,
(PyObject *)PyCFunction_New(&meth_bpy_escape_identifier, NULL));
PyModule_AddObject(mod,