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; + c = malloc(sizeof(hubbub_ctx)); + if (c == NULL) + return BINDING_NOMEM; - ctx->parser = NULL; - ctx->encoding = charset; - ctx->encoding_source = ENCODING_SOURCE_HEADER; - ctx->document = NULL; - ctx->owns_doc = true; + c->parser = NULL; + c->encoding = charset; + c->encoding_source = ENCODING_SOURCE_HEADER; + c->document = NULL; + c->owns_doc = true; - ctx->parser = hubbub_parser_create(charset, true, myrealloc, arena); - if (ctx->parser == NULL) { - free(ctx); - return NULL; + 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 = &ctx->tree_handler; - hubbub_parser_setopt(ctx->parser, HUBBUB_PARSER_TREE_HANDLER, ¶ms); + params.tree_handler = &c->tree_handler; + hubbub_parser_setopt(c->parser, HUBBUB_PARSER_TREE_HANDLER, ¶ms); - ref_node(ctx, ctx->document); - params.document_node = ctx->document; - hubbub_parser_setopt(ctx->parser, HUBBUB_PARSER_DOCUMENT_NODE, ¶ms); + ref_node(c, c->document); + params.document_node = c->document; + hubbub_parser_setopt(c->parser, HUBBUB_PARSER_DOCUMENT_NODE, ¶ms); - return (void *) ctx; + *ctx = (void *) c; + + 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);