summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--render/html.c32
-rw-r--r--render/hubbub_binding.c77
-rw-r--r--render/libxml_binding.c50
-rw-r--r--render/parser_binding.h5
4 files changed, 94 insertions, 70 deletions
diff --git a/render/html.c b/render/html.c
index 00f2d7615..e45d77e4d 100644
--- a/render/html.c
+++ b/render/html.c
@@ -104,6 +104,7 @@ bool html_create(struct content *c, const char *params[])
unsigned int i;
struct content_html_data *html = &c->data.html;
union content_msg_data msg_data;
+ binding_error error;
html->parser_binding = NULL;
html->document = 0;
@@ -131,22 +132,28 @@ bool html_create(struct content *c, const char *params[])
for (i = 0; params[i]; i += 2) {
if (strcasecmp(params[i], "charset") == 0) {
html->encoding = talloc_strdup(c, params[i + 1]);
- if (!html->encoding)
- goto no_memory;
+ if (!html->encoding) {
+ error = BINDING_NOMEM;
+ goto error;
+ }
html->encoding_source = ENCODING_SOURCE_HEADER;
break;
}
}
/* Create the parser binding */
- html->parser_binding = binding_create_tree(c, html->encoding);
- if (!html->parser_binding)
- goto no_memory;
+ error = binding_create_tree(c, html->encoding, &html->parser_binding);
+ if (error != BINDING_OK)
+ goto error;
return true;
-no_memory:
- msg_data.error = messages_get("NoMemory");
+error:
+ if (error == BINDING_BADENCODING)
+ msg_data.error = messages_get("BadEncoding");
+ else
+ msg_data.error = messages_get("NoMemory");
+
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
@@ -206,12 +213,15 @@ encoding_change:
binding_destroy_tree(c->data.html.parser_binding);
/* Create new binding, using the new encoding */
- c->data.html.parser_binding = binding_create_tree(c,
- c->data.html.encoding);
- if (!c->data.html.parser_binding) {
+ err = binding_create_tree(c, c->data.html.encoding,
+ &c->data.html.parser_binding);
+ if (err != BINDING_OK) {
union content_msg_data msg_data;
- msg_data.error = messages_get("NoMemory");
+ if (err == BINDING_BADENCODING)
+ msg_data.error = messages_get("BadEncoding");
+ else
+ msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
diff --git a/render/hubbub_binding.c b/render/hubbub_binding.c
index b014dcd9d..1cc4ad72e 100644
--- a/render/hubbub_binding.c
+++ b/render/hubbub_binding.c
@@ -117,59 +117,66 @@ static void *myrealloc(void *ptr, size_t len, void *pw)
return talloc_realloc_size(pw, ptr, len);
}
-void *binding_create_tree(void *arena, const char *charset)
+binding_error binding_create_tree(void *arena, const char *charset, void **ctx)
{
- hubbub_ctx *ctx;
+ hubbub_ctx *c;
hubbub_parser_optparams params;
+ hubbub_error error;
- ctx = malloc(sizeof(hubbub_ctx));
- if (ctx == NULL)
- return NULL;
-
- ctx->parser = NULL;
- ctx->encoding = charset;
- ctx->encoding_source = ENCODING_SOURCE_HEADER;
- ctx->document = NULL;
- ctx->owns_doc = true;
-
- ctx->parser = hubbub_parser_create(charset, true, myrealloc, arena);
- if (ctx->parser == NULL) {
- free(ctx);
- return NULL;
+ c = malloc(sizeof(hubbub_ctx));
+ if (c == NULL)
+ return BINDING_NOMEM;
+
+ c->parser = NULL;
+ c->encoding = charset;
+ c->encoding_source = ENCODING_SOURCE_HEADER;
+ c->document = NULL;
+ c->owns_doc = true;
+
+ error = hubbub_parser_create(charset, true, myrealloc, arena,
+ &c->parser);
+ if (error != HUBBUB_OK) {
+ free(c);
+ if (error == HUBBUB_BADENCODING)
+ return BINDING_BADENCODING;
+ else
+ return BINDING_NOMEM; /* Assume OOM */
}
- ctx->document = htmlNewDocNoDtD(NULL, NULL);
- if (ctx->document == NULL) {
- hubbub_parser_destroy(ctx->parser);
- free(ctx);
- return NULL;
+ c->document = htmlNewDocNoDtD(NULL, NULL);
+ if (c->document == NULL) {
+ hubbub_parser_destroy(c->parser);
+ free(c);
+ return BINDING_NOMEM;
}
- ctx->document->_private = (void *) 0;
+ c->document->_private = (void *) 0;
for (uint32_t i = 0;
- i < sizeof(ctx->namespaces) / sizeof(ctx->namespaces[0]); i++) {
- ctx->namespaces[i] = NULL;
+ i < sizeof(c->namespaces) / sizeof(c->namespaces[0]); i++) {
+ c->namespaces[i] = NULL;
}
- ctx->tree_handler = tree_handler;
- ctx->tree_handler.ctx = (void *) ctx;
+ c->tree_handler = tree_handler;
+ c->tree_handler.ctx = (void *) c;
+
+ params.tree_handler = &c->tree_handler;
+ hubbub_parser_setopt(c->parser, HUBBUB_PARSER_TREE_HANDLER, &params);
- params.tree_handler = &ctx->tree_handler;
- hubbub_parser_setopt(ctx->parser, HUBBUB_PARSER_TREE_HANDLER, &params);
+ ref_node(c, c->document);
+ params.document_node = c->document;
+ hubbub_parser_setopt(c->parser, HUBBUB_PARSER_DOCUMENT_NODE, &params);
- ref_node(ctx, ctx->document);
- params.document_node = ctx->document;
- hubbub_parser_setopt(ctx->parser, HUBBUB_PARSER_DOCUMENT_NODE, &params);
+ *ctx = (void *) c;
- return (void *) ctx;
+ return BINDING_OK;
}
-void binding_destroy_tree(void *ctx)
+binding_error binding_destroy_tree(void *ctx)
{
hubbub_ctx *c = (hubbub_ctx *) ctx;
if (ctx == NULL)
- return;
+ return BINDING_OK;
if (c->parser != NULL)
hubbub_parser_destroy(c->parser);
@@ -182,6 +189,8 @@ void binding_destroy_tree(void *ctx)
c->document = NULL;
free(c);
+
+ return BINDING_OK;
}
binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len)
diff --git a/render/libxml_binding.c b/render/libxml_binding.c
index 51cf0a6be..fdff19b70 100644
--- a/render/libxml_binding.c
+++ b/render/libxml_binding.c
@@ -47,44 +47,46 @@ typedef struct libxml_ctx {
static bool set_parser_encoding(libxml_ctx *c, const char *encoding);
static const char *detect_encoding(const char **data, size_t *size);
-void *binding_create_tree(void *arena, const char *charset)
+binding_error binding_create_tree(void *arena, const char *charset, void **ctx)
{
- libxml_ctx *ctx;
+ libxml_ctx *c;
- ctx = malloc(sizeof(libxml_ctx));
- if (ctx == NULL)
- return NULL;
+ c = malloc(sizeof(libxml_ctx));
+ if (c == NULL)
+ return BINDING_NOMEM;
- ctx->parser = NULL;
- ctx->encoding_handler = NULL;
- ctx->encoding = charset;
- ctx->encoding_source = ENCODING_SOURCE_HEADER;
- ctx->getenc = true;
+ c->parser = NULL;
+ c->encoding_handler = NULL;
+ c->encoding = charset;
+ c->encoding_source = ENCODING_SOURCE_HEADER;
+ c->getenc = true;
- ctx->parser = htmlCreatePushParserCtxt(0, 0, "", 0, 0,
+ c->parser = htmlCreatePushParserCtxt(0, 0, "", 0, 0,
XML_CHAR_ENCODING_NONE);
- if (ctx->parser == NULL) {
- free(ctx);
- return NULL;
+ if (c->parser == NULL) {
+ free(c);
+ return BINDING_NOMEM;
}
- if (ctx->encoding != NULL && !set_parser_encoding(ctx, charset)) {
- if (ctx->parser->myDoc != NULL)
- xmlFreeDoc(ctx->parser->myDoc);
- htmlFreeParserCtxt(ctx->parser);
- free(ctx);
- return NULL;
+ if (c->encoding != NULL && !set_parser_encoding(c, charset)) {
+ if (c->parser->myDoc != NULL)
+ xmlFreeDoc(c->parser->myDoc);
+ htmlFreeParserCtxt(c->parser);
+ free(c);
+ return BINDING_BADENCODING;
}
- return (void *) ctx;
+ *ctx = (void *) c;
+
+ return BINDING_OK;
}
-void binding_destroy_tree(void *ctx)
+binding_error binding_destroy_tree(void *ctx)
{
libxml_ctx *c = (libxml_ctx *) ctx;
if (ctx == NULL)
- return;
+ return BINDING_OK;
if (c->parser->myDoc != NULL)
xmlFreeDoc(c->parser->myDoc);
@@ -96,6 +98,8 @@ void binding_destroy_tree(void *ctx)
c->encoding = NULL;
free(c);
+
+ return BINDING_OK;
}
binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len)
diff --git a/render/parser_binding.h b/render/parser_binding.h
index 73e6e9708..10c0ad334 100644
--- a/render/parser_binding.h
+++ b/render/parser_binding.h
@@ -26,6 +26,7 @@
typedef enum binding_error {
BINDING_OK,
BINDING_NOMEM,
+ BINDING_BADENCODING,
BINDING_ENCODINGCHANGE
} binding_error;
@@ -35,8 +36,8 @@ typedef enum binding_encoding_source {
ENCODING_SOURCE_META
} binding_encoding_source;
-void *binding_create_tree(void *arena, const char *charset);
-void binding_destroy_tree(void *ctx);
+binding_error binding_create_tree(void *arena, const char *charset, void **ctx);
+binding_error binding_destroy_tree(void *ctx);
binding_error binding_parse_chunk(void *ctx, const uint8_t *data, size_t len);
binding_error binding_parse_completed(void *ctx);