From b0542e479435c9558d8c77f85a575dabdd61df92 Mon Sep 17 00:00:00 2001 From: dequis Date: Sun, 1 Mar 2015 04:23:08 -0300 Subject: facebook-json: add fb_json_str_escape() to properly escape messages Fixes issues such as losing messages that include a quote character. Only escapes the minimum needed to work - control characters, backslashes and quotes. UTF-8 chars are still valid json, so they are sent as-is. --- facebook/facebook-api.c | 7 ++++++- facebook/facebook-json.c | 32 ++++++++++++++++++++++++++++++++ facebook/facebook-json.h | 2 ++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/facebook/facebook-api.c b/facebook/facebook-api.c index a96175f..6c7fc1d 100644 --- a/facebook/facebook-api.c +++ b/facebook/facebook-api.c @@ -956,6 +956,7 @@ void fb_api_message(fb_api_t *api, fb_id_t id, gboolean thread, { guint64 msgid; const gchar *tpfx; + gchar *escaped; g_return_if_fail(api != NULL); g_return_if_fail(msg != NULL); @@ -963,12 +964,16 @@ void fb_api_message(fb_api_t *api, fb_id_t id, gboolean thread, msgid = FB_API_MSGID(g_get_real_time() / 1000, g_random_int()); tpfx = thread ? "tfbid_" : ""; + escaped = fb_json_str_escape(msg); + fb_api_publish(api, "/send_message2", "{" "\"body\":\"%s\"," "\"to\":\"%s%" FB_ID_FORMAT "\"," "\"sender_fbid\":\"%" FB_ID_FORMAT "\"," "\"msgid\":%" G_GUINT64_FORMAT - "}", msg, tpfx, id, api->uid, msgid); + "}", escaped, tpfx, id, api->uid, msgid); + + g_free(escaped); } /** diff --git a/facebook/facebook-json.c b/facebook/facebook-json.c index 6d26289..70f0b39 100644 --- a/facebook/facebook-json.c +++ b/facebook/facebook-json.c @@ -314,3 +314,35 @@ gboolean fb_json_str_chk(const json_value *json, const gchar *name, *val = jv->u.string.ptr; return TRUE; } + +/** + * Backslash-escapes a string to make it safe for json. The returned string + * should be freed with #g_free() when no longer needed. + * + * @param str The string to escape. + * + * @return The resulting string, or NULL on error. + **/ +gchar *fb_json_str_escape(const gchar *str) +{ + GString *out; + guint i; + + g_return_val_if_fail(str != NULL, NULL); + + /* let's overallocate a bit */ + out = g_string_sized_new(strlen(str) * 2); + + for (i = 0; str[i] != '\0'; i++) { + if ((str[i] > 0) && (str[i] < 0x20)) { + g_string_append_printf(out, "\\u%04x", str[i]); + continue; + } + if ((str[i] == '"') || (str[i] == '\\')) { + g_string_append_c(out, '\\'); + } + g_string_append_c(out, str[i]); + } + + return g_string_free(out, FALSE); +} diff --git a/facebook/facebook-json.h b/facebook/facebook-json.h index 1720137..9fecbab 100644 --- a/facebook/facebook-json.h +++ b/facebook/facebook-json.h @@ -71,4 +71,6 @@ const gchar *fb_json_str(const json_value *json, const gchar *name); gboolean fb_json_str_chk(const json_value *json, const gchar *name, const gchar **val); +gchar *fb_json_str_escape(const gchar *str); + #endif /* _FACEBOOK_JSON_H */ -- cgit v1.2.3