From 9720c024832c96d917de933b95c87cf2e4f867bf Mon Sep 17 00:00:00 2001 From: John-Mark Bell Date: Mon, 10 Feb 2014 01:24:43 +0000 Subject: Fix #2071: handle parse completion creating style or script nodes. --- render/html.c | 36 ++++++++++++++++++++++++++++-------- render/html_internal.h | 1 + 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/render/html.c b/render/html.c index 4336bead0..8d3daf1a4 100644 --- a/render/html.c +++ b/render/html.c @@ -731,6 +731,7 @@ html_create_html_data(html_content *c, const http_parameter *params) dom_hubbub_error error; c->parser = NULL; + c->parse_completed = false; c->document = NULL; c->quirks = DOM_DOCUMENT_QUIRKS_MODE_NONE; c->encoding = NULL; @@ -1070,16 +1071,35 @@ html_begin_conversion(html_content *htmlc) dom_string *node_name = NULL; dom_hubbub_error error; - LOG(("Completing parse")); - /* complete parsing */ - error = dom_hubbub_parser_completed(htmlc->parser); - if (error != DOM_HUBBUB_OK) { - LOG(("Parsing failed")); + /* The act of completing the parse can result in additional data + * being flushed through the parser. This may result in new style or + * script nodes, upon which the conversion depends. Thus, once we + * have completed the parse, we must check again to see if we can + * begin the conversion. If we can't, we must stop and wait for the + * new styles/scripts to be processed. Once they have been processed, + * we will be called again to begin the conversion for real. Thus, + * we must also ensure that we don't attempt to complete the parse + * multiple times, so store a flag to indicate that parsing is + * complete to avoid repeating the completion pointlessly. + */ + if (htmlc->parse_completed == false) { + LOG(("Completing parse")); + /* complete parsing */ + error = dom_hubbub_parser_completed(htmlc->parser); + if (error != DOM_HUBBUB_OK) { + LOG(("Parsing failed")); + + content_broadcast_errorcode(&htmlc->base, + libdom_hubbub_error_to_nserror(error)); - content_broadcast_errorcode(&htmlc->base, - libdom_hubbub_error_to_nserror(error)); + return false; + } + htmlc->parse_completed = true; + } - return false; + if (html_can_begin_conversion(htmlc) == false) { + /* We can't proceed (see commentary above) */ + return true; } /* Give up processing if we've been aborted */ diff --git a/render/html_internal.h b/render/html_internal.h index 43fce9bfd..e7768e39f 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -71,6 +71,7 @@ typedef struct html_content { struct content base; dom_hubbub_parser *parser; /**< Parser object handle */ + bool parse_completed; /**< Whether the parse has been completed */ /** Document tree */ dom_document *document; -- cgit v1.2.3