diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-05-13 09:01:26 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-05-13 09:01:26 +0300 |
commit | 0e0ebdb65c978a22db2bdcc71dd058ec89cac932 (patch) | |
tree | 09df8f1ab80c84025a3e07117cf4b58a3b8a1a26 /source/blender | |
parent | 75d0287cee1aae1a94e46d3fb90379ce016eda8c (diff) |
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.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/makesrna/intern/rna_wm.c | 38 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna_types_capi.c | 46 |
2 files changed, 45 insertions, 39 deletions
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 151c772f533..deeb4f5789c 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1233,39 +1233,6 @@ static bool rna_KeyMapItem_userdefined_get(PointerRNA *ptr) return kmi->id < 0; } -static void rna_wmClipboard_get(PointerRNA *UNUSED(ptr), char *value) -{ - char *pbuf; - int pbuf_len; - - pbuf = WM_clipboard_text_get(false, &pbuf_len); - if (pbuf) { - memcpy(value, pbuf, pbuf_len + 1); - MEM_freeN(pbuf); - } - else { - value[0] = '\0'; - } -} - -static int rna_wmClipboard_length(PointerRNA *UNUSED(ptr)) -{ - char *pbuf; - int pbuf_len; - - pbuf = WM_clipboard_text_get(false, &pbuf_len); - if (pbuf) { - MEM_freeN(pbuf); - } - - return pbuf_len; -} - -static void rna_wmClipboard_set(PointerRNA *UNUSED(ptr), const char *value) -{ - WM_clipboard_text_set((void *)value, false); -} - static PointerRNA rna_WindowManager_xr_session_state_get(PointerRNA *ptr) { wmWindowManager *wm = ptr->data; @@ -2493,11 +2460,6 @@ static void rna_def_windowmanager(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Key Configurations", "Registered key configurations"); rna_def_wm_keyconfigs(brna, prop); - prop = RNA_def_property(srna, "clipboard", PROP_STRING, PROP_NONE); - RNA_def_property_string_funcs( - prop, "rna_wmClipboard_get", "rna_wmClipboard_length", "rna_wmClipboard_set"); - RNA_def_property_ui_text(prop, "Text Clipboard", ""); - prop = RNA_def_property(srna, "xr_session_settings", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "xr.session_settings"); RNA_def_property_flag(prop, PROP_NEVER_NULL); 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 @@ -46,6 +46,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); } /** \} */ |