changeset 18905:3f95e691bad2

Rewrite escaping so that it is more correct, in order to fix #2521. Test it.
author Jeffrey Connelly <jaconnel@calpoly.edu>
date Sun, 12 Aug 2007 07:35:51 +0000
parents da2f37d232a9
children 8b3ca7be9b72
files libpurple/protocols/myspace/message.c libpurple/protocols/myspace/myspace.c libpurple/protocols/myspace/myspace.h
diffstat 3 files changed, 101 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/myspace/message.c	Sun Aug 12 06:54:15 2007 +0000
+++ b/libpurple/protocols/myspace/message.c	Sun Aug 12 07:35:51 2007 +0000
@@ -22,7 +22,6 @@
 #include "myspace.h"
 #include "message.h"
 
-static gchar *msim_unescape_or_escape(const gchar *msg, gboolean escape);
 static void msim_msg_free_element(gpointer data, gpointer user_data);
 static void msim_msg_debug_string_element(gpointer data, gpointer user_data);
 static gchar *msim_msg_pack_using(MsimMessage *msg, GFunc gf, const gchar *sep, const gchar *begin, const gchar *end);
@@ -33,56 +32,15 @@
  * escaping and unescaping. */
 static struct MSIM_ESCAPE_REPLACEMENT {
 	gchar *code;
-	gchar *text;
+	gchar text;
 } msim_escape_replacements[] = {
-	{ "/1", "/" },
-	{ "/2", "\\" },
+	{ "/1", '/' },
+	{ "/2", '\\' },
 	/* { "/3", "|" }, */      /* Not used here -- only for within arrays */
-	{ NULL, NULL }
+	{ NULL, 0 }
 };
 
 /**
- * Unescape or escape a protocol message.
- *
- * @param msg The message to be unescaped or escaped.
- * @param escape TRUE to escape, FALSE to unescape.
- *
- * @return The unescaped or escaped message. Caller must g_free().
- */
-static gchar *
-msim_unescape_or_escape(const gchar *original_msg, gboolean escape)
-{
-	gchar *tmp, *msg;
-	guint i;
-	struct MSIM_ESCAPE_REPLACEMENT* replacement;
-
-	/* Freed in loop below. */
-	msg = g_strdup(original_msg);
-
-	/* Replace each code in msim_replacement_code with
-	 * corresponding entry in msim_replacement_text. */
-	for (i = 0; (replacement = &msim_escape_replacements[i]); ++i) {
-		gchar *code, *text;
-
-		code = replacement->code;
-		text = replacement->text;
-
-		if (!code || !text)
-			break;
-
-		if (escape) {
-			tmp = str_replace(msg, text, code);
-		} else {
-			tmp = str_replace(msg, code, text);
-		}
-		g_free(msg);
-		msg = tmp;
-	}
-	
-	return msg;
-}
-
-/**
  * Escape a protocol message.
  *
  * @return The escaped message. Caller must g_free().
@@ -90,13 +48,75 @@
 gchar *
 msim_escape(const gchar *msg)
 {
-	return msim_unescape_or_escape(msg, TRUE);
+	GString *gs;
+	guint i, j;
+
+	gs = g_string_new("");
+
+
+	for (i = 0; i < strlen(msg); ++i) {
+		struct MSIM_ESCAPE_REPLACEMENT *replacement;
+		gchar *replace;
+
+		replace = NULL;
+
+		/* Check for characters that need to be escaped, and escape them. */
+		for (j = 0; (replacement = &msim_escape_replacements[j]) &&
+				replacement->code != NULL; ++j) {
+			if (msg[i] == replacement->text) {
+				replace = replacement->code;
+				break;
+			}
+		}
+
+		if (replace) {
+			g_string_append(gs, replace);
+		} else {
+			g_string_append_c(gs, msg[i]);
+		}
+	}
+	
+	purple_debug_info("msim", "msim_escape: msg=%s, ret=%s\n", msg, gs->str);
+
+	return gs->str;
 }
 
