From 61a6656bba99454d7e4ad3e9b8c4a4f7cabf68c3 Mon Sep 17 00:00:00 2001 From: Marek Kasik Date: Wed, 11 Feb 2015 12:13:40 +0100 Subject: [PATCH] Check for failed rendering jobs Check whether creating of thumbnails for sidebar, thumbnails for recent view or rendering of document itself failed to avoid crashes. https://bugzilla.gnome.org/show_bug.cgi?id=744049 --- libdocument/ev-document.c | 8 +++++--- libview/ev-jobs.c | 26 +++++++++++++++++++++++++- libview/ev-pixbuf-cache.c | 6 ++++++ shell/ev-recent-view.c | 3 ++- shell/ev-sidebar-thumbnails.c | 5 +++++ 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c index 6c2f1b9..6af0ad7 100644 --- a/libdocument/ev-document.c +++ b/libdocument/ev-document.c @@ -724,11 +724,13 @@ _ev_document_get_thumbnail (EvDocument *document, EvRenderContext *rc) { cairo_surface_t *surface; - GdkPixbuf *pixbuf; + GdkPixbuf *pixbuf = NULL; surface = ev_document_render (document, rc); - pixbuf = ev_document_misc_pixbuf_from_surface (surface); - cairo_surface_destroy (surface); + if (surface != NULL) { + pixbuf = ev_document_misc_pixbuf_from_surface (surface); + cairo_surface_destroy (surface); + } return pixbuf; } diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c index e118855..3bbe7b0 100644 --- a/libview/ev-jobs.c +++ b/libview/ev-jobs.c @@ -636,6 +636,21 @@ ev_job_render_run (EvJob *job) g_object_unref (ev_page); job_render->surface = ev_document_render (job->document, rc); + + if (job_render->surface == NULL) { + ev_document_fc_mutex_unlock (); + ev_document_doc_mutex_unlock (); + g_object_unref (rc); + + ev_job_failed (job, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("Failed to render page %d"), + job_render->page); + + return FALSE; + } + /* If job was cancelled during the page rendering, * we return now, so that the thread is finished ASAP */ @@ -868,7 +883,16 @@ ev_job_thumbnail_run (EvJob *job) g_object_unref (pixbuf); } - ev_job_succeeded (job); + if ((job_thumb->format == EV_JOB_THUMBNAIL_PIXBUF && pixbuf == NULL) || + job_thumb->thumbnail_surface == NULL) { + ev_job_failed (job, + EV_DOCUMENT_ERROR, + EV_DOCUMENT_ERROR_INVALID, + _("Failed to create thumbnail for page %d"), + job_thumb->page); + } else { + ev_job_succeeded (job); + } return FALSE; } diff --git a/libview/ev-pixbuf-cache.c b/libview/ev-pixbuf-cache.c index f308c9c..c7ae47a 100644 --- a/libview/ev-pixbuf-cache.c +++ b/libview/ev-pixbuf-cache.c @@ -337,6 +337,12 @@ job_finished_cb (EvJob *job, job_info = find_job_cache (pixbuf_cache, job_render->page); + if (ev_job_is_failed (job)) { + job_info->job = NULL; + g_object_unref (job); + return; + } + copy_job_to_job_info (job_render, job_info, pixbuf_cache); g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region); } diff --git a/shell/ev-recent-view.c b/shell/ev-recent-view.c index fb0004c..97f2f8e 100644 --- a/shell/ev-recent-view.c +++ b/shell/ev-recent-view.c @@ -350,7 +350,8 @@ static void thumbnail_job_completed_callback (EvJobThumbnail *job, GetDocumentInfoAsyncData *data) { - if (g_cancellable_is_cancelled (data->cancellable)) { + if (g_cancellable_is_cancelled (data->cancellable) || + ev_job_is_failed (EV_JOB (job))) { get_document_info_async_data_free (data); return; } diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c index 49045f3..4186994 100644 --- a/shell/ev-sidebar-thumbnails.c +++ b/shell/ev-sidebar-thumbnails.c @@ -936,7 +936,12 @@ thumbnail_job_completed_callback (EvJobThumbnail *job, cairo_surface_t *surface; #ifdef HAVE_HIDPI_SUPPORT gint device_scale; +#endif + + if (ev_job_is_failed (EV_JOB (job))) + return; +#ifdef HAVE_HIDPI_SUPPORT device_scale = gtk_widget_get_scale_factor (widget); cairo_surface_set_device_scale (job->thumbnail_surface, device_scale, device_scale); #endif -- 2.1.0