summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-03-09 13:47:12 +0000
committerVincent Sanders <vince@kyllikki.org>2015-03-09 13:47:12 +0000
commit84c29f1d8628fd77de72269b0f424d402fa59a47 (patch)
tree9ff54f5e665ad026fe6ab5dc562ad145d8e62e3e
parentc4e551cd0cecf4ec9aba2d033cba3ca97e669463 (diff)
downloadnetsurf-84c29f1d8628fd77de72269b0f424d402fa59a47.tar.gz
netsurf-84c29f1d8628fd77de72269b0f424d402fa59a47.tar.bz2
Add invalidate API to html content script handling and use it.
The html content script handling needs to invalidate its JavaScript context when the browsing context (browser_window) containing it is either closed or the content fetch is aborted (stopped) Previously the invalidation was only done on browser_window close which resulted in use after free crashes because of the now invalid JavaScript context.
-rw-r--r--render/html.c32
-rw-r--r--render/html_internal.h31
-rw-r--r--render/html_script.c28
3 files changed, 66 insertions, 25 deletions
diff --git a/render/html.c b/render/html.c
index d1a61a4f3..5fb2feabd 100644
--- a/render/html.c
+++ b/render/html.c
@@ -1106,7 +1106,7 @@ html_begin_conversion(html_content *htmlc)
}
/* complete script execution */
- html_scripts_exec(htmlc);
+ html_script_exec(htmlc);
/* fire a simple event that bubbles named DOMContentLoaded at
* the Document.
@@ -1213,12 +1213,21 @@ html_begin_conversion(html_content *htmlc)
/**
* Stop loading a CONTENT_HTML.
+ *
+ * called when the content is aborted. This must clean up any state
+ * created during the fetch.
*/
static void html_stop(struct content *c)
{
html_content *htmlc = (html_content *) c;
+ /* invalidate the html content reference to the javascript context
+ * as it is about to become invalid and must not be used any
+ * more.
+ */
+ html_script_invalidate_ctx(htmlc);
+
switch (c->status) {
case CONTENT_STATUS_LOADING:
/* Still loading; simply flag that we've been aborted
@@ -1466,7 +1475,7 @@ static void html_destroy(struct content *c)
html_css_free_stylesheets(html);
/* Free scripts */
- html_free_scripts(html);
+ html_script_free(html);
/* Free objects */
html_object_free_objects(html);
@@ -1531,24 +1540,25 @@ html_open(struct content *c,
static void html_close(struct content *c)
{
- html_content *html = (html_content *) c;
+ html_content *htmlc = (html_content *) c;
- selection_clear(&html->sel, false);
+ selection_clear(&htmlc->sel, false);
- if (html->search != NULL)
- search_destroy_context(html->search);
+ if (htmlc->search != NULL) {
+ search_destroy_context(htmlc->search);
+ }
/* clear the html content reference to the browser window */
- html->bw = NULL;
+ htmlc->bw = NULL;
- /* clear the html content reference to the javascript context
+ /* invalidate the html content reference to the javascript context
* as it is about to become invalid and must not be used any
* more.
*/
- html->jscontext = NULL;
+ html_script_invalidate_ctx(htmlc);
- /* remove all object references from teh html content */
- html_object_close_objects(html);
+ /* remove all object references from the html content */
+ html_object_close_objects(htmlc);
}
diff --git a/render/html_internal.h b/render/html_internal.h
index fd5cf8443..97ac2da55 100644
--- a/render/html_internal.h
+++ b/render/html_internal.h
@@ -264,9 +264,34 @@ void html_search_clear(struct content *c);
/* in render/html_script.c */
-dom_hubbub_error html_process_script(void *ctx, dom_node *node);
-void html_free_scripts(html_content *html);
-bool html_scripts_exec(html_content *c);
+dom_hubbub_error html_process_script(void *ctx, dom_node *node);
+
+/**
+ * Attempt script execution for defer and async scripts
+ *
+ * execute scripts using algorithm found in:
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element
+ *
+ * \param htmlc html content.
+ * \return NSERROR_OK error code.
+ */
+nserror html_script_exec(html_content *htmlc);
+
+/**
+ * Free all script resources and references for a html content.
+ *
+ * \param htmlc html content.
+ * \return NSERROR_OK or error code.
+ */
+nserror html_script_free(html_content *htmlc);
+
+/**
+ * Ensure the html content javascript context is invalidated.
+ *
+ * \param htmlc html content.
+ * \return NSERROR_OK or error code.
+ */
+nserror html_script_invalidate_ctx(html_content *htmlc);
/* in render/html_forms.c */
struct form *html_forms_get_forms(const char *docenc, dom_html_document *doc);
diff --git a/render/html_script.c b/render/html_script.c
index 4a82bcd70..2ebdffc12 100644
--- a/render/html_script.c
+++ b/render/html_script.c
@@ -50,20 +50,16 @@ static script_handler_t *select_script_handler(content_type ctype)
}
-/* attempt defer and async script execution
- *
- * execute scripts using algorithm found in:
- * http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element
- *
- */
-bool html_scripts_exec(html_content *c)
+/* exported internal interface documented in render/html_internal.h */
+nserror html_script_exec(html_content *c)
{
unsigned int i;
struct html_script *s;
script_handler_t *script_handler;
- if (c->jscontext == NULL)
- return false;
+ if (c->jscontext == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
for (i = 0, s = c->scripts; i != c->scripts_count; i++, s++) {
if (s->already_started) {
@@ -102,7 +98,7 @@ bool html_scripts_exec(html_content *c)
}
}
- return true;
+ return NSERROR_OK;
}
/* create new html script entry */
@@ -555,7 +551,8 @@ html_process_script(void *ctx, dom_node *node)
return err;
}
-void html_free_scripts(html_content *html)
+/* exported internal interface documented in render/html_internal.h */
+nserror html_script_free(html_content *html)
{
unsigned int i;
@@ -577,4 +574,13 @@ void html_free_scripts(html_content *html)
}
}
free(html->scripts);
+
+ return NSERROR_OK;
+}
+
+/* exported internal interface documented in render/html_internal.h */
+nserror html_script_invalidate_ctx(html_content *htmlc)
+{
+ htmlc->jscontext = NULL;
+ return NSERROR_OK;
}