summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorVadim ProductEngine <vsavchuk@productengine.com>2011-09-07 19:12:35 +0300
committerVadim ProductEngine <vsavchuk@productengine.com>2011-09-07 19:12:35 +0300
commit1fad7d997d99715cc88b6e69ae325f28be413206 (patch)
treeca45ec81d4db97a15db159bf9d8951d6a020b675 /indra/newview
parent7975ab138b6ac54fc831613e4d3dfb913c5efbd2 (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.cpp72
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml3
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, "&#xD;", ""); // 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>