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 56df0be21edf3..d2619afd5bfa3 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 +} + + |