Fix (unreported) crash with undo/outliner and drivers.
To reproduce the crash: * Add some shapekeys to default cube. * Add at least on driver (can be default empty one) to a shapekey value. * **Make this driver visible in Outliner**. * Delete all shapekeys. * Undo. * Crash. Root of the issue is outliner reading code in `blo_lib_link_screen_restore()`, which would try to `restore_pointer_by_name()` for all `TreeStoreElement->id` pointers. Thing is, those id pointers are not always IDs, they can be animdata, sequence, RNA struct/property... That's really not so great design, but also has reasons like size of the struct, we have to live with it. So now: * TreeStoreElement->type defines are braught back into DNA. * There we also define a `TSE_IS_REAL_ID` macro to check whether a given TreeStoreElement actually stores an ID pointer or not. * And in Outliner read code we only try to retore pointers by name for actual ID ones, and set the others to default NULL value. Also, added clear comment to TSE types that do not store a real ID pointer!
This commit is contained in:
		@@ -6607,8 +6607,14 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
 | 
			
		||||
 | 
			
		||||
						BLI_mempool_iternew(so->treestore, &iter);
 | 
			
		||||
						while ((tselem = BLI_mempool_iterstep(&iter))) {
 | 
			
		||||
							/* Do not try to restore pointers to drivers/sequence/etc., can crash in undo case! */
 | 
			
		||||
							if (TSE_IS_REAL_ID(tselem)) {
 | 
			
		||||
								tselem->id = restore_pointer_by_name(newmain, tselem->id, USER_IGNORE);
 | 
			
		||||
							}
 | 
			
		||||
							else {
 | 
			
		||||
								tselem->id = NULL;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						if (so->treehash) {
 | 
			
		||||
							/* rebuild hash table, because it depends on ids too */
 | 
			
		||||
							so->storeflag |= SO_TREESTORE_REBUILD;
 | 
			
		||||
 
 | 
			
		||||
@@ -68,47 +68,6 @@ typedef struct TreeElement {
 | 
			
		||||
#define TE_LAZY_CLOSED  4
 | 
			
		||||
#define TE_FREE_NAME    8
 | 
			
		||||
 | 
			
		||||
/* TreeStoreElem types */
 | 
			
		||||
#define TSE_NLA             1
 | 
			
		||||
#define TSE_NLA_ACTION      2
 | 
			
		||||
#define TSE_DEFGROUP_BASE   3
 | 
			
		||||
#define TSE_DEFGROUP        4
 | 
			
		||||
#define TSE_BONE            5
 | 
			
		||||
#define TSE_EBONE           6
 | 
			
		||||
#define TSE_CONSTRAINT_BASE 7
 | 
			
		||||
#define TSE_CONSTRAINT      8
 | 
			
		||||
#define TSE_MODIFIER_BASE   9
 | 
			
		||||
#define TSE_MODIFIER        10
 | 
			
		||||
#define TSE_LINKED_OB       11
 | 
			
		||||
// #define TSE_SCRIPT_BASE     12  // UNUSED
 | 
			
		||||
#define TSE_POSE_BASE       13
 | 
			
		||||
#define TSE_POSE_CHANNEL    14
 | 
			
		||||
#define TSE_ANIM_DATA       15
 | 
			
		||||
#define TSE_DRIVER_BASE     16
 | 
			
		||||
#define TSE_DRIVER          17
 | 
			
		||||
 | 
			
		||||
#define TSE_PROXY           18
 | 
			
		||||
#define TSE_R_LAYER_BASE    19
 | 
			
		||||
#define TSE_R_LAYER         20
 | 
			
		||||
#define TSE_R_PASS          21
 | 
			
		||||
#define TSE_LINKED_MAT      22
 | 
			
		||||
/* NOTE, is used for light group */
 | 
			
		||||
#define TSE_LINKED_LAMP     23
 | 
			
		||||
#define TSE_POSEGRP_BASE    24
 | 
			
		||||
#define TSE_POSEGRP         25
 | 
			
		||||
#define TSE_SEQUENCE        26
 | 
			
		||||
#define TSE_SEQ_STRIP       27
 | 
			
		||||
#define TSE_SEQUENCE_DUP    28
 | 
			
		||||
#define TSE_LINKED_PSYS     29
 | 
			
		||||
#define TSE_RNA_STRUCT      30
 | 
			
		||||
#define TSE_RNA_PROPERTY    31
 | 
			
		||||
#define TSE_RNA_ARRAY_ELEM  32
 | 
			
		||||
#define TSE_NLA_TRACK       33
 | 
			
		||||
#define TSE_KEYMAP          34
 | 
			
		||||
#define TSE_KEYMAP_ITEM     35
 | 
			
		||||
#define TSE_ID_BASE			36
 | 
			
		||||
#define TSE_GP_LAYER        37
 | 
			
		||||
 | 
			
		||||
/* button events */
 | 
			
		||||
#define OL_NAMEBUTTON       1
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,55 @@ typedef struct TreeStore {
 | 
			
		||||
#define TSE_CHILDSEARCH 8
 | 
			
		||||
#define TSE_SEARCHMATCH 16
 | 
			
		||||
 | 
			
		||||
/* TreeStoreElem types in BIF_outliner.h */
 | 
			
		||||
/* TreeStoreElem->types */
 | 
			
		||||
#define TSE_NLA             1  /* NO ID */
 | 
			
		||||
#define TSE_NLA_ACTION      2
 | 
			
		||||
#define TSE_DEFGROUP_BASE   3
 | 
			
		||||
#define TSE_DEFGROUP        4
 | 
			
		||||
#define TSE_BONE            5
 | 
			
		||||
#define TSE_EBONE           6
 | 
			
		||||
#define TSE_CONSTRAINT_BASE 7
 | 
			
		||||
#define TSE_CONSTRAINT      8
 | 
			
		||||
#define TSE_MODIFIER_BASE   9
 | 
			
		||||
#define TSE_MODIFIER        10
 | 
			
		||||
#define TSE_LINKED_OB       11
 | 
			
		||||
/* #define TSE_SCRIPT_BASE     12 */  /* UNUSED */
 | 
			
		||||
#define TSE_POSE_BASE       13
 | 
			
		||||
#define TSE_POSE_CHANNEL    14
 | 
			
		||||
#define TSE_ANIM_DATA       15
 | 
			
		||||
#define TSE_DRIVER_BASE     16  /* NO ID */
 | 
			
		||||
/* #define TSE_DRIVER          17 */  /* UNUSED */
 | 
			
		||||
 | 
			
		||||
#define TSE_PROXY           18
 | 
			
		||||
#define TSE_R_LAYER_BASE    19
 | 
			
		||||
#define TSE_R_LAYER         20
 | 
			
		||||
#define TSE_R_PASS          21
 | 
			
		||||
#define TSE_LINKED_MAT      22
 | 
			
		||||
/* NOTE, is used for light group */
 | 
			
		||||
#define TSE_LINKED_LAMP     23
 | 
			
		||||
#define TSE_POSEGRP_BASE    24
 | 
			
		||||
#define TSE_POSEGRP         25
 | 
			
		||||
#define TSE_SEQUENCE        26  /* NO ID */
 | 
			
		||||
#define TSE_SEQ_STRIP       27  /* NO ID */
 | 
			
		||||
#define TSE_SEQUENCE_DUP    28  /* NO ID */
 | 
			
		||||
#define TSE_LINKED_PSYS     29
 | 
			
		||||
#define TSE_RNA_STRUCT      30  /* NO ID */
 | 
			
		||||
#define TSE_RNA_PROPERTY    31  /* NO ID */
 | 
			
		||||
#define TSE_RNA_ARRAY_ELEM  32  /* NO ID */
 | 
			
		||||
#define TSE_NLA_TRACK       33  /* NO ID */
 | 
			
		||||
#define TSE_KEYMAP          34  /* NO ID */
 | 
			
		||||
#define TSE_KEYMAP_ITEM     35  /* NO ID */
 | 
			
		||||
#define TSE_ID_BASE         36  /* NO ID */
 | 
			
		||||
#define TSE_GP_LAYER        37  /* NO ID */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Check whether given TreeStoreElem should have a real ID in its ->id member. */
 | 
			
		||||
#define TSE_IS_REAL_ID(_tse) \
 | 
			
		||||
	(!ELEM((_tse)->type, TSE_NLA, TSE_NLA_TRACK, TSE_DRIVER_BASE, \
 | 
			
		||||
	                     TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, \
 | 
			
		||||
                         TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM, \
 | 
			
		||||
                         TSE_KEYMAP, TSE_KEYMAP_ITEM, TSE_ID_BASE, TSE_GP_LAYER))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user