summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--css/css.c67
-rw-r--r--css/css.h4
-rw-r--r--css/ruleset.c3
-rw-r--r--render/box.c86
-rw-r--r--render/html.c2
5 files changed, 119 insertions, 43 deletions
diff --git a/css/css.c b/css/css.c
index 1083c9f69..d9cd777b6 100644
--- a/css/css.c
+++ b/css/css.c
@@ -467,6 +467,73 @@ void css_destroy(struct content *c)
free(c->data.css.import_content);
}
+/**
+ * Duplicate a CSS style struct
+ *
+ * \param style The style to duplicate
+ * \return The duplicate style, or NULL if out of memory.
+ */
+struct css_style *css_duplicate_style(const struct css_style * const style)
+{
+ struct css_style *dup;
+
+ assert(style);
+
+ /* create duplicated style */
+ dup = calloc(1, sizeof(struct css_style));
+ if (!dup)
+ return NULL;
+
+ /* copy all style information into duplicate style */
+ memcpy(dup, style, sizeof(struct css_style));
+
+ /* duplicate strings, if in use */
+
+ /* background_image */
+ if (dup->background_image.type == CSS_BACKGROUND_IMAGE_URI) {
+ dup->background_image.uri = NULL;
+ dup->background_image.uri =
+ strdup(style->background_image.uri);
+ if (!dup->background_image.uri) {
+ free(dup);
+ return NULL;
+ }
+ }
+
+ /* list_style_image */
+ if (dup->list_style_image.type == CSS_LIST_STYLE_IMAGE_URI) {
+ dup->list_style_image.uri = NULL;
+ dup->list_style_image.uri =
+ strdup(style->list_style_image.uri);
+ if (!dup->list_style_image.uri) {
+ if (dup->background_image.type ==
+ CSS_BACKGROUND_IMAGE_URI)
+ free(dup->background_image.uri);
+ free(dup);
+ return NULL;
+ }
+ }
+
+ return dup;
+}
+
+/**
+ * Free a CSS style
+ *
+ * \param style The style to free
+ */
+void css_free_style(struct css_style *style)
+{
+ assert(style);
+
+ if (style->background_image.type == CSS_BACKGROUND_IMAGE_URI)
+ free(style->background_image.uri);
+
+ if (style->list_style_image.type == CSS_LIST_STYLE_IMAGE_URI)
+ free(style->list_style_image.uri);
+
+ free(style);
+}
/**
* Create a new struct css_node.
diff --git a/css/css.h b/css/css.h
index cc5e9bbd6..9c02cf26e 100644
--- a/css/css.h
+++ b/css/css.h
@@ -112,7 +112,7 @@ typedef enum {
CSS_VERTICAL_ALIGN_PERCENT,
CSS_VERTICAL_ALIGN_NOT_SET
} css_vertical_align_type;
-
+
struct css_counter {
const char *name;
css_list_style_type style;
@@ -560,6 +560,8 @@ const char *css_parser_TokenName(int tokenType);
#endif
void css_get_style(struct content *c, xmlNode *n, struct css_style * style);
+struct css_style *css_duplicate_style(const struct css_style * const style);
+void css_free_style(struct css_style *style);
void css_cascade(struct css_style * const style,
const struct css_style * const apply);
void css_merge(struct css_style * const style,
diff --git a/css/ruleset.c b/css/ruleset.c
index c2ea45618..50ed75743 100644
--- a/css/ruleset.c
+++ b/css/ruleset.c
@@ -483,13 +483,12 @@ void css_add_ruleset(struct content *c,
if (!found) {
/* not present: construct a new struct css_style */
LOG(("constructing new style"));
- style = malloc(sizeof *style);
+ style = css_duplicate_style(&css_empty_style);
if (!style) {
/** \todo report to user */
css_free_selector(sel);
return;
}
- memcpy(style, &css_empty_style, sizeof(*style));
sel->style = style;
sel->next = n;
if (prev)
diff --git a/render/box.c b/render/box.c
index 4d57c9f8c..061c022b2 100644
--- a/render/box.c
+++ b/render/box.c
@@ -344,15 +344,15 @@ bool xml_to_box(xmlNode *n, struct content *c)
root.float_children = NULL;
root.next_float = NULL;
- c->data.html.style = malloc(sizeof (struct css_style));
+ c->data.html.style = css_duplicate_style(&css_base_style);
if (!c->data.html.style)
return false;
- memcpy(c->data.html.style, &css_base_style, sizeof(struct css_style));
+
c->data.html.style->font_size.value.length.value =
option_font_size * 0.1;
c->data.html.fonts = nsfont_new_set();
if (!c->data.html.fonts) {
- free(c->data.html.style);
+ css_free_style(c->data.html.style);
return false;
}
@@ -433,8 +433,10 @@ bool convert_xml_to_box(xmlNode *n, struct content *content,
gui_multitask();
style = box_get_style(content, parent_style, n);
+ if (!style)
+ goto no_memory;
if (style->display == CSS_DISPLAY_NONE) {
- free(style);
+ css_free_style(style);
goto end;
}
/* floats are treated as blocks */
@@ -474,7 +476,7 @@ bool convert_xml_to_box(xmlNode *n, struct content *content,
if (!box) {
/* no box for this element */
assert(!convert_children);
- free(style);
+ css_free_style(style);
goto end;
}
} else {
@@ -745,7 +747,7 @@ no_memory:
if (!href_in)
xmlFree(status.href);
if (style && !box)
- free(style);
+ css_free_style(style);
return false;
}
@@ -774,23 +776,30 @@ struct css_style * box_get_style(struct content *c,
unsigned int stylesheet_count = c->data.html.stylesheet_count;
struct content **stylesheet = c->data.html.stylesheet_content;
struct css_style *style;
- struct css_style style_new;
+ struct css_style *style_new;
char *url;
url_func_result res;
- style = malloc(sizeof (struct css_style));
+ style = css_duplicate_style(parent_style);
if (!style)
return 0;
- memcpy(style, parent_style, sizeof(struct css_style));
- memcpy(&style_new, &css_blank_style, sizeof(struct css_style));
+ style_new = css_duplicate_style(&css_blank_style);
+ if (!style_new) {
+ css_free_style(style);
+ return 0;
+ }
+
for (i = 0; i != stylesheet_count; i++) {
if (stylesheet[i]) {
assert(stylesheet[i]->type == CONTENT_CSS);
- css_get_style(stylesheet[i], n, &style_new);
+ css_get_style(stylesheet[i], n, style_new);
}
}
- css_cascade(style, &style_new);
+ css_cascade(style, style_new);
+
+ /* style_new isn't needed past this point */
+ css_free_style(style_new);
/* This property only applies to the body element, if you believe
* the spec. Many browsers seem to allow it on other elements too,
@@ -798,7 +807,7 @@ struct css_style * box_get_style(struct content *c,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "background"))) {
res = url_join(s, c->data.html.base_url, &url);
if (res == URL_FUNC_NOMEM) {
- free(style);
+ css_free_style(style);
return 0;
} else if (res == URL_FUNC_OK) {
/* if url is equivalent to the parent's url,
@@ -935,10 +944,16 @@ struct css_style * box_get_style(struct content *c,
}
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "style")) != NULL) {
- struct css_style astyle;
- memcpy(&astyle, &css_empty_style, sizeof(struct css_style));
- css_parse_property_list(c, &astyle, s);
- css_cascade(style, &astyle);
+ struct css_style *astyle;
+ astyle = css_duplicate_style(&css_empty_style);
+ if (!astyle) {
+ xmlFree(s);
+ css_free_style(style);
+ return 0;
+ }
+ css_parse_property_list(c, astyle, s);
+ css_cascade(style, astyle);
+ css_free_style(astyle);
xmlFree(s);
}
@@ -1843,14 +1858,13 @@ bool box_normalise_block(struct box *block, pool box_pool)
case BOX_TABLE_ROW:
case BOX_TABLE_CELL:
/* insert implied table */
- style = malloc(sizeof *style);
+ style = css_duplicate_style(block->style);
if (!style)
return false;
- memcpy(style, block->style, sizeof *style);
css_cascade(style, &css_blank_style);
table = box_create(style, block->href, 0, 0, box_pool);
if (!table) {
- free(style);
+ css_free_style(style);
return false;
}
table->type = BOX_TABLE;
@@ -1982,19 +1996,18 @@ bool box_normalise_table(struct box *table, pool box_pool)
case BOX_TABLE_ROW:
case BOX_TABLE_CELL:
/* insert implied table row group */
- style = malloc(sizeof *style);
+ assert(table->style != NULL);
+ style = css_duplicate_style(table->style);
if (!style) {
free(col_info.spans);
return false;
}
- assert(table->style != NULL);
- memcpy(style, table->style, sizeof *style);
css_cascade(style, &css_blank_style);
row_group = box_create(style, table->href, 0,
0, box_pool);
if (!row_group) {
free(col_info.spans);
- free(style);
+ css_free_style(style);
return false;
}
row_group->type = BOX_TABLE_ROW_GROUP;
@@ -2091,16 +2104,15 @@ bool box_normalise_table_row_group(struct box *row_group,
case BOX_TABLE_ROW_GROUP:
case BOX_TABLE_CELL:
/* insert implied table row */
- style = malloc(sizeof *style);
+ assert(row_group->style != NULL);
+ style = css_duplicate_style(row_group->style);
if (!style)
return false;
- assert(row_group->style != NULL);
- memcpy(style, row_group->style, sizeof *style);
css_cascade(style, &css_blank_style);
row = box_create(style, row_group->href, 0,
0, box_pool);
if (!row) {
- free(style);
+ css_free_style(style);
return false;
}
row->type = BOX_TABLE_ROW;
@@ -2263,16 +2275,15 @@ bool box_normalise_table_row(struct box *row,
case BOX_TABLE_ROW_GROUP:
case BOX_TABLE_ROW:
/* insert implied table cell */
- style = malloc(sizeof *style);
+ assert(row->style != NULL);
+ style = css_duplicate_style(row->style);
if (!style)
return false;
- assert(row->style != NULL);
- memcpy(style, row->style, sizeof *style);
css_cascade(style, &css_blank_style);
cell = box_create(style, row->href, 0, 0,
box_pool);
if (!cell) {
- free(style);
+ css_free_style(style);
return false;
}
cell->type = BOX_TABLE_CELL;
@@ -2448,7 +2459,7 @@ void box_free_box(struct box *box)
free(box->title);
free(box->col);
if (!box->style_clone)
- free(box->style);
+ css_free_style(box->style);
}
free(box->usemap);
@@ -3035,14 +3046,13 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
/* create the frameset table */
c = n->children;
for (row = 0; c && row != rows; row++) {
- row_style = malloc(sizeof (struct css_style));
+ row_style = css_duplicate_style(style);
if (!row_style) {
box_free(box);
free(row_height);
free(col_width);
return (struct box_result) {0, false, true};
}
- memcpy(row_style, style, sizeof (struct css_style));
object_height = 1000; /** \todo get available height */
/* if (row_height) {
row_style->height.height = CSS_HEIGHT_LENGTH;
@@ -3080,14 +3090,13 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
if (col_width && col_width[col].type == LENGTH_PX)
object_width = col_width[col].value;
- cell_style = malloc(sizeof (struct css_style));
+ cell_style = css_duplicate_style(style);
if (!cell_style) {
box_free(box);
free(row_height);
free(col_width);
return (struct box_result) {0, false, true};
}
- memcpy(cell_style, style, sizeof (struct css_style));
css_cascade(cell_style, &css_blank_style);
cell_style->overflow = CSS_OVERFLOW_AUTO;
@@ -3115,14 +3124,13 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
continue;
}
- object_style = malloc(sizeof (struct css_style));
+ object_style = css_duplicate_style(style);
if (!object_style) {
box_free(box);
free(row_height);
free(col_width);
return (struct box_result) {0, false, true};
}
- memcpy(object_style, style, sizeof (struct css_style));
if (col_width && col_width[col].type == LENGTH_PX) {
object_style->width.width = CSS_WIDTH_LENGTH;
object_style->width.value.length.unit =
diff --git a/render/html.c b/render/html.c
index 068260d3d..36555e259 100644
--- a/render/html.c
+++ b/render/html.c
@@ -1035,7 +1035,7 @@ void html_destroy(struct content *c)
}
}
free(c->data.html.stylesheet_content);
- free(c->data.html.style);
+ css_free_style(c->data.html.style);
if (c->data.html.fonts)
nsfont_free_set(c->data.html.fonts);