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 && PY_VERSION_HEX < 0x030e0000
384# if PY_VERSION_HEX >= 0x030c0000
385 OK_OP(POP_JUMP_IF_FALSE)
386 OK_OP(CALL_INTRINSIC_1)
392# if PY_VERSION_HEX >= 0x030d0000
395 OK_OP(CALL_FUNCTION_EX);
398 OK_OP(CALL_ALLOC_AND_ENTER_INIT)
399 OK_OP(CALL_BOUND_METHOD_EXACT_ARGS)
400 OK_OP(CALL_BOUND_METHOD_GENERAL)
401 OK_OP(CALL_BUILTIN_CLASS)
402 OK_OP(CALL_BUILTIN_FAST)
403 OK_OP(CALL_BUILTIN_FAST_WITH_KEYWORDS)
404 OK_OP(CALL_BUILTIN_O)
405 OK_OP(CALL_ISINSTANCE)
407 OK_OP(CALL_LIST_APPEND)
408 OK_OP(CALL_METHOD_DESCRIPTOR_FAST)
409 OK_OP(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS)
410 OK_OP(CALL_METHOD_DESCRIPTOR_NOARGS)
411 OK_OP(CALL_METHOD_DESCRIPTOR_O)
412 OK_OP(CALL_NON_PY_GENERAL)
413 OK_OP(CALL_PY_EXACT_ARGS)
414 OK_OP(CALL_PY_GENERAL)
422# if PY_VERSION_HEX < 0x030c0000
432 PyObject *py_namespace_array[],
434 const char *error_prefix)
436 PyCodeObject *py_code = (PyCodeObject *)expr_code;
440 for (
int i = 0;
i < PyTuple_GET_SIZE(py_code->co_names);
i++) {
441 PyObject *name = PyTuple_GET_ITEM(py_code->co_names,
i);
442 const char *name_str = PyUnicode_AsUTF8(name);
443 bool contains_name =
false;
444 for (
int j = 0; py_namespace_array[j]; j++) {
445 if (PyDict_Contains(py_namespace_array[j], name)) {
446 contains_name =
true;
451 if ((contains_name ==
false) || (name_str[0] ==
'_')) {
454 "\t%s: restricted access disallows name '%s', "
455 "enable auto-execution to support\n",
466 const _Py_CODEUNIT *codestr;
471 co_code = PyCode_GetCode(py_code);
478 PyBytes_AsStringAndSize(co_code, (
char **)&codestr, &code_len);
479 code_len /=
sizeof(*codestr);
483 for (Py_ssize_t
i = 0;
i < code_len;
i++) {
484 const int opcode = _Py_OPCODE(codestr[
i]);
488 "\t%s: restricted access disallows opcode '%d', "
489 "enable auto-execution to support\n",
508 PyObject *py_namespace,
514 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
518 PyObject *py_namespaces[] = {
542 PyObject *driver_vars =
nullptr;
543 PyObject *retval =
nullptr;
549 PyGILState_STATE gilstate;
555 bool targets_ok =
true;
560 if (expr[0] ==
'\0') {
564#ifndef USE_BYTECODE_WHITELIST
568 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
570 printf(
"skipping driver '%s', automatic scripts are disabled\n", expr);
576 bool is_recompile =
false;
582 gilstate = PyGILState_Ensure();
591 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
593 PyGILState_Release(gilstate);
620 expr_code = Py_CompileString(expr,
"<bpy driver>", Py_eval_input);
621 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0, expr_code);
629#ifdef USE_BYTECODE_WHITELIST
634 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 0);
639 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
640 Py_XDECREF(expr_vars);
643 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 1, expr_vars);
648 PyTuple_SET_ITEM(expr_vars,
i++, PyUnicode_FromString(dvar->
name));
654 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
658 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
660 PyObject *driver_arg =
nullptr;
663#ifdef USE_RNA_AS_PYOBJECT
666 anim_eval_context, driver, dvar, &dvar->
targets[0]);
668 if (driver_arg ==
nullptr) {
669 driver_arg = PyFloat_FromDouble(0.0);
674 if (PyFloat_CheckExact(driver_arg)) {
675 dvar->
curval = float(PyFloat_AsDouble(driver_arg));
677 else if (PyLong_CheckExact(driver_arg)) {
678 dvar->
curval = float(PyLong_AsLong(driver_arg));
680 else if (PyBool_Check(driver_arg)) {
681 dvar->
curval = float(driver_arg == Py_True);
693 driver_arg = PyFloat_FromDouble(
double(tval));
698 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars,
i++), driver_arg) != -1) {
705 fprintf(stderr,
"\n%s: Error while evaluating PyDriver:\n", __func__);
709 fprintf(stderr,
"\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->
name);
714 Py_DECREF(driver_arg);
717#ifdef USE_BYTECODE_WHITELIST
718 if (is_recompile && expr_code) {
720 PyObject *py_namespaces[] = {
731 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
734 Py_DECREF(expr_code);
736 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0,
nullptr);
749 retval = PyEval_EvalCode(
755 Py_DECREF(driver_vars);
758 if (retval ==
nullptr) {
762 if (
UNLIKELY((
result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
774 PyGILState_Release(gilstate);
778 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)
static struct @105124230115325240302265150175313340056322333345 g_pydriver_state_prev
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)
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