26#include "RNA_prototypes.hh"
37#define USE_RNA_AS_PYOBJECT
39#define USE_BYTECODE_WHITELIST
41#ifdef USE_BYTECODE_WHITELIST
45#if PY_VERSION_HEX >= 0x030d0000
49# include <internal/pycore_code.h>
54#ifdef USE_BYTECODE_WHITELIST
75 PyDict_SetItemString(d,
"__builtins__", PyEval_GetBuiltins());
77 mod = PyImport_ImportModule(
"math");
79 PyDict_Merge(d, PyModule_GetDict(
mod), 0);
82#ifdef USE_BYTECODE_WHITELIST
83 PyObject *mod_math =
mod;
87 mod = PyImport_ImportModuleLevel(
"bpy",
nullptr,
nullptr,
nullptr, 0);
94 mod = PyImport_ImportModuleLevel(
"mathutils",
nullptr,
nullptr,
nullptr, 0);
96 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(
mod),
"noise");
102 mod = PyImport_ImportModuleLevel(
"bl_math",
nullptr,
nullptr,
nullptr, 0);
104 static const char *names[] = {
"clamp",
"lerp",
"smoothstep",
nullptr};
106 for (
const char **pname = names; *pname; ++pname) {
107 PyObject *func = PyDict_GetItemString(PyModule_GetDict(
mod), *pname);
114#ifdef USE_BYTECODE_WHITELIST
118 const char *whitelist[] = {
141 for (
int i = 0; whitelist[
i];
i++) {
146 if (mod_math !=
nullptr) {
147 PyObject *mod_math_dict = PyModule_GetDict(mod_math);
148 PyObject *arg_key, *arg_value;
149 Py_ssize_t arg_pos = 0;
150 while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
151 const char *
arg_str = PyUnicode_AsUTF8(arg_key);
179 PyObject *item = PyFloat_FromDouble(
evaltime);
249#ifdef USE_BYTECODE_WHITELIST
266 PyGILState_STATE gilstate;
267 const bool use_gil =
true;
269 gilstate = PyGILState_Ensure();
276 PyGILState_Release(gilstate);
289 const char *null_str =
"<null>";
293 "Error in PyDriver: expression failed: %s\n"
294 "For target: (type=%s, name=\"%s\", property=%s, property_index=%d)\n"
298 id ? id->
name + 2 : null_str,
307#ifdef USE_BYTECODE_WHITELIST
323# if PY_VERSION_HEX < 0x030c0000
324 OK_OP(UNARY_POSITIVE)
326 OK_OP(UNARY_NEGATIVE)
329# if PY_VERSION_HEX < 0x030e0000
333# if PY_VERSION_HEX < 0x030c0000
344# if PY_VERSION_HEX < 0x030c0000
345 OK_OP(JUMP_IF_FALSE_OR_POP)
346 OK_OP(JUMP_IF_TRUE_OR_POP)
347 OK_OP(POP_JUMP_FORWARD_IF_FALSE)
348 OK_OP(POP_JUMP_FORWARD_IF_TRUE)
357# if PY_VERSION_HEX < 0x030c0000
358 OK_OP(POP_JUMP_FORWARD_IF_NOT_NONE)
359 OK_OP(POP_JUMP_FORWARD_IF_NONE)
374# if PY_VERSION_HEX < 0x030c0000
375 OK_OP(POP_JUMP_BACKWARD_IF_NOT_NONE)
376 OK_OP(POP_JUMP_BACKWARD_IF_NONE)
377 OK_OP(POP_JUMP_BACKWARD_IF_FALSE)
378 OK_OP(POP_JUMP_BACKWARD_IF_TRUE)
381# if PY_VERSION_HEX >= 0x030c0000
383 OK_OP(POP_JUMP_IF_FALSE)
384 OK_OP(CALL_INTRINSIC_1)
390# if PY_VERSION_HEX >= 0x030d0000
393 OK_OP(CALL_FUNCTION_EX);
396 OK_OP(CALL_ALLOC_AND_ENTER_INIT)
397 OK_OP(CALL_BOUND_METHOD_EXACT_ARGS)
398 OK_OP(CALL_BOUND_METHOD_GENERAL)
399 OK_OP(CALL_BUILTIN_CLASS)
400 OK_OP(CALL_BUILTIN_FAST)
401 OK_OP(CALL_BUILTIN_FAST_WITH_KEYWORDS)
402 OK_OP(CALL_BUILTIN_O)
403 OK_OP(CALL_ISINSTANCE)
405 OK_OP(CALL_LIST_APPEND)
406 OK_OP(CALL_METHOD_DESCRIPTOR_FAST)
407 OK_OP(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS)
408 OK_OP(CALL_METHOD_DESCRIPTOR_NOARGS)
409 OK_OP(CALL_METHOD_DESCRIPTOR_O)
410 OK_OP(CALL_NON_PY_GENERAL)
411 OK_OP(CALL_PY_EXACT_ARGS)
412 OK_OP(CALL_PY_GENERAL)
420# if PY_VERSION_HEX < 0x030c0000
430 PyObject *py_namespace_array[],
432 const char *error_prefix)
434 PyCodeObject *py_code = (PyCodeObject *)expr_code;
438 for (
int i = 0;
i < PyTuple_GET_SIZE(py_code->co_names);
i++) {
439 PyObject *name = PyTuple_GET_ITEM(py_code->co_names,
i);
440 const char *name_str = PyUnicode_AsUTF8(name);
441 bool contains_name =
false;
442 for (
int j = 0; py_namespace_array[j]; j++) {
443 if (PyDict_Contains(py_namespace_array[j], name)) {
444 contains_name =
true;
449 if ((contains_name ==
false) || (name_str[0] ==
'_')) {
452 "\t%s: restricted access disallows name '%s', "
453 "enable auto-execution to support\n",
464 const _Py_CODEUNIT *codestr;
469 co_code = PyCode_GetCode(py_code);
476 PyBytes_AsStringAndSize(co_code, (
char **)&codestr, &code_len);
477 code_len /=
sizeof(*codestr);
481 for (Py_ssize_t
i = 0;
i < code_len;
i++) {
482 const int opcode = _Py_OPCODE(codestr[
i]);
486 "\t%s: restricted access disallows opcode '%d', "
487 "enable auto-execution to support\n",
506 PyObject *py_namespace,
512 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
516 PyObject *py_namespaces[] = {
540 PyObject *driver_vars =
nullptr;
541 PyObject *retval =
nullptr;
547 PyGILState_STATE gilstate;
553 bool targets_ok =
true;
558 if (expr[0] ==
'\0') {
562#ifndef USE_BYTECODE_WHITELIST
566 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
568 printf(
"skipping driver '%s', automatic scripts are disabled\n", expr);
574 bool is_recompile =
false;
580 gilstate = PyGILState_Ensure();
589 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
591 PyGILState_Release(gilstate);
618 expr_code = Py_CompileString(expr,
"<bpy driver>", Py_eval_input);
619 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0, expr_code);
627#ifdef USE_BYTECODE_WHITELIST
632 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 0);
637 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
638 Py_XDECREF(expr_vars);
641 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 1, expr_vars);
646 PyTuple_SET_ITEM(expr_vars,
i++, PyUnicode_FromString(dvar->
name));
652 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
656 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
658 PyObject *driver_arg =
nullptr;
661#ifdef USE_RNA_AS_PYOBJECT
664 anim_eval_context, driver, dvar, &dvar->
targets[0]);
666 if (driver_arg ==
nullptr) {
667 driver_arg = PyFloat_FromDouble(0.0);
672 if (PyFloat_CheckExact(driver_arg)) {
673 dvar->
curval = float(PyFloat_AsDouble(driver_arg));
675 else if (PyLong_CheckExact(driver_arg)) {
676 dvar->
curval = float(PyLong_AsLong(driver_arg));
678 else if (PyBool_Check(driver_arg)) {
679 dvar->
curval = float(driver_arg == Py_True);
691 driver_arg = PyFloat_FromDouble(
double(tval));
696 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars,
i++), driver_arg) != -1) {
703 fprintf(stderr,
"\n%s: Error while evaluating PyDriver:\n", __func__);
707 fprintf(stderr,
"\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->
name);
712 Py_DECREF(driver_arg);
715#ifdef USE_BYTECODE_WHITELIST
716 if (is_recompile && expr_code) {
718 PyObject *py_namespaces[] = {
729 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
732 Py_DECREF(expr_code);
734 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0,
nullptr);
747 retval = PyEval_EvalCode(
753 Py_DECREF(driver_vars);
756 if (retval ==
nullptr) {
760 if (
UNLIKELY((
result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
772 PyGILState_Release(gilstate);
776 fprintf(stderr,
"\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->
expression,
result);
float driver_get_variable_value(const struct AnimationEvalContext *anim_eval_context, struct ChannelDriver *driver, struct DriverVar *dvar)
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET
@ G_FLAG_SCRIPT_AUTOEXEC_FAIL
const char * BKE_idtype_idcode_to_name(short idcode)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define SNPRINTF(dst, format,...)
@ DRIVER_FLAG_PYTHON_BLOCKED
static PyObject * bpy_pydriver_Dict__whitelist
static bool is_opcode_secure(const int opcode)
PyObject * bpy_pydriver_Dict
static void bpy_pydriver_namespace_update_depsgraph(Depsgraph *depsgraph)
static void pydriver_error(ChannelDriver *driver, const PathResolvedRNA *anim_rna)
static void bpy_pydriver_namespace_update_self(PathResolvedRNA *anim_rna)
float BPY_driver_exec(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
BPy_StructRNA * depsgraph
static void bpy_pydriver_namespace_update_frame(const float evaltime)
static struct @206166051352076163221226375034341047277250336243 g_pydriver_state_prev
int bpy_pydriver_create_dict()
bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code, PyObject *py_namespace_array[], const bool verbose, const char *error_prefix)
static PyObject * bpy_pydriver_depsgraph_as_pyobject(Depsgraph *depsgraph)
static void bpy_pydriver_namespace_clear_self()
bool BPY_driver_secure_bytecode_test(PyObject *expr_code, PyObject *py_namespace, const bool verbose)
PyObject * bpy_intern_str_depsgraph
PyObject * bpy_intern_str_self
PyObject * bpy_intern_str_frame
void BPY_update_rna_module()
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
PyObject * pyrna_driver_get_variable_value(const AnimationEvalContext *anim_eval_context, ChannelDriver *driver, DriverVar *dvar, DriverTarget *dtar)
PyObject * pyrna_driver_self_from_anim_rna(PathResolvedRNA *anim_rna)
bool pyrna_driver_is_equal_anim_rna(const PathResolvedRNA *anim_rna, const PyObject *py_anim_rna)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const char * RNA_property_identifier(const PropertyRNA *prop)
#define CALL(member, value_str)
struct Depsgraph * depsgraph