[gimp] Bug 764450 - Crash in screenshot's gnome-shell backend



commit cb76253c6739d3286e158f4759689641fe4a56c7
Author: Michael Natterer <mitch gimp org>
Date:   Sat Apr 2 01:28:34 2016 +0200

    Bug 764450 - Crash in screenshot's gnome-shell backend
    
    Add error reporting to all screenshot backends, but only really use it
    in the gnome-shell backend: check all DBus calls for errors instead of
    crashing.
    
    Also fix detection if gnome-shell is running: just creating the
    GDBusProxy always succeeds, so call org.freedesktop.DBus.Peer.Ping
    on the newly created proxy.

 plug-ins/screenshot/screenshot-gnome-shell.c |   39 +++++++++++++++++++++----
 plug-ins/screenshot/screenshot-gnome-shell.h |    7 ++--
 plug-ins/screenshot/screenshot-osx.c         |    8 ++--
 plug-ins/screenshot/screenshot-osx.h         |    7 ++--
 plug-ins/screenshot/screenshot-x11.c         |    9 +++--
 plug-ins/screenshot/screenshot-x11.h         |    7 ++--
 plug-ins/screenshot/screenshot.c             |   29 ++++++++++++------
 7 files changed, 72 insertions(+), 34 deletions(-)
---
diff --git a/plug-ins/screenshot/screenshot-gnome-shell.c b/plug-ins/screenshot/screenshot-gnome-shell.c
index 064469f..5031f23 100644
--- a/plug-ins/screenshot/screenshot-gnome-shell.c
+++ b/plug-ins/screenshot/screenshot-gnome-shell.c
@@ -39,14 +39,31 @@ gboolean
 screenshot_gnome_shell_available (void)
 {
   proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                         G_DBUS_PROXY_FLAGS_NONE,
+                                         G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
                                          NULL,
                                          "org.gnome.Shell.Screenshot",
                                          "/org/gnome/Shell/Screenshot",
                                          "org.gnome.Shell.Screenshot",
                                          NULL, NULL);
 
-  return proxy != NULL;
+  if (proxy)
+    {
+      GError *error = NULL;
+
+      g_dbus_proxy_call_sync (proxy, "org.freedesktop.DBus.Peer.Ping",
+                              NULL,
+                              G_DBUS_CALL_FLAGS_NONE,
+                              -1, NULL, &error);
+      if (! error)
+        return TRUE;
+
+      g_clear_error (&error);
+
+      g_object_unref (proxy);
+      proxy = NULL;
+    }
+
+  return FALSE;
 }
 
 ScreenshotCapabilities
@@ -57,9 +74,10 @@ screenshot_gnome_shell_get_capabilities (void)
 }
 
 GimpPDBStatusType
