enigma-dev/enigma-dev — pull request #874 by sorlok (2014-11-28 01:53:56+00:00)
Title: Fix memory corruption from instance_deactivate_object()

A while ago, someone fixed the massive memory leak in iterator's object_basic constructor. This is a good thing! However, it lead to this issue in instance_deactivate_object:

```
//Paraphrased:
enigma::iterator it = enigma::fetch_inst_iter_by_int(obj);
enigma::instance_deactivated_list.insert(inode_pair((*it)->id,it.it));

//In fetch_inst_iter_by_int():
iterator ret = iterator(a->second->inst);
return a != instance_list.end() ? iterator(a->second->inst) : iterator();

//In iterator::iterator(object_basic*):
iterator::iterator(object_basic* ob) : temp_iter(ob, NULL, NULL), it(&temp_iter) {}

//And, finally, in the iterator class definition:
struct iterator {
inst_iter temp_iter;
struct inst_iter* it;
};
```

So, correct me if I am wrong (which is entirely possible!), but fetch_inst_iter_by_int() is returning a temporary as a pointer (the it(&temp_iter)), which will eventually blow up. I noticed this occurring somewhat-predictably in both Iji and An Untitled Story.

To fix this, I noted that any object_basic* is manually unlinked before being inserted into instance_deactivated_list, so I turned instance_deactivated_list into a map of object_basic* rather than inst_iter*.

This led to a bug with ```instance_iter_queue_for_destroy(ENOBJ_ITER_me)``` queueing up the wrong object, so I just replaced it with ```instance_iter_queue_for_destroy(this)```, which seems more correct anyway. I am not sure how ENOBJ_ITER_me gets corrupted (I know it happens if a destroy() event creates and links a new object of a different type), but I suspect the instance system in general.