/soc/2015/jgeboski/facebook: 129e87951cd6: facebook: fixed JSON ...

James Geboski jgeboski at gmail.com
Tue Jun 23 17:16:16 EDT 2015


Changeset: 129e87951cd6224042160341270969257052f71c
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-06-23 17:15 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/129e87951cd6

Description:

facebook: fixed JSON parsing for older json-glib versions

This fixes a lot of weird referencing with JsonNodes, which assumes to
much from the hidden side of json-glib. This became evident with older
versions of json-glib.

Additionally, a slew of inherent and possible memory leaks have been
addressed, while also cleaning up the JSON code a bit.

diffstat:

 libpurple/protocols/facebook/api.c  |  512 ++++++++++++++++++++++++++---------
 libpurple/protocols/facebook/api.h  |   69 ++++-
 libpurple/protocols/facebook/json.c |   14 +-
 libpurple/protocols/facebook/json.h |    4 +-
 4 files changed, 445 insertions(+), 154 deletions(-)

diffs (truncated from 1023 to 300 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
@@ -302,8 +302,9 @@ fb_api_error_quark(void)
 static gboolean
 fb_api_json_chk(FbApi *api, gconstpointer data, gsize size, JsonNode **node)
 {
-	const gchar *msg;
 	FbApiPrivate *priv;
+	gboolean success = FALSE;
+	gchar *msg = NULL;
 	GError *err = NULL;
 	gint64 code;
 	JsonNode *root;
@@ -314,17 +315,15 @@ fb_api_json_chk(FbApi *api, gconstpointe
 	root = fb_json_node_new(data, size, &err);
 	FB_API_ERROR_CHK(api, err, return FALSE);
 
-	if (fb_json_node_chk_int(root, "$.error_code", &code)) {
+	if (fb_json_node_chk_str(root, "$.failedSend.errorMessage", &msg)) {
+		fb_api_error(api, FB_API_ERROR_GENERAL, "%s", msg);
+	} else if (fb_json_node_chk_int(root, "$.error_code", &code)) {
 		if (!fb_json_node_chk_str(root, "$.error_msg", &msg)) {
-			msg = _("Generic error");
+			msg = g_strdup(_("Generic error"));
 		}
 
 		fb_api_error(api, FB_API_ERROR_GENERAL, "%s", msg);
-		json_node_free(root);
-		return FALSE;
-	}
-
-	if (fb_json_node_chk_str(root, "$.errorCode", &msg)) {
+	} else if (fb_json_node_chk_str(root, "$.errorCode", &msg)) {
 		if ((g_ascii_strcasecmp(msg, "ERROR_QUEUE_NOT_FOUND") == 0) ||
 		    (g_ascii_strcasecmp(msg, "ERROR_QUEUE_LOST") == 0))
 		{
@@ -333,23 +332,18 @@ fb_api_json_chk(FbApi *api, gconstpointe
 		}
 
 		fb_api_error(api, FB_API_ERROR_GENERAL, "%s", msg);
-		json_node_free(root);
-		return FALSE;
+	} else {
+		success = TRUE;
 	}
 
-	if (fb_json_node_chk_str(root, "$.failedSend.errorMessage", &msg)) {
-		fb_api_error(api, FB_API_ERROR_GENERAL, "%s", msg);
-		json_node_free(root);
-		return FALSE;
-	}
-
-	if (node != NULL) {
+	if (success && (node != NULL)) {
 		*node = root;
 	} else {
 		json_node_free(root);
 	}
 
-	return TRUE;
+	g_free(msg);
+	return success;
 }
 
 static gboolean
@@ -503,10 +497,10 @@ static void
 fb_api_cb_seqid(PurpleHttpConnection *con, PurpleHttpResponse *res,
                 gpointer data)
 {
-	const gchar *str;
 	FbApi *api = data;
 	FbApiPrivate *priv = api->priv;
 	gchar *json;
+	gchar *str;
 	GError *err = NULL;
 	gint64 nid;
 	JsonBuilder *bldr;
@@ -520,9 +514,10 @@ fb_api_cb_seqid(PurpleHttpConnection *co
 	}
 
 	str = fb_json_node_get_str(root, expr, &err);
+	json_node_free(root);
 	FB_API_ERROR_CHK(api, err, return);
 	nid = g_ascii_strtoll(str, NULL, 10);
-	json_node_free(root);
+	g_free(str);
 
 	bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
 	fb_json_bldr_add_int(bldr, "delta_batch_size", 125);
@@ -611,30 +606,29 @@ fb_api_cb_mqtt_connect(FbMqtt *mqtt, gpo
 static void
 fb_api_cb_publish_tn(FbApi *api, const GByteArray *pload)
 {
-	const gchar *str;
 	FbApiTyping typg;
-	GError *err = NULL;
-	gint64 state;
-	gint64 uid;
+	gboolean res;
+	gchar *str;
 	JsonNode *root;
 
 	if (!fb_api_json_chk(api, pload->data, pload->len, &root)) {
 		return;
 	}
 
-	if (!fb_json_node_chk_str(root, "$.type", &str) ||
-	    (g_ascii_strcasecmp(str, "typ") != 0)) {
+	if (fb_json_node_chk_str(root, "$.type", &str)) {
+		res = g_ascii_strcasecmp(str, "typ") == 0;
+		g_free(str);
+
+		if (!res) {
+			goto finish;
+		}
+	} else {
 		goto finish;
 	}
 
-	uid = fb_json_node_get_int(root, "$.sender_fbid", &err);
-	FB_API_ERROR_CHK(api, err, goto finish);
+	typg.uid = fb_json_node_get_int(root, "$.sender_fbid", NULL);
+	typg.state = fb_json_node_get_int(root, "$.state", NULL);
 
-	state = fb_json_node_get_int(root, "$.state", &err);
-	FB_API_ERROR_CHK(api, err, goto finish);
-
-	typg.uid = uid;
-	typg.state = state;
 	g_signal_emit_by_name(api, "typing", &typg);
 
 finish:
@@ -644,19 +638,19 @@ finish:
 static void
 fb_api_cb_publish_ms(FbApi *api, const GByteArray *pload)
 {
-	const gchar *str;
+	const gchar *strc;
 	FbApiMessage msg;
 	FbApiPrivate *priv = api->priv;
 	FbThrift *thft;
+	gchar *str;
 	GError *err = NULL;
-	gint64 tid;
-	gint64 uid;
 	GList *elms = NULL;
 	GList *l;
 	gpointer mptr;
 	GSList *msgs = NULL;
 	guint i;
-	JsonArray *arr;
+	JsonArray *arr = NULL;
+	JsonArray *arr2;
 	JsonNode *mode;
 	JsonNode *node;
 	JsonNode *root;
@@ -674,7 +668,7 @@ fb_api_cb_publish_ms(FbApi *api, const G
 
 	if (fb_json_node_chk_str(root, "$.syncToken", &str)) {
 		g_free(priv->stoken);
-		priv->stoken = g_strdup(str);
+		priv->stoken = str;
 		g_signal_emit_by_name(api, "connect");
 		goto finish;
 	}
@@ -685,6 +679,7 @@ fb_api_cb_publish_ms(FbApi *api, const G
 
 	for (l = elms; l != NULL; l = l->next) {
 		node = l->data;
+		fb_api_message_reset(&msg, FALSE);
 
 		if (!fb_json_node_chk(node, "$.deltaNewMessage", &node)) {
 			continue;
@@ -692,35 +687,30 @@ fb_api_cb_publish_ms(FbApi *api, const G
 
 		mode = fb_json_node_get(node, "$.messageMetadata", &err);
 		FB_API_ERROR_CHK(api, err, goto next);
+		msg.uid = fb_json_node_get_int(mode, "$.actorFbId", NULL);
 
-		uid = fb_json_node_get_int(mode, "$.actorFbId", &err);
-		FB_API_ERROR_CHK(api, err, goto next);
-
-		if (uid == priv->uid) {
+		if (msg.uid == priv->uid) {
 			goto next;
 		}
 
-		msg.uid = uid;
-		msg.tid = 0;
-
-		if (fb_json_node_chk_int(mode, "$.threadKey.threadFbId",
-		                         &tid))
-		{
-			msg.tid = tid;
-		}
+		msg.tid = fb_json_node_get_int(mode, "$.threadKey.threadFbId",
+		                               NULL);
 
 		if (fb_json_node_chk_str(node, "$.body", &str)) {
 			msg.text = str;
-			mptr = g_memdup(&msg, sizeof msg);
+			mptr = fb_api_message_dup(&msg, FALSE);
 			msgs = g_slist_prepend(msgs, mptr);
 		}
 
-		if (fb_json_node_chk_arr(node, "$.attachments", &arr) &&
-		    (json_array_get_length(arr) > 0))
-		{
-			msg.text = _("* Non-Displayable Attachments *");
-			mptr = g_memdup(&msg, sizeof msg);
-			msgs = g_slist_prepend(msgs, mptr);
+		if (fb_json_node_chk_arr(node, "$.attachments", &arr2)) {
+			if (json_array_get_length(arr2) > 0) {
+				strc = _("* Non-Displayable Attachments *");
+				msg.text = g_strdup(strc);
+				mptr = fb_api_message_dup(&msg, FALSE);
+				msgs = g_slist_prepend(msgs, mptr);
+			}
+
+			json_array_unref(arr2);
 		}
 
 next:
@@ -732,8 +722,12 @@ next:
 	g_signal_emit_by_name(api, "message", msgs);
 
 finish:
+	if (G_LIKELY(arr != NULL)) {
+		json_array_unref(arr);
+	}
+
 	g_list_free(elms);
-	g_slist_free_full(msgs, g_free);
+	g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free);
 	json_node_free(root);
 }
 
@@ -781,7 +775,7 @@ fb_api_cb_publish_p(FbApi *api, const GB
 		pres.uid = i64;
 		pres.active = i32 != 0;
 
-		mptr = g_memdup(&pres, sizeof pres);
+		mptr = fb_api_presence_dup(&pres);
 		press = g_slist_prepend(press, mptr);
 
 		/* Skip the last active timestamp field */
@@ -818,7 +812,7 @@ fb_api_cb_publish_p(FbApi *api, const GB
 
 	press = g_slist_reverse(press);
 	g_signal_emit_by_name(api, "presence", press);
-	g_slist_free_full(press, g_free);
+	g_slist_free_full(press, (GDestroyNotify) fb_api_presence_free);
 }
 
 static void
@@ -938,29 +932,19 @@ static void
 fb_api_cb_auth(PurpleHttpConnection *con, PurpleHttpResponse *res,
                gpointer data)
 {
-	const gchar *token;
 	FbApi *api = data;
 	FbApiPrivate *priv = api->priv;
-	GError *err = NULL;
-	gint64 uid;
 	JsonNode *root;
 
 	if (!fb_api_http_chk(api, res, &root)) {
 		return;
 	}
 
-	uid = fb_json_node_get_int(root, "$.uid", &err);
-	FB_API_ERROR_CHK(api, err, goto finish);
+	g_free(priv->token);
+	priv->token = fb_json_node_get_str(root, "$.access_token", NULL);
+	priv->uid = fb_json_node_get_int(root, "$.uid", NULL);
 
-	token = fb_json_node_get_str(root, "$.access_token", &err);
-	FB_API_ERROR_CHK(api, err, goto finish);
-
-	g_free(priv->token);
-	priv->token = g_strdup(token);
-	priv->uid = uid;
 	g_signal_emit_by_name(api, "auth");
-
-finish:
 	json_node_free(root);
 }
 
@@ -983,26 +967,20 @@ fb_api_auth(FbApi *api, const gchar *use
 }
 
 static void
-fb_api_cb_contacts_free(FbApiUser *user)
-{
-	g_free(user->csum);
-	g_free(user);
-}
-
-static void



More information about the Commits mailing list