0.9.6claws78
[claws.git] / src / textview.c
index 53a53bdca44ff62b7fd30d861dd6e2de0b2b7bb0..d96ca911c74d58c9cf16e5db4cf263f3301ff42b 100644 (file)
@@ -51,6 +51,7 @@
 #include "displayheader.h"
 #include "account.h"
 #include "mimeview.h"
+#include "alertpanel.h"
 
 typedef struct _RemoteURI      RemoteURI;
 
@@ -503,7 +504,7 @@ static void recursive_add_parts(TextView *textview, GNode *node)
                 
                 /*
                   text/plain : score 3
-                  text/    : score 2
+                  text/ *    : score 2
                   other      : score 1
                 */
                 prefered_body = NULL;
@@ -1314,6 +1315,21 @@ void textview_set_font(TextView *textview, const gchar *codeset)
                spacingfont = gdk_font_load("-*-*-medium-r-normal--6-*");
 }
 
+void textview_set_text(TextView *textview, const gchar *text)
+{
+       GtkSText *stext;
+
+       g_return_if_fail(textview != NULL);
+       g_return_if_fail(text != NULL);
+
+       textview_clear(textview);
+
+       stext = GTK_STEXT(textview->text);
+       gtk_stext_freeze(stext);
+       gtk_stext_insert(stext, textview->msgfont, NULL, NULL, text, strlen(text));
+       gtk_stext_thaw(stext);
+}
+
 enum
 {
        H_DATE          = 0,
@@ -1735,17 +1751,16 @@ static gint textview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                if (summaryview)
                        summary_pass_key_press_event(summaryview, event);
                break;
-       case GDK_n:
-       case GDK_N:
-       case GDK_p:
-       case GDK_P:
        case GDK_y:
        case GDK_t:
        case GDK_l:
-               KEY_PRESS_EVENT_STOP();
-               mimeview_pass_key_press_event(messageview->mimeview,
-                                             event);
-               /* fall through */
+               if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) == 0) {
+                       KEY_PRESS_EVENT_STOP();
+                       mimeview_pass_key_press_event(messageview->mimeview,
+                                                     event);
+                       break;
+               }
+               /* possible fall through */
        default:
                if (summaryview &&
                    event->window != messageview->mainwin->window->window) {
@@ -1775,6 +1790,67 @@ static gint show_url_timeout_cb(gpointer data)
                return FALSE;
 }
 
+/*!
+ *\brief    Check to see if a web URL has been disguised as a different
+ *          URL (possible with HTML email).
+ *
+ *\param    uri The uri to check
+ *
+ *\param    textview The TextView the URL is contained in
+ *
+ *\return   gboolean TRUE if the URL is ok, or if the user chose to open
+ *          it anyway, otherwise FALSE          
+ */
+static gboolean uri_security_check(RemoteURI *uri, TextView *textview) 
+{
+       gchar *clicked_str;
+       gboolean retval = TRUE;
+
+       if (g_strncasecmp(uri->uri, "http:", 5) &&
+           g_strncasecmp(uri->uri, "https:", 6) &&
+           g_strncasecmp(uri->uri, "www.", 4)) 
+               return retval;
+
+       clicked_str = gtk_editable_get_chars(GTK_EDITABLE(textview->text),
+                                            uri->start,
+                                            uri->end);
+       
+       if (strcmp(clicked_str, uri->uri) &&
+           (!g_strncasecmp(clicked_str, "http:",  5) ||
+            !g_strncasecmp(clicked_str, "https:", 6) ||
+            !g_strncasecmp(clicked_str, "www.",   4))) {
+               retval = FALSE;
+
+               /* allow uri->uri    == http://somewhere.com
+                  and   clicked_str ==        somewhere.com */
+               gchar *str = g_strconcat("http://", clicked_str, NULL);
+
+               if (!g_strcasecmp(str, uri->uri))
+                       retval = TRUE;
+               g_free(str);
+       }
+
+       if (retval == FALSE) {
+               gchar *msg = NULL;
+               AlertValue resp;
+
+               msg = g_strdup_printf(_("The real URL (%s) is different from\n"
+                                       "the apparent URL (%s).  \n"
+                                       "Open it anyway?"),
+                                       uri->uri, clicked_str);
+               resp = alertpanel(_("Warning"), 
+                                 msg,
+                                 _("Yes"), 
+                                 _("No"),
+                                 NULL);
+               g_free(msg);
+               if (resp == G_ALERTDEFAULT)
+                       retval = TRUE;
+       } 
+       g_free(clicked_str);
+       return retval;
+}
+
 static gint textview_button_pressed(GtkWidget *widget, GdkEventButton *event,
                                    TextView *textview)
 {
@@ -1857,8 +1933,9 @@ static gint textview_button_released(GtkWidget *widget, GdkEventButton *event,
                                                compose_new(account, uri->uri + 7, NULL);
                                        }
                                } else {
-                                       open_uri(uri->uri,
-                                                prefs_common.uri_cmd);
+                                       if (uri_security_check(uri, textview) == TRUE) 
+                                               open_uri(uri->uri,
+                                                        prefs_common.uri_cmd);
                                }
                                g_free(trimmed_uri);
                        }