summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2004-12-09 22:22:13 +0000
committerJames Bursa <james@netsurf-browser.org>2004-12-09 22:22:13 +0000
commitf3ce5e1e48d09cd250374d269c8e11afcdace3f2 (patch)
treeb7d0caca04b25bc97e0e544db0d43feb3df76a89
parent441b364600c8ec4f1fc2e8afacada78b2e352421 (diff)
downloadnetsurf-f3ce5e1e48d09cd250374d269c8e11afcdace3f2.tar.gz
netsurf-f3ce5e1e48d09cd250374d269c8e11afcdace3f2.tar.bz2
[project @ 2004-12-09 22:22:13 by bursa]
xcalloc/xrealloc/xstrdup-purge week, part 1. svn path=/import/netsurf/; revision=1398
-rw-r--r--render/box.c341
-rw-r--r--render/box.h2
2 files changed, 212 insertions, 131 deletions
diff --git a/render/box.c b/render/box.c
index 74b79cc16..74dc502b6 100644
--- a/render/box.c
+++ b/render/box.c
@@ -109,15 +109,13 @@ struct columns {
unsigned int num_rows;
};
-static struct box * convert_xml_to_box(xmlNode * n, struct content *content,
- struct css_style * parent_style,
- struct box * parent, struct box *inline_container,
+static bool convert_xml_to_box(xmlNode *n, struct content *content,
+ struct css_style *parent_style,
+ struct box *parent, struct box **inline_container,
struct box_status status);
-static struct css_style * box_get_style(struct content *c,
- struct content ** stylesheet,
- unsigned int stylesheet_count,
- struct css_style * parent_style,
- xmlNode * n);
+struct css_style * box_get_style(struct content *c,
+ struct css_style *parent_style,
+ xmlNode *n);
static void box_text_transform(char *s, unsigned int len,
css_text_transform tt);
static struct box_result box_a(xmlNode *n, struct box_status *status,
@@ -220,6 +218,13 @@ void box_add_child(struct box * parent, struct box * child)
/**
* Create a box tree node.
+ *
+ * \param style style for the box (not copied)
+ * \param href href for the box (copied), or 0
+ * \param title title for the box (copied), or 0
+ * \param id id for the box (copied), or 0
+ * \param box_pool pool to allocate box from
+ * \return allocated and initialised box, or 0 on memory exhaustion
*/
struct box * box_create(struct css_style * style,
@@ -228,9 +233,31 @@ struct box * box_create(struct css_style * style,
{
unsigned int i;
struct box *box;
+ char *href1 = 0;
+ char *title1 = 0;
+ char *id1 = 0;
+
+ if (href)
+ href1 = strdup(href);
+ if (title)
+ title1 = strdup(title);
+ if (id)
+ id1 = strdup(id);
+ if ((href && !href1) || (title && !title1) || (id && !id1)) {
+ free(href1);
+ free(title1);
+ free(id1);
+ return 0;
+ }
+
+ box = pool_alloc(box_pool, sizeof (struct box));
+ if (!box) {
+ free(href1);
+ free(title1);
+ free(id1);
+ return 0;
+ }
- if ((box = pool_alloc(box_pool, sizeof (struct box))) == NULL)
- return NULL;
box->type = BOX_INLINE;
box->style = style;
box->x = box->y = 0;
@@ -248,8 +275,8 @@ struct box * box_create(struct css_style * style,
box->space = 0;
box->clone = 0;
box->style_clone = 0;
- box->href = href ? xstrdup(href) : NULL;
- box->title = title ? xstrdup(title) : NULL;
+ box->href = href1;
+ box->title = title1;
box->columns = 1;
box->rows = 1;
box->start_column = 0;
@@ -264,7 +291,7 @@ struct box * box_create(struct css_style * style,
box->font = NULL;
box->gadget = NULL;
box->usemap = NULL;
- box->id = id ? xstrdup(id) : NULL;
+ box->id = id1;
box->background = NULL;
box->object = NULL;
box->object_params = NULL;
@@ -291,13 +318,18 @@ void box_insert_sibling(struct box *box, struct box *new_box)
/**
- * make a box tree with style data from an xml tree
+ * Construct a box tree from an xml tree and stylesheets.
+ *
+ * \param n xml tree
+ * \param c content of type CONTENT_HTML to construct box tree in
+ * \return true on success, false on memory exhaustion
*/
-void xml_to_box(xmlNode *n, struct content *c)
+bool xml_to_box(xmlNode *n, struct content *c)
{
struct box root;
struct box_status status = {c, 0, 0, 0, 0};
+ struct box *inline_container = 0;
assert(c->type == CONTENT_HTML);
@@ -311,37 +343,31 @@ void xml_to_box(xmlNode *n, struct content *c)
root.float_children = NULL;
root.next_float = NULL;
- c->data.html.style = xcalloc(1, sizeof(struct css_style));
+ c->data.html.style = malloc(sizeof (struct css_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);
+ return false;
+ }
c->data.html.object_count = 0;
- c->data.html.object = xcalloc(0, sizeof(*c->data.html.object));
+ c->data.html.object = 0;
- convert_xml_to_box(n, c, c->data.html.style, &root, 0, status);
+ convert_xml_to_box(n, c, c->data.html.style, &root, &inline_container,
+ status);
box_normalise_block(&root, c->data.html.box_pool);
c->data.html.layout = root.children;
c->data.html.layout->parent = NULL;
-}
+ return true;
+}
-/**
- * make a box tree with style data from an xml tree
- *
- * arguments:
- * n xml tree
- * content content structure
- * parent_style style at this point in xml tree
- * parent parent in box tree
- * inline_container current inline container box, or 0
- * status status for forms etc.
- *
- * returns:
- * updated current inline container
- */
/* mapping from CSS display to box type
* this table must be in sync with css/css_enums */
@@ -364,82 +390,96 @@ static const box_type box_map[] = {
BOX_INLINE /*CSS_DISPLAY_TABLE_CAPTION,*/
};
-struct box * convert_xml_to_box(xmlNode * n, struct content *content,
- struct css_style * parent_style,
- struct box * parent, struct box *inline_container,
+
+/**
+ * Recursively construct a box tree from an xml tree and stylesheets.
+ *
+ * \param n fragment of xml tree
+ * \param content content of type CONTENT_HTML that is being processed
+ * \param parent_style style at this point in xml tree
+ * \param parent parent in box tree
+ * \param inline_container current inline container box, or 0, updated to
+ * new current inline container on exit
+ * \param status status for forms etc.
+ * \return true on success, false on memory exhaustion
+ */
+
+bool convert_xml_to_box(xmlNode *n, struct content *content,
+ struct css_style *parent_style,
+ struct box *parent, struct box **inline_container,
struct box_status status)
{
- struct box * box = 0;
- struct box * inline_container_c;
- struct css_style * style = 0;
- xmlNode * c;
- char * s;
- xmlChar * title0;
- char * title = 0, *id = 0;
+ struct box *box = 0;
+ struct box *inline_container_c;
+ struct css_style *style = 0;
+ xmlNode *c;
+ char *s;
+ xmlChar *title0, *id0;
+ char *title = 0, *id = 0;
bool convert_children = true;
char *href_in = status.href;
- assert(n != 0 && parent_style != 0 && parent != 0);
- LOG(("node %p, node type %i", n, n->type));
+ assert(n);
+ assert(parent_style);
+ assert(parent);
+ assert(inline_container);
if (n->type == XML_ELEMENT_NODE) {
struct element_entry *element;
-#ifndef NDEBUG
- xmlElemDump(stderr, n->doc, n);
- fprintf(stderr "\n");
-#endif
-
gui_multitask();
- style = box_get_style(content, content->data.html.stylesheet_content,
- content->data.html.stylesheet_count, parent_style, n);
- LOG(("display: %s", css_display_name[style->display]));
+ style = box_get_style(content, parent_style, n);
if (style->display == CSS_DISPLAY_NONE) {
free(style);
- LOG(("node %p, node type %i END", n, n->type));
goto end;
}
/* floats are treated as blocks */
- if (style->float_ == CSS_FLOAT_LEFT || style->float_ == CSS_FLOAT_RIGHT)
+ if (style->float_ == CSS_FLOAT_LEFT ||
+ style->float_ == CSS_FLOAT_RIGHT)
if (style->display == CSS_DISPLAY_INLINE)
style->display = CSS_DISPLAY_BLOCK;
/* extract title attribute, if present */
- if ((title0 = xmlGetProp(n, (const xmlChar *) "title")) != NULL) {
+ if ((title0 = xmlGetProp(n, (const xmlChar *) "title"))) {
status.title = title = squash_whitespace(title0);
xmlFree(title0);
+ if (!title)
+ goto no_memory;
}
/* extract id attribute, if present */
- if ((title0 = xmlGetProp(n, (const xmlChar *) "id")) != NULL) {
- status.id = id = squash_whitespace(title0);
- xmlFree(title0);
+ if ((id0 = xmlGetProp(n, (const xmlChar *) "id"))) {
+ status.id = id = squash_whitespace(id0);
+ xmlFree(id0);
+ if (!id)
+ goto no_memory;
}
/* special elements */
element = bsearch((const char *) n->name, element_table,
ELEMENT_TABLE_COUNT, sizeof(element_table[0]),
(int (*)(const void *, const void *)) strcmp);
- if (element != 0) {
+ if (element) {
/* a special convert function exists for this element */
- struct box_result res = element->convert(n, &status, style);
+ struct box_result res =
+ element->convert(n, &status, style);
box = res.box;
convert_children = res.convert_children;
- if (res.memory_error) {
- /** \todo handle memory exhaustion */
- }
- if (box == 0) {
+ if (res.memory_error)
+ goto no_memory;
+ if (!box) {
/* no box for this element */
- assert(convert_children == 0);
+ assert(!convert_children);
free(style);
- LOG(("node %p, node type %i END", n, n->type));
goto end;
}
} else {
/* general element */
box = box_create(style, status.href, title, id,
content->data.html.box_pool);
+ if (!box)
+ goto no_memory;
}
/* set box type from style if it has not been set already */
if (box->type == BOX_INLINE)
@@ -450,7 +490,6 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
} else {
/* not an element or text node: ignore it (eg. comment) */
- LOG(("node %p, node type %i END", n, n->type));
goto end;
}
@@ -460,28 +499,38 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
(parent_style->white_space == CSS_WHITE_SPACE_NORMAL ||
parent_style->white_space == CSS_WHITE_SPACE_NOWRAP)) {
char *text = squash_whitespace(n->content);
+ if (!text)
+ goto no_memory;
/* if the text is just a space, combine it with the preceding
* text node, if any */
if (text[0] == ' ' && text[1] == 0) {
- if (inline_container != 0) {
- assert(inline_container->last != 0);
- inline_container->last->space = 1;
+ if (*inline_container) {
+ assert((*inline_container)->last != 0);
+ (*inline_container)->last->space = 1;
}
free(text);
goto end;
}
- if (inline_container == 0) {
+ if (!*inline_container) {
/* this is the first inline node: make a container */
- inline_container = box_create(0, 0, 0, 0,
+ *inline_container = box_create(0, 0, 0, 0,
content->data.html.box_pool);
- inline_container->type = BOX_INLINE_CONTAINER;
- box_add_child(parent, inline_container);
+ if (!*inline_container) {
+ free(text);
+ goto no_memory;
+ }
+ (*inline_container)->type = BOX_INLINE_CONTAINER;
+ box_add_child(parent, *inline_container);
}
box = box_create(parent_style, status.href, title, id,
content->data.html.box_pool);
+ if (!box) {
+ free(text);
+ goto no_memory;
+ }
box->text = text;
box->style_clone = 1;
box->length = strlen(text);
@@ -496,21 +545,21 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
if (parent_style->white_space == CSS_WHITE_SPACE_NOWRAP) {
unsigned int i;
for (i = 0; i != box->length && text[i] != ' '; ++i)
- /* no body */;
+ ; /* no body */
if (i != box->length) {
/* there is a space in text block and we
* want all spaces to be converted to NBSP
*/
- char *org_text = box->text;
- org_text[box->length] = '\0';
- box->text = cnv_space2nbsp(org_text);
- free(org_text);
- box->length = strlen(box->text);
+ box->text = cnv_space2nbsp(text);
+ if (!box->text) {
+ free(text);
+ goto no_memory;
+ }
}
}
box->font = nsfont_open(content->data.html.fonts, box->style);
- box_add_child(inline_container, box);
+ box_add_child(*inline_container, box);
if (box->text[0] == ' ') {
box->length--;
memmove(box->text, &box->text[1], box->length);
@@ -524,6 +573,8 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
char *text = cnv_space2nbsp(n->content);
char *current;
assert(parent_style->white_space == CSS_WHITE_SPACE_PRE);
+ if (!text)
+ goto no_memory;
if (parent_style->text_transform != CSS_TEXT_TRANSFORM_NONE)
box_text_transform(text, strlen(text),
parent_style->text_transform);
@@ -532,28 +583,42 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
size_t len = strcspn(current, "\r\n");
char old = current[len];
current[len] = 0;
- if (!inline_container) {
- inline_container = box_create(0, 0, 0, 0,
+ if (!*inline_container) {
+ *inline_container = box_create(0, 0, 0, 0,
content->data.html.box_pool);
- inline_container->type = BOX_INLINE_CONTAINER;
- box_add_child(parent, inline_container);
+ if (!*inline_container) {
+ free(text);
+ goto no_memory;
+ }
+ (*inline_container)->type =
+ BOX_INLINE_CONTAINER;
+ box_add_child(parent, *inline_container);
}
box = box_create(parent_style, status.href, title,
id, content->data.html.box_pool);
+ if (!box) {
+ free(text);
+ goto no_memory;
+ }
box->type = BOX_INLINE;
box->style_clone = 1;
- box->text = xstrdup(current);
+ box->text = strdup(current);
+ if (!box->text) {
+ free(text);
+ goto no_memory;
+ }
box->length = strlen(box->text);
- box->font = nsfont_open(content->data.html.fonts, box->style);
- box_add_child(inline_container, box);
+ box->font = nsfont_open(content->data.html.fonts,
+ box->style);
+ box_add_child(*inline_container, box);
current[len] = old;
current += len;
if (current[0] == '\r' && current[1] == '\n') {
current += 2;
- inline_container = 0;
+ *inline_container = 0;
} else if (current[0] != 0) {
current++;
- inline_container = 0;
+ *inline_container = 0;
}
} while (*current);
free(text);
@@ -565,49 +630,57 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
style->float_ == CSS_FLOAT_RIGHT ||
box->type == BOX_BR) {
/* this is an inline box */
- if (inline_container == 0) {
+ if (!*inline_container) {
/* this is the first inline node: make a container */
- inline_container = box_create(0, 0, 0, 0,
+ *inline_container = box_create(0, 0, 0, 0,
content->data.html.box_pool);
- inline_container->type = BOX_INLINE_CONTAINER;
- box_add_child(parent, inline_container);
+ if (!*inline_container)
+ goto no_memory;
+ (*inline_container)->type = BOX_INLINE_CONTAINER;
+ box_add_child(parent, *inline_container);
}
if (box->type == BOX_INLINE || box->type == BOX_BR) {
/* inline box: add to tree and recurse */
- box_add_child(inline_container, box);
+ box_add_child(*inline_container, box);
if (convert_children) {
for (c = n->children; c != 0; c = c->next)
- inline_container = convert_xml_to_box(c, content, style,
- parent, inline_container,
- status);
+ if (!convert_xml_to_box(c, content,
+ style, parent,
+ inline_container,
+ status))
+ goto no_memory;
}
- LOG(("node %p, node type %i END", n, n->type));
goto end;
} else if (box->type == BOX_INLINE_BLOCK) {
/* inline block box: add to tree and recurse */
- box_add_child(inline_container, box);
+ box_add_child(*inline_container, box);
if (convert_children) {
inline_container_c = 0;
for (c = n->children; c != 0; c = c->next)
- inline_container_c = convert_xml_to_box(c, content, style,
- box, inline_container_c,
- status);
+ if (!convert_xml_to_box(c, content,
+ style, box,
+ &inline_container_c,
+ status))
+ goto no_memory;
}
- LOG(("node %p, node type %i END", n, n->type));
goto end;
} else {
- /* float: insert a float box between the parent and current node */
- assert(style->float_ == CSS_FLOAT_LEFT || style->float_ == CSS_FLOAT_RIGHT);
- LOG(("float"));
+ /* float: insert a float box between the parent and
+ * current node */
+ assert(style->float_ == CSS_FLOAT_LEFT ||
+ style->float_ == CSS_FLOAT_RIGHT);
parent = box_create(0, status.href, title, id,
content->data.html.box_pool);
+ if (!parent)
+ goto no_memory;
if (style->float_ == CSS_FLOAT_LEFT)
parent->type = BOX_FLOAT_LEFT;
else
parent->type = BOX_FLOAT_RIGHT;
- box_add_child(inline_container, parent);
- if (box->type == BOX_INLINE || box->type == BOX_INLINE_BLOCK)
+ box_add_child(*inline_container, parent);
+ if (box->type == BOX_INLINE ||
+ box->type == BOX_INLINE_BLOCK)
box->type = BOX_BLOCK;
}
}
@@ -619,13 +692,13 @@ struct box * convert_xml_to_box(xmlNode * n, struct content *content,
if (convert_children) {
inline_container_c = 0;
for (c = n->children; c != 0; c = c->next)
- inline_container_c = convert_xml_to_box(c, content, style,
- box, inline_container_c,
- status);
+ if (!convert_xml_to_box(c, content, style,
+ box, &inline_container_c, status))
+ goto no_memory;
}
if (style->float_ == CSS_FLOAT_NONE)
/* new inline container unless this is a float */
- inline_container = 0;
+ *inline_container = 0;
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "colspan")) != NULL) {
box->columns = strtol(s, NULL, 10);
@@ -652,17 +725,24 @@ end:
if (box && box->style && box->style->background_image.type ==
CSS_BACKGROUND_IMAGE_URI) {
char *url = strdup(box->style->background_image.uri);
- if (!url) {
- /** \todo handle this */
- return inline_container;
- }
+ if (!url)
+ return false;
/* start fetch */
html_fetch_object(content, url, box, image_types,
content->available_width, 1000, true);
}
- LOG(("node %p, node type %i END", n, n->type));
- return inline_container;
+ return true;
+
+no_memory:
+ free(title);
+ free(id);
+ if (!href_in)
+ xmlFree(status.href);
+ if (style && !box)
+ free(style);
+
+ return false;
}
@@ -676,15 +756,16 @@ end:
*/
struct css_style * box_get_style(struct content *c,
- struct content ** stylesheet,
- unsigned int stylesheet_count, struct css_style * parent_style,
- xmlNode * n)
+ struct css_style *parent_style,
+ xmlNode *n)
{
struct css_style * style = xcalloc(1, sizeof(struct css_style));
struct css_style style_new;
char * s;
unsigned int i;
url_func_result res;
+ struct content **stylesheet = c->data.html.stylesheet_content;
+ unsigned int stylesheet_count = c->data.html.stylesheet_count;
memcpy(style, parent_style, sizeof(struct css_style));
memcpy(&style_new, &css_blank_style, sizeof(struct css_style));
@@ -820,7 +901,7 @@ struct css_style * box_get_style(struct content *c,
(const xmlChar *) "cellspacing"))) {
if (!strrchr(s, '%')) { /* % not implemented */
int value = atoi(s);
- if (0 < value) {
+ if (0 <= value) {
style->border_spacing.border_spacing =
CSS_BORDER_SPACING_LENGTH;
style->border_spacing.horz.unit =
@@ -2271,7 +2352,7 @@ struct box_result box_object(xmlNode *n, struct box_status *status,
if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
free(po);
xmlFree(s);
- return (struct box_result) {box, true, true};
+ return (struct box_result) {0, true, true};
}
po->data = strdup(s);
LOG(("object '%s'", po->data));
@@ -2405,7 +2486,7 @@ struct box_result box_embed(xmlNode *n, struct box_status *status,
if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
free(po);
xmlFree(s);
- return (struct box_result) {box, false, true};
+ return (struct box_result) {0, false, true};
}
LOG(("embed '%s'", url));
po->data = strdup(s);
@@ -2585,7 +2666,7 @@ struct box_result box_iframe(xmlNode *n, struct box_status *status,
if (res != URL_FUNC_OK || strcasecmp(url, status->content->data.html.base_url) == 0) {
free(po);
xmlFree(s);
- return (struct box_result) {box, false, true};
+ return (struct box_result) {0, false, true};
}
LOG(("embed '%s'", url));
po->data = strdup(s);
@@ -2872,9 +2953,9 @@ struct box_result box_frameset(xmlNode *n, struct box_status *status,
object_style->width.width = CSS_WIDTH_LENGTH;
object_style->width.value.length.unit =
CSS_UNIT_PX;
- object_style->width.value.length.value =
- object_width;
- }
+ object_style->width.value.length.value =
+ object_width;
+ }
object_box = box_create(object_style, 0, 0, 0,
status->content->data.html.box_pool);
diff --git a/render/box.h b/render/box.h
index b401799fa..048c566dd 100644
--- a/render/box.h
+++ b/render/box.h
@@ -234,7 +234,7 @@ struct column {
#define UNKNOWN_MAX_WIDTH INT_MAX
-void xml_to_box(xmlNode *n, struct content *c);
+bool xml_to_box(xmlNode *n, struct content *c);
void box_dump(struct box *box, unsigned int depth);
struct box * box_create(struct css_style *style,
const char *href, const char *title,