149 lines
4.2 KiB
Diff
149 lines
4.2 KiB
Diff
From e5594f96468bf737bb90fee92a26f20837b614d5 Mon Sep 17 00:00:00 2001
|
|
From: Nelson Benítez León <nbenitezl@gmail.com>
|
|
Date: Sun, 30 Jan 2022 21:37:07 -0400
|
|
Subject: pdf: let launch action to open pdfs from click event
|
|
|
|
Issue #1333 removed Evince ability to run any command
|
|
from pdf 'launch action', while the security concerns
|
|
brought up in #1333 were valid, the measure implemented
|
|
was maybe too drastic, as there are valid use cases
|
|
where launching a pdf is needed.
|
|
|
|
For instance, the cases described in issue #48, one of
|
|
them is the document 'Nissan Patrol Maintenance Manual'
|
|
which is comprised of several pdf files, where there is
|
|
one acting as index for the others, this index pdf file
|
|
uses the launch action to open the other pdf's.
|
|
|
|
So this commit allows to launch a file from a link
|
|
action only when:
|
|
|
|
- that file is a pdf file.
|
|
- the launch action originates from click event,
|
|
to be sure the user requested the action.
|
|
|
|
Besides, we don't just let the system execute the
|
|
file, but because it's a pdf we do it ourselves by
|
|
launching a new evince instance (or if that file was
|
|
already opened then presenting its window).
|
|
|
|
Fixes issue #48
|
|
|
|
Modified by Marek Kasik to not change API when merging this to CentOS!
|
|
|
|
diff --git a/shell/ev-window.c b/shell/ev-window.c
|
|
index 921be7de..88d770e8 100644
|
|
--- a/shell/ev-window.c
|
|
+++ b/shell/ev-window.c
|
|
@@ -6636,12 +6636,106 @@ window_configure_event_cb (EvWindow *window, GdkEventConfigure *event, gpointer
|
|
return FALSE;
|
|
}
|
|
|
|
+static gchar *
|
|
+get_uri (const char *filename, EvWindow *window)
|
|
+{
|
|
+ EvWindowPrivate *priv = GET_PRIVATE (window);
|
|
+ gchar *ret;
|
|
+
|
|
+ if (g_path_is_absolute (filename)) {
|
|
+ ret = g_strdup (filename);
|
|
+ } else {
|
|
+ GFile *base_file, *file;
|
|
+ gchar *dir;
|
|
+
|
|
+ dir = g_path_get_dirname (priv->uri);
|
|
+ base_file = g_file_new_for_uri (dir);
|
|
+ file = g_file_resolve_relative_path (base_file, filename);
|
|
+ ret = g_file_get_uri (file);
|
|
+
|
|
+ g_free (dir);
|
|
+ g_object_unref (base_file);
|
|
+ g_object_unref (file);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+file_is_pdf (const char *uri)
|
|
+{
|
|
+ GFile *file;
|
|
+ GFileInfo *file_info;
|
|
+ gboolean ret = FALSE;
|
|
+
|
|
+ file = g_file_new_for_uri (uri);
|
|
+ file_info = g_file_query_info (file,
|
|
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
|
+ G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
|
+ if (file_info != NULL) {
|
|
+ const gchar *content_type;
|
|
+ content_type = g_file_info_get_content_type (file_info);
|
|
+ if (content_type) {
|
|
+ gchar *mime_type;
|
|
+ mime_type = g_content_type_get_mime_type (content_type);
|
|
+ if (g_ascii_strcasecmp (mime_type, "application/pdf") == 0)
|
|
+ ret = TRUE;
|
|
+ g_free (mime_type);
|
|
+ }
|
|
+ g_object_unref (file_info);
|
|
+ }
|
|
+ g_object_unref (file);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+current_event_is_type (EvView *view, GdkEventType type)
|
|
+{
|
|
+ GdkEvent *event;
|
|
+ gboolean ret = FALSE;
|
|
+
|
|
+ event = gtk_get_current_event ();
|
|
+ if (event) {
|
|
+ if (event->type == type &&
|
|
+ gdk_event_get_window (event) == gtk_widget_get_window (GTK_WIDGET (view))) {
|
|
+ ret = TRUE;
|
|
+ }
|
|
+ gdk_event_free (event);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static void
|
|
-launch_action (EvWindow *window, EvLinkAction *action)
|
|
+launch_action (EvWindow *ev_window, EvLinkAction *action)
|
|
{
|
|
- ev_window_warning_message (window,
|
|
- _("Security alert: this document has been prevented from opening the file “%s”"),
|
|
- ev_link_action_get_filename (action));
|
|
+ EvView *view;
|
|
+ EvWindowPrivate *priv = GET_PRIVATE (ev_window);
|
|
+ const char *filename = ev_link_action_get_filename (action);
|
|
+ gchar *uri;
|
|
+
|
|
+ if (filename == NULL)
|
|
+ return;
|
|
+
|
|
+ uri = get_uri (filename, ev_window);
|
|
+ view = EV_VIEW (priv->view);
|
|
+
|
|
+ if (!file_is_pdf (uri) || !current_event_is_type (view, GDK_BUTTON_RELEASE)) {
|
|
+ ev_window_warning_message (ev_window,
|
|
+ _("Security alert: this document has been prevented from opening the file “%s”"),
|
|
+ filename);
|
|
+ g_free (uri);
|
|
+ return;
|
|
+ }
|
|
+ /* We are asked to open a PDF file, from a click event, proceed with that - Issue #48
|
|
+ * This spawns new Evince process or if already opened presents its window */
|
|
+ ev_application_open_uri_at_dest (EV_APP, uri,
|
|
+ gtk_window_get_screen (GTK_WINDOW (ev_window)),
|
|
+ ev_link_action_get_dest (action),
|
|
+ priv->window_mode, NULL,
|
|
+ gtk_get_current_event_time ());
|
|
+ g_free (uri);
|
|
+
|
|
}
|
|
|
|
static void
|