[Bf-blender-cvs] [4e0fd7fff11] master: VSE: Sanitize move_to_meta usage

Richard Antalik noreply at git.blender.org
Tue Mar 23 11:23:45 CET 2021


Commit: 4e0fd7fff11b76e52a5f11ba8704028c9b3c3ab0
Author: Richard Antalik
Date:   Tue Mar 23 10:49:48 2021 +0100
Branches: master
https://developer.blender.org/rB4e0fd7fff11b76e52a5f11ba8704028c9b3c3ab0

VSE: Sanitize move_to_meta usage

There were multiple cases that could lead to problems like moving meta
strip into itself or into it's children meta strips.

Print error string to console when invalid action is requested.

===================================================================

M	source/blender/makesrna/intern/rna_sequencer_api.c
M	source/blender/sequencer/SEQ_edit.h
M	source/blender/sequencer/intern/strip_edit.c

===================================================================

diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 1fb0e502ec6..a49a404fe6c 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -81,15 +81,16 @@ static void rna_Sequence_swap_internal(Sequence *seq_self,
   }
 }
 
-static void rna_Sequences_move_strip_to_meta(ID *id,
-                                             Sequence *seq_self,
-                                             Main *bmain,
-                                             Sequence *meta_dst)
+static void rna_Sequences_move_strip_to_meta(
+    ID *id, Sequence *seq_self, Main *bmain, ReportList *reports, Sequence *meta_dst)
 {
   Scene *scene = (Scene *)id;
+  const char *error_msg;
 
   /* Move strip to meta. */
-  SEQ_edit_move_strip_to_meta(scene, seq_self, meta_dst);
+  if (!SEQ_edit_move_strip_to_meta(scene, seq_self, meta_dst, &error_msg)) {
+    BKE_report(reports, RPT_ERROR, error_msg);
+  }
 
   /* Update depsgraph. */
   DEG_relations_tag_update(bmain);
@@ -651,7 +652,7 @@ void RNA_api_sequence_strip(StructRNA *srna)
   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
 
   func = RNA_def_function(srna, "move_to_meta", "rna_Sequences_move_strip_to_meta");
-  RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
+  RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID | FUNC_USE_MAIN);
   parm = RNA_def_pointer(func,
                          "meta_sequence",
                          "Sequence",
diff --git a/source/blender/sequencer/SEQ_edit.h b/source/blender/sequencer/SEQ_edit.h
index 38ce665563c..2711e0a7ee3 100644
--- a/source/blender/sequencer/SEQ_edit.h
+++ b/source/blender/sequencer/SEQ_edit.h
@@ -33,9 +33,10 @@ struct Scene;
 struct Sequence;
 
 int SEQ_edit_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
-int SEQ_edit_move_strip_to_meta(struct Scene *scene,
-                                struct Sequence *src_seq,
-                                struct Sequence *dst_seqm);
+bool SEQ_edit_move_strip_to_meta(struct Scene *scene,
+                                 struct Sequence *src_seq,
+                                 struct Sequence *dst_seqm,
+                                 const char **error_str);
 void SEQ_edit_flag_for_removal(struct Scene *scene,
                                struct ListBase *seqbase,
                                struct Sequence *seq);
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c
index e21a25a7e4f..4a042ee2598 100644
--- a/source/blender/sequencer/intern/strip_edit.c
+++ b/source/blender/sequencer/intern/strip_edit.c
@@ -104,26 +104,6 @@ int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_
   return 1;
 }
 
-int SEQ_edit_move_strip_to_meta(Scene *scene, Sequence *src_seq, Sequence *dst_seqm)
-{
-  /* Find the appropriate seqbase */
-  Editing *ed = SEQ_editing_get(scene, false);
-  ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq);
-
-  /* Move to meta */
-  BLI_remlink(seqbase, src_seq);
-  BLI_addtail(&dst_seqm->seqbase, src_seq);
-  SEQ_relations_invalidate_cache_preprocessed(scene, src_seq);
-
-  /* Update meta */
-  SEQ_time_update_sequence(scene, dst_seqm);
-  if (SEQ_transform_test_overlap(&dst_seqm->seqbase, src_seq)) {
-    SEQ_transform_seqbase_shuffle(&dst_seqm->seqbase, src_seq, scene);
-  }
-
-  return 0;
-}
-
 static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
 {
   Sequence *seq;
@@ -224,6 +204,72 @@ void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
   }
 }
 
+bool seq_exists_in_seqbase(Sequence *seq, ListBase *seqbase)
+{
+  LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
+    if (seq_test->type == SEQ_TYPE_META && seq_exists_in_seqbase(seq, &seq_test->seqbase)) {
+      return true;
+    }
+    if (seq_test == seq) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool SEQ_edit_move_strip_to_meta(Scene *scene,
+                                 Sequence *src_seq,
+                                 Sequence *dst_seqm,
+                                 const char **error_str)
+{
+  /* Find the appropriate seqbase */
+  Editing *ed = SEQ_editing_get(scene, false);
+  ListBase *seqbase = SEQ_get_seqbase_by_seq(&ed->seqbase, src_seq);
+
+  if (dst_seqm->type != SEQ_TYPE_META) {
+    *error_str = N_("Can not move strip to non-meta strip");
+    return false;
+  }
+
+  if (src_seq == dst_seqm) {
+    *error_str = N_("Strip can not be moved into itself");
+    return false;
+  }
+
+  if (seqbase == &dst_seqm->seqbase) {
+    *error_str = N_("Moved strip is already inside provided meta strip");
+    return false;
+  }
+
+  if (src_seq->type == SEQ_TYPE_META && seq_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) {
+    *error_str = N_("Moved strip is parent of provided meta strip");
+    return false;
+  }
+
+  if (!seq_exists_in_seqbase(dst_seqm, &ed->seqbase)) {
+    *error_str = N_("Can not move strip to different scene");
+    return false;
+  }
+
+  /* Remove users of src_seq. Ideally these could be moved into meta as well, but this would be
+   * best to do with generalized iterator as described in D10337. */
+  sequencer_flag_users_for_removal(scene, seqbase, src_seq);
+  SEQ_edit_remove_flagged_sequences(scene, seqbase);
+
+  /* Move to meta. */
+  BLI_remlink(seqbase, src_seq);
+  BLI_addtail(&dst_seqm->seqbase, src_seq);
+  SEQ_relations_invalidate_cache_preprocessed(scene, src_seq);
+
+  /* Update meta. */
+  SEQ_time_update_sequence(scene, dst_seqm);
+  if (SEQ_transform_test_overlap(&dst_seqm->seqbase, src_seq)) {
+    SEQ_transform_seqbase_shuffle(&dst_seqm->seqbase, src_seq, scene);
+  }
+
+  return true;
+}
+
 static void seq_split_set_left_hold_offset(Sequence *seq, int timeline_frame)
 {
   /* Adjust within range of extended stillframes before strip. */



More information about the Bf-blender-cvs mailing list