g_app_info_launch_default_for_uri: don't use GFile if we don't have to
authorDan Winship <danw@gnome.org>
Fri, 18 May 2012 12:49:05 +0000 (08:49 -0400)
committerDan Winship <danw@gnome.org>
Fri, 18 May 2012 16:17:28 +0000 (12:17 -0400)
GFile doesn't handle some "real" URIs, so check if there's a default
handler for the URI scheme first, and only use g_file_new_for_uri()
and g_file_query_default_handler() if not. Eg, this fixes the case of
opening http URIs with "%2F" in the path.

https://bugzilla.gnome.org/show_bug.cgi?id=666386

gio/gappinfo.c

index 53d3c39..d18a30f 100644 (file)
@@ -683,21 +683,37 @@ g_app_info_launch_default_for_uri (const char         *uri,
                                   GAppLaunchContext  *launch_context,
                                   GError            **error)
 {
+  char *uri_scheme;
   GAppInfo *app_info;
-  GFile *file;
   GList l;
   gboolean res;
 
-  file = g_file_new_for_uri (uri);
-  app_info = g_file_query_default_handler (file, NULL, error);
-  g_object_unref (file);
-  if (app_info == NULL)
-    return FALSE;
-
-  /* Use the uri, not the GFile, as the GFile roundtrip may
-   * affect the uri which we don't want (for instance for a
-   * mailto: uri).
+  /* g_file_query_default_handler() calls
+   * g_app_info_get_default_for_uri_scheme() too, but we have to do it
+   * here anyway in case GFile can't parse @uri correctly.
    */
+  uri_scheme = g_uri_parse_scheme (uri);
+  if (uri_scheme && uri_scheme[0] != '\0')
+    app_info = g_app_info_get_default_for_uri_scheme (uri_scheme);
+  g_free (uri_scheme);
+
+  if (!app_info)
+    {
+      GFile *file;
+
+      file = g_file_new_for_uri (uri);
+      app_info = g_file_query_default_handler (file, NULL, error);
+      g_object_unref (file);
+      if (app_info == NULL)
+       return FALSE;
+
+      /* We still use the original @uri rather than calling
+       * g_file_get_uri(), because GFile might have modified the URI
+       * in ways we don't want (eg, removing the fragment identifier
+       * from a file: URI).
+       */
+    }
+
   l.data = (char *)uri;
   l.next = l.prev = NULL;
   res = g_app_info_launch_uris (app_info, &l,