summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2022-03-01 12:51:21 +0100
committerGitHub <noreply@github.com>2022-03-01 12:51:21 +0100
commit3827b4ffdf6fb74d6e2898a169baae4da00dc5da (patch)
treefbd17c6d7f27634dae03188b4b8fbe17816beb1a
parent97e5367fe8f62eb2481bf7e43b4ffb4bd56dc028 (diff)
parentb00b7f9b7c2af2d9682dd13e892c7f0d5cfcdac8 (diff)
Merge pull request #58652 from timothyqiu/undo-crash
Fix `UndoRedo::create_action()` invalid memory usage
-rw-r--r--core/object/undo_redo.cpp44
-rw-r--r--core/object/undo_redo.h2
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 {