From 8b1c37dcd82e24b1249b00395f90b6b4b847563c Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 25 May 2015 21:52:57 +0000 Subject: fix for the correct json node validation git-svn-id: http://svn.miranda-ng.org/main/trunk@13835 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Gadu-Gadu/src/avatar.cpp | 22 +++---- protocols/Twitter/src/twitter.cpp | 126 +++++++++++++++++-------------------- protocols/WhatsApp/src/proto.cpp | 32 +++++----- 3 files changed, 83 insertions(+), 97 deletions(-) (limited to 'protocols') diff --git a/protocols/Gadu-Gadu/src/avatar.cpp b/protocols/Gadu-Gadu/src/avatar.cpp index 37a106802a..a02171539a 100644 --- a/protocols/Gadu-Gadu/src/avatar.cpp +++ b/protocols/Gadu-Gadu/src/avatar.cpp @@ -104,17 +104,17 @@ bool GGPROTO::getAvatarFileInfo(uin_t uin, char **avatarurl, char **avatarts) } else if (strncmp(resp->pData, "{\"result\":", 10) == 0){ //if this url returns json data (11.2013 gg convention) - JSONROOT respJSON(resp->pData); - if (respJSON != NULL) { - JSONNODE* respJSONavatars = json_get(json_get(json_get(json_get(respJSON, "result"), "users"), "user"), "avatars"); - if (respJSONavatars != NULL) { - JSONNODE *respJSONavatar = json_at(respJSONavatars, 0); - ptrT respJSON_blank(json_as_string(json_get(respJSONavatar, "_blank"))); - ptrT respJSONoriginBigAvatar(json_as_string(json_get(respJSONavatar, "originBigAvatar"))); - ptrT respJSONtimestamp(json_as_string(json_get(respJSONavatar, "timestamp"))); - if (respJSON_blank && mir_tstrcmp(respJSON_blank, TEXT("1")) && respJSONoriginBigAvatar && respJSONtimestamp){ - *avatarurl = mir_t2a(respJSONoriginBigAvatar); - *avatarts = mir_t2a(respJSONtimestamp); + JSONNode root = JSONNode::parse(resp->pData); + if (root) { + const JSONNode &respJSONavatars = root["result"].at("users").at("user").at("avatars"); + if (respJSONavatars) { + const JSONNode &respJSONavatar = *respJSONavatars.begin(); + std::string respJSON_blank = respJSONavatar["_blank"].as_string(); + std::string respJSONoriginBigAvatar = respJSONavatar["originBigAvatar"].as_string(); + std::string respJSONtimestamp = respJSONavatar["timestamp"].as_string(); + if (respJSON_blank == "1" && !respJSONoriginBigAvatar.empty() && !respJSONtimestamp.empty()) { + *avatarurl = mir_strdup(respJSONoriginBigAvatar.c_str()); + *avatarts = mir_strdup(respJSONtimestamp.c_str()); } } } diff --git a/protocols/Twitter/src/twitter.cpp b/protocols/Twitter/src/twitter.cpp index 98da36c8d5..5f86e5c64b 100644 --- a/protocols/Twitter/src/twitter.cpp +++ b/protocols/Twitter/src/twitter.cpp @@ -74,27 +74,22 @@ std::vector twitter::get_friends() if (resp.code != 200) throw bad_response(); - JSONNODE *root = json_parse(resp.data.c_str()); - if (root == NULL) + JSONNode root = JSONNode::parse(resp.data.c_str()); + if (!root) throw std::exception("unable to parse response"); - JSONNODE *nodes = json_as_array(root); - for (int i = 0;; i++) { - JSONNODE *pNode = json_at(nodes, i); - if (pNode == NULL) - break; - + for (auto it = root.begin(); it != root.end(); ++it) { twitter_user user; - user.username = json_as_pstring(json_get(pNode, "screen_name")); - user.real_name = json_as_pstring(json_get(pNode, "name")); - user.profile_image_url = json_as_pstring(json_get(pNode, "profile_image_url")); + user.username = (*it)["screen_name"].as_string(); + user.real_name = (*it)["name"].as_string(); + user.profile_image_url = (*it)["profile_image_url"].as_string(); - JSONNODE *pStatus = json_get(pNode, "status"); - if (pStatus != NULL) { - user.status.text = json_as_pstring(json_get(pStatus, "text")); - user.status.id = str2int(json_as_pstring(json_get(pStatus, "id"))); + const JSONNode &pStatus = (*it)["status"]; + if (pStatus) { + user.status.text = pStatus["text"].as_string(); + user.status.id = str2int(pStatus["id"].as_string()); - std::string timestr = json_as_pstring(json_get(pStatus, "created_at")); + std::string timestr = pStatus["created_at"].as_string(); user.status.time = parse_time(timestr); } @@ -115,16 +110,16 @@ bool twitter::get_info(const std::string &name, twitter_user *info) if (resp.code != 200) throw bad_response(); - JSONNODE *root = json_parse(resp.data.c_str()); - if (root == NULL) + JSONNode root = JSONNode::parse(resp.data.c_str()); + if (!root) return false; - if (json_get(root, "error") != NULL) + if (root.at("error")) return false; - info->username = json_as_pstring(json_get(root, "screen_name")); - info->real_name = json_as_pstring(json_get(root, "name")); - info->profile_image_url = json_as_pstring(json_get(root, "profile_image_url")); + info->username = root["screen_name"].as_string(); + info->real_name = root["name"].as_string(); + info->profile_image_url = root["profile_image_url"].as_string(); return true; } @@ -139,16 +134,16 @@ bool twitter::get_info_by_email(const std::string &email, twitter_user *info) if (resp.code != 200) throw bad_response(); - JSONNODE *root = json_parse(resp.data.c_str()); - if (root == NULL) + JSONNode root = JSONNode::parse(resp.data.c_str()); + if (!root) return false; - if (json_get(root, "error") != NULL) + if (root["error"] != NULL) return false; - info->username = json_as_pstring(json_get(root, "screen_name")); - info->real_name = json_as_pstring(json_get(root, "name")); - info->profile_image_url = json_as_pstring(json_get(root, "profile_image_url")); + info->username = root["screen_name"].as_string(); + info->real_name = root["name"].as_string(); + info->profile_image_url = root["profile_image_url"].as_string(); return true; } @@ -160,19 +155,19 @@ twitter_user twitter::add_friend(const std::string &name) if (resp.code != 200) throw bad_response(); - JSONNODE *root = json_parse(resp.data.c_str()); - if (root == NULL) + JSONNode root = JSONNode::parse(resp.data.c_str()); + if (!root) throw std::exception("unable to parse response"); twitter_user ret; - ret.username = json_as_pstring(json_get(root, "screen_name")); - ret.real_name = json_as_pstring(json_get(root, "name")); - ret.profile_image_url = json_as_pstring(json_get(root, "profile_image_url")); - - JSONNODE *pStatus = json_get(root, "status"); - if (pStatus != NULL) { - ret.status.text = json_as_pstring(json_get(pStatus, "text")); - ret.status.id = str2int(json_as_pstring(json_get(pStatus, "id"))); + ret.username = root["screen_name"].as_string(); + ret.real_name = root["name"].as_string(); + ret.profile_image_url = root["profile_image_url"].as_string(); + + JSONNode &pStatus = root["status"]; + if (pStatus) { + ret.status.text = pStatus["text"].as_string(); + ret.status.id = str2int(pStatus["id"].as_string()); } return ret; @@ -218,33 +213,28 @@ std::vector twitter::get_statuses(int count, twitter_id id) if (resp.code != 200) throw bad_response(); - JSONNODE *root = json_parse(resp.data.c_str()); - if (root == NULL) + JSONNode root = JSONNode::parse(resp.data.c_str()); + if (!root) throw std::exception("unable to parse response"); - JSONNODE *pNodes = json_as_array(root); - for (int i = 0;; i++) { - JSONNODE *pNode = json_at(pNodes, i); - if (pNode == NULL) - break; - - JSONNODE *pUser = json_get(pNode, "user"); + const JSONNode &pNodes = root.as_array(); + for (auto it = pNodes.begin(); it != pNodes.end(); ++it) { + const JSONNode &pUser = (*it)["user"]; twitter_user u; - u.username = json_as_pstring(json_get(pUser, "screen_name")); - u.profile_image_url = json_as_pstring(json_get(pUser, "profile_image_url")); + u.username = pUser["screen_name"].as_string(); + u.profile_image_url = pUser["profile_image_url"].as_string(); // the tweet will be truncated unless we take action. i hate you twitter API - JSONNODE *pStatus = json_get(pNode, "retweeted_status"); - if (pStatus != NULL) { + const JSONNode &pStatus = (*it)["retweeted_status"]; + if (pStatus) { // here we grab the "retweeted_status" um.. section? it's in here that all the info we need is // at this point the user will get no tweets and an error popup if the tweet happens to be exactly 140 chars, start with // "RT @", end in " ...", and notactually be a real retweet. it's possible but unlikely, wish i knew how to get // the retweet_count variable to work :( - JSONNODE *pUser2 = json_get(pStatus, "user"); - - std::string retweeteesName = json_as_pstring(json_get(pUser2, "screen_name")); // the user that is being retweeted - std::string retweetText = json_as_pstring(json_get(pUser2, "text")); // their tweet in all it's untruncated glory + const JSONNode &pUser2 = pStatus["user"]; + std::string retweeteesName = pUser2["screen_name"].as_string(); // the user that is being retweeted + std::string retweetText = pUser2["text"].as_string(); // their tweet in all it's untruncated glory // fix "&" in the tweets :( for (size_t pos = 0; (pos = retweetText.find("&", pos)) != std::string::npos; pos++) @@ -254,7 +244,7 @@ std::vector twitter::get_statuses(int count, twitter_id id) } else { // if it's not truncated, then the twitter API returns the native RT correctly anyway, - std::string rawText = json_as_pstring(json_get(pNode, "text")); + std::string rawText = (*it)["text"].as_string(); // ok here i'm trying some way to fix all the "&" things that are showing up // i dunno why it's happening, so i'll just find and replace each occurance :/ for (size_t pos = 0; (pos = rawText.find("&", pos)) != std::string::npos; pos++) @@ -263,8 +253,8 @@ std::vector twitter::get_statuses(int count, twitter_id id) u.status.text = rawText; } - u.status.id = str2int(json_as_pstring(json_get(pNode, "id"))); - std::string timestr = json_as_pstring(json_get(pNode, "created_at")); + u.status.id = str2int((*it)["id"].as_string()); + std::string timestr = (*it)["created_at"].as_string(); u.status.time = parse_time(timestr); statuses.push_back(u); @@ -286,22 +276,18 @@ std::vector twitter::get_direct(twitter_id id) if (resp.code != 200) throw bad_response(); - JSONNODE *root = json_parse(resp.data.c_str()); - if (root == NULL) + JSONNode root = JSONNode::parse(resp.data.c_str()); + if (!root) throw std::exception("unable to parse response"); - JSONNODE *pNodes = json_as_array(root); - for (int i = 0;; i++) { - JSONNODE *pNode = json_at(pNodes, i); - if (pNode == NULL) - break; - + const JSONNode &pNodes = root.as_array(); + for (auto it = pNodes.begin(); it != pNodes.end(); ++it) { twitter_user u; - u.username = json_as_pstring(json_get(pNode, "sender_screen_name")); + u.username = (*it)["sender_screen_name"].as_string(); - u.status.text = json_as_pstring(json_get(pNode, "text")); - u.status.id = str2int(json_as_pstring(json_get(pNode, "id"))); - std::string timestr = json_as_pstring(json_get(pNode, "created_at")); + u.status.text = (*it)["text"].as_string(); + u.status.id = str2int((*it)["id"].as_string()); + std::string timestr = (*it)["created_at"].as_string(); u.status.time = parse_time(timestr); messages.push_back(u); } diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index b594ad63fd..a26284fb0b 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -267,24 +267,24 @@ bool WhatsAppProto::Register(int state, const string &cc, const string &number, debugLogA("Server response: %s", pnlhr->pData); - JSONROOT resp(pnlhr->pData); - if (resp == NULL) { + JSONNode resp = JSONNode::parse(pnlhr->pData); + if (!resp) { NotifyEvent(ptszTitle, TranslateT("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); return false; } // Status = fail - JSONNODE *val = json_get(resp, "status"); - if (!mir_tstrcmp(ptrT(json_as_string(val)), _T("fail"))) { - JSONNODE *tmpVal = json_get(resp, "reason"); - if (!mir_tstrcmp(ptrT(json_as_string(tmpVal)), _T("stale"))) + std::string status = resp["status"].as_string(); + if (status == "fail") { + std::string reason = resp["reason"].as_string(); + if (reason == "stale") NotifyEvent(ptszTitle, TranslateT("Registration failed due to stale code. Please request a new code"), NULL, WHATSAPP_EVENT_CLIENT); else NotifyEvent(ptszTitle, TranslateT("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); - tmpVal = json_get(resp, "retry_after"); - if (tmpVal != NULL) { - CMString tmp(FORMAT, TranslateT("Please try again in %i seconds"), json_as_int(tmpVal)); + const JSONNode &tmpVal = resp["retry_after"]; + if (tmpVal) { + CMString tmp(FORMAT, TranslateT("Please try again in %i seconds"), tmpVal.as_int()); NotifyEvent(ptszTitle, tmp, NULL, WHATSAPP_EVENT_OTHER); } return false; @@ -292,19 +292,19 @@ bool WhatsAppProto::Register(int state, const string &cc, const string &number, // Request code if (state == REG_STATE_REQ_CODE) { - val = json_get(resp, "pw"); - if (val != NULL) - ret = _T2A(ptrT(json_as_string(val))); - else if (!mir_tstrcmp(ptrT(json_as_string(val)), _T("sent"))) + std::string pw = resp["pw"].as_string(); + if (!pw.empty()) + ret = pw; + else if (status == "sent") NotifyEvent(ptszTitle, TranslateT("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); return true; } // Register if (state == REG_STATE_REG_CODE) { - val = json_get(resp, "pw"); - if (val != NULL) { - ret = _T2A(ptrT(json_as_string(val))); + std::string pw = resp["pw"].as_string(); + if (!pw.empty()) { + ret = pw; return true; } NotifyEvent(ptszTitle, TranslateT("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); -- cgit v1.2.3