diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-04-12 20:53:30 +0300 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-04-12 21:53:35 +0300 |
commit | 4053bae85dabf7840c9c2bd2444c0d034d697973 (patch) | |
tree | 38f525c1e3b36140dccec7fa476faffb4113121a | |
parent | 713d443ae89f871761eb305ece18d2cc1c9ac482 (diff) |
viewer#1081 Fix XMLPRC not being parced to LLSD correctly
which interferred with getting benefits from LLSD array
-rw-r--r-- | indra/newview/llxmlrpclistener.cpp | 94 |
1 files changed, 48 insertions, 46 deletions
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index b816f9a3b5..c4f9be5fcd 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -411,34 +411,20 @@ private: return parseValues(status_string, "", param); } - /** - * Parse key/value pairs from a given XMLRPC_VALUE into an LLSD map. - * @param key_pfx Used to describe a given key in log messages. At top - * level, pass "". When parsing an options array, pass the top-level key - * name of the array plus the index of the array entry; to this we'll - * append the subkey of interest. - * @param param XMLRPC_VALUE iterator. At top level, pass - * XMLRPC_RequestGetData(XMLRPC_REQUEST). - */ - LLSD parseValues(std::string& status_string, const std::string& key_pfx, XMLRPC_VALUE param) + LLSD parseValue(std::string& status_string, const std::string& key, const std::string& key_pfx, XMLRPC_VALUE param) { - LLSD responses; - for (XMLRPC_VALUE current = XMLRPC_VectorRewind(param); current; - current = XMLRPC_VectorNext(param)) + LLSD response; + + XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(param); + switch (type) { - std::string key(XMLRPC_GetValueID(current)); - LL_DEBUGS("LLXMLRPCListener") << "key: " << key_pfx << key << LL_ENDL; - XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(current); - switch (type) - { case xmlrpc_type_empty: LL_INFOS("LLXMLRPCListener") << "Empty result for key " << key_pfx << key << LL_ENDL; - responses.insert(key, LLSD()); break; case xmlrpc_type_base64: { - S32 len = XMLRPC_GetValueStringLen(current); - const char* buf = XMLRPC_GetValueBase64(current); + S32 len = XMLRPC_GetValueStringLen(param); + const char* buf = XMLRPC_GetValueBase64(param); if ((len > 0) && buf) { // During implementation this code was not tested @@ -449,49 +435,44 @@ private: LLSD::Binary data; data.resize(len); memcpy((void*)&data[0], (void*)buf, len); - responses.insert(key, data); + response = data; } else { LL_WARNS("LLXMLRPCListener") << "Potentially malformed xmlrpc_type_base64 for key " << key_pfx << key << LL_ENDL; - responses.insert(key, LLSD()); } break; } case xmlrpc_type_boolean: { - LLSD::Boolean val(XMLRPC_GetValueBoolean(current)); - LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL; - responses.insert(key, val); + response = LLSD::Boolean(XMLRPC_GetValueBoolean(param)); + LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; break; } case xmlrpc_type_datetime: { - std::string iso8601_date(XMLRPC_GetValueDateTime_ISO8601(current)); + std::string iso8601_date(XMLRPC_GetValueDateTime_ISO8601(param)); LL_DEBUGS("LLXMLRPCListener") << "val: " << iso8601_date << LL_ENDL; - responses.insert(key, LLSD::Date(iso8601_date)); + response = LLSD::Date(iso8601_date); break; } case xmlrpc_type_double: { - LLSD::Real val(XMLRPC_GetValueDouble(current)); - LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL; - responses.insert(key, val); + response = LLSD::Real(XMLRPC_GetValueDouble(param)); + LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; break; } case xmlrpc_type_int: { - LLSD::Integer val(XMLRPC_GetValueInt(current)); - LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL; - responses.insert(key, val); + response = LLSD::Integer(XMLRPC_GetValueInt(param)); + LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; break; } case xmlrpc_type_string: { - LLSD::String val(XMLRPC_GetValueString(current)); - LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL; - responses.insert(key, val); + response = LLSD::String(XMLRPC_GetValueString(param)); + LL_DEBUGS("LLXMLRPCListener") << "val: " << response << LL_ENDL; break; } case xmlrpc_type_mixed: @@ -501,8 +482,8 @@ private: // recursively parsing each submap and collecting them. LLSD array; int i = 0; // for descriptive purposes - for (XMLRPC_VALUE row = XMLRPC_VectorRewind(current); row; - row = XMLRPC_VectorNext(current), ++i) + for (XMLRPC_VALUE row = XMLRPC_VectorRewind(param); row; + row = XMLRPC_VectorNext(param), ++i) { // Recursive call. For the lower-level key_pfx, if 'key' // is "foo", pass "foo[0]:", then "foo[1]:", etc. In the @@ -510,21 +491,21 @@ private: // "foo[0]:bar", and so forth. // Parse the scalar subkey/value pairs from this array // entry into a temp submap. Collect such submaps in 'array'. - array.append(parseValues(status_string, + + array.append(parseValue(status_string, "", STRINGIZE(key_pfx << key << '[' << i << "]:"), row)); } // Having collected an 'array' of 'submap's, insert that whole // 'array' as the value of this 'key'. - responses.insert(key, array); + response = array; break; } case xmlrpc_type_struct: { - LLSD submap = parseValues(status_string, + response = parseValues(status_string, STRINGIZE(key_pfx << key << ':'), - current); - responses.insert(key, submap); + param); break; } case xmlrpc_type_none: // Not expected @@ -532,9 +513,30 @@ private: // whoops - unrecognized type LL_WARNS("LLXMLRPCListener") << "Unhandled xmlrpc type " << type << " for key " << key_pfx << key << LL_ENDL; - responses.insert(key, STRINGIZE("<bad XMLRPC type " << type << '>')); + response = STRINGIZE("<bad XMLRPC type " << type << '>'); status_string = "BadType"; - } + } + return response; + } + + /** + * Parse key/value pairs from a given XMLRPC_VALUE into an LLSD map. + * @param key_pfx Used to describe a given key in log messages. At top + * level, pass "". When parsing an options array, pass the top-level key + * name of the array plus the index of the array entry; to this we'll + * append the subkey of interest. + * @param param XMLRPC_VALUE iterator. At top level, pass + * XMLRPC_RequestGetData(XMLRPC_REQUEST). + */ + LLSD parseValues(std::string& status_string, const std::string& key_pfx, XMLRPC_VALUE param) + { + LLSD responses; + for (XMLRPC_VALUE current = XMLRPC_VectorRewind(param); current; + current = XMLRPC_VectorNext(param)) + { + std::string key(XMLRPC_GetValueID(current)); + LL_DEBUGS("LLXMLRPCListener") << "key: " << key_pfx << key << LL_ENDL; + responses.insert(key, parseValue(status_string, key, key_pfx, current)); } return responses; } |