-screenshot_gnome_shell_shoot (ScreenshotValues *shootvals,
-                              GdkScreen        *screen,
-                              gint32           *image_ID)
+screenshot_gnome_shell_shoot (ScreenshotValues  *shootvals,
+                              GdkScreen         *screen,
+                              gint32            *image_ID,
+                              GError           **error)
 {
   gchar       *filename;
   const gchar *method = NULL;
@@ -85,7 +103,10 @@ screenshot_gnome_shell_shoot (ScreenshotValues *shootvals,
     case SHOOT_REGION:
       retval = g_dbus_proxy_call_sync (proxy, "SelectArea", NULL,
                                        G_DBUS_CALL_FLAGS_NONE,
-                                       -1, NULL, NULL);
+                                       -1, NULL, error);
+      if (! retval)
+        goto failure;
+
       g_variant_get (retval, "(iiii)",
                      &shootvals->x1,
                      &shootvals->y1,
@@ -120,7 +141,9 @@ screenshot_gnome_shell_shoot (ScreenshotValues *shootvals,
 
   retval = g_dbus_proxy_call_sync (proxy, method, args,
                                    G_DBUS_CALL_FLAGS_NONE,
-                                   -1, NULL, NULL);
+                                   -1, NULL, error);
+  if (! retval)
+    goto failure;
 
   g_variant_get (retval, "(bs)",
                  &success,
@@ -143,6 +166,8 @@ screenshot_gnome_shell_shoot (ScreenshotValues *shootvals,
       return GIMP_PDB_SUCCESS;
     }
 
+ failure:
+
   g_free (filename);
 
   g_object_unref (proxy);
diff --git a/plug-ins/screenshot/screenshot-gnome-shell.h b/plug-ins/screenshot/screenshot-gnome-shell.h
index f9c7746..6cb1bcc 100644
--- a/plug-ins/screenshot/screenshot-gnome-shell.h
+++ b/plug-ins/screenshot/screenshot-gnome-shell.h
@@ -23,9 +23,10 @@ gboolean               screenshot_gnome_shell_available        (void);
 
 ScreenshotCapabilities screenshot_gnome_shell_get_capabilities (void);
 
-GimpPDBStatusType      screenshot_gnome_shell_shoot            (ScreenshotValues *shootvals,
-                                                                GdkScreen        *screen,
-                                                                gint32           *image_ID);
+GimpPDBStatusType      screenshot_gnome_shell_shoot            (ScreenshotValues  *shootvals,
+                                                                GdkScreen         *screen,
+                                                                gint32            *image_ID,
+                                                                GError           **error);
 
 
 #endif /* __SCREENSHOT_GNOME_SHELL_H__ */
diff --git a/plug-ins/screenshot/screenshot-osx.c b/plug-ins/screenshot/screenshot-osx.c
index 8fdecd0..f6836c4 100644
--- a/plug-ins/screenshot/screenshot-osx.c
+++ b/plug-ins/screenshot/screenshot-osx.c
@@ -70,9 +70,10 @@ screenshot_osx_get_capabilities (void)
 }
 
 GimpPDBStatusType
-screenshot_osx_shoot (ScreenshotValues *shootvals,
-                      GdkScreen        *screen,
-                      gint32           *image_ID)
+screenshot_osx_shoot (ScreenshotValues  *shootvals,
+                      GdkScreen         *screen,
+                      gint32            *image_ID,
+                      GError           **error)
 {
   const gchar *mode    = " ";
   const gchar *cursor  = " ";
@@ -107,7 +108,6 @@ screenshot_osx_shoot (ScreenshotValues *shootvals,
 
   delay = g_strdup_printf ("-T %i", shootvals->select_delay);
 
-
   filename = gimp_temp_name ("png");
   quoted   = g_shell_quote (filename);
 
diff --git a/plug-ins/screenshot/screenshot-osx.h b/plug-ins/screenshot/screenshot-osx.h
index a97414d..9ee378f 100644
--- a/plug-ins/screenshot/screenshot-osx.h
+++ b/plug-ins/screenshot/screenshot-osx.h
@@ -25,9 +25,10 @@ gboolean               screenshot_osx_available        (void);
 
 ScreenshotCapabilities screenshot_osx_get_capabilities (void);
 
-GimpPDBStatusType      screenshot_osx_shoot            (ScreenshotValues *shootvals,
-                                                        GdkScreen        *screen,
-                                                        gint32           *image_ID);
+GimpPDBStatusType      screenshot_osx_shoot            (ScreenshotValues  *shootvals,
+                                                        GdkScreen         *screen,
+                                                        gint32            *image_ID,
+                                                        GError           **error);
 
 #endif /* PLATFORM_OSX */
 
diff --git a/plug-ins/screenshot/screenshot-x11.c b/plug-ins/screenshot/screenshot-x11.c
index 1090b9c..f889762 100644
--- a/plug-ins/screenshot/screenshot-x11.c
+++ b/plug-ins/screenshot/screenshot-x11.c
@@ -560,9 +560,10 @@ screenshot_x11_get_capabilities (void)
 }
 
 GimpPDBStatusType
-screenshot_x11_shoot (ScreenshotValues *shootvals,
-                      GdkScreen        *screen,
-                      gint32           *image_ID)
+screenshot_x11_shoot (ScreenshotValues  *shootvals,
+                      GdkScreen         *screen,
+                      gint32            *image_ID,
+                      GError           **error)
 {
   GdkDisplay      *display;
   GdkWindow       *window;
@@ -619,7 +620,7 @@ screenshot_x11_shoot (ScreenshotValues *shootvals,
 
       if (! window)
         {
-          g_message (_("Specified window not found"));
+          g_set_error_literal (error, 0, 0, _("Specified window not found"));
           return GIMP_PDB_EXECUTION_ERROR;
         }
 
diff --git a/plug-ins/screenshot/screenshot-x11.h b/plug-ins/screenshot/screenshot-x11.h
index 72b5169..fd3d0db 100644
--- a/plug-ins/screenshot/screenshot-x11.h
+++ b/plug-ins/screenshot/screenshot-x11.h
@@ -25,9 +25,10 @@ gboolean               screenshot_x11_available        (void);
 
 ScreenshotCapabilities screenshot_x11_get_capabilities (void);
 
-GimpPDBStatusType      screenshot_x11_shoot            (ScreenshotValues *shootvals,
-                                                        GdkScreen        *screen,
-                                                        gint32           *image_ID);
+GimpPDBStatusType      screenshot_x11_shoot            (ScreenshotValues  *shootvals,
+                                                        GdkScreen         *screen,
+                                                        gint32            *image_ID,
+                                                        GError           **error);
 
 #endif /* GDK_WINDOWING_X11 */
 
diff --git a/plug-ins/screenshot/screenshot.c b/plug-ins/screenshot/screenshot.c
index a416644..3ecd8d3 100644
--- a/plug-ins/screenshot/screenshot.c
+++ b/plug-ins/screenshot/screenshot.c
@@ -138,7 +138,8 @@ static void                run                 (const gchar      *name,
                                                 GimpParam       **return_vals);
 
 static GimpPDBStatusType   shoot               (GdkScreen        *screen,
-                                                gint32           *image_ID);
+                                                gint32           *image_ID,
+                                                GError          **error);
 
 static gboolean            shoot_dialog        (GdkScreen       **screen);
 static gboolean            shoot_quit_timeout  (gpointer          data);
@@ -241,10 +242,11 @@ run (const gchar      *name,
      GimpParam       **return_vals)
 {
   static GimpParam   values[2];
-  GimpPDBStatusType  status   = GIMP_PDB_SUCCESS;
+  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
   GimpRunMode        run_mode;
-  GdkScreen         *screen   = NULL;
+  GdkScreen         *screen = NULL;
   gint32             image_ID;
+  GError            *error  = NULL;
 
   INIT_I18N ();
   gegl_init (NULL, NULL);
@@ -338,7 +340,7 @@ run (const gchar      *name,
 
   if (status == GIMP_PDB_SUCCESS)
     {
-      status = shoot (screen, &image_ID);
+      status = shoot (screen, &image_ID, &error);
     }
 
   if (status == GIMP_PDB_SUCCESS)
@@ -358,13 +360,19 @@ run (const gchar      *name,
             }
         }
 
-      /* set return values */
       *nreturn_vals = 2;
 
       values[1].type         = GIMP_PDB_IMAGE;
       values[1].data.d_image = image_ID;
     }
 
+  if (status != GIMP_PDB_SUCCESS && error)
+    {
+      *nreturn_vals = 2;
+      values[1].type          = GIMP_PDB_STRING;
+      values[1].data.d_string = error->message;
+    }
+
   values[0].data.d_status = status;
 }
 
@@ -372,20 +380,21 @@ run (const gchar      *name,
 /* The main Screenshot function */
 
 static GimpPDBStatusType
-shoot (GdkScreen *screen,
-       gint32    *image_ID)
+shoot (GdkScreen  *screen,
+       gint32     *image_ID,
+       GError    **error)
 {
 #ifdef PLATFORM_OSX
   if (backend == SCREENSHOT_BACKEND_OSX)
-    return screenshot_osx_shoot (&shootvals, screen, image_ID);
+    return screenshot_osx_shoot (&shootvals, screen, image_ID, error);
 #endif
 
   if (backend == SCREENSHOT_BACKEND_GNOME_SHELL)
-    return screenshot_gnome_shell_shoot (&shootvals, screen, image_ID);
+    return screenshot_gnome_shell_shoot (&shootvals, screen, image_ID, error);
 
 #ifdef GDK_WINDOWING_X11
   if (backend == SCREENSHOT_BACKEND_X11)
-    return screenshot_x11_shoot (&shootvals, screen, image_ID);
+    return screenshot_x11_shoot (&shootvals, screen, image_ID, error);
 #endif
 
   return GIMP_PDB_CALLING_ERROR; /* silence compiler */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]