From 7d8ee5a1478a00af3e14fd8c563b7ae271723e79 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 7 Feb 2017 18:55:01 -0800 Subject: document: add destroy notify to page callback This ensures that we only free the async data struct when the document is guaranteed to be done calling our callback. Without this, we risk potentially accessing the async request data after we have freed it when a mallard document reloads. https://bugzilla.gnome.org/show_bug.cgi?id=778258 --- libyelp/yelp-docbook-document.c | 9 ++++++--- libyelp/yelp-document.c | 17 +++++++++++++---- libyelp/yelp-document.h | 6 ++++-- libyelp/yelp-help-list.c | 9 ++++++--- libyelp/yelp-info-document.c | 9 ++++++--- libyelp/yelp-mallard-document.c | 9 ++++++--- libyelp/yelp-man-document.c | 9 ++++++--- libyelp/yelp-simple-document.c | 6 ++++-- libyelp/yelp-view.c | 4 ++-- 9 files changed, 53 insertions(+), 25 deletions(-) diff --git a/libyelp/yelp-docbook-document.c b/libyelp/yelp-docbook-document.c index 4ac09a97..9b430b09 100644 --- a/libyelp/yelp-docbook-document.c +++ b/libyelp/yelp-docbook-document.c @@ -60,7 +60,8 @@ static gboolean docbook_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); static void docbook_process (YelpDocbookDocument *docbook); static void docbook_disconnect (YelpDocbookDocument *docbook); @@ -239,7 +240,8 @@ docbook_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { YelpDocbookDocumentPrivate *priv = GET_PRIV (document); gchar *docuri; @@ -257,7 +259,8 @@ docbook_request_page (YelpDocument *document, page_id, cancellable, callback, - user_data); + user_data, + notify); if (handled) { return handled; } diff --git a/libyelp/yelp-document.c b/libyelp/yelp-document.c index f26ebd2b..547ef24d 100644 --- a/libyelp/yelp-document.c +++ b/libyelp/yelp-document.c @@ -51,6 +51,7 @@ struct _Request { GCancellable *cancellable; YelpDocumentCallback callback; gpointer user_data; + GDestroyNotify notify; GError *error; gint idle_funcs; @@ -113,7 +114,8 @@ static gboolean document_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); static gboolean document_indexed (YelpDocument *document); static const gchar * document_read_contents (YelpDocument *document, const gchar *page_id); @@ -810,7 +812,8 @@ yelp_document_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { g_return_val_if_fail (YELP_IS_DOCUMENT (document), FALSE); g_return_val_if_fail (YELP_DOCUMENT_GET_CLASS (document)->request_page != NULL, FALSE); @@ -821,7 +824,8 @@ yelp_document_request_page (YelpDocument *document, page_id, cancellable, callback, - user_data); + user_data, + notify); } static gboolean @@ -829,7 +833,8 @@ document_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { Request *request; gchar *real_id; @@ -855,6 +860,7 @@ document_request_page (YelpDocument *document, request->callback = callback; request->user_data = user_data; + request->notify = notify; request->idle_funcs = 0; g_mutex_lock (&document->priv->mutex); @@ -1510,6 +1516,9 @@ request_try_free (Request *request) static void request_free (Request *request) { + if (request->notify) + request->notify (request->user_data); + g_object_unref (request->document); g_free (request->page_id); g_object_unref (request->cancellable); diff --git a/libyelp/yelp-document.h b/libyelp/yelp-document.h index 75157d5a..175b281a 100644 --- a/libyelp/yelp-document.h +++ b/libyelp/yelp-document.h @@ -63,7 +63,8 @@ struct _YelpDocumentClass { const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); const gchar * (*read_contents) (YelpDocument *document, const gchar *page_id); void (*finish_read) (YelpDocument *document, @@ -85,7 +86,8 @@ gboolean yelp_document_request_page (YelpDocument *docum const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); void yelp_document_clear_contents (YelpDocument *document); gchar ** yelp_document_get_requests (YelpDocument *document); diff --git a/libyelp/yelp-help-list.c b/libyelp/yelp-help-list.c index f5020229..9005e48f 100644 --- a/libyelp/yelp-help-list.c +++ b/libyelp/yelp-help-list.c @@ -43,7 +43,8 @@ static gboolean help_list_request_page (YelpDocument *doc const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); static void help_list_think (YelpHelpList *list); static void help_list_handle_page (YelpHelpList *list, const gchar *page_id); @@ -179,7 +180,8 @@ help_list_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { gboolean handled; YelpHelpListPrivate *priv = GET_PRIV (document); @@ -192,7 +194,8 @@ help_list_request_page (YelpDocument *document, page_id, cancellable, callback, - user_data); + user_data, + notify); if (handled) { return TRUE; } diff --git a/libyelp/yelp-info-document.c b/libyelp/yelp-info-document.c index b6f50771..7b532744 100644 --- a/libyelp/yelp-info-document.c +++ b/libyelp/yelp-info-document.c @@ -75,7 +75,8 @@ static gboolean info_request_page (YelpDocument const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); /* YelpTransform */ static void transform_chunk_ready (YelpTransform *transform, @@ -178,7 +179,8 @@ info_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { YelpInfoDocumentPrivate *priv = GET_PRIV (document); gchar *docuri; @@ -193,7 +195,8 @@ info_request_page (YelpDocument *document, page_id, cancellable, callback, - user_data); + user_data, + notify); if (handled) { return TRUE; } diff --git a/libyelp/yelp-mallard-document.c b/libyelp/yelp-mallard-document.c index e42f40b4..f0713078 100644 --- a/libyelp/yelp-mallard-document.c +++ b/libyelp/yelp-mallard-document.c @@ -79,7 +79,8 @@ static gboolean mallard_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); static void transform_chunk_ready (YelpTransform *transform, gchar *chunk_id, @@ -250,7 +251,8 @@ mallard_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { YelpMallardDocumentPrivate *priv = GET_PRIV (document); gchar *docuri; @@ -268,7 +270,8 @@ mallard_request_page (YelpDocument *document, page_id, cancellable, callback, - user_data); + user_data, + notify); if (handled) { return TRUE; } diff --git a/libyelp/yelp-man-document.c b/libyelp/yelp-man-document.c index 77e74143..4e165d57 100644 --- a/libyelp/yelp-man-document.c +++ b/libyelp/yelp-man-document.c @@ -124,7 +124,8 @@ static gboolean man_request_page (YelpDocument const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); /* YelpTransform */ static void transform_chunk_ready (YelpTransform *transform, @@ -203,7 +204,8 @@ man_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { YelpManDocumentPrivate *priv = GET_PRIV (document); gchar *docuri, *fulluri; @@ -222,7 +224,8 @@ man_request_page (YelpDocument *document, page_id, cancellable, callback, - user_data); + user_data, + notify); if (handled) { return handled; } diff --git a/libyelp/yelp-simple-document.c b/libyelp/yelp-simple-document.c index 47145621..501d7881 100644 --- a/libyelp/yelp-simple-document.c +++ b/libyelp/yelp-simple-document.c @@ -66,7 +66,8 @@ static gboolean document_request_page (YelpDocument const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data); + gpointer user_data, + GDestroyNotify notify); static const gchar * document_read_contents (YelpDocument *document, const gchar *page_id); static void document_finish_read (YelpDocument *document, @@ -181,7 +182,8 @@ document_request_page (YelpDocument *document, const gchar *page_id, GCancellable *cancellable, YelpDocumentCallback callback, - gpointer user_data) + gpointer user_data, + GDestroyNotify notify) { YelpSimpleDocument *simple = YELP_SIMPLE_DOCUMENT (document); Request *request; diff --git a/libyelp/yelp-view.c b/libyelp/yelp-view.c index 0e0d1d3f..c4432217 100644 --- a/libyelp/yelp-view.c +++ b/libyelp/yelp-view.c @@ -787,7 +787,6 @@ document_callback (YelpDocument *document, stream, content_length, mime_type); - request_async_data_free (data); g_free (mime_type); g_object_unref (stream); } @@ -810,7 +809,8 @@ help_cb_uri_resolved (YelpUri *uri, data->page_id, NULL, (YelpDocumentCallback) document_callback, - data); + data, + (GDestroyNotify) request_async_data_free); g_object_unref (document); } else { -- cgit v1.2.1