From 9e9c0cc7ffae7707734f99fe6693b03d2a78d28d Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Wed, 28 Apr 2010 23:00:44 +0000 Subject: Stop leaking references to interned strings obtained from presentational hints svn path=/trunk/libcss/; revision=10513 --- include/libcss/hint.h | 13 +-- src/select/properties.c | 204 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 143 insertions(+), 74 deletions(-) diff --git a/include/libcss/hint.h b/include/libcss/hint.h index 7bee217..363534f 100644 --- a/include/libcss/hint.h +++ b/include/libcss/hint.h @@ -27,18 +27,7 @@ typedef struct css_hint_length { * Presentational hints */ typedef struct css_hint { - /* Objects pointed to by fields in this struct are copied for - * use in the computed style. Note that the copy occurs using - * memcpy, so if the object contains pointers itself, then the - * data pointed to by those pointers is *not* copied. - */ - - /* Computed styles are transient objects which provide a window onto - * the internal styling and do not reference the strings they point to. - * Thus, any strings passed in by the client through this struct will - * not be referenced either. Therefore, such strings must be guaranteed - * to persist for the life of the document. - */ + /* Ownership of all data is passed to libcss */ union { css_computed_clip_rect *clip; css_color color; diff --git a/src/select/properties.c b/src/select/properties.c index 4338cb8..4cfe579 100644 --- a/src/select/properties.c +++ b/src/select/properties.c @@ -301,7 +301,14 @@ css_error cascade_background_image(uint32_t opv, css_style *style, css_error set_background_image_from_hint(const css_hint *hint, css_computed_style *style) { - return set_background_image(style, hint->status, hint->data.string); + css_error error; + + error = set_background_image(style, hint->status, hint->data.string); + + if (hint->data.string != NULL) + lwc_string_unref(hint->data.string); + + return error; } css_error initial_background_image(css_select_state *state) @@ -1580,12 +1587,11 @@ css_error set_content_from_hint(const css_hint *hint, css_computed_style *style) { uint32_t n_items = 0; + css_computed_content_item *item; css_computed_content_item *copy = NULL; - css_error error; + css_error error = CSS_OK; if (hint->status == CSS_CONTENT_SET) { - const css_computed_content_item *item; - for (item = hint->data.content; item != NULL && item->type != CSS_COMPUTED_CONTENT_NONE; item++) @@ -1594,16 +1600,44 @@ css_error set_content_from_hint(const css_hint *hint, copy = style->alloc(NULL, (n_items + 1) * sizeof(css_computed_content_item), style->pw); - if (copy == NULL) - return CSS_NOMEM; + if (copy == NULL) { + error = CSS_NOMEM; + } else { + memcpy(copy, hint->data.content, (n_items + 1) * + sizeof(css_computed_content_item)); + } + } - memcpy(copy, hint->data.content, (n_items + 1) * - sizeof(css_computed_content_item)); + if (error == CSS_OK) { + error = set_content(style, hint->status, copy); + if (error != CSS_OK && copy != NULL) + style->alloc(copy, 0, style->pw); } - error = set_content(style, hint->status, copy); - if (error != CSS_OK && copy != NULL) - style->alloc(copy, 0, style->pw); + for (item = hint->data.content; item != NULL && + item->type != CSS_COMPUTED_CONTENT_NONE; + item++) { + switch (item->type) { + case CSS_COMPUTED_CONTENT_STRING: + lwc_string_unref(item->data.string); + break; + case CSS_COMPUTED_CONTENT_URI: + lwc_string_unref(item->data.uri); + break; + case CSS_COMPUTED_CONTENT_COUNTER: + lwc_string_unref(item->data.counter.name); + break; + case CSS_COMPUTED_CONTENT_COUNTERS: + lwc_string_unref(item->data.counters.name); + lwc_string_unref(item->data.counters.sep); + break; + case CSS_COMPUTED_CONTENT_ATTR: + lwc_string_unref(item->data.attr); + break; + default: + break; + } + } return error; } @@ -1705,29 +1739,38 @@ css_error set_counter_increment_from_hint(const css_hint *hint, css_computed_style *style) { uint32_t n_items = 0; + css_computed_counter *item; css_computed_counter *copy = NULL; - css_error error; + css_error error = CSS_OK; if (hint->status == CSS_COUNTER_INCREMENT_NAMED && hint->data.counter != NULL) { - const css_computed_counter *item; - for (item = hint->data.counter; item->name != NULL; item++) n_items++; copy = style->alloc(NULL, (n_items + 1) * sizeof(css_computed_counter), style->pw); - if (copy == NULL) - return CSS_NOMEM; + if (copy == NULL) { + error = CSS_NOMEM; + } else { + memcpy(copy, hint->data.counter, (n_items + 1) * + sizeof(css_computed_counter)); + } + } - memcpy(copy, hint->data.counter, (n_items + 1) * - sizeof(css_computed_counter)); + if (error == CSS_OK) { + error = set_counter_increment(style, hint->status, copy); + if (error != CSS_OK && copy != NULL) + style->alloc(copy, 0, style->pw); } - error = set_counter_increment(style, hint->status, copy); - if (error != CSS_OK && copy != NULL) - style->alloc(copy, 0, style->pw); + if (hint->status == CSS_COUNTER_INCREMENT_NAMED && + hint->data.counter != NULL) { + for (item = hint->data.counter; item->name != NULL; item++) { + lwc_string_unref(item->name); + } + } return error; } @@ -1816,29 +1859,38 @@ css_error set_counter_reset_from_hint(const css_hint *hint, css_computed_style *style) { uint32_t n_items = 0; + css_computed_counter *item; css_computed_counter *copy = NULL; - css_error error; + css_error error = CSS_OK; if (hint->status == CSS_COUNTER_RESET_NAMED && hint->data.counter != NULL) { - const css_computed_counter *item; - for (item = hint->data.counter; item->name != NULL; item++) n_items++; copy = style->alloc(NULL, (n_items + 1) * sizeof(css_computed_counter), style->pw); - if (copy == NULL) - return CSS_NOMEM; + if (copy == NULL) { + error = CSS_NOMEM; + } else { + memcpy(copy, hint->data.counter, (n_items + 1) * + sizeof(css_computed_counter)); + } + } - memcpy(copy, hint->data.counter, (n_items + 1) * - sizeof(css_computed_counter)); + if (error == CSS_OK) { + error = set_counter_increment(style, hint->status, copy); + if (error != CSS_OK && copy != NULL) + style->alloc(copy, 0, style->pw); } - error = set_counter_reset(style, hint->status, copy); - if (error != CSS_OK && copy != NULL) - style->alloc(copy, 0, style->pw); + if (hint->status == CSS_COUNTER_RESET_NAMED && + hint->data.counter != NULL) { + for (item = hint->data.counter; item->name != NULL; item++) { + lwc_string_unref(item->name); + } + } return error; } @@ -2124,27 +2176,34 @@ css_error set_cursor_from_hint(const css_hint *hint, css_computed_style *style) { uint32_t n_items = 0; + lwc_string **item; lwc_string **copy = NULL; - css_error error; + css_error error = CSS_OK; if (hint->data.strings != NULL) { - lwc_string **item; - for (item = hint->data.strings; (*item) != NULL; item++) n_items++; copy = style->alloc(NULL, (n_items + 1) * sizeof(lwc_string *), style->pw); - if (copy == NULL) - return CSS_NOMEM; + if (copy == NULL) { + error = CSS_NOMEM; + } else { + memcpy(copy, hint->data.strings, (n_items + 1) * + sizeof(lwc_string *)); + } + } - memcpy(copy, hint->data.strings, (n_items + 1) * - sizeof(lwc_string *)); + if (error == CSS_OK) { + error = set_cursor(style, hint->status, copy); + if (error != CSS_OK && copy != NULL) + style->alloc(copy, 0, style->pw); } - error = set_cursor(style, hint->status, copy); - if (error != CSS_OK && copy != NULL) - style->alloc(copy, 0, style->pw); + for (item = hint->data.strings; + item != NULL && (*item) != NULL; item++) { + lwc_string_unref(*item); + } return error; } @@ -2671,27 +2730,34 @@ css_error set_font_family_from_hint(const css_hint *hint, css_computed_style *style) { uint32_t n_items = 0; + lwc_string **item; lwc_string **copy = NULL; - css_error error; + css_error error = CSS_OK; if (hint->data.strings != NULL) { - lwc_string **item; - for (item = hint->data.strings; (*item) != NULL; item++) n_items++; copy = style->alloc(NULL, (n_items + 1) * sizeof(lwc_string *), style->pw); - if (copy == NULL) - return CSS_NOMEM; + if (copy == NULL) { + error = CSS_NOMEM; + } else { + memcpy(copy, hint->data.strings, (n_items + 1) * + sizeof(lwc_string *)); + } + } - memcpy(copy, hint->data.strings, (n_items + 1) * - sizeof(lwc_string *)); + if (error == CSS_OK) { + error = set_font_family(style, hint->status, copy); + if (error != CSS_OK && copy != NULL) + style->alloc(copy, 0, style->pw); } - error = set_font_family(style, hint->status, copy); - if (error != CSS_OK && copy != NULL) - style->alloc(copy, 0, style->pw); + for (item = hint->data.strings; + item != NULL && (*item) != NULL; item++) { + lwc_string_unref(*item); + } return error; } @@ -3275,7 +3341,14 @@ css_error cascade_list_style_image(uint32_t opv, css_style *style, css_error set_list_style_image_from_hint(const css_hint *hint, css_computed_style *style) { - return set_list_style_image(style, hint->status, hint->data.string); + css_error error; + + error = set_list_style_image(style, hint->status, hint->data.string); + + if (hint->data.string != NULL) + lwc_string_unref(hint->data.string); + + return error; } css_error initial_list_style_image(css_select_state *state) @@ -4700,27 +4773,34 @@ css_error set_quotes_from_hint(const css_hint *hint, css_computed_style *style) { uint32_t n_items = 0; + lwc_string **item; lwc_string **copy = NULL; - css_error error; + css_error error = CSS_OK; if (hint->data.strings != NULL) { - lwc_string **item; - for (item = hint->data.strings; (*item) != NULL; item++) n_items++; copy = style->alloc(NULL, (n_items + 1) * sizeof(lwc_string *), style->pw); - if (copy == NULL) - return CSS_NOMEM; + if (copy == NULL) { + error = CSS_NOMEM; + } else { + memcpy(copy, hint->data.strings, (n_items + 1) * + sizeof(lwc_string *)); + } + } - memcpy(copy, hint->data.strings, (n_items + 1) * - sizeof(lwc_string *)); + if (error == CSS_OK) { + error = set_quotes(style, hint->status, copy); + if (error != CSS_OK && copy != NULL) + style->alloc(copy, 0, style->pw); } - error = set_quotes(style, hint->status, copy); - if (error != CSS_OK && copy != NULL) - style->alloc(copy, 0, style->pw); + for (item = hint->data.strings; + item != NULL && (*item) != NULL; item++) { + lwc_string_unref(*item); + } return error; } -- cgit v1.2.3