[Bf-blender-cvs] [0e0ebdb65c9] blender-v2.83-release: Fix crash accessing the clipboard

Campbell Barton noreply at git.blender.org
Wed May 13 08:05:51 CEST 2020


Commit: 0e0ebdb65c978a22db2bdcc71dd058ec89cac932
Author: Campbell Barton
Date:   Wed May 13 16:01:26 2020 +1000
Branches: blender-v2.83-release
https://developer.blender.org/rB0e0ebdb65c978a22db2bdcc71dd058ec89cac932

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.

===================================================================

M	source/blender/makesrna/intern/rna_wm.c
M	source/blender/python/intern/bpy_rna_types_capi.c

===================================================================

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
@@ -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);
 }
 
 /** \} */



More information about the Bf-blender-cvs mailing list