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/python | |
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/python')
-rw-r--r-- | source/blender/python/intern/bpy_rna_types_capi.c | 46 |
1 files changed, 45 insertions, 1 deletions
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); } /** \} */ |