kiki-the-nano-bot (1.0.2+dfsg1-3) kikiaction-delete-hack.patch

Summary

 src/base/KikiAction.cpp |   16 +++++++++++++++-
 src/base/KikiAction.h   |    2 ++
 2 files changed, 17 insertions(+), 1 deletion(-)

    
download this patch

Patch contents

This works around a subtle memory corruption.

Consider the following chain of events:
 - KikiAction::finished() is called
 - This method calls KikiActionObject::actionFinished(), a virtual method
 - Some implementations of this method (e.g. KikiBotFume's) delete
   themselves ("delete this;")
 - The destructor of KikiActionObject deletes all associated actions,
   which includes the KikiAction whose finished() method is still executing!
 - And this finished() method goes on to read/write freed memory.

I haven't found a proper fix, so this hack will have to do.
   

Peter De Wachter (pdewacht@gmail.com)
placed in the public domain

Status: in upstream CVS

--- a/src/base/KikiAction.cpp
+++ b/src/base/KikiAction.cpp
@@ -19,6 +19,8 @@
     mode		= m;
     duration		= d;
     event		= NULL;
+
+    delete_flag_ptr     = NULL;
     
     reset();
 }
@@ -32,6 +34,8 @@
     duration		= d;
     event		= NULL;
 
+    delete_flag_ptr     = NULL;
+
     reset();
 }
 
@@ -40,6 +44,7 @@
 {
     if (event) event->removeAction(this);
     if (action_object) action_object->removeAction(this);
+    if (delete_flag_ptr) *delete_flag_ptr = true;
 }
 
 // --------------------------------------------------------------------------------------------------------
@@ -50,9 +55,18 @@
 void KikiAction::finish ()  { action_object->finishAction (this); }
 // --------------------------------------------------------------------------------------------------------
 void KikiAction::finished () 
-{ 
+{
+    bool delete_flag = false;
+    delete_flag_ptr = &delete_flag;
+
     action_object->actionFinished(this);
 
+    if (delete_flag)
+    {
+        return;
+    }
+    delete_flag_ptr = NULL;
+
     if (current == getDuration()) // if keepRest wasn't called -> reset start and current values
     {
         reset();
--- a/src/base/KikiAction.h
+++ b/src/base/KikiAction.h
@@ -68,6 +68,8 @@
     int			duration;
     int			mode;
     KikiEvent * 	event;
+
+    bool *              delete_flag_ptr;
 };
 
 // __________________________________________________________________________________________________