[gnome-flashback] notifications: fix hyperlinks in body



commit f7cb7b864c40fa6a5b6ee929c1fea88326584d80
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Sat Sep 8 22:53:08 2018 +0300

    notifications: fix hyperlinks in body
    
    We are reporting `body-hyperlinks` capability, but it did not work
    because hyperlinks are not allowed in pango markup. Fix this by
    removing links from markup before using `pango_parse_markup` to
    validate markup.

 gnome-flashback/libnotifications/gf-bubble.c       |   2 +-
 .../libnotifications/nd-notification-box.c         |   2 +-
 gnome-flashback/libnotifications/nd-notification.c | 150 +++++++++++++++++++++
 gnome-flashback/libnotifications/nd-notification.h |   2 +
 4 files changed, 154 insertions(+), 2 deletions(-)
---
diff --git a/gnome-flashback/libnotifications/gf-bubble.c b/gnome-flashback/libnotifications/gf-bubble.c
index f185a6c..4adac80 100644
--- a/gnome-flashback/libnotifications/gf-bubble.c
+++ b/gnome-flashback/libnotifications/gf-bubble.c
@@ -307,7 +307,7 @@ update_bubble (GfBubble *bubble)
 
   body = nd_notification_get_body (priv->notification);
 
-  if (pango_parse_markup (body, -1, 0, NULL, NULL, NULL, NULL))
+  if (validate_markup (body))
     {
       gtk_label_set_markup (GTK_LABEL (priv->body_label), body);
     }
diff --git a/gnome-flashback/libnotifications/nd-notification-box.c 
b/gnome-flashback/libnotifications/nd-notification-box.c
index 7fdda68..36e3703 100644
--- a/gnome-flashback/libnotifications/nd-notification-box.c
+++ b/gnome-flashback/libnotifications/nd-notification-box.c
@@ -219,7 +219,7 @@ update_notification_box (NdNotificationBox *notification_box)
 
         /* body */
         body = nd_notification_get_body (notification_box->priv->notification);
-        if (pango_parse_markup (body, -1, 0, NULL, NULL, NULL, NULL))
+        if (validate_markup (body))
                 gtk_label_set_markup (GTK_LABEL (notification_box->priv->body_label), body);
         else {
                 gchar *tmp;
diff --git a/gnome-flashback/libnotifications/nd-notification.c 
b/gnome-flashback/libnotifications/nd-notification.c
index aec0330..1f960f4 100644
--- a/gnome-flashback/libnotifications/nd-notification.c
+++ b/gnome-flashback/libnotifications/nd-notification.c
@@ -75,6 +75,124 @@ get_next_notification_serial (void)
         return serial;
 }
 
+static void
+start_element_cb (GMarkupParseContext  *context,
+                  const gchar          *element_name,
+                  const gchar         **attribute_names,
+                  const gchar         **attribute_values,
+                  gpointer              user_data,
+                  GError              **error)
+{
+  GString *str;
+  gint i;
+
+  if (g_strcmp0 (element_name, "a") == 0)
+    return;
+
+  str = user_data;
+
+  g_string_append (str, "<");
+  g_string_append (str, element_name);
+
+  for (i = 0; attribute_names[i] != NULL; i++)
+    {
+      gchar *tmp;
+
+      tmp = g_markup_escape_text (attribute_values[i], -1);
+      g_string_append_printf (str, " %s=\"%s\"", attribute_names[i], tmp);
+      g_free (tmp);
+    }
+
+  g_string_append (str, ">");
+}
+
+static void
+end_element_cb (GMarkupParseContext  *context,
+                const gchar          *element_name,
+                gpointer              user_data,
+                GError              **error)
+{
+  GString *str;
+
+  if (g_strcmp0 (element_name, "a") == 0)
+    return;
+
+  str = user_data;
+
+  g_string_append_printf (str, "</%s>", element_name);
+}
+
+static void
+text_cb (GMarkupParseContext  *context,
+         const gchar          *text,
+         gsize                 text_len,
+         gpointer              user_data,
+         GError              **error)
+{
+  GString *str;
+  gchar *tmp;
+
+  str = user_data;
+
+  tmp = g_markup_escape_text (text, text_len);
+  g_string_append (str, tmp);
+  g_free (tmp);
+}
+
+static gboolean
+parse_markup (const gchar  *text,
+              gchar       **parsed_markup,
+              GError      **error)
+{
+  GString *str;
+  GMarkupParseContext *context;
+
+  str = g_string_new (NULL);
+  context = g_markup_parse_context_new (&(GMarkupParser) {
+                                          start_element_cb,
+                                          end_element_cb,
+                                          text_cb
+                                        },
+                                        0, str, NULL);
+
+  if (!g_markup_parse_context_parse (context, "<markup>", -1, error))
+    {
+      g_markup_parse_context_free (context);
+      g_string_free (str, TRUE);
+
+      return FALSE;
+    }
+
+  if (!g_markup_parse_context_parse (context, text, -1, error))
+    {
+      g_markup_parse_context_free (context);
+      g_string_free (str, TRUE);
+
+      return FALSE;
+    }
+
+  if (!g_markup_parse_context_parse (context, "</markup>", -1, error))
+    {
+      g_markup_parse_context_free (context);
+      g_string_free (str, TRUE);
+
+      return FALSE;
+    }
+
+  if (!g_markup_parse_context_end_parse (context, error))
+    {
+      g_markup_parse_context_free (context);
+      g_string_free (str, TRUE);
+
+      return FALSE;
+    }
+
+  *parsed_markup = g_string_free (str, FALSE);
+  g_markup_parse_context_free (context);
+
+  return TRUE;
+}
+
 static void
 nd_notification_class_init (NdNotificationClass *class)
 {
@@ -566,3 +684,35 @@ nd_notification_new (const char *sender)
 
         return notification;
 }
+
+gboolean
+validate_markup (const gchar *markup)
+{
+  gchar *parsed_markup;
+  GError *error;
+
+  parsed_markup = NULL;
+  error = NULL;
+
+  if (!parse_markup (markup, &parsed_markup, &error))
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+
+      return FALSE;
+    }
+
+  if (!pango_parse_markup (parsed_markup, -1, 0, NULL, NULL, NULL, &error))
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+
+      g_free (parsed_markup);
+
+      return FALSE;
+    }
+
+  g_free (parsed_markup);
+
+  return TRUE;
+}
diff --git a/gnome-flashback/libnotifications/nd-notification.h 
b/gnome-flashback/libnotifications/nd-notification.h
index e320f24..1ed3a38 100644
--- a/gnome-flashback/libnotifications/nd-notification.h
+++ b/gnome-flashback/libnotifications/nd-notification.h
@@ -85,6 +85,8 @@ void                  nd_notification_action_invoked      (NdNotification *notif
 void                  nd_notification_url_clicked         (NdNotification *notification,
                                                            const char     *url);
 
+gboolean              validate_markup                     (const gchar    *markup);
+
 G_END_DECLS
 
 #endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]