diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-09-09 17:26:53 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-09-09 17:36:23 +0300 |
commit | c028b5980bc2db662a67b9c7e9c5743b4d5a72e5 (patch) | |
tree | 78dfbaf8b4fb4b96a011dd75daa838c4b0f4f6df /source/blender/blenloader/intern | |
parent | 12e4103bdd7be6dfe867e64ef510db1fafc8a90d (diff) |
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!
Diffstat (limited to 'source/blender/blenloader/intern')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6625c9159f7..55cadaef459 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6607,7 +6607,13 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc BLI_mempool_iternew(so->treestore, &iter); while ((tselem = BLI_mempool_iterstep(&iter))) { - tselem->id = restore_pointer_by_name(newmain, tselem->id, USER_IGNORE); + /* 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 */ |