From 67b824a81bb8254827023de351a4a094031f0e94 Mon Sep 17 00:00:00 2001 From: Mikhail Gusarov Date: Sun, 6 Jun 2010 20:37:07 +0700 Subject: [PATCH] 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 Reviewed-by: Jamey Sharp --- randr/rrproperty.c | 76 +++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/randr/rrproperty.c b/randr/rrproperty.c index a4402e147..481eb8674 100644 --- a/randr/rrproperty.c +++ b/randr/rrproperty.c @@ -53,25 +53,39 @@ static void RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event) WalkTree(pScreen, DeliverPropertyEvent, event); } +static void +RRDestroyOutputProperty (RRPropertyPtr prop) +{ + free(prop->valid_values); + free(prop->current.data); + free(prop->pending.data); + free(prop); +} + +static void +RRDeleteProperty(RROutputRec *output, RRPropertyRec *prop) +{ + xRROutputPropertyNotifyEvent event; + event.type = RREventBase + RRNotify; + event.subCode = RRNotify_OutputProperty; + event.output = output->id; + event.state = PropertyDelete; + event.atom = prop->propertyName; + event.timestamp = currentTime.milliseconds; + + RRDeliverPropertyEvent(output->pScreen, (xEvent *)&event); + + RRDestroyOutputProperty(prop); +} + void -RRDeleteAllOutputProperties (RROutputPtr output) +RRDeleteAllOutputProperties(RROutputPtr output) { RRPropertyPtr prop, next; - xRROutputPropertyNotifyEvent event; - for (prop = output->properties; prop; prop = next) - { + for (prop = output->properties; prop; prop = next) { next = prop->next; - event.type = RREventBase + RRNotify; - event.subCode = RRNotify_OutputProperty; - event.output = output->id; - event.state = PropertyDelete; - event.atom = prop->propertyName; - event.timestamp = currentTime.milliseconds; - RRDeliverPropertyEvent (output->pScreen, (xEvent *)&event); - free(prop->current.data); - free(prop->pending.data); - free(prop); + RRDeleteProperty(output, prop); } } @@ -104,37 +118,17 @@ RRCreateOutputProperty (Atom property) 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 -RRDeleteOutputProperty (RROutputPtr output, Atom property) +RRDeleteOutputProperty(RROutputPtr output, Atom property) { - RRPropertyPtr prop, *prev; - xRROutputPropertyNotifyEvent event; + RRPropertyRec *prop, **prev; for (prev = &output->properties; (prop = *prev); prev = &(prop->next)) - if (prop->propertyName == property) - break; - if (prop) - { - *prev = prop->next; - event.type = RREventBase + RRNotify; - event.subCode = RRNotify_OutputProperty; - event.output = output->id; - event.state = PropertyDelete; - event.atom = prop->propertyName; - event.timestamp = currentTime.milliseconds; - RRDeliverPropertyEvent (output->pScreen, (xEvent *)&event); - RRDestroyOutputProperty (prop); - } + if (prop->propertyName == property) { + *prev = prop->next; + RRDeleteProperty(output, prop); + return; + } } int