+/**
+ * Unescape a protocol message.
+ *
+ * @return The unescaped message, caller must g_free().
+ */
 gchar *
 msim_unescape(const gchar *msg)
 {
-	return msim_unescape_or_escape(msg, FALSE);
+	GString *gs;
+	guint i, j;
+
+	gs = g_string_new("");
+
+	for (i = 0; i < strlen(msg); ++i) {
+		struct MSIM_ESCAPE_REPLACEMENT *replacement;
+		gchar replace;
+
+		replace = msg[i];
+
+		for (j = 0; (replacement = &msim_escape_replacements[j]) &&
+				replacement->code != NULL; ++j) {
+			if (msg[i] == replacement->code[0] &&
+			    i + 1 < strlen(msg) &&
+			    msg[i + 1] == replacement->code[1]) {
+				replace = replacement->text;
+				++i;
+				break;
+			}
+		}
+
+		g_string_append_c(gs, replace);
+	}
+
+	purple_debug_info("msim", "msim_unescape: msg=%s, ret=%s\n", msg, gs->str);
+
+	return gs->str;
 }
 
 /** Create a new MsimMessage. 
@@ -112,7 +132,7 @@
 	va_list argp;
 
 	if (first_key) {
-        va_start(argp, first_key);
+	va_start(argp, first_key);
 		return msim_msg_new_v(first_key, argp);
 	} else {
 		return NULL;
@@ -134,7 +154,7 @@
 	gchar *key, *value;
 	MsimMessageType type;
 	MsimMessage *msg;
-    gboolean first;
+	gboolean first;
 
 	GString *gs;
 	GList *gl;
@@ -142,22 +162,22 @@
 
 	/* Begin with an empty message. */
 	msg = NULL;
-    
-    /* First parameter can be given explicitly. */
-    first = first_key != NULL;
+
+	/* First parameter can be given explicitly. */
+	first = first_key != NULL;
 
 	/* Read key, type, value triplets until NULL. */
 	do {
-        if (first)
-        {
-            key = first_key;
-            first = FALSE;
-        } else {
-            key = va_arg(argp, gchar *);
-            if (!key) {
-                break;
-            }
-        }
+		if (first)
+		{
+			key = first_key;
+			first = FALSE;
+		} else {
+			key = va_arg(argp, gchar *);
+			if (!key) {
+				break;
+			}
+		}
 
 		type = va_arg(argp, int);
 
@@ -742,7 +762,6 @@
 			return elem->data ? g_strdup("On") : g_strdup("Off");
 
 		case MSIM_TYPE_DICTIONARY:
-			/* TODO: pack using k=v\034k2=v2\034... */
 			return msim_msg_pack_dict((MsimMessage *)elem->data);
 			
 		case MSIM_TYPE_LIST:
--- a/libpurple/protocols/myspace/myspace.c	Sun Aug 12 06:54:15 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.c	Sun Aug 12 07:35:51 2007 +0000
@@ -3918,6 +3918,7 @@
 	PurpleAccountOption *option;
 #ifdef MSIM_SELF_TEST
 	msim_test_all();
+	exit(0);
 #endif /* MSIM_SELF_TEST */
 
 
--- a/libpurple/protocols/myspace/myspace.h	Sun Aug 12 06:54:15 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.h	Sun Aug 12 07:35:51 2007 +0000
@@ -65,7 +65,7 @@
  * the results to the Purple debug log, then exit. Useful to 
  * run with 'pidgin -d' to see the output. Don't define if
  * you want to actually use the plugin! */
-/*#define MSIM_SELF_TEST            */
+#define MSIM_SELF_TEST            
 
 /* Constants */
 
@@ -175,7 +175,7 @@
 #define MSIM_INBOX_FRIEND_REQUEST       (1 << 3)
 #define MSIM_INBOX_PICTURE_COMMENT      (1 << 4)
 
-/* Everything needed to keep track of a session. */
+/* Everything needed to keep track of a session (proto_data field in PurpleConnection) */
 typedef struct _MsimSession
 {
 	guint magic;                        /**< MSIM_SESSION_STRUCT_MAGIC */
@@ -199,6 +199,21 @@
 	guint inbox_status;                 /**< Bit field of inbox notifications */
 } MsimSession;
 
+#if 0
+/* Hold ephemeral information about buddies, for proto_data of PurpleBuddy. */
+/* GHashTable? */
+typedef struct _MsimBuddy
+{
+	guint client_cv;
+	gchar *client_info;
+	guint age;
+	guint total_friends;
+	gchar *headline;
+	gchar *display_name;
+	gchar *username;
+} MsimBuddy;
+#endif
+
 /* Check if an MsimSession is valid */
 #define MSIM_SESSION_VALID(s) (session != NULL && session->magic == MSIM_SESSION_STRUCT_MAGIC)