/soc/2015/jgeboski/facebook: 14857ad5b6b7: facebook: fixed URL c...

James Geboski jgeboski at gmail.com
Mon Aug 17 23:15:21 EDT 2015


Changeset: 14857ad5b6b7c06fa8fa99ac86812ef16bf2f924
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-08-17 23:15 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/14857ad5b6b7

Description:

facebook: fixed URL comparisons being overly strict

diffstat:

 libpurple/protocols/facebook/api.c  |  52 +++++++++++++----------------
 libpurple/protocols/facebook/http.c |  64 +++++++++++++++++++++++++++++++++++++
 libpurple/protocols/facebook/http.h |  15 ++++++++
 3 files changed, 103 insertions(+), 28 deletions(-)

diffs (205 lines):

diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -1166,14 +1166,14 @@ fb_api_cb_publish_typing(FbApi *api, GBy
 	json_node_free(root);
 }
 
-static gchar *
-fb_api_message_parse_xma(FbApi *api, JsonNode *root, GError **error)
+static gboolean
+fb_api_xma_parse(FbApi *api, FbApiMessage *msg, const gchar *body,
+                 JsonNode *root, GError **error)
 {
 	const gchar *str;
 	const gchar *url;
 	FbHttpParams *params;
 	FbJsonValues *values;
-	gchar *ret;
 	GError *err = NULL;
 
 	values = fb_json_values_new(root);
@@ -1186,7 +1186,7 @@ fb_api_message_parse_xma(FbApi *api, Jso
 	if (G_UNLIKELY(err != NULL)) {
 		g_propagate_error(error, err);
 		fb_json_values_free(values);
-		return NULL;
+		return FALSE;
 	}
 
 	str = fb_json_values_next_str(values, NULL);
@@ -1194,14 +1194,20 @@ fb_api_message_parse_xma(FbApi *api, Jso
 
 	if (purple_strequal(str, "ExternalUrl")) {
 		params = fb_http_params_new_parse(url, TRUE);
-		ret = fb_http_params_dup_str(params, "u", NULL);
+		msg->text = fb_http_params_dup_str(params, "u", NULL);
 		fb_http_params_free(params);
 	} else {
-		ret = g_strdup(url);
+		msg->text = g_strdup(url);
 	}
 
+	if (fb_http_urlcmp(body, msg->text, FALSE)) {
+		g_free(msg->text);
+		fb_json_values_free(values);
+		return FALSE;
+	}
+
 	fb_json_values_free(values);
-	return ret;
+	return TRUE;
 }
 
 static GSList *
@@ -1242,22 +1248,18 @@ fb_api_message_parse_attach(FbApi *api, 
 			}
 
 			xode = fb_json_node_get_nth(node, 0);
-			msg->text = fb_api_message_parse_xma(api, xode, &err);
+
+			if (fb_api_xma_parse(api, msg, body, xode, &err)) {
+				mptr = fb_api_message_dup(msg, FALSE);
+				msgs = g_slist_prepend(msgs, mptr);
+			}
+
 			json_node_free(node);
 
 			if (G_UNLIKELY(err != NULL)) {
 				break;
 			}
 
-			if (purple_strequal(msg->text, body)) {
-				g_free(msg->text);
-				continue;
-			}
-
-			if (G_LIKELY(msg->text != NULL)) {
-				mptr = fb_api_message_dup(msg, FALSE);
-				msgs = g_slist_prepend(msgs, mptr);
-			}
 			continue;
 		}
 
@@ -2184,22 +2186,16 @@ fb_api_cb_unread_msgs(PurpleHttpConnecti
 		xode = fb_json_node_get(node, "$.extensible_attachment", NULL);
 
 		if (xode != NULL) {
-			msg.text = fb_api_message_parse_xma(api, xode, &err);
+			if (fb_api_xma_parse(api, &msg, body, xode, &err)) {
+				mptr = fb_api_message_dup(&msg, FALSE);
+				msgs = g_slist_prepend(msgs, mptr);
+			}
+
 			json_node_free(xode);
 
 			if (G_UNLIKELY(err != NULL)) {
 				break;
 			}
-
-			if (purple_strequal(msg.text, body)) {
-				g_free(msg.text);
-				continue;
-			}
-
-			if (msg.text != NULL) {
-				mptr = fb_api_message_dup(&msg, FALSE);
-				msgs = g_slist_prepend(msgs, mptr);
-			}
 		}
 
 		msgs = fb_api_cb_unread_parse_attach(api, &msg, msgs, node,
diff --git a/libpurple/protocols/facebook/http.c b/libpurple/protocols/facebook/http.c
--- a/libpurple/protocols/facebook/http.c
+++ b/libpurple/protocols/facebook/http.c
@@ -294,3 +294,67 @@ fb_http_params_set_strf(FbHttpParams *pa
 
 	fb_http_params_set(params, name, val);
 }
+
+gboolean
+fb_http_urlcmp(const gchar *url1, const gchar *url2, gboolean protocol)
+{
+	const gchar *str1;
+	const gchar *str2;
+	gboolean ret = TRUE;
+	gint int1;
+	gint int2;
+	guint i;
+	PurpleHttpURL *purl1;
+	PurpleHttpURL *purl2;
+
+	static const const gchar * (*funcs[]) (const PurpleHttpURL *url) = {
+		/* Always first so it can be skipped */
+		purple_http_url_get_protocol,
+
+		purple_http_url_get_fragment,
+		purple_http_url_get_host,
+		purple_http_url_get_password,
+		purple_http_url_get_path,
+		purple_http_url_get_username
+	};
+
+	if ((url1 == NULL) || (url2 == NULL)) {
+		return url1 == url2;
+	}
+
+	purl1 = purple_http_url_parse(url1);
+
+	if (purl1 == NULL) {
+		return g_ascii_strcasecmp(url1, url2) == 0;
+	}
+
+	purl2 = purple_http_url_parse(url2);
+
+	if (purl2 == NULL) {
+		purple_http_url_free(purl1);
+		return g_ascii_strcasecmp(url1, url2) == 0;
+	}
+
+	for (i = protocol ? 0 : 1; i < G_N_ELEMENTS(funcs); i++) {
+		str1 = funcs[i](purl1);
+		str2 = funcs[i](purl2);
+
+		if (!purple_strequal(str1, str2)) {
+			ret = FALSE;
+			break;
+		}
+	}
+
+	if (ret && protocol) {
+		int1 = purple_http_url_get_port(purl1);
+		int2 = purple_http_url_get_port(purl2);
+
+		if (int1 != int2) {
+			ret = FALSE;
+		}
+	}
+
+	purple_http_url_free(purl1);
+	purple_http_url_free(purl2);
+	return ret;
+}
diff --git a/libpurple/protocols/facebook/http.h b/libpurple/protocols/facebook/http.h
--- a/libpurple/protocols/facebook/http.h
+++ b/libpurple/protocols/facebook/http.h
@@ -274,4 +274,19 @@ fb_http_params_set_strf(FbHttpParams *pa
                         const gchar *format, ...)
                         G_GNUC_PRINTF(3, 4);
 
+/**
+ * fb_http_urlcmp:
+ * @url1: The first URL.
+ * @url2: The second URL.
+ * @protocol: #TRUE to match the protocols, otherwise #FALSE.
+ *
+ * Compares two URLs. This is more reliable than just comparing two URL
+ * strings, as it avoids casing in some areas, while not in others. It
+ * can also, optionally, ignore the matching of the URL protocol.
+ *
+ * Returns: #TRUE if the URLs match, otherwise #FALSE.
+ */
+gboolean
+fb_http_urlcmp(const gchar *url1, const gchar *url2, gboolean protocol);
+
 #endif /* _FACEBOOK_HTTP_H_ */



More information about the Commits mailing list