[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40660] trunk/blender/source/blender: fix for crash with demo mode addon, modal operator loading a blend file would free all window data which was then accessed , causing a crash.

Campbell Barton ideasman42 at gmail.com
Wed Sep 28 17:42:56 CEST 2011


Revision: 40660
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40660
Author:   campbellbarton
Date:     2011-09-28 15:42:55 +0000 (Wed, 28 Sep 2011)
Log Message:
-----------
fix for crash with demo mode addon, modal operator loading a blend file would free all window data which was then accessed, causing a crash.

Modified Paths:
--------------
    trunk/blender/source/blender/python/intern/bpy_rna.c
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c

Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.c	2011-09-28 15:22:13 UTC (rev 40659)
+++ trunk/blender/source/blender/python/intern/bpy_rna.c	2011-09-28 15:42:55 UTC (rev 40660)
@@ -6238,8 +6238,12 @@
 	ParameterIterator iter;
 	PointerRNA funcptr;
 	int err= 0, i, flag, ret_len=0;
-	int is_static= RNA_function_flag(func) & FUNC_NO_SELF;
+	const char is_static= (RNA_function_flag(func) & FUNC_NO_SELF) != 0;
 
+	/* annoying!, need to check if the screen gets set to NULL which is a
+	 * hint that the file was actually re-loaded. */
+	const char is_valid_screen= (CTX_wm_screen(C) != NULL);
+
 	PropertyRNA *pret_single= NULL;
 	void *retdata_single= NULL;
 
@@ -6498,7 +6502,11 @@
 	if(err != 0) {
 		ReportList *reports;
 		/* alert the user, else they wont know unless they see the console. */
-		if (!is_static && ptr->data && RNA_struct_is_a(ptr->type, &RNA_Operator)) {
+		if (    (!is_static) &&
+		        (ptr->data) &&
+		        (RNA_struct_is_a(ptr->type, &RNA_Operator)) &&
+		        is_valid_screen == (CTX_wm_screen(C) != NULL))
+		{
 			wmOperator *op= ptr->data;
 			reports= op->reports;
 		}

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2011-09-28 15:22:13 UTC (rev 40659)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2011-09-28 15:42:55 UTC (rev 40660)
@@ -1223,41 +1223,47 @@
 			retval= ot->modal(C, op, event);
 			OPERATOR_RETVAL_CHECK(retval);
 
-			if(ot->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm)
-				wm->op_undo_depth--;
+			/* when this is _not_ the case the modal modifier may have loaded
+			 * a new blend file (demo mode does this), so we have to assume
+			 * the event, operator etc have all been freed. - campbell */
+			if(CTX_wm_manager(C) == wm) {
 
-			/* putting back screen context, reval can pass trough after modal failures! */
-			if((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
-				CTX_wm_area_set(C, area);
-				CTX_wm_region_set(C, region);
-			}
-			else {
-				/* this special cases is for areas and regions that get removed */
-				CTX_wm_area_set(C, NULL);
-				CTX_wm_region_set(C, NULL);
-			}		
+				if(ot->flag & OPTYPE_UNDO)
+					wm->op_undo_depth--;
 
-			if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED))
-				wm_operator_reports(C, op, retval, 0);
-			
-			if(retval & OPERATOR_FINISHED) {
-				wm_operator_finished(C, op, 0);
-				handler->op= NULL;
-			}
-			else if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
-				WM_operator_free(op);
-				handler->op= NULL;
-			}
-			
-			/* remove modal handler, operator itself should have been cancelled and freed */
-			if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
-				WM_cursor_ungrab(CTX_wm_window(C));
+				/* putting back screen context, reval can pass trough after modal failures! */
+				if((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
+					CTX_wm_area_set(C, area);
+					CTX_wm_region_set(C, region);
+				}
+				else {
+					/* this special cases is for areas and regions that get removed */
+					CTX_wm_area_set(C, NULL);
+					CTX_wm_region_set(C, NULL);
+				}
 
-				BLI_remlink(handlers, handler);
-				wm_event_free_handler(handler);
-				
-				/* prevent silly errors from operator users */
-				//retval &= ~OPERATOR_PASS_THROUGH;
+				if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED))
+					wm_operator_reports(C, op, retval, 0);
+
+				if(retval & OPERATOR_FINISHED) {
+					wm_operator_finished(C, op, 0);
+					handler->op= NULL;
+				}
+				else if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
+					WM_operator_free(op);
+					handler->op= NULL;
+				}
+
+				/* remove modal handler, operator itself should have been cancelled and freed */
+				if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
+					WM_cursor_ungrab(CTX_wm_window(C));
+
+					BLI_remlink(handlers, handler);
+					wm_event_free_handler(handler);
+
+					/* prevent silly errors from operator users */
+					//retval &= ~OPERATOR_PASS_THROUGH;
+				}
 			}
 			
 		}




More information about the Bf-blender-cvs mailing list