From 7049f972404064683b156346f4267d1b5a676358 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Sun, 4 Apr 2010 18:44:36 +0000 Subject: Correct management of string references in computed styles. svn path=/trunk/libcss/; revision=10240 --- src/select/propset.h | 157 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 23 deletions(-) (limited to 'src/select/propset.h') diff --git a/src/select/propset.h b/src/select/propset.h index 69dba45..97d76b9 100644 --- a/src/select/propset.h +++ b/src/select/propset.h @@ -174,22 +174,32 @@ static inline css_error set_counter_increment( css_computed_counter *counters) { uint8_t *bits; + css_computed_counter *oldcounters; + css_computed_counter *c; ENSURE_UNCOMMON; bits = &style->uncommon->bits[COUNTER_INCREMENT_INDEX]; + oldcounters = style->uncommon->counter_increment; /* 1bit: type */ *bits = (*bits & ~COUNTER_INCREMENT_MASK) | ((type & 0x1) << COUNTER_INCREMENT_SHIFT); - /* Free existing array */ - if (style->uncommon->counter_increment != NULL && - style->uncommon->counter_increment != counters) - style->alloc(style->uncommon->counter_increment, 0, style->pw); + for (c = counters; c != NULL && c->name != NULL; c++) + lwc_string_ref(c->name); style->uncommon->counter_increment = counters; + /* Free existing array */ + if (oldcounters != NULL) { + for (c = oldcounters; c->name != NULL; c++) + lwc_string_unref(c->name); + + if (oldcounters != counters) + style->alloc(oldcounters, 0, style->pw); + } + return CSS_OK; } #undef COUNTER_INCREMENT_MASK @@ -204,22 +214,32 @@ static inline css_error set_counter_reset( css_computed_counter *counters) { uint8_t *bits; + css_computed_counter *oldcounters; + css_computed_counter *c; ENSURE_UNCOMMON; bits = &style->uncommon->bits[COUNTER_RESET_INDEX]; + oldcounters = style->uncommon->counter_reset; /* 1bit: type */ *bits = (*bits & ~COUNTER_RESET_MASK) | ((type & 0x1) << COUNTER_RESET_SHIFT); - /* Free existing array */ - if (style->uncommon->counter_reset != NULL && - style->uncommon->counter_reset != counters) - style->alloc(style->uncommon->counter_reset, 0, style->pw); + for (c = counters; c != NULL && c->name != NULL; c++) + lwc_string_ref(c->name); style->uncommon->counter_reset = counters; + /* Free existing array */ + if (oldcounters != NULL) { + for (c = oldcounters; c->name != NULL; c++) + lwc_string_unref(c->name); + + if (oldcounters != counters) + style->alloc(oldcounters, 0, style->pw); + } + return CSS_OK; } #undef COUNTER_RESET_MASK @@ -234,21 +254,32 @@ static inline css_error set_cursor( lwc_string **urls) { uint8_t *bits; + lwc_string **oldurls; + lwc_string **s; ENSURE_UNCOMMON; bits = &style->uncommon->bits[CURSOR_INDEX]; + oldurls = style->uncommon->cursor; /* 5bits: type */ *bits = (*bits & ~CURSOR_MASK) | ((type & 0x1f) << CURSOR_SHIFT); - /* Free existing array */ - if (style->uncommon->cursor != NULL && style->uncommon->cursor != urls) - style->alloc(style->uncommon->cursor, 0, style->pw); + for (s = urls; s != NULL && *s != NULL; s++) + lwc_string_ref(*s); style->uncommon->cursor = urls; + /* Free existing array */ + if (oldurls != NULL) { + for (s = oldurls; *s != NULL; s++) + lwc_string_unref(*s); + + if (oldurls != urls) + style->alloc(oldurls, 0, style->pw); + } + return CSS_OK; } #undef CURSOR_MASK @@ -322,22 +353,74 @@ static inline css_error set_content( css_computed_content_item *content) { uint8_t *bits; + css_computed_content_item *oldcontent; + css_computed_content_item *c; ENSURE_UNCOMMON; /* 2bits: type */ bits = &style->uncommon->bits[CONTENT_INDEX]; + oldcontent = style->uncommon->content; *bits = (*bits & ~CONTENT_MASK) | ((type & 0x3) << CONTENT_SHIFT); - /* Free existing array */ - if (style->uncommon->content != NULL && - style->uncommon->content != content) - style->alloc(style->uncommon->content, 0, style->pw); + for (c = content; c != NULL && + c->type != CSS_COMPUTED_CONTENT_NONE; c++) { + switch (c->type) { + case CSS_COMPUTED_CONTENT_STRING: + lwc_string_ref(c->data.string); + break; + case CSS_COMPUTED_CONTENT_URI: + lwc_string_ref(c->data.uri); + break; + case CSS_COMPUTED_CONTENT_ATTR: + lwc_string_ref(c->data.attr); + break; + case CSS_COMPUTED_CONTENT_COUNTER: + lwc_string_ref(c->data.counter.name); + break; + case CSS_COMPUTED_CONTENT_COUNTERS: + lwc_string_ref(c->data.counters.name); + lwc_string_ref(c->data.counters.sep); + break; + default: + break; + } + } style->uncommon->content = content; + /* Free existing array */ + if (oldcontent != NULL) { + for (c = oldcontent; + c->type != CSS_COMPUTED_CONTENT_NONE; c++) { + switch (c->type) { + case CSS_COMPUTED_CONTENT_STRING: + lwc_string_unref(c->data.string); + break; + case CSS_COMPUTED_CONTENT_URI: + lwc_string_unref(c->data.uri); + break; + case CSS_COMPUTED_CONTENT_ATTR: + lwc_string_unref(c->data.attr); + break; + case CSS_COMPUTED_CONTENT_COUNTER: + lwc_string_unref(c->data.counter.name); + break; + case CSS_COMPUTED_CONTENT_COUNTERS: + lwc_string_unref(c->data.counters.name); + lwc_string_unref(c->data.counters.sep); + break; + default: + break; + } + } + + if (oldcontent != content) + style->alloc(oldcontent, 0, style->pw); + } + return CSS_OK; } #undef CONTENT_MASK @@ -479,17 +562,21 @@ static inline css_error set_background_image( lwc_string *url) { uint8_t *bits = &style->bits[BACKGROUND_IMAGE_INDEX]; + lwc_string *oldurl = style->background_image; /* 1bit: type */ *bits = (*bits & ~BACKGROUND_IMAGE_MASK) | ((type & 0x1) << BACKGROUND_IMAGE_SHIFT); if (url != NULL) { - style->background_image = url; + style->background_image = lwc_string_ref(url); } else { style->background_image = NULL; } + if (oldurl != NULL) + lwc_string_unref(oldurl); + return CSS_OK; } #undef BACKGROUND_IMAGE_MASK @@ -525,17 +612,21 @@ static inline css_error set_list_style_image( lwc_string *url) { uint8_t *bits = &style->bits[LIST_STYLE_IMAGE_INDEX]; + lwc_string *oldurl = style->list_style_image; /* 1bit: type */ *bits = (*bits & ~LIST_STYLE_IMAGE_MASK) | ((type & 0x1) << LIST_STYLE_IMAGE_SHIFT); if (url != NULL) { - style->list_style_image = url; + style->list_style_image = lwc_string_ref(url); } else { style->list_style_image = NULL; } + if (oldurl != NULL) + lwc_string_unref(oldurl); + return CSS_OK; } #undef LIST_STYLE_IMAGE_MASK @@ -550,17 +641,27 @@ static inline css_error set_quotes( lwc_string **quotes) { uint8_t *bits = &style->bits[QUOTES_INDEX]; + lwc_string **oldquotes = style->quotes; + lwc_string **s; /* 1bit: type */ *bits = (*bits & ~QUOTES_MASK) | ((type & 0x1) << QUOTES_SHIFT); - /* Free current quotes */ - if (style->quotes != NULL && style->quotes != quotes) - style->alloc(style->quotes, 0, style->pw); + for (s = quotes; s != NULL && *s != NULL; s++) + lwc_string_ref(*s); style->quotes = quotes; + /* Free current quotes */ + if (oldquotes != NULL) { + for (s = oldquotes; *s != NULL; s++) + lwc_string_unref(*s); + + if (oldquotes != quotes) + style->alloc(oldquotes, 0, style->pw); + } + return CSS_OK; } #undef QUOTES_MASK @@ -1446,17 +1547,27 @@ static inline css_error set_font_family( lwc_string **names) { uint8_t *bits = &style->bits[FONT_FAMILY_INDEX]; + lwc_string **oldnames = style->font_family; + lwc_string **s; /* 3bits: type */ *bits = (*bits & ~FONT_FAMILY_MASK) | ((type & 0x7) << FONT_FAMILY_SHIFT); - /* Free existing families */ - if (style->font_family != NULL && style->font_family != names) - style->alloc(style->font_family, 0, style->pw); + for (s = names; s != NULL && *s != NULL; s++) + lwc_string_ref(*s); style->font_family = names; + /* Free existing families */ + if (oldnames != NULL) { + for (s = oldnames; *s != NULL; s++) + lwc_string_unref(*s); + + if (oldnames != names) + style->alloc(oldnames, 0, style->pw); + } + return CSS_OK; } #undef FONT_FAMILY_MASK -- cgit v1.2.3