fix crash using freed memory with SCREEN_OT_screen_set while the current screen has...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 30 Apr 2011 11:28:09 +0000 (11:28 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 30 Apr 2011 11:28:09 +0000 (11:28 +0000)
source/blender/editors/screen/screen_ops.c

index 56a27da54df7a3ba810f09c655ebe75365e7d9ff..b5f980ab7cb4ffdad53e4e49992c5b461fb384ed 100644 (file)
@@ -1871,6 +1871,8 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
 static int screen_set_exec(bContext *C, wmOperator *op)
 {
        bScreen *screen= CTX_wm_screen(C);
+       bScreen *screen_prev= screen;
+       
        ScrArea *sa= CTX_wm_area(C);
        int tot= BLI_countlist(&CTX_data_main(C)->screen);
        int delta= RNA_int_get(op->ptr, "delta");
@@ -1879,15 +1881,11 @@ static int screen_set_exec(bContext *C, wmOperator *op)
        if(screen->temp)
                return OPERATOR_CANCELLED;
        
-       /* return to previous state before switching screens */
-       if(sa && sa->full)
-               ED_screen_full_restore(C, sa);
-       
        if(delta==1) {
                while(tot--) {
                        screen= screen->id.next;
                        if(screen==NULL) screen= CTX_data_main(C)->screen.first;
-                       if(screen->winid==0 && screen->full==0)
+                       if(screen->winid==0 && screen->full==0 && screen != screen_prev)
                                break;
                }
        }
@@ -1895,7 +1893,7 @@ static int screen_set_exec(bContext *C, wmOperator *op)
                while(tot--) {
                        screen= screen->id.prev;
                        if(screen==NULL) screen= CTX_data_main(C)->screen.last;
-                       if(screen->winid==0 && screen->full==0)
+                       if(screen->winid==0 && screen->full==0 && screen != screen_prev)
                                break;
                }
        }
@@ -1903,7 +1901,12 @@ static int screen_set_exec(bContext *C, wmOperator *op)
                screen= NULL;
        }
        
-       if(screen) {
+       if(screen && screen_prev != screen) {
+               /* return to previous state before switching screens */
+               if(sa && sa->full) {
+                       ED_screen_full_restore(C, sa); /* may free 'screen_prev' */
+               }
+               
                ED_screen_set(C, screen);
                return OPERATOR_FINISHED;
        }