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(); } | 
