diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-02-13 12:41:36 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-02-13 12:42:32 +0300 |
commit | 539cbf639faff9c92cc0eb53273c367838216e77 (patch) | |
tree | 839e12829e606dfc3dce3a3d36617abc34b8b2de /source/blender/editors/animation | |
parent | f54c3e35006de9e726f70d722719e540e284ce7c (diff) |
Fix crash removing drivers
Was a use-after-free during relations update.
Now we do similar dependency graph tags, but without any
extra animation update logic, which was accessing various
pointers.
Was found when looking into a file from T56635.
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 12f5463e923..2a1f8d2b99f 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -1625,6 +1625,27 @@ static void ANIM_OT_channels_ungroup(wmOperatorType *ot) /* ******************** Delete Channel Operator *********************** */ +static void update_dependencies_on_delete(bAnimListElem *ale) +{ + ID *id = ale->id; + AnimData *adt = BKE_animdata_from_id(id); + /* TODO(sergey): Technically, if the animation element is being deleted + * from a driver we don't have to tag action. This is something we can check + * for in the future. For now just do most reliable tag whic hwas always + * happening. */ + if (adt != NULL) { + DEG_id_tag_update(id, ID_RECALC_ANIMATION); + if (adt->action != NULL) { + DEG_id_tag_update(&adt->action->id, ID_RECALC_COPY_ON_WRITE); + } + } + /* Deals with NLA and drivers. + * Doesn't cause overhead for action updates, since object will receive + * animation update after dependency graph flushes update from action to + * all its users. */ + DEG_id_tag_update(id, ID_RECALC_ANIMATION); +} + static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) { bAnimContext ac; @@ -1697,7 +1718,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* try to free F-Curve */ ANIM_fcurve_delete_from_animdata(&ac, adt, fcu); - ale->update = ANIM_UPDATE_DEPS; + update_dependencies_on_delete(ale); break; } case ANIMTYPE_NLACURVE: @@ -1719,7 +1740,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* unlink and free the F-Curve */ BLI_remlink(&strip->fcurves, fcu); free_fcurve(fcu); - ale->update = ANIM_UPDATE_DEPS; + update_dependencies_on_delete(ale); break; } case ANIMTYPE_GPLAYER: @@ -1747,7 +1768,6 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) } /* cleanup */ - ANIM_animdata_update(&ac, &anim_data); ANIM_animdata_freelist(&anim_data); /* send notifier that things have changed */ |