27#include "RNA_prototypes.hh"
38#define USE_RNA_AS_PYOBJECT
40#define USE_BYTECODE_WHITELIST
42#ifdef USE_BYTECODE_WHITELIST
48#ifdef USE_BYTECODE_WHITELIST
69 PyDict_SetItemString(d,
"__builtins__", PyEval_GetBuiltins());
71 mod = PyImport_ImportModule(
"math");
73 PyDict_Merge(d, PyModule_GetDict(
mod), 0);
76#ifdef USE_BYTECODE_WHITELIST
77 PyObject *mod_math =
mod;
81 mod = PyImport_ImportModuleLevel(
"bpy",
nullptr,
nullptr,
nullptr, 0);
88 mod = PyImport_ImportModuleLevel(
"mathutils",
nullptr,
nullptr,
nullptr, 0);
90 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(
mod),
"noise");
96 mod = PyImport_ImportModuleLevel(
"bl_math",
nullptr,
nullptr,
nullptr, 0);
98 static const char *names[] = {
"clamp",
"lerp",
"smoothstep",
nullptr};
100 for (
const char **pname = names; *pname; ++pname) {
101 PyObject *func = PyDict_GetItemString(PyModule_GetDict(
mod), *pname);
108#ifdef USE_BYTECODE_WHITELIST
112 const char *whitelist[] = {
135 for (
int i = 0; whitelist[i]; i++) {
140 if (mod_math !=
nullptr) {
141 PyObject *mod_math_dict = PyModule_GetDict(mod_math);
142 PyObject *arg_key, *arg_value;
143 Py_ssize_t arg_pos = 0;
144 while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
145 const char *
arg_str = PyUnicode_AsUTF8(arg_key);
173 PyObject *item = PyFloat_FromDouble(
evaltime);
243#ifdef USE_BYTECODE_WHITELIST
260 PyGILState_STATE gilstate;
261 const bool use_gil =
true;
264 gilstate = PyGILState_Ensure();
271 PyGILState_Release(gilstate);
284 const char *null_str =
"<null>";
288 "Error in PyDriver: expression failed: %s\n"
289 "For target: (type=%s, name=\"%s\", property=%s, property_index=%d)\n"
293 id ?
id->name + 2 : null_str,
302#ifdef USE_BYTECODE_WHITELIST
318# if PY_VERSION_HEX < 0x030c0000
319 OK_OP(UNARY_POSITIVE)
321 OK_OP(UNARY_NEGATIVE)
326# if PY_VERSION_HEX < 0x030c0000
337# if PY_VERSION_HEX < 0x030c0000
338 OK_OP(JUMP_IF_FALSE_OR_POP)
339 OK_OP(JUMP_IF_TRUE_OR_POP)
340 OK_OP(POP_JUMP_FORWARD_IF_FALSE)
341 OK_OP(POP_JUMP_FORWARD_IF_TRUE)
350# if PY_VERSION_HEX < 0x030c0000
351 OK_OP(POP_JUMP_FORWARD_IF_NOT_NONE)
352 OK_OP(POP_JUMP_FORWARD_IF_NONE)
367# if PY_VERSION_HEX < 0x030c0000
368 OK_OP(POP_JUMP_BACKWARD_IF_NOT_NONE)
369 OK_OP(POP_JUMP_BACKWARD_IF_NONE)
370 OK_OP(POP_JUMP_BACKWARD_IF_FALSE)
371 OK_OP(POP_JUMP_BACKWARD_IF_TRUE)
380# if PY_VERSION_HEX < 0x030c0000
390 PyObject *py_namespace_array[],
392 const char *error_prefix)
394 PyCodeObject *py_code = (PyCodeObject *)expr_code;
398 for (
int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
399 PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
400 const char *name_str = PyUnicode_AsUTF8(name);
401 bool contains_name =
false;
402 for (
int j = 0; py_namespace_array[j]; j++) {
403 if (PyDict_Contains(py_namespace_array[j], name)) {
404 contains_name =
true;
409 if ((contains_name ==
false) || (name_str[0] ==
'_')) {
412 "\t%s: restricted access disallows name '%s', "
413 "enable auto-execution to support\n",
424 const _Py_CODEUNIT *codestr;
429 co_code = PyCode_GetCode(py_code);
436 PyBytes_AsStringAndSize(co_code, (
char **)&codestr, &code_len);
437 code_len /=
sizeof(*codestr);
441 for (Py_ssize_t i = 0; i < code_len; i++) {
442 const int opcode = _Py_OPCODE(codestr[i]);
446 "\t%s: restricted access disallows opcode '%d', "
447 "enable auto-execution to support\n",
466 PyObject *py_namespace,
472 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
476 PyObject *py_namespaces[] = {
500 PyObject *driver_vars =
nullptr;
501 PyObject *retval =
nullptr;
507 PyGILState_STATE gilstate;
513 bool targets_ok =
true;
518 if (expr[0] ==
'\0') {
522#ifndef USE_BYTECODE_WHITELIST
526 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
528 printf(
"skipping driver '%s', automatic scripts are disabled\n", expr);
534 bool is_recompile =
false;
540 gilstate = PyGILState_Ensure();
549 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
551 PyGILState_Release(gilstate);
578 expr_code = Py_CompileString(expr,
"<bpy driver>", Py_eval_input);
579 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0, expr_code);
581 driver_orig->
flag &= ~DRIVER_FLAG_RECOMPILE;
585 driver_orig->
flag &= ~DRIVER_FLAG_PYTHON_BLOCKED;
587#ifdef USE_BYTECODE_WHITELIST
592 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 0);
597 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
598 Py_XDECREF(expr_vars);
601 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 1, expr_vars);
606 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->
name));
609 driver_orig->
flag &= ~DRIVER_FLAG_RENAMEVAR;
612 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
616 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
618 PyObject *driver_arg =
nullptr;
621#ifdef USE_RNA_AS_PYOBJECT
624 anim_eval_context, driver, dvar, &dvar->
targets[0]);
626 if (driver_arg ==
nullptr) {
627 driver_arg = PyFloat_FromDouble(0.0);
632 if (PyFloat_CheckExact(driver_arg)) {
633 dvar->
curval =
float(PyFloat_AsDouble(driver_arg));
635 else if (PyLong_CheckExact(driver_arg)) {
638 else if (PyBool_Check(driver_arg)) {
651 driver_arg = PyFloat_FromDouble(
double(tval));
656 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
663 fprintf(stderr,
"\n%s: Error while evaluating PyDriver:\n", __func__);
667 fprintf(stderr,
"\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->
name);
672 Py_DECREF(driver_arg);
675#ifdef USE_BYTECODE_WHITELIST
676 if (is_recompile && expr_code) {
678 PyObject *py_namespaces[] = {
689 SNPRINTF(
G.autoexec_fail,
"Driver '%s'", expr);
692 Py_DECREF(expr_code);
694 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0,
nullptr);
707 retval = PyEval_EvalCode(
713 Py_DECREF(driver_vars);
716 if (retval ==
nullptr) {
720 if (
UNLIKELY((result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
726 driver->
flag &= ~DRIVER_FLAG_INVALID;
732 PyGILState_Release(gilstate);
736 fprintf(stderr,
"\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->
expression, result);
740 return float(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 struct 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 @1344 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)
draw_view in_light_buf[] float
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
const char * RNA_property_identifier(const PropertyRNA *prop)
#define CALL(member, value_str)
struct Depsgraph * depsgraph
PyObject_HEAD PointerRNA ptr
ccl_device_inline int mod(int x, int m)