From 0e0ebdb65c978a22db2bdcc71dd058ec89cac932 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 May 2020 16:01:26 +1000 Subject: Fix crash accessing the clipboard The clipboard can change between checking it's length and copying into the allocated buffer. Move this from RNA to the C/Python API. --- source/blender/python/intern/bpy_rna_types_capi.c | 46 ++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'source/blender/python/intern/bpy_rna_types_capi.c') diff --git a/source/blender/python/intern/bpy_rna_types_capi.c b/source/blender/python/intern/bpy_rna_types_capi.c index 00442295e0b..cfd6b7f54a8 100644 --- a/source/blender/python/intern/bpy_rna_types_capi.c +++ b/source/blender/python/intern/bpy_rna_types_capi.c @@ -45,6 +45,40 @@ #include "WM_api.h" +/* -------------------------------------------------------------------- */ +/** \name Window Manager Clipboard Property + * + * Avoid using the RNA API because this value may change between checking it's length + * and creating the buffer, causing writes past the allocated length. + * \{ */ + +static PyObject *pyrna_WindowManager_clipboard_get(PyObject *UNUSED(self), void *UNUSED(flag)) +{ + int text_len = 0; + char *text = WM_clipboard_text_get(false, &text_len); + PyObject *result = PyC_UnicodeFromByteAndSize(text ? text : "", text_len); + if (text != NULL) { + MEM_freeN(text); + } + return result; +} + +static int pyrna_WindowManager_clipboard_set(PyObject *UNUSED(self), + PyObject *value, + void *UNUSED(flag)) +{ + PyObject *value_coerce = NULL; + const char *text = PyC_UnicodeAsByte(value, &value_coerce); + if (text == NULL) { + return -1; + } + WM_clipboard_text_set(text, false); + Py_XDECREF(value_coerce); + return 0; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Window Manager Type * \{ */ @@ -61,6 +95,15 @@ static struct PyMethodDef pyrna_windowmanager_methods[] = { {NULL, NULL, 0, NULL}, }; +static struct PyGetSetDef pyrna_windowmanager_getset[] = { + {"clipboard", + pyrna_WindowManager_clipboard_get, + pyrna_WindowManager_clipboard_set, + NULL, + NULL}, + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ +}; + /** \} */ /* -------------------------------------------------------------------- */ @@ -122,7 +165,8 @@ static struct PyMethodDef pyrna_space_methods[] = { void BPY_rna_types_extend_capi(void) { pyrna_struct_type_extend_capi(&RNA_Space, pyrna_space_methods, NULL); - pyrna_struct_type_extend_capi(&RNA_WindowManager, pyrna_windowmanager_methods, NULL); + pyrna_struct_type_extend_capi( + &RNA_WindowManager, pyrna_windowmanager_methods, pyrna_windowmanager_getset); } /** \} */ -- cgit v1.2.3