From 719f4cd5e586f7a54b33d9e1ba5857899e72c8e1 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Tue, 1 Mar 2022 17:59:37 +0800 Subject: [PATCH] Fix `UndoRedo::create_action()` invalid memory usage (cherry picked from commit b00b7f9b7c2af2d9682dd13e892c7f0d5cfcdac8) --- core/undo_redo.cpp | 45 +++++++++++++++++---------------------------- core/undo_redo.h | 2 ++ 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp index fdb6ece905d..c9e1211ea55 100644 --- a/core/undo_redo.cpp +++ b/core/undo_redo.cpp @@ -33,6 +33,20 @@ #include "core/os/os.h" #include "core/resource.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; @@ -40,16 +54,7 @@ void UndoRedo::_discard_redo() { for (int i = current_action + 1; i < actions.size(); i++) { for (List::Element *E = actions.write[i].do_ops.front(); E; E = E->next()) { - if (E->get().type == Operation::TYPE_REFERENCE) { - if (E->get().ref.is_valid()) { - E->get().ref.unref(); - } else { - Object *obj = ObjectDB::get_instance(E->get().object); - if (obj) { - memdelete(obj); - } - } - } + E->get().delete_reference(); } //ERASE do data } @@ -72,14 +77,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) { List::Element *E = actions.write[current_action + 1].do_ops.front(); while (E) { - if (E->get().type == Operation::TYPE_REFERENCE) { - Object *obj = ObjectDB::get_instance(E->get().object); - - if (obj) { - memdelete(obj); - } - } - + E->get().delete_reference(); E = E->next(); actions.write[current_action + 1].do_ops.pop_front(); } @@ -224,16 +222,7 @@ void UndoRedo::_pop_history_tail() { } for (List::Element *E = actions.write[0].undo_ops.front(); E; E = E->next()) { - if (E->get().type == Operation::TYPE_REFERENCE) { - if (E->get().ref.is_valid()) { - E->get().ref.unref(); - } else { - Object *obj = ObjectDB::get_instance(E->get().object); - if (obj) { - memdelete(obj); - } - } - } + E->get().delete_reference(); } actions.remove(0); diff --git a/core/undo_redo.h b/core/undo_redo.h index 517f12b4a68..ae9cab1f187 100644 --- a/core/undo_redo.h +++ b/core/undo_redo.h @@ -64,6 +64,8 @@ private: ObjectID object; String name; Variant args[VARIANT_ARG_MAX]; + + void delete_reference(); }; struct Action {