Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-05-13 09:01:26 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-05-13 09:01:26 +0300
commit0e0ebdb65c978a22db2bdcc71dd058ec89cac932 (patch)
tree09df8f1ab80c84025a3e07117cf4b58a3b8a1a26
parent75d0287cee1aae1a94e46d3fb90379ce016eda8c (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.
-rw-r--r--source/blender/makesrna/intern/rna_wm.c38
-rw-r--r--source/blender/python/intern/bpy_rna_types_capi.c46
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);
}
/** \} */