diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-07-09 01:17:22 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-09 01:17:22 +0300 |
commit | a5a7c7c8f5b529f766147c06cfe834f2f0c5f74c (patch) | |
tree | c24d14ce8c535cca8dbdc576faf9ecc032c36f9a /indra/llcommon | |
parent | cd5d35ddab52ae577e286140ee54664202a0091d (diff) | |
parent | db6fdcf2df62d1b2bef2bd0a9019b74663b8568c (diff) |
Merge pull request #1949 from sldevel/xmlrpc-crash-fix
Fix for crash in XMLRPC reply decoding on login with large inventories
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llsd.cpp | 147 | ||||
-rw-r--r-- | indra/llcommon/llsd.h | 10 |
2 files changed, 0 insertions, 157 deletions
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 2bbe06e72f..77fe545c3f 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -1018,153 +1018,6 @@ const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); LLSD::String LLSD::asXMLRPCValue() const { return "<value>" + safe(impl).asXMLRPCValue() + "</value>"; } -static bool inline check(bool condition, const char* warning_message) -{ - if (!condition) - { - LL_WARNS() << warning_message << LL_ENDL; - } - - return condition; -} - -static bool parseXMLRPCArrayValue(LLSD& target, LLSD::TreeNode* node) -{ - LLSD::TreeNode* data = node->getFirstChild(); - if (!check(data, "No array inner XML element (<data> expected)") || - !check(data->hasName("data"), "Invalid array inner XML element (<data> expected)") || - !check(!data->getNextSibling(), "Multiple array inner XML elements (single <data> expected)")) - return false; - - for (LLSD::TreeNode* item = data->getFirstChild(); item; item = item->getNextSibling()) - { - LLSD value; - if (!value.fromXMLRPCValue(item)) - return false; - - target.append(value); - } - - return true; -} - -static bool parseXMLRPCStructValue(LLSD& target, LLSD::TreeNode* node) -{ - for (LLSD::TreeNode* item = node->getFirstChild(); item; item = item->getNextSibling()) - { - if (!check(item->hasName("member"), "Invalid struct inner XML element (<member> expected)")) - return false; - - std::string name; - LLSD value; - for (LLSD::TreeNode* subitem = item->getFirstChild(); subitem; subitem = subitem->getNextSibling()) - { - if (subitem->hasName("name")) - { - name = LLStringFn::xml_decode(subitem->getTextContents()); - } - else if (!value.fromXMLRPCValue(subitem)) - { - return false; - } - } - if (!check(!name.empty(), "Empty struct member name")) - return false; - - target.insert(name, value); - } - - return true; -} - -bool LLSD::fromXMLRPCValue(TreeNode* node) -{ - clear(); - - llassert(node); - if (!node) - return false; - - if (!check(node->hasName("value"), "Invalid XML element (<value> expected)")) - return false; - - TreeNode* inner = node->getFirstChild(); - if (!inner) - { - check(false, "No inner XML element (value type expected)"); - // Value with no type qualifier is treated as string - assign(LLStringFn::xml_decode(node->getTextContents())); - return true; - } - - if (!check(!inner->getNextSibling(), "Multiple inner XML elements (single expected)")) - return false; - - if (inner->hasName("string")) - { - assign(LLStringFn::xml_decode(inner->getTextContents())); - return true; - } - - if (inner->hasName("int") || inner->hasName("i4")) - { - assign(std::stoi(inner->getTextContents())); - return true; - } - - if (inner->hasName("double")) - { - assign(std::stod(inner->getTextContents())); - return true; - } - - if (inner->hasName("boolean")) - { - assign(!!std::stoi(inner->getTextContents())); - return true; - } - - if (inner->hasName("dateTime.iso8601")) - { - assign(Date(inner->getTextContents())); - return true; - } - - if (inner->hasName("base64")) - { - std::string decoded = LLBase64::decodeAsString(inner->getTextContents()); - Binary binary(decoded.size()); - memcpy(binary.data(), decoded.data(), decoded.size()); - assign(binary); - return true; - } - - if (inner->hasName("array")) - { - if (!parseXMLRPCArrayValue(*this, inner)) - { - clear(); - return false; - } - return true; - } - - if (inner->hasName("struct")) - { - if (!parseXMLRPCStructValue(*this, inner)) - { - clear(); - return false; - } - return true; - } - - check(false, "Unknown inner XML element (known value type expected)"); - // Value with unknown type qualifier is treated as string - assign(LLStringFn::xml_decode(inner->getTextContents())); - return true; -} - // const char * helpers LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } void LLSD::assign(const char* v) diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 781e8d58e9..d2b3548831 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -290,16 +290,6 @@ public: // See http://xmlrpc.com/spec.md String asXMLRPCValue() const; - struct TreeNode - { - virtual bool hasName(const String& name) const = 0; - virtual String getTextContents() const = 0; - virtual TreeNode* getFirstChild() const = 0; - virtual TreeNode* getNextSibling() const = 0; - }; - - bool fromXMLRPCValue(TreeNode* node); - operator Boolean() const { return asBoolean(); } operator Integer() const { return asInteger(); } operator Real() const { return asReal(); } |