mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 18:11:05 -05:00
state: clutter_state_remove_key_internal fix memory corruption
When we free a state because there are no more keys with it as a target use a goto to re-initialize temporary variables that have become invalid. Fixing bug #2273
This commit is contained in:
parent
66018a7035
commit
04d55107f3
@ -269,6 +269,8 @@ clutter_state_remove_key_internal (ClutterState *this,
|
||||
if (source_state_name)
|
||||
source_state = clutter_state_fetch_state (this, source_state_name, FALSE);
|
||||
|
||||
again_from_start:
|
||||
|
||||
if (target_state_name != NULL)
|
||||
state_list = g_list_append (NULL, (gpointer) target_state_name);
|
||||
else
|
||||
@ -278,31 +280,36 @@ clutter_state_remove_key_internal (ClutterState *this,
|
||||
{
|
||||
State *target_state;
|
||||
target_state = clutter_state_fetch_state (this, s->data, FALSE);
|
||||
|
||||
/* Go through each TargetState */
|
||||
if (target_state)
|
||||
{
|
||||
GList *k;
|
||||
again:
|
||||
again_for_target_state:
|
||||
for (k = target_state->keys; k != NULL; k = k->next)
|
||||
{
|
||||
ClutterStateKey *key = k->data;
|
||||
|
||||
/* Check if each key matches query */
|
||||
if ( (object == NULL || (object == key->object))
|
||||
&& (source_state == NULL || (source_state == key->source_state))
|
||||
&& (property_name == NULL || ((property_name == key->property_name))))
|
||||
{
|
||||
/* Remove matching key */
|
||||
target_state->keys = g_list_remove (target_state->keys, key);
|
||||
|
||||
if (target_state->keys == NULL)
|
||||
{
|
||||
/* no more keys, so remove this state */
|
||||
clutter_state_remove_key (this, s->data, NULL, NULL, NULL);
|
||||
g_hash_table_remove (this->priv->states, s->data);
|
||||
}
|
||||
|
||||
key->is_inert = is_inert;
|
||||
clutter_state_key_free (key);
|
||||
goto again;
|
||||
|
||||
/* no more keys with transitions to this target_state*/
|
||||
if (target_state->keys == NULL)
|
||||
{
|
||||
/* remove any keys that exist that uses this state as a source */
|
||||
clutter_state_remove_key (this, s->data, NULL, NULL, NULL);
|
||||
|
||||
g_hash_table_remove (this->priv->states, s->data);
|
||||
goto again_from_start; /* we have just freed State *target_state, so
|
||||
need to restart removal */
|
||||
}
|
||||
goto again_for_target_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user