25 #include "RNA_prototypes.h"
37 #define USE_RNA_AS_PYOBJECT
39 #define USE_BYTECODE_WHITELIST
41 #ifdef USE_BYTECODE_WHITELIST
47 #ifdef USE_BYTECODE_WHITELIST
68 PyDict_SetItemString(d,
"__builtins__", PyEval_GetBuiltins());
70 mod = PyImport_ImportModule(
"math");
72 PyDict_Merge(d, PyModule_GetDict(
mod), 0);
75 #ifdef USE_BYTECODE_WHITELIST
76 PyObject *mod_math =
mod;
89 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(
mod),
"noise");
97 static const char *
names[] = {
"clamp",
"lerp",
"smoothstep",
NULL};
100 PyObject *func = PyDict_GetItemString(PyModule_GetDict(
mod), *
pname);
107 #ifdef USE_BYTECODE_WHITELIST
111 const char *whitelist[] = {
134 for (
int i = 0; whitelist[i]; i++) {
139 if (mod_math !=
NULL) {
140 PyObject *mod_math_dict = PyModule_GetDict(mod_math);
141 PyObject *arg_key, *arg_value;
142 Py_ssize_t arg_pos = 0;
143 while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
144 const char *
arg_str = PyUnicode_AsUTF8(arg_key);
176 PyObject *item = PyFloat_FromDouble(
evaltime);
245 #ifdef USE_BYTECODE_WHITELIST
262 PyGILState_STATE gilstate;
263 const bool use_gil =
true;
266 gilstate = PyGILState_Ensure();
273 PyGILState_Release(gilstate);
286 const char *null_str =
"<null>";
290 "Error in PyDriver: expression failed: %s\n"
291 "For target: (type=%s, name=\"%s\", property=%s, property_index=%d)\n"
295 id ?
id->
name + 2 : null_str,
304 #ifdef USE_BYTECODE_WHITELIST
306 # define OK_OP(op) [op] = true
309 # if PY_VERSION_HEX >= 0x030b0000
315 OK_OP(UNARY_POSITIVE),
316 OK_OP(UNARY_NEGATIVE),
319 OK_OP(BINARY_SUBSCR),
321 OK_OP(LIST_TO_TUPLE),
330 OK_OP(JUMP_IF_FALSE_OR_POP),
331 OK_OP(JUMP_IF_TRUE_OR_POP),
332 OK_OP(POP_JUMP_FORWARD_IF_FALSE),
333 OK_OP(POP_JUMP_FORWARD_IF_TRUE),
341 OK_OP(POP_JUMP_FORWARD_IF_NOT_NONE),
342 OK_OP(POP_JUMP_FORWARD_IF_NONE),
355 OK_OP(POP_JUMP_BACKWARD_IF_NOT_NONE),
356 OK_OP(POP_JUMP_BACKWARD_IF_NONE),
357 OK_OP(POP_JUMP_BACKWARD_IF_FALSE),
358 OK_OP(POP_JUMP_BACKWARD_IF_TRUE),
376 OK_OP(UNARY_POSITIVE),
377 OK_OP(UNARY_NEGATIVE),
380 OK_OP(BINARY_MATRIX_MULTIPLY),
381 OK_OP(INPLACE_MATRIX_MULTIPLY),
383 OK_OP(BINARY_MULTIPLY),
384 OK_OP(BINARY_MODULO),
386 OK_OP(BINARY_SUBTRACT),
387 OK_OP(BINARY_SUBSCR),
388 OK_OP(BINARY_FLOOR_DIVIDE),
389 OK_OP(BINARY_TRUE_DIVIDE),
390 OK_OP(INPLACE_FLOOR_DIVIDE),
391 OK_OP(INPLACE_TRUE_DIVIDE),
392 # if PY_VERSION_HEX >= 0x030a0000
396 OK_OP(INPLACE_SUBTRACT),
397 OK_OP(INPLACE_MULTIPLY),
398 OK_OP(INPLACE_MODULO),
399 OK_OP(BINARY_LSHIFT),
400 OK_OP(BINARY_RSHIFT),
404 OK_OP(INPLACE_POWER),
405 OK_OP(INPLACE_LSHIFT),
406 OK_OP(INPLACE_RSHIFT),
410 OK_OP(LIST_TO_TUPLE),
412 # if PY_VERSION_HEX >= 0x030a0000
421 OK_OP(JUMP_IF_FALSE_OR_POP),
422 OK_OP(JUMP_IF_TRUE_OR_POP),
423 OK_OP(JUMP_ABSOLUTE),
424 OK_OP(POP_JUMP_IF_FALSE),
425 OK_OP(POP_JUMP_IF_TRUE),
447 OK_OP(CALL_FUNCTION),
448 OK_OP(CALL_FUNCTION_KW),
449 OK_OP(CALL_FUNCTION_EX),
457 PyObject *namespace_array[],
459 const char *error_prefix)
461 PyCodeObject *py_code = (PyCodeObject *)expr_code;
465 for (
int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
466 PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
467 const char *name_str = PyUnicode_AsUTF8(name);
468 bool contains_name =
false;
469 for (
int j = 0; namespace_array[j]; j++) {
470 if (PyDict_Contains(namespace_array[j], name)) {
471 contains_name =
true;
476 if ((contains_name ==
false) || (name_str[0] ==
'_')) {
479 "\t%s: restricted access disallows name '%s', "
480 "enable auto-execution to support\n",
491 const _Py_CODEUNIT *codestr;
496 # if PY_VERSION_HEX >= 0x030b0000
497 co_code = PyCode_GetCode(py_code);
504 co_code = py_code->co_code;
507 PyBytes_AsStringAndSize(co_code, (
char **)&codestr, &code_len);
508 code_len /=
sizeof(*codestr);
512 for (Py_ssize_t i = 0; i < code_len; i++) {
513 const int opcode = _Py_OPCODE(codestr[i]);
517 "\t%s: restricted access disallows opcode '%d', "
518 "enable auto-execution to support\n",
527 # if PY_VERSION_HEX >= 0x030b0000
543 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
577 PyObject *driver_vars =
NULL;
578 PyObject *retval =
NULL;
584 PyGILState_STATE gilstate;
590 bool targets_ok =
true;
595 if (expr[0] ==
'\0') {
599 #ifndef USE_BYTECODE_WHITELIST
603 BLI_snprintf(
G.autoexec_fail,
sizeof(
G.autoexec_fail),
"Driver '%s'", expr);
605 printf(
"skipping driver '%s', automatic scripts are disabled\n", expr);
610 bool is_recompile =
false;
616 gilstate = PyGILState_Ensure();
625 fprintf(stderr,
"%s: couldn't create Python dictionary\n", __func__);
627 PyGILState_Release(gilstate);
654 expr_code = Py_CompileString(expr,
"<bpy driver>", Py_eval_input);
655 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0, expr_code);
661 #ifdef USE_BYTECODE_WHITELIST
666 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 0);
671 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
672 Py_XDECREF(expr_vars);
675 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 1, expr_vars);
678 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->
name));
684 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
688 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
690 PyObject *driver_arg =
NULL;
693 #ifdef USE_RNA_AS_PYOBJECT
697 if (driver_arg ==
NULL) {
698 driver_arg = PyFloat_FromDouble(0.0);
703 if (PyFloat_CheckExact(driver_arg)) {
704 dvar->
curval = (
float)PyFloat_AsDouble(driver_arg);
706 else if (PyLong_CheckExact(driver_arg)) {
709 else if (PyBool_Check(driver_arg)) {
710 dvar->
curval = (driver_arg == Py_True);
722 driver_arg = PyFloat_FromDouble((
double)tval);
727 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
734 fprintf(stderr,
"\n%s: Error while evaluating PyDriver:\n", __func__);
738 fprintf(stderr,
"\t%s: couldn't add variable '%s' to namespace\n", __func__, dvar->
name);
743 Py_DECREF(driver_arg);
746 #ifdef USE_BYTECODE_WHITELIST
747 if (is_recompile && expr_code) {
762 BLI_snprintf(
G.autoexec_fail,
sizeof(
G.autoexec_fail),
"Driver '%s'", expr);
765 Py_DECREF(expr_code);
767 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0,
NULL);
784 Py_DECREF(driver_vars);
787 if (retval ==
NULL) {
791 if (
UNLIKELY((
result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred())) {
803 PyGILState_Release(gilstate);
807 fprintf(stderr,
"\t%s: driver '%s' evaluates to '%f'\n", __func__, driver->
expression,
result);
typedef float(TangentPoint)[2]
float driver_get_variable_value(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)
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
struct Depsgraph Depsgraph
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum pname
static PyObject * bpy_pydriver_Dict__whitelist
static struct @1157 g_pydriver_state_prev
bool BPY_driver_secure_bytecode_test(PyObject *expr_code, PyObject *namespace, const bool verbose)
PyObject * bpy_pydriver_Dict
static void pydriver_error(ChannelDriver *driver, const struct PathResolvedRNA *anim_rna)
static void bpy_pydriver_namespace_update_depsgraph(struct Depsgraph *depsgraph)
BPy_StructRNA * depsgraph
static void bpy_pydriver_namespace_update_frame(const float evaltime)
static void bpy_pydriver_namespace_clear_self(void)
void BPY_driver_exit(void)
void BPY_driver_reset(void)
static PyObject * bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph)
int bpy_pydriver_create_dict(void)
static const bool secure_opcodes[255]
bool BPY_driver_secure_bytecode_test_ex(PyObject *expr_code, PyObject *namespace_array[], const bool verbose, const char *error_prefix)
static void bpy_pydriver_namespace_update_self(struct PathResolvedRNA *anim_rna)
float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, const AnimationEvalContext *anim_eval_context)
PyObject * bpy_intern_str_depsgraph
PyObject * bpy_intern_str_self
PyObject * bpy_intern_str_frame
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
void BPY_update_rna_module(void)
PyObject * pyrna_driver_self_from_anim_rna(PathResolvedRNA *anim_rna)
PyObject * pyrna_driver_get_variable_value(struct ChannelDriver *driver, struct DriverTarget *dtar)
bool pyrna_driver_is_equal_anim_rna(const PathResolvedRNA *anim_rna, const PyObject *py_anim_rna)
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
const char * RNA_property_identifier(const PropertyRNA *prop)
#define CALL(member, value_str)
struct Depsgraph * depsgraph
struct PropertyRNA * prop
ccl_device_inline int mod(int x, int m)