diff --git a/libview/ev-print-operation.c b/libview/ev-print-operation.c index 663026b1..dae5d450 100644 --- a/libview/ev-print-operation.c +++ b/libview/ev-print-operation.c @@ -851,33 +851,27 @@ export_print_done (EvPrintOperationExport *export) g_key_file_free (key_file); if (!error) { - GAppInfo *app; - GdkAppLaunchContext *ctx; - gchar *cmd; - gchar *quoted_filename; - gchar *quoted_settings_filename; - - quoted_filename = g_shell_quote (export->temp_file); - quoted_settings_filename = g_shell_quote (print_settings_file); - cmd = g_strdup_printf ("xreader-previewer --unlink-tempfile --print-settings %s %s", - quoted_settings_filename, quoted_filename); - - g_free (quoted_filename); - g_free (quoted_settings_filename); - - app = g_app_info_create_from_commandline (cmd, NULL, 0, &error); - - if (app != NULL) { - ctx = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (export->parent_window))); - gdk_app_launch_context_set_screen (ctx, gtk_window_get_screen (export->parent_window)); - - g_app_info_launch (app, NULL, G_APP_LAUNCH_CONTEXT (ctx), &error); - - g_object_unref (app); - g_object_unref (ctx); - } - - g_free (cmd); + /* Use g_spawn_async with an explicit argv array rather than + * g_app_info_create_from_commandline(). The latter parses a + * command-line string and re-splits it, which is fragile if any + * argument contains whitespace or quoting-special characters. + * With argv, each element is passed verbatim to the child. + * + * The spawned previewer inherits the parent's environment + * (including DISPLAY/Wayland socket), so no explicit launch + * context is required. + */ + gchar *argv[] = { + (gchar *) "xreader-previewer", + (gchar *) "--unlink-tempfile", + (gchar *) "--print-settings", + print_settings_file, + export->temp_file, + NULL + }; + + g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, &error); } if (error) { diff --git a/shell/main.c b/shell/main.c index bc5f96fc..0562cba5 100644 --- a/shell/main.c +++ b/shell/main.c @@ -80,56 +80,53 @@ static const GOptionEntry goption_options[] = static gboolean launch_previewer (void) { - GString *cmd_str; - gchar *cmd; + gchar **argv; + gint argc; gboolean retval = FALSE; GError *error = NULL; /* Rebuild the command line, ignoring options * not supported by the previewer and taking only - * the first path given + * the first path given. + * + * Use g_spawn_async() with an explicit argv[] array rather than + * g_app_info_create_from_commandline() so each argument is passed + * verbatim to the child. print_settings and file_arguments come from + * the xreader command line itself; even if g_shell_quote() is applied + * defensively, going through the commandline-string parser is fragile + * and mirrors the pattern recently patched in ev_spawn (50052ea). */ - cmd_str = g_string_new ("xreader-previewer"); - + argc = 1; + if (print_settings) argc += 2; + if (unlink_temp_file) argc += 1; + if (file_arguments) argc += 1; + argc += 1; /* trailing NULL */ + + argv = g_new0 (gchar *, argc); + argc = 0; + argv[argc++] = (gchar *) "xreader-previewer"; if (print_settings) { - gchar *quoted; - - quoted = g_shell_quote (print_settings); - g_string_append_printf (cmd_str, " --print-settings %s", quoted); - g_free (quoted); + argv[argc++] = (gchar *) "--print-settings"; + argv[argc++] = print_settings; } - if (unlink_temp_file) - g_string_append (cmd_str, " --unlink-tempfile"); - - if (file_arguments) { - gchar *quoted; - - quoted = g_shell_quote (file_arguments[0]); - g_string_append_printf (cmd_str, " %s", quoted); - g_free (quoted); + argv[argc++] = (gchar *) "--unlink-tempfile"; + if (file_arguments) + argv[argc++] = file_arguments[0]; + argv[argc] = NULL; + + if (g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, &error)) { + retval = TRUE; } - cmd = g_string_free (cmd_str, FALSE); - - if (!error) { - GAppInfo *app; - - app = g_app_info_create_from_commandline (cmd, NULL, 0, &error); - - if (app != NULL) { - retval = g_app_info_launch (app, NULL, NULL, &error); - g_object_unref (app); - } - } + g_free (argv); if (error) { g_warning ("Error launching previewer: %s\n", error->message); g_error_free (error); } - g_free (cmd); - return retval; }