From d52773fc3edbe5cd8e824109c4590d7d2ee69ee6 Mon Sep 17 00:00:00 2001 From: rbuj Date: Tue, 17 Mar 2020 20:23:08 +0100 Subject: Filter-out img elements from notification body --- .build.yml | 1 + configure.ac | 2 ++ src/themes/coco/coco-theme.c | 64 +++++++++++++++++++++++++++++++++++----- src/themes/nodoka/nodoka-theme.c | 61 ++++++++++++++++++++++++++++++++++---- src/themes/slider/theme.c | 59 ++++++++++++++++++++++++++++++++---- src/themes/standard/Makefile.am | 4 +-- src/themes/standard/theme.c | 59 ++++++++++++++++++++++++++++++++---- 7 files changed, 225 insertions(+), 25 deletions(-) diff --git a/.build.yml b/.build.yml index 1d17c35..f144c8f 100644 --- a/.build.yml +++ b/.build.yml @@ -59,6 +59,7 @@ requires: - libcanberra-devel - libnotify-devel - libwnck3-devel + - libxml2-devel - make - mate-common - mate-desktop-devel diff --git a/configure.ac b/configure.ac index 9ce86e5..ee0f754 100644 --- a/configure.ac +++ b/configure.ac @@ -106,9 +106,11 @@ dnl Requirements for the themes dnl --------------------------------------------------------------------------- GTK_REQUIRED=3.22.0 +XML_REQUIRED=2.9.0 PKG_CHECK_MODULES(THEME, gtk+-3.0 >= $GTK_REQUIRED + libxml-2.0 >= $XML_REQUIRED ) AC_SUBST(THEME_CFLAGS) AC_SUBST(THEME_LIBS) diff --git a/src/themes/coco/coco-theme.c b/src/themes/coco/coco-theme.c index 6cfa677..856eebd 100644 --- a/src/themes/coco/coco-theme.c +++ b/src/themes/coco/coco-theme.c @@ -27,6 +27,8 @@ #include #include +#include + /* Define basic coco types */ typedef void (*ActionInvokedCb)(GtkWindow *nw, const char *key); typedef void (*UrlClickedCb)(GtkWindow *nw, const char *url); @@ -488,11 +490,11 @@ void set_notification_text(GtkWindow *nw, const char *summary, const char *body) { char *str; - char* quoted; - const char *body_label_text; + char *quoted; WindowData *windata = g_object_get_data(G_OBJECT(nw), "windata"); g_assert(windata != NULL); + /* title */ quoted = g_markup_escape_text(summary, -1); str = g_strdup_printf( "%s", quoted); @@ -500,12 +502,60 @@ set_notification_text(GtkWindow *nw, const char *summary, const char *body) gtk_label_set_markup(GTK_LABEL(windata->summary_label), str); g_free(str); - str = g_strdup_printf("%s", body); + /* body */ + xmlDocPtr doc; + xmlInitParser(); + str = g_strconcat ("", "", body, "", "", NULL); + /* parse notification body */ + doc = xmlReadMemory(str, strlen (str), "noname.xml", NULL, 0); + g_free (str); + if (doc != NULL) { + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlNodeSetPtr nodes; + const char *body_label_text; + int i, size; + + /* filterout img nodes */ + xpathCtx = xmlXPathNewContext(doc); + xpathObj = xmlXPathEvalExpression((unsigned char *)"//img", xpathCtx); + nodes = xpathObj->nodesetval; + size = (nodes) ? nodes->nodeNr : 0; + for(i = size - 1; i >= 0; i--) { + xmlUnlinkNode (nodes->nodeTab[i]); + xmlFreeNode (nodes->nodeTab[i]); + } + + /* write doc to string */ + xmlBufferPtr buf = xmlBufferCreate(); + (void) xmlNodeDump(buf, doc, xmlDocGetRootElement (doc), 0, 0); + str = (char *)buf->content; + gtk_label_set_markup (GTK_LABEL (windata->body_label), str); + + /* cleanup */ + xmlBufferFree (buf); + xmlXPathFreeObject (xpathObj); + xmlXPathFreeContext (xpathCtx); + xmlFreeDoc (doc); + + /* Does it render properly? */ + body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); + if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) { + goto render_fail; + } + goto renrer_ok; + } + +render_fail: + /* could not parse notification body */ + quoted = g_markup_escape_text(body, -1); + str = g_strconcat ("", quoted, "", NULL); gtk_label_set_markup (GTK_LABEL (windata->body_label), str); - g_free(str); - body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); - if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) - gtk_label_set_text (GTK_LABEL (windata->body_label), body); + g_free (quoted); + g_free (str); + +renrer_ok: + xmlCleanupParser (); if (body == NULL || *body == '\0') gtk_widget_hide(windata->body_label); diff --git a/src/themes/nodoka/nodoka-theme.c b/src/themes/nodoka/nodoka-theme.c index 12dea08..65fd67f 100644 --- a/src/themes/nodoka/nodoka-theme.c +++ b/src/themes/nodoka/nodoka-theme.c @@ -29,6 +29,8 @@ #include #include +#include + /* Define basic nodoka types */ typedef void (*ActionInvokedCb)(GtkWindow *nw, const char *key); typedef void (*UrlClickedCb)(GtkWindow *nw, const char *url); @@ -875,7 +877,6 @@ set_notification_text(GtkWindow *nw, const char *summary, const char *body) { char *str; char* quoted; - const char *body_label_text; WindowData *windata = g_object_get_data(G_OBJECT(nw), "windata"); g_assert(windata != NULL); @@ -886,12 +887,60 @@ set_notification_text(GtkWindow *nw, const char *summary, const char *body) gtk_label_set_markup(GTK_LABEL(windata->summary_label), str); g_free(str); - str = g_strdup_printf("%s", body); + /* body */ + xmlDocPtr doc; + xmlInitParser(); + str = g_strconcat ("", "", body, "", "", NULL); + /* parse notification body */ + doc = xmlReadMemory(str, strlen (str), "noname.xml", NULL, 0); + g_free (str); + if (doc != NULL) { + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlNodeSetPtr nodes; + const char *body_label_text; + int i, size; + + /* filterout img nodes */ + xpathCtx = xmlXPathNewContext(doc); + xpathObj = xmlXPathEvalExpression((unsigned char *)"//img", xpathCtx); + nodes = xpathObj->nodesetval; + size = (nodes) ? nodes->nodeNr : 0; + for(i = size - 1; i >= 0; i--) { + xmlUnlinkNode (nodes->nodeTab[i]); + xmlFreeNode (nodes->nodeTab[i]); + } + + /* write doc to string */ + xmlBufferPtr buf = xmlBufferCreate(); + (void) xmlNodeDump(buf, doc, xmlDocGetRootElement (doc), 0, 0); + str = (char *)buf->content; + gtk_label_set_markup (GTK_LABEL (windata->body_label), str); + + /* cleanup */ + xmlBufferFree (buf); + xmlXPathFreeObject (xpathObj); + xmlXPathFreeContext (xpathCtx); + xmlFreeDoc (doc); + + /* Does it render properly? */ + body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); + if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) { + goto render_fail; + } + goto renrer_ok; + } + +render_fail: + /* could not parse notification body */ + quoted = g_markup_escape_text(body, -1); + str = g_strconcat ("", quoted, "", NULL); gtk_label_set_markup (GTK_LABEL (windata->body_label), str); - g_free(str); - body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); - if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) - gtk_label_set_text (GTK_LABEL (windata->body_label), body); + g_free (quoted); + g_free (str); + +renrer_ok: + xmlCleanupParser (); if (body == NULL || *body == '\0') gtk_widget_hide(windata->body_label); diff --git a/src/themes/slider/theme.c b/src/themes/slider/theme.c index 9edb1d7..438049b 100644 --- a/src/themes/slider/theme.c +++ b/src/themes/slider/theme.c @@ -25,6 +25,8 @@ #include #include +#include + typedef void (*ActionInvokedCb) (GtkWindow* nw, const char* key); typedef void (*UrlClickedCb) (GtkWindow* nw, const char* url); @@ -494,7 +496,6 @@ void set_notification_text(GtkWindow* nw, const char* summary, const char* body) { char* str; char* quoted; - const char *body_label_text; GtkRequisition req; WindowData* windata; int summary_width; @@ -510,10 +511,58 @@ void set_notification_text(GtkWindow* nw, const char* summary, const char* body) gtk_label_set_markup(GTK_LABEL(windata->summary_label), str); g_free(str); - gtk_label_set_markup (GTK_LABEL (windata->body_label), body); - body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); - if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) - gtk_label_set_text (GTK_LABEL (windata->body_label), body); + /* body */ + xmlDocPtr doc; + xmlInitParser(); + str = g_strconcat ("", body, "", NULL); + /* parse notification body */ + doc = xmlReadMemory(str, strlen (str), "noname.xml", NULL, 0); + g_free (str); + if (doc != NULL) { + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlNodeSetPtr nodes; + const char *body_label_text; + int i, size; + + /* filterout img nodes */ + xpathCtx = xmlXPathNewContext(doc); + xpathObj = xmlXPathEvalExpression((unsigned char *)"//img", xpathCtx); + nodes = xpathObj->nodesetval; + size = (nodes) ? nodes->nodeNr : 0; + for(i = size - 1; i >= 0; i--) { + xmlUnlinkNode (nodes->nodeTab[i]); + xmlFreeNode (nodes->nodeTab[i]); + } + + /* write doc to string */ + xmlBufferPtr buf = xmlBufferCreate(); + (void) xmlNodeDump(buf, doc, xmlDocGetRootElement (doc), 0, 0); + str = (char *)buf->content; + gtk_label_set_markup (GTK_LABEL (windata->body_label), str); + + /* cleanup */ + xmlBufferFree (buf); + xmlXPathFreeObject (xpathObj); + xmlXPathFreeContext (xpathCtx); + xmlFreeDoc (doc); + + /* Does it render properly? */ + body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); + if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) { + goto render_fail; + } + goto renrer_ok; + } + +render_fail: + /* could not parse notification body */ + quoted = g_markup_escape_text(body, -1); + gtk_label_set_markup (GTK_LABEL (windata->body_label), quoted); + g_free (quoted); + +renrer_ok: + xmlCleanupParser (); if (body == NULL || *body == '\0') gtk_widget_hide(windata->body_label); diff --git a/src/themes/standard/Makefile.am b/src/themes/standard/Makefile.am index 7f82f54..42476a4 100644 --- a/src/themes/standard/Makefile.am +++ b/src/themes/standard/Makefile.am @@ -5,8 +5,8 @@ engine_LTLIBRARIES = libstandard.la libstandard_la_SOURCES = theme.c libstandard_la_CFLAGS = $(WARN_CFLAGS) libstandard_la_LDFLAGS = -module -avoid-version -no-undefined -libstandard_la_LIBADD = $(NOTIFICATION_DAEMON_LIBS) +libstandard_la_LIBADD = $(NOTIFICATION_DAEMON_LIBS) $(THEME_LIBS) -AM_CPPFLAGS = $(NOTIFICATION_DAEMON_CFLAGS) +AM_CPPFLAGS = $(NOTIFICATION_DAEMON_CFLAGS) $(THEME_CFLAGS) -include $(top_srcdir)/git.mk diff --git a/src/themes/standard/theme.c b/src/themes/standard/theme.c index c81ac34..4ab72de 100644 --- a/src/themes/standard/theme.c +++ b/src/themes/standard/theme.c @@ -24,6 +24,8 @@ #include #include +#include + typedef void (*ActionInvokedCb) (GtkWindow* nw, const char* key); typedef void (*UrlClickedCb) (GtkWindow* nw, const char* url); @@ -844,7 +846,6 @@ void set_notification_text(GtkWindow* nw, const char* summary, const char* body) { char* str; char* quoted; - const char *body_label_text; GtkRequisition req; WindowData* windata; @@ -858,10 +859,58 @@ void set_notification_text(GtkWindow* nw, const char* summary, const char* body) gtk_label_set_markup(GTK_LABEL(windata->summary_label), str); g_free(str); - gtk_label_set_markup (GTK_LABEL (windata->body_label), body); - body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); - if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) - gtk_label_set_text (GTK_LABEL (windata->body_label), body); + /* body */ + xmlDocPtr doc; + xmlInitParser(); + str = g_strconcat ("", body, "", NULL); + /* parse notification body */ + doc = xmlReadMemory(str, strlen (str), "noname.xml", NULL, 0); + g_free (str); + if (doc != NULL) { + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlNodeSetPtr nodes; + const char *body_label_text; + int i, size; + + /* filterout img nodes */ + xpathCtx = xmlXPathNewContext(doc); + xpathObj = xmlXPathEvalExpression((unsigned char *)"//img", xpathCtx); + nodes = xpathObj->nodesetval; + size = (nodes) ? nodes->nodeNr : 0; + for(i = size - 1; i >= 0; i--) { + xmlUnlinkNode (nodes->nodeTab[i]); + xmlFreeNode (nodes->nodeTab[i]); + } + + /* write doc to string */ + xmlBufferPtr buf = xmlBufferCreate(); + (void) xmlNodeDump(buf, doc, xmlDocGetRootElement (doc), 0, 0); + str = (char *)buf->content; + gtk_label_set_markup (GTK_LABEL (windata->body_label), str); + + /* cleanup */ + xmlBufferFree (buf); + xmlXPathFreeObject (xpathObj); + xmlXPathFreeContext (xpathCtx); + xmlFreeDoc (doc); + + /* Does it render properly? */ + body_label_text = gtk_label_get_text (GTK_LABEL (windata->body_label)); + if ((body_label_text == NULL) || (strlen (body_label_text) == 0)) { + goto render_fail; + } + goto renrer_ok; + } + +render_fail: + /* could not parse notification body */ + quoted = g_markup_escape_text(body, -1); + gtk_label_set_markup (GTK_LABEL (windata->body_label), quoted); + g_free (quoted); + +renrer_ok: + xmlCleanupParser (); if (body == NULL || *body == '\0') gtk_widget_hide(windata->body_label); -- cgit v1.2.1