diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-03-01 12:51:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-01 12:51:21 +0100 |
commit | 3827b4ffdf6fb74d6e2898a169baae4da00dc5da (patch) | |
tree | fbd17c6d7f27634dae03188b4b8fbe17816beb1a /core | |
parent | 97e5367fe8f62eb2481bf7e43b4ffb4bd56dc028 (diff) | |
parent | b00b7f9b7c2af2d9682dd13e892c7f0d5cfcdac8 (diff) |
Merge pull request #58652 from timothyqiu/undo-crash
Fix `UndoRedo::create_action()` invalid memory usage
Diffstat (limited to 'core')
-rw-r--r-- | core/object/undo_redo.cpp | 44 | ||||
-rw-r--r-- | core/object/undo_redo.h | 2 |
2 files changed, 19 insertions, 27 deletions
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index f72dec8edf..b78328fb42 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -34,6 +34,20 @@ #include "core/os/os.h" #include "core/templates/local_vector.h" +void UndoRedo::Operation::delete_reference() { + if (type != Operation::TYPE_REFERENCE) { + return; + } + if (ref.is_valid()) { + ref.unref(); + } else { + Object *obj = ObjectDB::get_instance(object); + if (obj) { + memdelete(obj); + } + } +} + void UndoRedo::_discard_redo() { if (current_action == actions.size() - 1) { return; @@ -41,16 +55,7 @@ void UndoRedo::_discard_redo() { for (int i = current_action + 1; i < actions.size(); i++) { for (Operation &E : actions.write[i].do_ops) { - if (E.type == Operation::TYPE_REFERENCE) { - if (E.ref.is_valid()) { - E.ref.unref(); - } else { - Object *obj = ObjectDB::get_instance(E.object); - if (obj) { - memdelete(obj); - } - } - } + E.delete_reference(); } //ERASE do data } @@ -97,13 +102,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) { for (unsigned int i = 0; i < to_remove.size(); i++) { List<Operation>::Element *E = to_remove[i]; // Delete all object references - if (E->get().type == Operation::TYPE_REFERENCE) { - Object *obj = ObjectDB::get_instance(E->get().object); - - if (obj) { - memdelete(obj); - } - } + E->get().delete_reference(); E->erase(); } } @@ -270,16 +269,7 @@ void UndoRedo::_pop_history_tail() { } for (Operation &E : actions.write[0].undo_ops) { - if (E.type == Operation::TYPE_REFERENCE) { - if (E.ref.is_valid()) { - E.ref.unref(); - } else { - Object *obj = ObjectDB::get_instance(E.object); - if (obj) { - memdelete(obj); - } - } - } + E.delete_reference(); } actions.remove_at(0); diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h index 75639f8abf..5eede74e2d 100644 --- a/core/object/undo_redo.h +++ b/core/object/undo_redo.h @@ -66,6 +66,8 @@ private: ObjectID object; StringName name; Variant args[VARIANT_ARG_MAX]; + + void delete_reference(); }; struct Action { |