diff options
Diffstat (limited to 'source/Utility/StringExtractorGDBRemote.cpp')
| -rw-r--r-- | source/Utility/StringExtractorGDBRemote.cpp | 133 | 
1 files changed, 130 insertions, 3 deletions
| diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp index 56df0be21edf..d2619afd5bfa 100644 --- a/source/Utility/StringExtractorGDBRemote.cpp +++ b/source/Utility/StringExtractorGDBRemote.cpp @@ -15,8 +15,6 @@  // Project includes  #include "Utility/StringExtractorGDBRemote.h" - -  StringExtractorGDBRemote::ResponseType  StringExtractorGDBRemote::GetResponseType () const  { @@ -227,7 +225,7 @@ StringExtractorGDBRemote::GetServerPacketType () const      case 'j':          if (PACKET_MATCHES("jSignalsInfo"))                     return eServerPacketType_jSignalsInfo;          if (PACKET_MATCHES("jThreadsInfo"))                     return eServerPacketType_jThreadsInfo; - +        break;      case 'v':              if (PACKET_STARTS_WITH("vFile:")) @@ -391,3 +389,132 @@ StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str)      return str.size();  } +static bool +OKErrorNotSupportedResponseValidator(void *, const StringExtractorGDBRemote &response) +{ +    switch (response.GetResponseType()) +    { +        case StringExtractorGDBRemote::eOK: +        case StringExtractorGDBRemote::eError: +        case StringExtractorGDBRemote::eUnsupported: +            return true; + +        case StringExtractorGDBRemote::eAck: +        case StringExtractorGDBRemote::eNack: +        case StringExtractorGDBRemote::eResponse: +            break; +    } +    return false; +} + +static bool +JSONResponseValidator(void *, const StringExtractorGDBRemote &response) +{ +    switch (response.GetResponseType()) +    { +        case StringExtractorGDBRemote::eUnsupported: +        case StringExtractorGDBRemote::eError: +            return true; // Accept unsupported or EXX as valid responses + +        case StringExtractorGDBRemote::eOK: +        case StringExtractorGDBRemote::eAck: +        case StringExtractorGDBRemote::eNack: +            break; + +        case StringExtractorGDBRemote::eResponse: +            // JSON that is returned in from JSON query packets is currently always +            // either a dictionary which starts with a '{', or an array which +            // starts with a '['. This is a quick validator to just make sure the +            // response could be valid JSON without having to validate all of the +            // JSON content. +            switch (response.GetStringRef()[0]) +            { +                case '{': return true; +                case '[': return true; +                default: +                    break; +            } +            break; +    } +    return false; +} + +static bool +ASCIIHexBytesResponseValidator(void *, const StringExtractorGDBRemote &response) +{ +    switch (response.GetResponseType()) +    { +        case StringExtractorGDBRemote::eUnsupported: +        case StringExtractorGDBRemote::eError: +            return true; // Accept unsupported or EXX as valid responses + +        case StringExtractorGDBRemote::eOK: +        case StringExtractorGDBRemote::eAck: +        case StringExtractorGDBRemote::eNack: +            break; + +        case StringExtractorGDBRemote::eResponse: +            { +                uint32_t valid_count = 0; +                for (const char ch : response.GetStringRef()) +                { +                    if (!isxdigit(ch)) +                    { +                        return false; +                    } +                    if (++valid_count >= 16) +                        break; // Don't validate all the characters in case the packet is very large +                } +                return true; +            } +            break; +    } +    return false; +} + +void +StringExtractorGDBRemote::CopyResponseValidator(const StringExtractorGDBRemote& rhs) +{ +    m_validator = rhs.m_validator; +    m_validator_baton = rhs.m_validator_baton; +} + +void +StringExtractorGDBRemote::SetResponseValidator(ResponseValidatorCallback callback, void *baton) +{ +    m_validator = callback; +    m_validator_baton = baton; +} + +void +StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() +{ +    m_validator = OKErrorNotSupportedResponseValidator; +    m_validator_baton = nullptr; +} + +void +StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() +{ +    m_validator = ASCIIHexBytesResponseValidator; +    m_validator_baton = nullptr; +} + +void +StringExtractorGDBRemote::SetResponseValidatorToJSON() +{ +    m_validator = JSONResponseValidator; +    m_validator_baton = nullptr; +} + +bool +StringExtractorGDBRemote::ValidateResponse() const +{ +    // If we have a validator callback, try to validate the callback +    if (m_validator) +        return m_validator(m_validator_baton, *this); +    else +        return true; // No validator, so response is valid +} + + | 
