randr: Make deletion of output properties more robust

Previously there was two branches of code with small discrepancies between them
(especially prop->valid_values field was not free(3)ed). Extract the common
routine and fix double-free prop->valid_values in RRDestroyOutputProperty by
the way.

Signed-off-by: Mikhail Gusarov <dottedmag@dottedmag.net>
Reviewed-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
Mikhail Gusarov 2010-06-06 20:37:07 +07:00
parent 0a4d8cbdcd
commit 67b824a81b

View File

@ -53,25 +53,39 @@ static void RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
WalkTree(pScreen, DeliverPropertyEvent, event); WalkTree(pScreen, DeliverPropertyEvent, event);
} }
void static void
RRDeleteAllOutputProperties (RROutputPtr output) RRDestroyOutputProperty (RRPropertyPtr prop)
{ {
RRPropertyPtr prop, next; free(prop->valid_values);
xRROutputPropertyNotifyEvent event; free(prop->current.data);
free(prop->pending.data);
free(prop);
}
for (prop = output->properties; prop; prop = next) static void
RRDeleteProperty(RROutputRec *output, RRPropertyRec *prop)
{ {
next = prop->next; xRROutputPropertyNotifyEvent event;
event.type = RREventBase + RRNotify; event.type = RREventBase + RRNotify;
event.subCode = RRNotify_OutputProperty; event.subCode = RRNotify_OutputProperty;
event.output = output->id; event.output = output->id;
event.state = PropertyDelete; event.state = PropertyDelete;
event.atom = prop->propertyName; event.atom = prop->propertyName;
event.timestamp = currentTime.milliseconds; event.timestamp = currentTime.milliseconds;
RRDeliverPropertyEvent(output->pScreen, (xEvent *)&event); RRDeliverPropertyEvent(output->pScreen, (xEvent *)&event);
free(prop->current.data);
free(prop->pending.data); RRDestroyOutputProperty(prop);
free(prop); }
void
RRDeleteAllOutputProperties(RROutputPtr output)
{
RRPropertyPtr prop, next;
for (prop = output->properties; prop; prop = next) {
next = prop->next;
RRDeleteProperty(output, prop);
} }
} }
@ -104,36 +118,16 @@ RRCreateOutputProperty (Atom property)
return prop; return prop;
} }
static void
RRDestroyOutputProperty (RRPropertyPtr prop)
{
free(prop->valid_values);
free(prop->current.data);
free(prop->pending.data);
free(prop->valid_values);
free(prop);
}
void void
RRDeleteOutputProperty(RROutputPtr output, Atom property) RRDeleteOutputProperty(RROutputPtr output, Atom property)
{ {
RRPropertyPtr prop, *prev; RRPropertyRec *prop, **prev;
xRROutputPropertyNotifyEvent event;
for (prev = &output->properties; (prop = *prev); prev = &(prop->next)) for (prev = &output->properties; (prop = *prev); prev = &(prop->next))
if (prop->propertyName == property) if (prop->propertyName == property) {
break;
if (prop)
{
*prev = prop->next; *prev = prop->next;
event.type = RREventBase + RRNotify; RRDeleteProperty(output, prop);
event.subCode = RRNotify_OutputProperty; return;
event.output = output->id;
event.state = PropertyDelete;
event.atom = prop->propertyName;
event.timestamp = currentTime.milliseconds;
RRDeliverPropertyEvent (output->pScreen, (xEvent *)&event);
RRDestroyOutputProperty (prop);
} }
} }