[Bf-blender-cvs] [77e6a00] master: Fix T44376: Buttons context, invalid data access

Campbell Barton noreply at git.blender.org
Mon May 4 08:14:10 CEST 2015


Commit: 77e6a001a96b7eb3b2b1c2216a48c85c1b6906e0
Author: Campbell Barton
Date:   Mon May 4 15:07:24 2015 +1000
Branches: master
https://developer.blender.org/rB77e6a001a96b7eb3b2b1c2216a48c85c1b6906e0

Fix T44376: Buttons context, invalid data access

Removing a scene from the buttons window would crash from a Python operator.

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

M	source/blender/blenkernel/BKE_screen.h
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenkernel/intern/screen.c
M	source/blender/editors/include/ED_buttons.h
M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/include/ED_util.h
M	source/blender/editors/space_buttons/buttons_context.c
M	source/blender/editors/util/ed_util.c
M	source/blender/windowmanager/intern/wm_init_exit.c

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

diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index bb76454..c584051 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -273,6 +273,9 @@ void BKE_spacedata_freelist(ListBase *lb);
 void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2);
 void BKE_spacedata_draw_locks(int set);
 
+void BKE_spacedata_callback_id_unref_set(void (*func)(struct SpaceLink *sl, const struct ID *));
+void BKE_spacedata_id_unref(struct SpaceLink *sl, const struct ID *id);
+
 /* area/regions */
 struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar);
 void            BKE_area_region_free(struct SpaceType *st, struct ARegion *ar);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 5b34504..c246495 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -82,6 +82,7 @@
 #include "BKE_paint.h"
 #include "BKE_rigidbody.h"
 #include "BKE_scene.h"
+#include "BKE_screen.h"
 #include "BKE_sequencer.h"
 #include "BKE_sound.h"
 #include "BKE_unit.h"
@@ -823,6 +824,8 @@ static void scene_unlink_space_buts(SpaceButs *sbuts, Scene *sce)
 	if (sbuts->pinid == &sce->id) {
 		sbuts->pinid = NULL;
 	}
+
+	BKE_spacedata_id_unref((SpaceLink *)sbuts, &sce->id);
 }
 
 void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 36fd598..840e1f9 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -272,6 +272,19 @@ void BKE_spacedata_draw_locks(int set)
 	}
 }
 
+static void (*spacedata_id_unref_cb)(struct SpaceLink *sl, const struct ID *id) = NULL;
+
+void BKE_spacedata_callback_id_unref_set(void (*func)(struct SpaceLink *sl, const struct ID *))
+{
+	spacedata_id_unref_cb = func;
+}
+
+void BKE_spacedata_id_unref(struct SpaceLink *sl, const struct ID *id)
+{
+	if (spacedata_id_unref_cb) {
+		spacedata_id_unref_cb(sl, id);
+	}
+}
 
 /* not region itself */
 void BKE_area_region_free(SpaceType *st, ARegion *ar)
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index 64c1660..9a987d7 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -37,4 +37,6 @@ bool ED_texture_context_check_particles(const struct bContext *C);
 bool ED_texture_context_check_linestyle(const struct bContext *C);
 bool ED_texture_context_check_others(const struct bContext *C);
 
+void ED_buttons_id_unref(struct SpaceButs *sbuts, const struct ID *id);
+
 #endif /*  __ED_BUTTONS_H__ */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 5b0b464..8de9a7f 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -76,7 +76,6 @@ void	ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
 void    ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
 int     ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco);
 
-
 /* areas */
 void    ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa);
 void    ED_area_exit(struct bContext *C, struct ScrArea *sa);
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 9556c60..496ce7f 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -42,6 +42,8 @@ void    ED_editors_exit(struct bContext *C);
 
 bool    ED_editors_flush_edits(const struct bContext *C, bool for_render);
 
+void ED_spacedata_id_unref(struct SpaceLink *sl, const struct ID *id);
+
 /* ************** Undo ************************ */
 
 /* undo.c */
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 73091e7..b00a2c5 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -59,6 +59,7 @@
 
 #include "RNA_access.h"
 
+#include "ED_buttons.h"
 #include "ED_armature.h"
 #include "ED_screen.h"
 #include "ED_physics.h"
@@ -1179,3 +1180,28 @@ ID *buttons_context_id_path(const bContext *C)
 
 	return NULL;
 }
+
+void ED_buttons_id_unref(SpaceButs *sbuts, const ID *id)
+{
+	if (sbuts->path) {
+		ButsContextPath *path = sbuts->path;
+		int i;
+
+		for (i = 0; i < path->len; i++) {
+			if (path->ptr[i].id.data == id) {
+				break;
+			}
+		}
+
+		if (i == path->len) {
+			/* pass */
+		}
+		else if (i == 0) {
+			MEM_SAFE_FREE(sbuts->path);
+		}
+		else {
+			memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
+			path->len = i;
+		}
+	}
+}
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 438eb1f..d162bec 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -38,6 +38,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_packedFile_types.h"
 
@@ -58,9 +59,11 @@
 #include "BKE_paint.h"
 
 #include "ED_armature.h"
+#include "ED_buttons.h"
 #include "ED_image.h"
 #include "ED_mesh.h"
 #include "ED_object.h"
+#include "ED_outliner.h"
 #include "ED_paint.h"
 #include "ED_space_api.h"
 #include "ED_util.h"
@@ -318,3 +321,21 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info
 	glEnd();
 	setlinestyle(0);
 }
+
+/**
+ * Use to free ID references within runtime data (stored outside of DNA)
+ *
+ * \note Typically notifiers take care of this,
+ * but there are times we have to free references immediately, see: T44376
+ */
+void ED_spacedata_id_unref(struct SpaceLink *sl, const ID *id)
+{
+	switch (sl->spacetype) {
+		case SPACE_OUTLINER:
+			ED_outliner_id_unref((SpaceOops *)sl, id);
+			break;
+		case SPACE_BUTS:
+			ED_buttons_id_unref((SpaceButs *)sl, id);
+			break;
+	}
+}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 7ca82c0..b5c267e 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -153,6 +153,7 @@ void WM_init(bContext *C, int argc, const char **argv)
 	BKE_library_callback_free_notifier_reference_set(WM_main_remove_notifier_reference);   /* library.c */
 	BKE_library_callback_free_editor_id_reference_set(WM_main_remove_editor_id_reference);   /* library.c */
 	BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */
+	BKE_spacedata_callback_id_unref_set(ED_spacedata_id_unref); /* screen.c */
 	DAG_editors_update_cb(ED_render_id_flush_update, ED_render_scene_update); /* depsgraph.c */
 	
 	ED_spacetypes_init();   /* editors/space_api/spacetype.c */




More information about the Bf-blender-cvs mailing list