diff options
author | Vadim ProductEngine <vsavchuk@productengine.com> | 2011-09-07 19:12:35 +0300 |
---|---|---|
committer | Vadim ProductEngine <vsavchuk@productengine.com> | 2011-09-07 19:12:35 +0300 |
commit | 1fad7d997d99715cc88b6e69ae325f28be413206 (patch) | |
tree | ca45ec81d4db97a15db159bf9d8951d6a020b675 /indra/newview | |
parent | 7975ab138b6ac54fc831613e4d3dfb913c5efbd2 (diff) |
STORM-1577 Made parsing translation responses more robust.
JsonCpp is prone to aborting the program on failed assertions,
so be super-careful and verify the response format.
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/lltranslate.cpp | 72 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 3 |
2 files changed, 67 insertions, 8 deletions
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 6576cbbe64..895d8f78eb 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -31,6 +31,7 @@ #include <curl/curl.h> #include "llbufferstream.h" +#include "lltrans.h" #include "llui.h" #include "llversioninfo.h" #include "llviewercontrol.h" @@ -94,21 +95,66 @@ public: return false; } + if (!root.isObject()) // empty response? should not happen + { + return false; + } + if (status != STATUS_OK) { - const Json::Value& error = root["error"]; - err_msg = error["message"].asString(); - status = error["code"].asInt(); + // Request failed. Extract error message from the response. + parseErrorResponse(root, status, err_msg); return false; } - const Json::Value& response_data = root["data"]["translations"][0U]; - translation = response_data["translatedText"].asString(); - detected_lang = response_data["detectedSourceLanguage"].asString(); - return true; + // Request succeeded, extract translation from the response. + return parseTranslation(root, translation, detected_lang); } private: + static void parseErrorResponse( + const Json::Value& root, + int& status, + std::string& err_msg) + { + const Json::Value& error = root.get("error", 0); + if (!error.isObject() || !error.isMember("message") || !error.isMember("code")) + { + return; + } + + err_msg = error["message"].asString(); + status = error["code"].asInt(); + } + + static bool parseTranslation( + const Json::Value& root, + std::string& translation, + std::string& detected_lang) + { + const Json::Value& data = root.get("data", 0); + if (!data.isObject() || !data.isMember("translations")) + { + return false; + } + + const Json::Value& translations = data["translations"]; + if (!translations.isArray() || translations.size() == 0) + { + return false; + } + + const Json::Value& first = translations[0U]; + if (!first.isObject() || !first.isMember("translatedText")) + { + return false; + } + + translation = first["translatedText"].asString(); + detected_lang = first.get("detectedSourceLanguage", "").asString(); + return true; + } + static std::string getAPIKey() { return gSavedSettings.getString("GoogleTranslateAPIKey"); @@ -143,7 +189,12 @@ public: { if (status != STATUS_OK) { - size_t begin = body.find("Message: "); + static const std::string MSG_BEGIN_MARKER = "Message: "; + size_t begin = body.find(MSG_BEGIN_MARKER); + if (begin != std::string::npos) + { + begin += MSG_BEGIN_MARKER.size(); + } size_t end = body.find("</p>", begin); err_msg = body.substr(begin, end-begin); LLStringUtil::replaceString(err_msg, "
", ""); // strip CR @@ -211,6 +262,11 @@ void LLTranslate::TranslationReceiver::completedRaw( } else { + if (err_msg.empty()) + { + err_msg = LLTrans::getString("TranslationResponseParseError"); + } + llwarns << "Translation request failed: " << err_msg << llendl; LL_DEBUGS("Translate") << "HTTP status: " << status << " " << reason << LL_ENDL; LL_DEBUGS("Translate") << "Error response body: " << body << LL_ENDL; diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 2094275bed..146665b47d 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3502,6 +3502,9 @@ Try enclosing path to the editor with double quotes. <string name="ExternalEditorCommandParseError">Error parsing the external editor command.</string> <string name="ExternalEditorFailedToRun">External editor failed to run.</string> + <!-- Machine translation of chat messahes --> + <string name="TranslationResponseParseError">Error parsing translation response.</string> + <!-- Key names begin --> <string name="Esc">Esc</string> <string name="Space">Space</string> |