52 #define USE_RNA_AS_PYOBJECT
54 #define USE_BYTECODE_WHITELIST
56 #ifdef USE_BYTECODE_WHITELIST
66 #ifdef USE_BYTECODE_WHITELIST
90 PyDict_SetItemString(d,
"__builtins__", PyEval_GetBuiltins());
92 mod = PyImport_ImportModule(
"math");
94 PyDict_Merge(d, PyModule_GetDict(
mod), 0);
97 #ifdef USE_BYTECODE_WHITELIST
98 PyObject *mod_math =
mod;
111 PyObject *modsub = PyDict_GetItemString(PyModule_GetDict(
mod),
"noise");
119 static const char *
names[] = {
"clamp",
"lerp",
"smoothstep",
NULL};
122 PyObject *func = PyDict_GetItemString(PyModule_GetDict(
mod), *
pname);
129 #ifdef USE_BYTECODE_WHITELIST
133 const char *whitelist[] = {
156 for (
int i = 0; whitelist[i]; i++) {
161 if (mod_math !=
NULL) {
162 PyObject *mod_math_dict = PyModule_GetDict(mod_math);
163 PyObject *arg_key, *arg_value;
164 Py_ssize_t arg_pos = 0;
165 while (PyDict_Next(mod_math_dict, &arg_pos, &arg_key, &arg_value)) {
166 const char *
arg_str = PyUnicode_AsUTF8(arg_key);
194 PyObject *item = PyFloat_FromDouble(
evaltime);
230 PyGILState_STATE gilstate;
231 const bool use_gil =
true;
234 gilstate = PyGILState_Ensure();
243 #ifdef USE_BYTECODE_WHITELIST
257 PyGILState_Release(gilstate);
266 "\nError in Driver: The following Python expression failed:\n\t'%s'\n\n",
274 #ifdef USE_BYTECODE_WHITELIST
276 # define OK_OP(op) [op] = 1
285 OK_OP(UNARY_POSITIVE),
286 OK_OP(UNARY_NEGATIVE),
289 OK_OP(BINARY_MATRIX_MULTIPLY),
290 OK_OP(INPLACE_MATRIX_MULTIPLY),
292 OK_OP(BINARY_MULTIPLY),
293 OK_OP(BINARY_MODULO),
295 OK_OP(BINARY_SUBTRACT),
296 OK_OP(BINARY_SUBSCR),
297 OK_OP(BINARY_FLOOR_DIVIDE),
298 OK_OP(BINARY_TRUE_DIVIDE),
299 OK_OP(INPLACE_FLOOR_DIVIDE),
300 OK_OP(INPLACE_TRUE_DIVIDE),
302 OK_OP(INPLACE_SUBTRACT),
303 OK_OP(INPLACE_MULTIPLY),
304 OK_OP(INPLACE_MODULO),
305 OK_OP(BINARY_LSHIFT),
306 OK_OP(BINARY_RSHIFT),
310 OK_OP(INPLACE_POWER),
311 OK_OP(INPLACE_LSHIFT),
312 OK_OP(INPLACE_RSHIFT),
323 OK_OP(JUMP_IF_FALSE_OR_POP),
324 OK_OP(JUMP_IF_TRUE_OR_POP),
325 OK_OP(JUMP_ABSOLUTE),
326 OK_OP(POP_JUMP_IF_FALSE),
327 OK_OP(POP_JUMP_IF_TRUE),
338 OK_OP(CALL_FUNCTION),
339 OK_OP(CALL_FUNCTION_KW),
340 OK_OP(CALL_FUNCTION_EX),
347 PyCodeObject *py_code = (PyCodeObject *)expr_code;
351 for (
int i = 0; i < PyTuple_GET_SIZE(py_code->co_names); i++) {
352 PyObject *name = PyTuple_GET_ITEM(py_code->co_names, i);
353 const char *name_str = PyUnicode_AsUTF8(name);
355 bool contains_name =
false;
356 for (
int j = 0; dict_arr[j]; j++) {
357 if (PyDict_Contains(dict_arr[j], name)) {
358 contains_name =
true;
363 if ((contains_name ==
false) || (name_str[0] ==
'_')) {
365 "\tBPY_driver_eval() - restricted access disallows name '%s', "
366 "enable auto-execution to support\n",
375 const _Py_CODEUNIT *codestr;
378 PyBytes_AsStringAndSize(py_code->co_code, (
char **)&codestr, &code_len);
379 code_len /=
sizeof(*codestr);
381 for (Py_ssize_t i = 0; i < code_len; i++) {
382 const int opcode = _Py_OPCODE(codestr[i]);
385 "\tBPY_driver_eval() - restricted access disallows opcode '%d', "
386 "enable auto-execution to support\n",
422 const char *depsgraph_variable_name =
"depsgraph";
424 if (PyDict_SetItemString(driver_vars, depsgraph_variable_name, py_depsgraph) == -1) {
426 "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n",
427 depsgraph_variable_name);
431 Py_DECREF(py_depsgraph);
456 PyObject *driver_vars =
NULL;
457 PyObject *retval =
NULL;
463 PyGILState_STATE gilstate;
469 short targets_ok = 1;
474 if (expr[0] ==
'\0') {
478 #ifndef USE_BYTECODE_WHITELIST
482 BLI_snprintf(
G.autoexec_fail,
sizeof(
G.autoexec_fail),
"Driver '%s'", expr);
484 printf(
"skipping driver '%s', automatic scripts are disabled\n", expr);
489 bool is_recompile =
false;
495 gilstate = PyGILState_Ensure();
505 fprintf(stderr,
"PyDriver error: couldn't create Python dictionary\n");
507 PyGILState_Release(gilstate);
532 expr_code = Py_CompileString(expr,
"<bpy driver>", Py_eval_input);
533 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0, expr_code);
539 #ifdef USE_BYTECODE_WHITELIST
544 expr_code = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 0);
549 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
550 Py_XDECREF(expr_vars);
553 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 1, expr_vars);
556 PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->
name));
562 expr_vars = PyTuple_GET_ITEM(((PyObject *)driver_orig->
expr_comp), 1);
566 driver_vars = _PyDict_NewPresized(PyTuple_GET_SIZE(expr_vars));
568 PyObject *driver_arg =
NULL;
571 #ifdef USE_RNA_AS_PYOBJECT
575 if (driver_arg ==
NULL) {
576 driver_arg = PyFloat_FromDouble(0.0);
581 if (PyFloat_CheckExact(driver_arg)) {
582 dvar->
curval = (
float)PyFloat_AsDouble(driver_arg);
584 else if (PyLong_CheckExact(driver_arg)) {
587 else if (PyBool_Check(driver_arg)) {
588 dvar->
curval = (driver_arg == Py_True);
600 driver_arg = PyFloat_FromDouble((
double)tval);
605 if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) != -1) {
606 Py_DECREF(driver_arg);
612 fprintf(stderr,
"\nBPY_driver_eval() - Error while evaluating PyDriver:\n");
617 stderr,
"\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", dvar->
name);
624 #ifdef USE_BYTECODE_WHITELIST
625 if (is_recompile && expr_code) {
636 BLI_snprintf(
G.autoexec_fail,
sizeof(
G.autoexec_fail),
"Driver '%s'", expr);
639 Py_DECREF(expr_code);
641 PyTuple_SET_ITEM(((PyObject *)driver_orig->
expr_comp), 0,
NULL);
660 Py_DECREF(driver_vars);
663 if (retval ==
NULL) {
666 else if ((
result = PyFloat_AsDouble(retval)) == -1.0 && PyErr_Occurred()) {
678 PyGILState_Release(gilstate);
686 stderr,
"\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", 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
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 const char secure_opcodes[255]
static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *dict_arr[])
PyObject * bpy_pydriver_Dict
static void pydriver_error(ChannelDriver *driver)
static void bpy_pydriver_namespace_update_frame(const float evaltime)
static void bpy_pydriver_namespace_clear_self(void)
void BPY_driver_reset(void)
static PyObject * bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph)
static struct @1121 g_pydriver_state_prev
int bpy_pydriver_create_dict(void)
static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars, struct Depsgraph *depsgraph)
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_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)
const Depsgraph * depsgraph
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
struct Depsgraph * depsgraph
ccl_device_inline int mod(int x, int m)