[Xfce4-commits] <midori:master> Rework sokoke_spawn_command internals

Christian Dywan noreply at xfce.org
Sun Jul 1 21:28:02 CEST 2012


Updating branch refs/heads/master
         to aa1ffbf1d00567ee33b8968bab227734cdd685c0 (commit)
       from 262ded52222620891b2b37fa9ffcdc95b79edefd (commit)

commit aa1ffbf1d00567ee33b8968bab227734cdd685c0
Author: Christian Dywan <christian at twotoasts.de>
Date:   Sun Jul 1 21:21:01 2012 +0200

    Rework sokoke_spawn_command internals
    
    Caller decides if the command and the argument are quoted,
    otherwise quoting only affects %s. The actual quoting is
    split to allow use in test cases.
    
    The Hildon version was dropped.
    The GAppInfo version was dropped.
    A test case with a cuple examples was added.

 extensions/addons.c     |    2 +-
 midori/midori-browser.c |    6 +-
 midori/sokoke.c         |  201 ++++++++++++++++++++++------------------------
 midori/sokoke.h         |   10 ++-
 tests/magic-uri.c       |   44 ++++++++++
 5 files changed, 153 insertions(+), 110 deletions(-)

diff --git a/extensions/addons.c b/extensions/addons.c
index 6051627..ad705a1 100644
--- a/extensions/addons.c
+++ b/extensions/addons.c
@@ -491,7 +491,7 @@ addons_open_in_editor_clicked_cb (GtkWidget* toolitem,
 
         g_object_get (settings, "text-editor", &text_editor, NULL);
         if (text_editor && *text_editor)
-            sokoke_spawn_program (text_editor, element->fullpath);
+            sokoke_spawn_program (text_editor, TRUE, element->fullpath, TRUE);
         else
         {
             gchar* element_uri = g_filename_to_uri (element->fullpath, NULL, NULL);
diff --git a/midori/midori-browser.c b/midori/midori-browser.c
index 7c61e5a..4554470 100644
--- a/midori/midori-browser.c
+++ b/midori/midori-browser.c
@@ -2495,9 +2495,9 @@ midori_browser_subscribe_to_news_feed (MidoriBrowser* browser,
         /* Special-case Liferea because a helper script may be required */
         if (g_str_equal (browser->news_aggregator, "liferea")
          && g_find_program_in_path ("liferea-add-feed"))
-            sokoke_spawn_program ("liferea-add-feed", feed);
+            sokoke_spawn_program ("liferea-add-feed", FALSE, feed, TRUE);
         else
-            sokoke_spawn_program (browser->news_aggregator, feed);
+            sokoke_spawn_program (browser->news_aggregator, TRUE, feed, TRUE);
         g_free (feed);
     }
     else
@@ -3483,7 +3483,7 @@ _action_source_view_activate (GtkAction*     action,
     }
     else
     {
-        sokoke_spawn_program (text_editor, filename);
+        sokoke_spawn_program (text_editor, TRUE, filename, TRUE);
         g_free (filename);
     }
     g_free (text_editor);
diff --git a/midori/sokoke.c b/midori/sokoke.c
index c87c3c8..ab04352 100644
--- a/midori/sokoke.c
+++ b/midori/sokoke.c
@@ -228,7 +228,7 @@ sokoke_open_with_response_cb (GtkWidget* dialog,
     {
         const gchar* command = gtk_entry_get_text (entry);
         const gchar* uri = g_object_get_data (G_OBJECT (dialog), "uri");
-        sokoke_spawn_program (command, uri);
+        sokoke_spawn_program (command, FALSE, uri, TRUE);
     }
     gtk_widget_destroy (dialog);
 }
@@ -379,117 +379,112 @@ sokoke_show_uri (GdkScreen*   screen,
     #endif
 }
 
-gboolean
-sokoke_spawn_program (const gchar* command,
-                      const gchar* argument)
+/**
+ * sokoke_prepare_command:
+ * @command: the command, properly quoted
+ * @argument: any arguments, properly quoted
+ * @quote_command: if %TRUE, @command will be quoted
+ * @quote_argument: if %TRUE, @argument will be quoted, ie. a URI or filename
+ *
+ * If @command contains %s, @argument will be quoted and inserted into
+ * @command, which is left unquoted regardless of @quote_command.
+ *
+ * Return value: the command prepared for spawning
+ **/
+gchar*
+sokoke_prepare_command (const gchar* command,
+                        gboolean     quote_command,
+                        const gchar* argument,
+                        gboolean     quote_argument)
 {
-    GError* error;
-
     g_return_val_if_fail (command != NULL, FALSE);
     g_return_val_if_fail (argument != NULL, FALSE);
 
-    if (!g_strstr_len (argument, 8, "://")
-     && !g_str_has_prefix (argument, "about:"))
-    {
-        gboolean success;
-
-        #if HAVE_HILDON
-        osso_context_t* osso;
-        DBusConnection* dbus;
+    g_print ("Preparing command: %s %d %s %d\n",
+             command, quote_command, argument, quote_argument);
 
-        osso = osso_initialize (PACKAGE_NAME, PACKAGE_VERSION, FALSE, NULL);
-        if (!osso)
-        {
-            sokoke_message_dialog (GTK_MESSAGE_ERROR,
-                                   _("Could not run external program."),
-                                   "Failed to initialize libosso", FALSE);
-            return FALSE;
-        }
-
-        dbus = (DBusConnection *) osso_get_dbus_connection (osso);
-        if (!dbus)
-        {
-            osso_deinitialize (osso);
-            sokoke_message_dialog (GTK_MESSAGE_ERROR,
-                                   _("Could not run external program."),
-                                   "Failed to get dbus connection from osso context", FALSE);
-            return FALSE;
-        }
-
-        error = NULL;
-        /* FIXME: This is not correct, find a proper way to do this */
-        success = (osso_application_top (osso, command, argument) == OSSO_OK);
-        osso_deinitialize (osso);
-        #else
-        GAppInfo* info;
-        GFile* file;
-        GList* files;
-
-        info = g_app_info_create_from_commandline (command,
-            NULL, G_APP_INFO_CREATE_NONE, NULL);
-        file = g_file_new_for_commandline_arg (argument);
-        files = g_list_append (NULL, file);
-
-        error = NULL;
-        success = g_app_info_launch (info, files, NULL, &error);
-        g_object_unref (file);
-        g_list_free (files);
-        #endif
-
-        if (!success)
-        {
-            sokoke_message_dialog (GTK_MESSAGE_ERROR,
-                _("Could not run external program."),
-                error ? error->message : "", FALSE);
-            if (error)
-                g_error_free (error);
-            return FALSE;
-        }
-    }
-    else
     {
-        /* FIXME: Implement Hildon specific version */
         gchar* uri_format;
-        gchar* argument_quoted;
+        gchar* real_command;
         gchar* command_ready;
-        gchar** argv;
 
+        /* .desktop files accept %u as URI, we cheap and treat it like %s */
         if ((uri_format = strstr (command, "%u")))
             uri_format[1] = 's';
 
-        argument_quoted = g_shell_quote (argument);
-        if (strstr (command, "%s"))
-            command_ready = g_strdup_printf (command, argument_quoted);
-        else
-            command_ready = g_strconcat (command, " ", argument_quoted, NULL);
-        g_free (argument_quoted);
+        real_command = quote_command ? g_shell_quote (command) : g_strdup (command);
 
-        error = NULL;
-        if (!g_shell_parse_argv (command_ready, NULL, &argv, &error))
+        if (strstr (command, "%s"))
         {
-            sokoke_message_dialog (GTK_MESSAGE_ERROR,
-                                   _("Could not run external program."),
-                                   error->message, FALSE);
-            g_error_free (error);
-            g_free (command_ready);
-            return FALSE;
+            gchar* argument_quoted = g_shell_quote (argument);
+            command_ready = sokoke_replace_variables (real_command, "%s", argument_quoted);
+            g_free (argument_quoted);
         }
-        g_free (command_ready);
-
-        error = NULL;
-        if (!g_spawn_async (NULL, argv, NULL,
-            (GSpawnFlags)G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-            NULL, NULL, NULL, &error))
+        else if (quote_argument)
         {
-            sokoke_message_dialog (GTK_MESSAGE_ERROR,
-                                   _("Could not run external program."),
-                                   error->message, FALSE);
-            g_error_free (error);
+            gchar* argument_quoted = g_shell_quote (argument);
+            command_ready = g_strconcat (real_command, " ", argument_quoted, NULL);
+            g_free (argument_quoted);
         }
+        else
+            command_ready = g_strconcat (real_command, " ", argument, NULL);
+        g_free (real_command);
+        return command_ready;
+    }
+}
 
-        g_strfreev (argv);
+/**
+ * sokoke_spawn_program:
+ * @command: the command, properly quoted
+ * @argument: any arguments, properly quoted
+ * @quote_command: if %TRUE, @command will be quoted
+ * @quote_argument: if %TRUE, @argument will be quoted, ie. a URI or filename
+ *
+ * If @command contains %s, @argument will be quoted and inserted into
+ * @command, which is left unquoted regardless of @quote_command.
+ *
+ * Return value: %TRUE on success, %FALSE if an error occurred
+ **/
+gboolean
+sokoke_spawn_program (const gchar* command,
+                      gboolean     quote_command,
+                      const gchar* argument,
+                      gboolean     quote_argument)
+{
+    GError* error;
+    gchar* command_ready;
+    gchar** argv;
+
+    g_return_val_if_fail (command != NULL, FALSE);
+    g_return_val_if_fail (argument != NULL, FALSE);
+
+    command_ready = sokoke_prepare_command (command, quote_command, argument, quote_argument);
+    g_print ("Launching command: %s\n", command_ready);
+
+    error = NULL;
+    if (!g_shell_parse_argv (command_ready, NULL, &argv, &error))
+    {
+        sokoke_message_dialog (GTK_MESSAGE_ERROR,
+                               _("Could not run external program."),
+                               error->message, FALSE);
+        g_error_free (error);
+        g_free (command_ready);
+        return FALSE;
+    }
+    g_free (command_ready);
+
+    error = NULL;
+    if (!g_spawn_async (NULL, argv, NULL,
+        (GSpawnFlags)G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+        NULL, NULL, NULL, &error))
+    {
+        sokoke_message_dialog (GTK_MESSAGE_ERROR,
+                               _("Could not run external program."),
+                               error->message, FALSE);
+        g_error_free (error);
     }
 
+    g_strfreev (argv);
     return TRUE;
 }
 
@@ -498,23 +493,19 @@ sokoke_spawn_app (const gchar* uri,
                   gboolean     private)
 {
     const gchar* executable = midori_app_get_command_line ()[0];
-    /* "midori"
-       "/usr/bin/midori"
-       "c:/Program Files/Midori/bin/midori.exe" */
-    gchar* quoted = g_shell_quote (executable);
-    gchar* command;
+    gchar* uri_quoted = g_shell_quote (uri);
+    gchar* argument;
     if (private)
     {
-        gchar* quoted_config = g_shell_quote (sokoke_set_config_dir (NULL));
-        command = g_strconcat (quoted, " -c ", quoted_config,
-                                       " -p", NULL);
-        g_free (quoted_config);
+        gchar* config_quoted = g_shell_quote (sokoke_set_config_dir (NULL));
+        argument = g_strconcat ("-c ", config_quoted,
+                                " -p ", uri_quoted, NULL);
     }
     else
-        command = g_strconcat (quoted, " -a", NULL);
-    g_free (quoted);
-    sokoke_spawn_program (command, uri);
-    g_free (command);
+        argument = g_strconcat ("-a ", uri_quoted, NULL);
+    g_free (uri_quoted);
+    sokoke_spawn_program (executable, TRUE, argument, FALSE);
+    g_free (argument);
 }
 
 static void
diff --git a/midori/sokoke.h b/midori/sokoke.h
index 375d815..488a225 100644
--- a/midori/sokoke.h
+++ b/midori/sokoke.h
@@ -42,9 +42,17 @@ sokoke_show_uri                         (GdkScreen*      screen,
                                          guint32         timestamp,
                                          GError**        error);
 
+gchar*
+sokoke_prepare_command                  (const gchar*    command,
+                                         gboolean        quote_command,
+                                         const gchar*    argument,
+                                         gboolean        quote_argument);
+
 gboolean
 sokoke_spawn_program                    (const gchar* command,
-                                         const gchar* argument);
+                                         gboolean        quote_command,
+                                         const gchar*    argument,
+                                         gboolean        quote_argument);
 
 void
 sokoke_spawn_app                        (const gchar*    uri,
diff --git a/tests/magic-uri.c b/tests/magic-uri.c
index f06a8b3..8a3a73c 100644
--- a/tests/magic-uri.c
+++ b/tests/magic-uri.c
@@ -287,6 +287,49 @@ magic_uri_prefetch (void)
     g_assert (!sokoke_prefetch_uri (NULL, "javascript: alert()", NULL, NULL));
 }
 
+static void
+magic_uri_commands (void)
+{
+    typedef struct
+    {
+        const gchar* command;
+        gboolean quote;
+        const gchar* expected;
+    } CommandItem;
+
+    static const CommandItem commands[] = {
+        { "midori", TRUE, NULL },
+        { "/usr/bin/midori", TRUE, NULL },
+        { "C:/Program Files/Midori/bin/midori.exe", TRUE, NULL },
+        { "C:/Programme/Midori/bin/midori.exe", TRUE, NULL },
+    };
+    static const CommandItem arguments[] = {
+        { "-a 'http://lunduke.com/?p=3606'", FALSE, NULL },
+        { "about:private", FALSE, NULL },
+    };
+    guint i, j;
+
+    for (i = 0; i < G_N_ELEMENTS (commands); i++)
+        for (j = 0; j < G_N_ELEMENTS (arguments); j++)
+        {
+            gchar* input = g_strconcat (commands[i].command, " ", arguments[j].command, NULL);
+            gchar* ce = commands[i].expected ? commands[i].expected
+             : g_strconcat ("'", commands[i].command, "'", NULL);
+            gchar* ae = arguments[j].expected ? arguments[j].expected
+              : (arguments[j].quote ? g_strconcat ("'", arguments[j].command, "'", NULL)
+              : g_strdup (arguments[j].command));
+            gchar* expected = g_strconcat (ce, " ", ae, NULL);
+            gchar* result = sokoke_prepare_command (commands[i].command,
+                commands[i].quote, arguments[j].command, arguments[j].quote);
+            katze_assert_str_equal (input, result, expected);
+            g_free (input);
+            g_free (ce);
+            g_free (ae);
+            g_free (expected);
+            g_free (result);
+        }
+}
+
 int
 main (int    argc,
       char** argv)
@@ -303,6 +346,7 @@ main (int    argc,
     g_test_add_func ("/magic-uri/fingerprint", magic_uri_fingerprint);
     g_test_add_func ("/magic-uri/format", magic_uri_format);
     g_test_add_func ("/magic-uri/prefetch", magic_uri_prefetch);
+    g_test_add_func ("/magic-uri/commands", magic_uri_commands);
 
     return g_test_run ();
 }


More information about the Xfce4-commits mailing list