From 524965b867e9aaef4ba75d6e077fdfd6c0b88401 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 23 Aug 2019 21:58:07 +0100 Subject: [PATCH] Box Conversion: Cancel conversion during html_destroy If dom_to_box is still in progress when we destroy an HTML content, we need to cancel the conversion otherwise we will end up with a scheduled callback into infinity. Signed-off-by: Daniel Silverstone --- content/handlers/html/box.h | 3 ++- content/handlers/html/box_construct.c | 23 ++++++++++++++++++++++- content/handlers/html/html.c | 11 ++++++++++- content/handlers/html/html_internal.h | 4 ++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/content/handlers/html/box.h b/content/handlers/html/box.h index 6939cfe1a..089c66433 100644 --- a/content/handlers/html/box.h +++ b/content/handlers/html/box.h @@ -359,7 +359,8 @@ bool box_vscrollbar_present(const struct box *box); bool box_hscrollbar_present(const struct box *box); nserror dom_to_box(struct dom_node *n, struct html_content *c, - box_construct_complete_cb cb); + box_construct_complete_cb cb, void **box_conversion_context); +nserror cancel_dom_to_box(void *box_conversion_context); bool box_normalise_block( struct box *block, diff --git a/content/handlers/html/box_construct.c b/content/handlers/html/box_construct.c index 1f15d82b7..f0d68ac2e 100644 --- a/content/handlers/html/box_construct.c +++ b/content/handlers/html/box_construct.c @@ -163,10 +163,12 @@ static const struct element_entry element_table[] = { * \return netsurf error code indicating status of call */ -nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb) +nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb, void **box_conversion_context) { struct box_construct_ctx *ctx; + assert(box_conversion_context != NULL); + if (c->bctx == NULL) { /* create a context allocation for this box tree */ c->bctx = talloc_zero(0, int); @@ -186,9 +188,28 @@ nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb) ctx->cb = cb; ctx->bctx = c->bctx; + *box_conversion_context = ctx; + return guit->misc->schedule(0, (void *)convert_xml_to_box, ctx); } +nserror cancel_dom_to_box(void *box_conversion_context) +{ + struct box_construct_ctx *ctx = box_conversion_context; + nserror err; + + err = guit->misc->schedule(-1, (void *)convert_xml_to_box, ctx); + if (err != NSERROR_OK) { + return err; + } + + dom_node_unref(ctx->n); + free(ctx); + + return NSERROR_OK; +} + + /* mapping from CSS display to box type * this table must be in sync with libcss' css_display enum */ static const box_type box_map[] = { diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c index ed48af20e..33dcf2aaa 100644 --- a/content/handlers/html/html.c +++ b/content/handlers/html/html.c @@ -115,6 +115,8 @@ static void html_box_convert_done(html_content *c, bool success) NSLOG(netsurf, INFO, "Done XML to box (%p)", c); + c->box_conversion_context = NULL; + /* Clean up and report error if unsuccessful or aborted */ if ((success == false) || (c->aborted)) { html_object_free_objects(c); @@ -656,7 +658,7 @@ void html_finish_conversion(html_content *htmlc) html_get_dimensions(htmlc); - error = dom_to_box(html, htmlc, html_box_convert_done); + error = dom_to_box(html, htmlc, html_box_convert_done, &htmlc->box_conversion_context); if (error != NSERROR_OK) { NSLOG(netsurf, INFO, "box conversion failed"); dom_node_unref(html); @@ -1710,6 +1712,13 @@ static void html_destroy(struct content *c) NSLOG(netsurf, INFO, "content %p", c); + /* If we're still converting a layout, cancel it */ + if (html->box_conversion_context != NULL) { + if (cancel_dom_to_box(html->box_conversion_context) != NSERROR_OK) { + NSLOG(netsurf, CRITICAL, "WARNING, Unable to cancel conversion context, browser may crash"); + } + } + /* Destroy forms */ for (f = html->forms; f != NULL; f = g) { g = f->prev; diff --git a/content/handlers/html/html_internal.h b/content/handlers/html/html_internal.h index 7a8d95612..fd6354a5a 100644 --- a/content/handlers/html/html_internal.h +++ b/content/handlers/html/html_internal.h @@ -138,6 +138,10 @@ typedef struct html_content { /** A talloc context purely for the render box tree */ int *bctx; + /** A context pointer for the box conversion, NULL if no conversion + * is in progress. + */ + void *box_conversion_context; /** Box tree, or NULL. */ struct box *layout; /** Document background colour. */