Fix T91096: VSE use after free with overwrite enabled

Strip was flagged for deletion in `seq_transform_handle_overwrite()`
on `STRIP_OVERLAP_IS_FULL`. Then it is removed in
`SEQ_edit_strip_split()` before it should be.

Handle `STRIP_OVERLAP_IS_FULL` in separate loop.

This may not be complete solution, because in example file overlap is
caused between 2 transformed strips and one that is "static".
Such operation should not be possible in first place. This fixes the
crash at lest, so improvement in behavior can be handled separately.

Differential Revision: https://developer.blender.org/D12751
This commit is contained in:
Richard Antalik 2021-10-09 10:11:10 +02:00
parent e541f37529
commit 2561145da8
Notes: blender-bot 2023-02-14 04:20:36 +01:00
Referenced by issue #91096, Sequencer: crash transforming strips with overwrite enabled
1 changed files with 11 additions and 6 deletions

View File

@ -458,6 +458,7 @@ static void seq_transform_handle_overwrite_split(const TransInfo *t,
SEQ_edit_strip_split(
bmain, scene, seqbase, split_strip, transformed->enddisp, SEQ_SPLIT_SOFT, NULL);
SEQ_edit_flag_for_removal(scene, seqbase_active_get(t), split_strip);
SEQ_edit_remove_flagged_sequences(t->scene, seqbase_active_get(t));
}
/* Trim strips by adjusting handle position.
@ -498,8 +499,8 @@ static void seq_transform_handle_overwrite_trim(const TransInfo *t,
static void seq_transform_handle_overwrite(const TransInfo *t, SeqCollection *transformed_strips)
{
SeqCollection *targets = query_overwrite_targets(t, transformed_strips);
SeqCollection *strips_to_delete = SEQ_collection_create(__func__);
bool strips_delete = false;
Sequence *target;
Sequence *transformed;
SEQ_ITERATOR_FOREACH (target, targets) {
@ -511,13 +512,10 @@ static void seq_transform_handle_overwrite(const TransInfo *t, SeqCollection *tr
const eOvelapDescrition overlap = overlap_description_get(transformed, target);
if (overlap == STRIP_OVERLAP_IS_FULL) {
/* Remove covered strip. */
SEQ_edit_flag_for_removal(t->scene, seqbase_active_get(t), target);
strips_delete = true;
SEQ_collection_append_strip(target, strips_to_delete);
}
else if (overlap == STRIP_OVERLAP_IS_INSIDE) {
seq_transform_handle_overwrite_split(t, transformed, target);
strips_delete = true;
}
else if (ELEM(overlap, STRIP_OVERLAP_LEFT_SIDE, STRIP_OVERLAP_RIGHT_SIDE)) {
seq_transform_handle_overwrite_trim(t, transformed, target, overlap);
@ -527,9 +525,16 @@ static void seq_transform_handle_overwrite(const TransInfo *t, SeqCollection *tr
SEQ_collection_free(targets);
if (strips_delete) {
/* Remove covered strips. This must be done in separate loop, because `SEQ_edit_strip_split()`
* also uses `SEQ_edit_remove_flagged_sequences()`. See T91096. */
if (SEQ_collection_len(strips_to_delete) > 0) {
Sequence *seq;
SEQ_ITERATOR_FOREACH (seq, strips_to_delete) {
SEQ_edit_flag_for_removal(t->scene, seqbase_active_get(t), seq);
}
SEQ_edit_remove_flagged_sequences(t->scene, seqbase_active_get(t));
}
SEQ_collection_free(strips_to_delete);
}
static void seq_transform_handle_overlap_shuffle(const TransInfo *t,