Blob Blame History Raw
From 61a6656bba99454d7e4ad3e9b8c4a4f7cabf68c3 Mon Sep 17 00:00:00 2001
From: Marek Kasik <mkasik@redhat.com>
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