The argument is now always treated as a plain string and passed directly
to the cheat. This is the behavior expected by all the functions in
xCheat.py, which parse the string argument manually where needed.
The previous implementation evaluated the argument value as a Python
expression. This theoretically allowed passing non-string arguments, but
none of the cheats use this (and it's also a potential code execution
issue). If no argument was passed, the function was called with no
arguments, which is also not supported by any of the cheats.
In practice, this required unintuitive syntax for calling the cheats
correctly, for example:
Python.Cheat GetPlayerID None
Python.Cheat GetSDL "'FirstWeekClothing'"
With the new argument handling, these have been simplified to:
Python.Cheat GetPlayerID
Python.Cheat GetSDL FirstWeekClothing
Short explanation: the destructor of plRegistryKeyList may indirectly
access other entries of fKeyLists where the plRegistryKeyList has
already been deleted, but not yet removed from the map.
Long explanation:
* Deleting a plRegistryKeyList also deletes all plKeys inside it, which
decrements the reference count of the objects they point to.
* If one of the deleted keys happens to be the last reference to an
object, this also deletes the object itself.
* The object's destructor might in turn delete another plKey, which
calls SetKeyUnused, which tries to look up the key in its page.
* If this second plKey belongs to the page that is currently being
unloaded, then its plRegistryKeyList may be partially or completely
deleted, but still listed in the fKeyLists map. In this case, the key
lookup accesses already freed memory.
(ported from H-uru/Plasma@a529e35fd940543752fd74efd0fe63039a03c4a6)