changeset 1470:a8b924b5474c

The OTR protocol expects (X)HTML messsages
author Mikael Berthe <mikael@lilotux.net>
date Sun, 13 Apr 2008 13:01:32 +0200
parents 1f7990dd416b
children 08acf7cebe01
files mcabber/src/Makefile.am mcabber/src/nohtml.c mcabber/src/nohtml.h mcabber/src/otr.c
diffstat 4 files changed, 184 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/src/Makefile.am	Sun Apr 13 08:33:50 2008 +0200
+++ b/mcabber/src/Makefile.am	Sun Apr 13 13:01:32 2008 +0200
@@ -8,7 +8,7 @@
 		  fifo.c fifo.h help.c help.h
 
 if OTR
-mcabber_SOURCES += otr.c otr.h
+mcabber_SOURCES += otr.c otr.h nohtml.c nohtml.h
 endif
 
 LDADD = $(GLIB_LIBS) $(GPGME_LIBS) $(LIBOTR_LIBS) \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/nohtml.c	Sun Apr 13 13:01:32 2008 +0200
@@ -0,0 +1,162 @@
+/*
+ * nohtml.c     -- (X)HTML helper functions
+ *
+ * Copyright (C) 2008 Mikael Berthe <mikael@lilotux.net>
+ * Some portions come from the jabberd project, see below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ *
+ * Some parts come from libjabber/str.c:
+ * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
+ * information for Jabber.com, Inc. is available at http://www.jabber.com/.
+ * Portions Copyright (c) 1998-1999 Jeremie Miller.
+ */
+
+#include <string.h>
+#include <glib.h>
+#include <config.h>
+
+
+/*  html_strip(htmlbuf)
+ * Remove html entities from htmlbuf and try to convert it to plain text.
+ * The caller must g_free the string after use.
+ * Code mostly derived from strunescape(), in libjabber.
+ */
+char *html_strip(const char *htmlbuf)
+{
+  int i, j=0;
+  char *nohtml;
+
+  if (!htmlbuf) return(NULL);
+
+  nohtml = g_strdup(htmlbuf);
+
+  if (!strchr(htmlbuf, '&') && !strchr(htmlbuf, '<'))
+    return(nohtml);
+
+  for (i = 0; i < (int)strlen(htmlbuf); i++) {
+    if (htmlbuf[i] == '&') {
+      if (!strncmp(&htmlbuf[i],"&amp;",5)) {
+        nohtml[j] = '&';
+        i += 4;
+      } else if (!strncmp(&htmlbuf[i],"&quot;", 6)) {
+        nohtml[j] = '\"';
+        i += 5;
+      } else if (!strncmp(&htmlbuf[i],"&apos;", 6)) {
+        nohtml[j] = '\'';
+        i += 5;
+      } else if (!strncmp(&htmlbuf[i],"&lt;", 4)) {
+        nohtml[j] = '<';
+        i += 3;
+      } else if (!strncmp(&htmlbuf[i],"&gt;", 4)) {
+        nohtml[j] = '>';
+        i += 3;
+      }
+    } else if (!strncmp(&htmlbuf[i],"<br>", 4) ||
+               !strncmp(&htmlbuf[i],"<br/>", 5)) {
+      nohtml[j] = '\n';
+      i += (htmlbuf[i+3] == '/' ? 4 : 3);
+    } else if (htmlbuf[i] == '<') {
+      /* Let's strip all unknown tags */
+      j--;
+      while (htmlbuf[++i] != '>');
+    } else
+      nohtml[j] = htmlbuf[i];
+    j++;
+  }
+  nohtml[j] = '\0';
+  return nohtml;
+}
+
+/*  html_escape(text)
+ * Add (x)html entities to the text.
+ * The caller must g_free the string after use.
+ * Code mostly derived from strescape(), in libjabber.
+ */
+char *html_escape(const char *text)
+{
+  int i, j;
+  int oldlen, newlen;
+  char *html;
+
+  if (!text) return(NULL);
+
+  oldlen = newlen = strlen(text);
+
+  for (i = 0; i < oldlen; i++) {
+    switch(text[i])
+    {
+      case '&':
+          newlen += 5;
+          break;
+      case '\'':
+          newlen += 6;
+          break;
+          case '\"':
+              newlen += 6;
+          break;
+      case '<':
+          newlen += 4;
+          break;
+      case '>':
+          newlen += 4;
+          break;
+      case '\n':
+          newlen += 5;
+    }
+  }
+
+  if (oldlen == newlen)
+    return g_strdup(text);
+
+  html = g_new0(char, newlen+1);
+
+  for (i = j = 0; i < oldlen; i++) {
+    switch(text[i])
+    {
+      case '&':
+          memcpy(&html[j], "&amp;", 5);
+          j += 5;
+          break;
+      case '\'':
+          memcpy(&html[j], "&apos;", 6);
+          j += 6;
+          break;
+      case '\"':
+          memcpy(&html[j], "&quot;", 6);
+          j += 6;
+          break;
+      case '<':
+          memcpy(&html[j], "&lt;", 4);
+          j += 4;
+          break;
+      case '>':
+          memcpy(&html[j], "&gt;", 4);
+          j += 4;
+          break;
+      case '\n':
+          memcpy(&html[j], "<br/>", 5);
+          j += 5;
+          break;
+      default:
+          html[j++] = text[i];
+    }
+  }
+  return html;
+}
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcabber/src/nohtml.h	Sun Apr 13 13:01:32 2008 +0200
@@ -0,0 +1,9 @@
+#ifndef __NOHTML_H__
+#define __NOHTML_H__ 1
+
+char *html_strip(const char *buf);
+char *html_escape(const char *text);
+
+#endif /* __NOHTML_H__ */
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
--- a/mcabber/src/otr.c	Sun Apr 13 08:33:50 2008 +0200
+++ b/mcabber/src/otr.c	Sun Apr 13 13:01:32 2008 +0200
@@ -20,6 +20,7 @@
  */
 
 #include <config.h>
+#include <glib.h>
 
 #ifdef HAVE_LIBOTR
 
@@ -31,6 +32,7 @@
 #include "utils.h"
 #include "screen.h"
 #include "settings.h"
+#include "nohtml.h"
 
 
 static OtrlUserState userstate = NULL;
@@ -379,7 +381,7 @@
 
   if (!ignore_message && newmessage) {
     *free_msg = 1;
-    *otr_data = g_strdup(newmessage);
+    *otr_data = html_strip(newmessage);
     otrl_message_free(newmessage);
     if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
       return 1;
@@ -391,10 +393,15 @@
 {
   gcry_error_t err;
   char *newmessage = NULL;
+  char *htmlmsg;
   ConnContext * ctx = otr_get_context(buddy);
 
+  htmlmsg = html_escape(*msg);
+
   err = otrl_message_sending(userstate, &ops, NULL, account, "jabber", buddy,
-    *msg, NULL, &newmessage, NULL, NULL);
+                             htmlmsg, NULL, &newmessage, NULL, NULL);
+
+  g_free(htmlmsg);
 
   if (err)
     *msg = NULL; /*something went wrong, don't send the plain-message! */
@@ -655,7 +662,9 @@
                                   const char *protocol, const char *username,
                                   const char *msg)
 {
-  scr_WriteIncomingMessage(username, msg, 0, HBB_PREFIX_INFO, 0);
+  char *strippedmsg = html_strip(msg);
+  scr_WriteIncomingMessage(username, strippedmsg, 0, HBB_PREFIX_INFO, 0);
+  g_free(strippedmsg);
   return 0;
 }