forked from OSchip/llvm-project
Revert r280137 and 280139 and subsequent build fixes
The rewrite of StringExtractor::GetHexMaxU32 changes functionality in a way which makes lldb-server crash. The crash (assert) happens when parsing the "qRegisterInfo0" packet, because the function tries to drop_front more bytes than the packet contains. It's not clear to me whether we should consider this a bug in the caller or the callee, but it any case, it worked before, so I am reverting this until we can figure out what the proper interface should be. llvm-svn: 280207
This commit is contained in:
parent
f21aade0d8
commit
b9739d4090
|
@ -265,9 +265,8 @@ public:
|
|||
ArchSpec (const llvm::Triple &triple);
|
||||
explicit
|
||||
ArchSpec (const char *triple_cstr);
|
||||
explicit ArchSpec(llvm::StringRef triple_str);
|
||||
explicit ArchSpec(const char *triple_cstr, Platform *platform);
|
||||
ArchSpec(llvm::StringRef triple_str, Platform *platform);
|
||||
explicit
|
||||
ArchSpec (const char *triple_cstr, Platform *platform);
|
||||
//------------------------------------------------------------------
|
||||
/// Constructor over architecture name.
|
||||
///
|
||||
|
|
|
@ -202,10 +202,7 @@ public:
|
|||
/// The NULL terminated C string of the copy of \a arg_cstr.
|
||||
//------------------------------------------------------------------
|
||||
const char *
|
||||
AppendArgument(llvm::StringRef arg_str, char quote_char = '\0');
|
||||
|
||||
const char *
|
||||
AppendArgument(const char *arg_cstr, char quote_char = '\0');
|
||||
AppendArgument (const char *arg_cstr, char quote_char = '\0');
|
||||
|
||||
void
|
||||
AppendArguments (const Args &rhs);
|
||||
|
@ -230,8 +227,6 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
const char *
|
||||
InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char = '\0');
|
||||
const char *
|
||||
InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char = '\0');
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Replaces the argument value at index \a idx to \a arg_cstr
|
||||
|
|
|
@ -112,10 +112,10 @@ public:
|
|||
char
|
||||
PeekChar (char fail_value = '\0')
|
||||
{
|
||||
llvm::StringRef str = Peek();
|
||||
if (str.empty())
|
||||
return fail_value;
|
||||
return str[0];
|
||||
const char *cstr = Peek();
|
||||
if (cstr)
|
||||
return cstr[0];
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -154,6 +154,9 @@ public:
|
|||
size_t
|
||||
GetHexBytesAvail (llvm::MutableArrayRef<uint8_t> dest);
|
||||
|
||||
uint64_t
|
||||
GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value);
|
||||
|
||||
size_t
|
||||
GetHexByteString (std::string &str);
|
||||
|
||||
|
@ -163,13 +166,13 @@ public:
|
|||
size_t
|
||||
GetHexByteStringTerminatedBy (std::string &str,
|
||||
char terminator);
|
||||
|
||||
llvm::StringRef
|
||||
Peek() const
|
||||
|
||||
const char *
|
||||
Peek ()
|
||||
{
|
||||
if (!IsGood())
|
||||
return llvm::StringRef();
|
||||
return llvm::StringRef(m_packet).drop_front(m_index);
|
||||
if (m_index < m_packet.size())
|
||||
return m_packet.c_str() + m_index;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -434,12 +434,6 @@ ArchSpec::ArchSpec (const char *triple_cstr, Platform *platform) :
|
|||
SetTriple(triple_cstr, platform);
|
||||
}
|
||||
|
||||
ArchSpec::ArchSpec(llvm::StringRef triple_str, Platform *platform)
|
||||
: m_triple(), m_core(kCore_invalid), m_byte_order(eByteOrderInvalid), m_flags(0), m_distribution_id()
|
||||
{
|
||||
if (!triple_str.empty())
|
||||
SetTriple(triple_str.str().c_str(), platform);
|
||||
}
|
||||
|
||||
ArchSpec::ArchSpec (const char *triple_cstr) :
|
||||
m_triple (),
|
||||
|
@ -452,13 +446,6 @@ ArchSpec::ArchSpec (const char *triple_cstr) :
|
|||
SetTriple(triple_cstr);
|
||||
}
|
||||
|
||||
ArchSpec::ArchSpec(llvm::StringRef triple_str)
|
||||
: m_triple(), m_core(kCore_invalid), m_byte_order(eByteOrderInvalid), m_flags(0), m_distribution_id()
|
||||
{
|
||||
if (!triple_str.empty())
|
||||
SetTriple(triple_str.str().c_str());
|
||||
}
|
||||
|
||||
ArchSpec::ArchSpec(const llvm::Triple &triple) :
|
||||
m_triple (),
|
||||
m_core (kCore_invalid),
|
||||
|
|
|
@ -430,19 +430,13 @@ Args::AppendArguments (const char **argv)
|
|||
}
|
||||
|
||||
const char *
|
||||
Args::AppendArgument(llvm::StringRef arg_str, char quote_char)
|
||||
{
|
||||
return InsertArgumentAtIndex(GetArgumentCount(), arg_str, quote_char);
|
||||
}
|
||||
|
||||
const char *
|
||||
Args::AppendArgument(const char *arg_cstr, char quote_char)
|
||||
Args::AppendArgument (const char *arg_cstr, char quote_char)
|
||||
{
|
||||
return InsertArgumentAtIndex (GetArgumentCount(), arg_cstr, quote_char);
|
||||
}
|
||||
|
||||
const char *
|
||||
Args::InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char)
|
||||
Args::InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char)
|
||||
{
|
||||
// Since we are using a std::list to hold onto the copied C string and
|
||||
// we don't have direct access to the elements, we have to iterate to
|
||||
|
@ -452,8 +446,8 @@ Args::InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char
|
|||
for (pos = m_args.begin(); i > 0 && pos != end; ++pos)
|
||||
--i;
|
||||
|
||||
pos = m_args.insert(pos, std::string(arg_str.data(), arg_str.size()));
|
||||
|
||||
pos = m_args.insert(pos, arg_cstr);
|
||||
|
||||
if (idx >= m_args_quote_char.size())
|
||||
{
|
||||
m_args_quote_char.resize(idx + 1);
|
||||
|
@ -461,19 +455,13 @@ Args::InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char
|
|||
}
|
||||
else
|
||||
m_args_quote_char.insert(m_args_quote_char.begin() + idx, quote_char);
|
||||
|
||||
|
||||
UpdateArgvFromArgs();
|
||||
return GetArgumentAtIndex(idx);
|
||||
}
|
||||
|
||||
const char *
|
||||
Args::InsertArgumentAtIndex(size_t idx, const char *arg_cstr, char quote_char)
|
||||
{
|
||||
return InsertArgumentAtIndex(idx, llvm::StringRef(arg_cstr), quote_char);
|
||||
}
|
||||
|
||||
const char *
|
||||
Args::ReplaceArgumentAtIndex(size_t idx, const char *arg_cstr, char quote_char)
|
||||
Args::ReplaceArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char)
|
||||
{
|
||||
// Since we are using a std::list to hold onto the copied C string and
|
||||
// we don't have direct access to the elements, we have to iterate to
|
||||
|
|
|
@ -1620,7 +1620,7 @@ ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegio
|
|||
{
|
||||
memory_region_info.Clear();
|
||||
|
||||
StringExtractor line_extractor (maps_line);
|
||||
StringExtractor line_extractor (maps_line.c_str ());
|
||||
|
||||
// Format: {address_start_hex}-{address_end_hex} perms offset dev inode pathname
|
||||
// perms: rwxp (letter is present if set, '-' if not, final character is p=private, s=shared).
|
||||
|
@ -1687,7 +1687,9 @@ ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegio
|
|||
line_extractor.GetU64(0, 10); // Read the inode number
|
||||
|
||||
line_extractor.SkipSpaces();
|
||||
memory_region_info.SetName(line_extractor.Peek().str().c_str());
|
||||
const char* name = line_extractor.Peek();
|
||||
if (name)
|
||||
memory_region_info.SetName(name);
|
||||
|
||||
return Error ();
|
||||
}
|
||||
|
|
|
@ -3240,7 +3240,7 @@ GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
|
|||
uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
|
||||
if (retcode == UINT32_MAX)
|
||||
return retcode;
|
||||
const char next = (response.GetBytesLeft() ? response.PeekChar() : 0);
|
||||
const char next = (response.Peek() ? *response.Peek() : 0);
|
||||
if (next == ',')
|
||||
return 0;
|
||||
if (next == ';')
|
||||
|
@ -3428,7 +3428,7 @@ GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_s
|
|||
return false;
|
||||
if (response.GetChar() != ',')
|
||||
return false;
|
||||
if (response.GetBytesLeft() && response.PeekChar() == 'x')
|
||||
if (response.Peek() && *response.Peek() == 'x')
|
||||
return false;
|
||||
low = response.GetHexMaxU64(false, UINT64_MAX);
|
||||
high = response.GetHexMaxU64(false, UINT64_MAX);
|
||||
|
|
|
@ -966,7 +966,7 @@ GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded (StringExtract
|
|||
{
|
||||
std::string str;
|
||||
packet.GetHexByteString(str);
|
||||
m_process_launch_info.GetEnvironmentEntries().AppendArgument(str);
|
||||
m_process_launch_info.GetEnvironmentEntries().AppendArgument(str.c_str());
|
||||
return SendOKResponse();
|
||||
}
|
||||
return SendErrorResponse(12);
|
||||
|
@ -979,7 +979,8 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch (StringExtractorGDBRemote
|
|||
const uint32_t bytes_left = packet.GetBytesLeft();
|
||||
if (bytes_left > 0)
|
||||
{
|
||||
ArchSpec arch_spec(packet.Peek(), nullptr);
|
||||
const char* arch_triple = packet.Peek();
|
||||
ArchSpec arch_spec(arch_triple,NULL);
|
||||
m_process_launch_info.SetArchitecture(arch_spec);
|
||||
return SendOKResponse();
|
||||
}
|
||||
|
|
|
@ -1186,7 +1186,7 @@ GDBRemoteCommunicationServerLLGS::Handle_C (StringExtractorGDBRemote &packet)
|
|||
if (packet.GetBytesLeft () > 0)
|
||||
{
|
||||
// FIXME add continue at address support for $C{signo}[;{continue-address}].
|
||||
if (packet.PeekChar() == ';')
|
||||
if (*packet.Peek () == ';')
|
||||
return SendUnimplementedResponse (packet.GetStringRef().c_str());
|
||||
else
|
||||
return SendIllFormedResponse (packet, "unexpected content after $C{signal-number}");
|
||||
|
@ -1257,8 +1257,7 @@ GDBRemoteCommunicationServerLLGS::Handle_c (StringExtractorGDBRemote &packet)
|
|||
if (has_continue_address)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("GDBRemoteCommunicationServerLLGS::%s not implemented for c{address} variant [%s remains]",
|
||||
__FUNCTION__, packet.Peek().str().c_str());
|
||||
log->Printf ("GDBRemoteCommunicationServerLLGS::%s not implemented for c{address} variant [%s remains]", __FUNCTION__, packet.Peek ());
|
||||
return SendUnimplementedResponse (packet.GetStringRef().c_str());
|
||||
}
|
||||
|
||||
|
@ -1319,13 +1318,13 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet
|
|||
}
|
||||
|
||||
// Check if this is all continue (no options or ";c").
|
||||
if (packet.Peek() == ";c")
|
||||
if (::strcmp (packet.Peek (), ";c") == 0)
|
||||
{
|
||||
// Move past the ';', then do a simple 'c'.
|
||||
packet.SetFilePos (packet.GetFilePos () + 1);
|
||||
return Handle_c (packet);
|
||||
}
|
||||
else if (packet.Peek() == ";s")
|
||||
else if (::strcmp (packet.Peek (), ";s") == 0)
|
||||
{
|
||||
// Move past the ';', then do a simple 's'.
|
||||
packet.SetFilePos (packet.GetFilePos () + 1);
|
||||
|
@ -1342,7 +1341,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet
|
|||
|
||||
ResumeActionList thread_actions;
|
||||
|
||||
while (packet.GetBytesLeft() && packet.PeekChar() == ';')
|
||||
while (packet.GetBytesLeft () && *packet.Peek () == ';')
|
||||
{
|
||||
// Skip the semi-colon.
|
||||
packet.GetChar ();
|
||||
|
@ -1384,7 +1383,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet
|
|||
}
|
||||
|
||||
// Parse out optional :{thread-id} value.
|
||||
if (packet.GetBytesLeft() && packet.PeekChar() == ':')
|
||||
if (packet.GetBytesLeft () && (*packet.Peek () == ':'))
|
||||
{
|
||||
// Consume the separator.
|
||||
packet.GetChar ();
|
||||
|
@ -2927,7 +2926,7 @@ GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix (StringExtractorGDBRemote
|
|||
return thread_sp;
|
||||
|
||||
// Parse out thread: portion.
|
||||
if (packet.Peek().startswith("thread:"))
|
||||
if (strncmp (packet.Peek (), "thread:", strlen("thread:")) != 0)
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected 'thread:' but not found, packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
#include <tuple>
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
static inline int
|
||||
xdigit_to_sint (char ch)
|
||||
|
@ -100,16 +98,6 @@ StringExtractor::GetChar (char fail_value)
|
|||
return fail_value;
|
||||
}
|
||||
|
||||
static llvm::Optional<uint8_t>
|
||||
translateHexChar(char ch1, char ch2)
|
||||
{
|
||||
const int hi_nibble = xdigit_to_sint(ch1);
|
||||
const int lo_nibble = xdigit_to_sint(ch2);
|
||||
if (hi_nibble == -1 || lo_nibble == -1)
|
||||
return llvm::None;
|
||||
return (uint8_t)((hi_nibble << 4) + lo_nibble);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// If a pair of valid hex digits exist at the head of the
|
||||
// StringExtractor they are decoded into an unsigned byte and returned
|
||||
|
@ -123,12 +111,17 @@ StringExtractor::DecodeHexU8()
|
|||
{
|
||||
SkipSpaces();
|
||||
if (GetBytesLeft() < 2)
|
||||
{
|
||||
return -1;
|
||||
auto result = translateHexChar(m_packet[m_index], m_packet[m_index + 1]);
|
||||
if (!result.hasValue())
|
||||
}
|
||||
const int hi_nibble = xdigit_to_sint(m_packet[m_index]);
|
||||
const int lo_nibble = xdigit_to_sint(m_packet[m_index+1]);
|
||||
if (hi_nibble == -1 || lo_nibble == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
m_index += 2;
|
||||
return *result;
|
||||
return (uint8_t)((hi_nibble << 4) + lo_nibble);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -236,60 +229,131 @@ StringExtractor::GetS64 (int64_t fail_value, int base)
|
|||
return fail_value;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
uint32_t nibble_count = 0;
|
||||
|
||||
SkipSpaces();
|
||||
|
||||
// Allocate enough space for 2 uint32's. In big endian, if the user writes
|
||||
// "AB" then this should be treated as 0xAB, not 0xAB000000. In order to
|
||||
// do this, we decode into the second half of the array, and then shift the
|
||||
// starting point of the big endian translation left by however many bytes
|
||||
// of a uint32 were missing from the input. We're essentially padding left
|
||||
// with 0's.
|
||||
uint8_t bytes[2 * sizeof(uint32_t) - 1] = {0};
|
||||
llvm::MutableArrayRef<uint8_t> byte_array(bytes);
|
||||
llvm::MutableArrayRef<uint8_t> decode_loc = byte_array.take_back(sizeof(uint32_t));
|
||||
uint32_t bytes_decoded = GetHexBytesAvail(decode_loc);
|
||||
if (bytes_decoded == sizeof(uint32_t) && ::isxdigit(PeekChar()))
|
||||
return fail();
|
||||
|
||||
using namespace llvm::support;
|
||||
if (little_endian)
|
||||
return endian::read<uint32_t, endianness::little>(decode_loc.data());
|
||||
{
|
||||
uint32_t shift_amount = 0;
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint32_t...
|
||||
if (nibble_count >= (sizeof(uint32_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble_lo;
|
||||
uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
nibble_lo = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
result |= ((uint32_t)nibble_hi << (shift_amount + 4));
|
||||
result |= ((uint32_t)nibble_lo << shift_amount);
|
||||
nibble_count += 2;
|
||||
shift_amount += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
result |= ((uint32_t)nibble_hi << shift_amount);
|
||||
nibble_count += 1;
|
||||
shift_amount += 4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decode_loc = byte_array.drop_front(bytes_decoded - 1).take_front(sizeof(uint32_t));
|
||||
return endian::read<uint32_t, endianness::big>(decode_loc.data());
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint32_t...
|
||||
if (nibble_count >= (sizeof(uint32_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
|
||||
// Big Endian
|
||||
result <<= 4;
|
||||
result |= nibble;
|
||||
|
||||
++m_index;
|
||||
++nibble_count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
uint32_t nibble_count = 0;
|
||||
|
||||
SkipSpaces();
|
||||
|
||||
// Allocate enough space for 2 uint64's. In big endian, if the user writes
|
||||
// "AB" then this should be treated as 0x000000AB, not 0xAB000000. In order
|
||||
// to do this, we decode into the second half of the array, and then shift
|
||||
// the starting point of the big endian translation left by however many bytes
|
||||
// of a uint32 were missing from the input. We're essentially padding left
|
||||
// with 0's.
|
||||
uint8_t bytes[2 * sizeof(uint64_t) - 1] = {0};
|
||||
llvm::MutableArrayRef<uint8_t> byte_array(bytes);
|
||||
llvm::MutableArrayRef<uint8_t> decode_loc = byte_array.take_back(sizeof(uint64_t));
|
||||
uint32_t bytes_decoded = GetHexBytesAvail(decode_loc);
|
||||
if (bytes_decoded == sizeof(uint64_t) && ::isxdigit(PeekChar()))
|
||||
return fail();
|
||||
|
||||
using namespace llvm::support;
|
||||
if (little_endian)
|
||||
return endian::read<uint64_t, endianness::little>(decode_loc.data());
|
||||
{
|
||||
uint32_t shift_amount = 0;
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint64_t...
|
||||
if (nibble_count >= (sizeof(uint64_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble_lo;
|
||||
uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
nibble_lo = xdigit_to_sint (m_packet[m_index]);
|
||||
++m_index;
|
||||
result |= ((uint64_t)nibble_hi << (shift_amount + 4));
|
||||
result |= ((uint64_t)nibble_lo << shift_amount);
|
||||
nibble_count += 2;
|
||||
shift_amount += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
result |= ((uint64_t)nibble_hi << shift_amount);
|
||||
nibble_count += 1;
|
||||
shift_amount += 4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
decode_loc = byte_array.drop_front(bytes_decoded - 1).take_front(sizeof(uint64_t));
|
||||
return endian::read<uint64_t, endianness::big>(decode_loc.data());
|
||||
while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
|
||||
{
|
||||
// Make sure we don't exceed the size of a uint64_t...
|
||||
if (nibble_count >= (sizeof(uint64_t) * 2))
|
||||
{
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
|
||||
// Big Endian
|
||||
result <<= 4;
|
||||
result |= nibble;
|
||||
|
||||
++m_index;
|
||||
++nibble_count;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -333,6 +397,41 @@ StringExtractor::GetHexBytesAvail (llvm::MutableArrayRef<uint8_t> dest)
|
|||
return bytes_extracted;
|
||||
}
|
||||
|
||||
// Consume ASCII hex nibble character pairs until we have decoded byte_size
|
||||
// bytes of data.
|
||||
|
||||
uint64_t
|
||||
StringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value)
|
||||
{
|
||||
if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
uint32_t i;
|
||||
if (little_endian)
|
||||
{
|
||||
// Little Endian
|
||||
uint32_t shift_amount;
|
||||
for (i = 0, shift_amount = 0;
|
||||
i < byte_size && IsGood();
|
||||
++i, shift_amount += 8)
|
||||
{
|
||||
result |= ((uint64_t)GetHexU8() << shift_amount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Big Endian
|
||||
for (i = 0; i < byte_size && IsGood(); ++i)
|
||||
{
|
||||
result <<= 8;
|
||||
result |= GetHexU8();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_index = UINT64_MAX;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
size_t
|
||||
StringExtractor::GetHexByteString (std::string &str)
|
||||
{
|
||||
|
@ -348,16 +447,11 @@ size_t
|
|||
StringExtractor::GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length)
|
||||
{
|
||||
str.clear();
|
||||
llvm::StringRef nibs = Peek().take_front(nibble_length);
|
||||
while (nibs.size() >= 2)
|
||||
{
|
||||
auto ch = translateHexChar(nibs[0], nibs[1]);
|
||||
if (!ch.hasValue())
|
||||
break;
|
||||
str.push_back(*ch);
|
||||
nibs = nibs.drop_front(2);
|
||||
}
|
||||
m_index += str.size() * 2;
|
||||
|
||||
uint32_t nibble_count = 0;
|
||||
for (const char *pch = Peek(); (nibble_count < nibble_length) && (pch != nullptr); str.append(1, GetHexU8(0, false)), pch = Peek (), nibble_count += 2)
|
||||
{}
|
||||
|
||||
return str.size();
|
||||
}
|
||||
|
||||
|
@ -369,7 +463,7 @@ StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
|
|||
char ch;
|
||||
while ((ch = GetHexU8(0,false)) != '\0')
|
||||
str.append(1, ch);
|
||||
if (GetBytesLeft() > 0 && PeekChar() == terminator)
|
||||
if (Peek() && *Peek() == terminator)
|
||||
return str.size();
|
||||
|
||||
str.clear();
|
||||
|
|
|
@ -20,6 +20,7 @@ TEST_F (StringExtractorTest, InitEmpty)
|
|||
ASSERT_STREQ (kEmptyString, ex.GetStringRef().c_str());
|
||||
ASSERT_EQ (true, ex.Empty());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, InitMisc)
|
||||
|
@ -32,7 +33,7 @@ TEST_F (StringExtractorTest, InitMisc)
|
|||
ASSERT_STREQ (kInitMiscString, ex.GetStringRef().c_str());
|
||||
ASSERT_EQ (false, ex.Empty());
|
||||
ASSERT_EQ (sizeof(kInitMiscString)-1, ex.GetBytesLeft());
|
||||
ASSERT_EQ(kInitMiscString[0], ex.PeekChar());
|
||||
ASSERT_EQ (kInitMiscString[0], *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, DecodeHexU8_Underflow)
|
||||
|
@ -45,6 +46,7 @@ TEST_F (StringExtractorTest, DecodeHexU8_Underflow)
|
|||
ASSERT_EQ (0u, ex.GetFilePos());
|
||||
ASSERT_EQ (true, ex.Empty());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, DecodeHexU8_Underflow2)
|
||||
|
@ -56,7 +58,7 @@ TEST_F (StringExtractorTest, DecodeHexU8_Underflow2)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (0u, ex.GetFilePos());
|
||||
ASSERT_EQ (1u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('1', ex.PeekChar());
|
||||
ASSERT_EQ ('1', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, DecodeHexU8_InvalidHex)
|
||||
|
@ -68,7 +70,7 @@ TEST_F (StringExtractorTest, DecodeHexU8_InvalidHex)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (0u, ex.GetFilePos());
|
||||
ASSERT_EQ (2u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('x', ex.PeekChar());
|
||||
ASSERT_EQ ('x', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, DecodeHexU8_InvalidHex2)
|
||||
|
@ -80,7 +82,7 @@ TEST_F (StringExtractorTest, DecodeHexU8_InvalidHex2)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (0u, ex.GetFilePos());
|
||||
ASSERT_EQ (2u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('a', ex.PeekChar());
|
||||
ASSERT_EQ ('a', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, DecodeHexU8_Exact)
|
||||
|
@ -92,6 +94,7 @@ TEST_F (StringExtractorTest, DecodeHexU8_Exact)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (2u, ex.GetFilePos());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, DecodeHexU8_Extra)
|
||||
|
@ -103,7 +106,7 @@ TEST_F (StringExtractorTest, DecodeHexU8_Extra)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (2u, ex.GetFilePos());
|
||||
ASSERT_EQ (2u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('3', ex.PeekChar());
|
||||
ASSERT_EQ ('3', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Underflow)
|
||||
|
@ -116,6 +119,7 @@ TEST_F (StringExtractorTest, GetHexU8_Underflow)
|
|||
ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
|
||||
ASSERT_EQ (true, ex.Empty());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Underflow2)
|
||||
|
@ -127,6 +131,7 @@ TEST_F (StringExtractorTest, GetHexU8_Underflow2)
|
|||
ASSERT_EQ (false, ex.IsGood());
|
||||
ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_InvalidHex)
|
||||
|
@ -138,6 +143,7 @@ TEST_F (StringExtractorTest, GetHexU8_InvalidHex)
|
|||
ASSERT_EQ (false, ex.IsGood());
|
||||
ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Exact)
|
||||
|
@ -149,6 +155,7 @@ TEST_F (StringExtractorTest, GetHexU8_Exact)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (2u, ex.GetFilePos());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Extra)
|
||||
|
@ -160,7 +167,7 @@ TEST_F (StringExtractorTest, GetHexU8_Extra)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (2u, ex.GetFilePos());
|
||||
ASSERT_EQ (2u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('3', ex.PeekChar());
|
||||
ASSERT_EQ ('3', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Underflow_NoEof)
|
||||
|
@ -174,6 +181,7 @@ TEST_F (StringExtractorTest, GetHexU8_Underflow_NoEof)
|
|||
ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
|
||||
ASSERT_EQ (true, ex.Empty());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Underflow2_NoEof)
|
||||
|
@ -186,7 +194,7 @@ TEST_F (StringExtractorTest, GetHexU8_Underflow2_NoEof)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (0u, ex.GetFilePos());
|
||||
ASSERT_EQ (1u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('1', ex.PeekChar());
|
||||
ASSERT_EQ ('1', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_InvalidHex_NoEof)
|
||||
|
@ -199,7 +207,7 @@ TEST_F (StringExtractorTest, GetHexU8_InvalidHex_NoEof)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (0u, ex.GetFilePos());
|
||||
ASSERT_EQ (2u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('x', ex.PeekChar());
|
||||
ASSERT_EQ ('x', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Exact_NoEof)
|
||||
|
@ -212,6 +220,7 @@ TEST_F (StringExtractorTest, GetHexU8_Exact_NoEof)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (2u, ex.GetFilePos());
|
||||
ASSERT_EQ (0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ (nullptr, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexU8_Extra_NoEof)
|
||||
|
@ -224,7 +233,7 @@ TEST_F (StringExtractorTest, GetHexU8_Extra_NoEof)
|
|||
ASSERT_EQ (true, ex.IsGood());
|
||||
ASSERT_EQ (2u, ex.GetFilePos());
|
||||
ASSERT_EQ (2u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('3', ex.PeekChar());
|
||||
ASSERT_EQ ('3', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexBytes)
|
||||
|
@ -248,7 +257,7 @@ TEST_F (StringExtractorTest, GetHexBytes)
|
|||
ASSERT_EQ(2*kValidHexPairs, ex.GetFilePos());
|
||||
ASSERT_EQ(false, ex.Empty());
|
||||
ASSERT_EQ(4u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('x', ex.PeekChar());
|
||||
ASSERT_EQ('x', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F(StringExtractorTest, GetHexBytes_FullString)
|
||||
|
@ -335,6 +344,7 @@ TEST_F (StringExtractorTest, GetHexBytes_Underflow)
|
|||
ASSERT_EQ(UINT64_MAX, ex.GetFilePos());
|
||||
ASSERT_EQ(false, ex.Empty());
|
||||
ASSERT_EQ(0u, ex.GetBytesLeft());
|
||||
ASSERT_EQ(0, ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexBytes_Partial)
|
||||
|
@ -364,7 +374,7 @@ TEST_F (StringExtractorTest, GetHexBytes_Partial)
|
|||
ASSERT_EQ(kReadBytes*2, ex.GetFilePos());
|
||||
ASSERT_EQ(false, ex.Empty());
|
||||
ASSERT_EQ(12u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('2', ex.PeekChar());
|
||||
ASSERT_EQ('2', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexBytesAvail)
|
||||
|
@ -388,7 +398,7 @@ TEST_F (StringExtractorTest, GetHexBytesAvail)
|
|||
ASSERT_EQ(2*kValidHexPairs, ex.GetFilePos());
|
||||
ASSERT_EQ(false, ex.Empty());
|
||||
ASSERT_EQ(4u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('x', ex.PeekChar());
|
||||
ASSERT_EQ('x', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F(StringExtractorTest, GetHexBytesAvail_FullString)
|
||||
|
@ -471,7 +481,7 @@ TEST_F (StringExtractorTest, GetHexBytesAvail_Underflow)
|
|||
ASSERT_EQ(kValidHexPairs*2, ex.GetFilePos());
|
||||
ASSERT_EQ(false, ex.Empty());
|
||||
ASSERT_EQ(4u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('x', ex.PeekChar());
|
||||
ASSERT_EQ('x', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F (StringExtractorTest, GetHexBytesAvail_Partial)
|
||||
|
@ -501,7 +511,7 @@ TEST_F (StringExtractorTest, GetHexBytesAvail_Partial)
|
|||
ASSERT_EQ(kReadBytes*2, ex.GetFilePos());
|
||||
ASSERT_EQ(false, ex.Empty());
|
||||
ASSERT_EQ(12u, ex.GetBytesLeft());
|
||||
ASSERT_EQ('2', ex.PeekChar());
|
||||
ASSERT_EQ('2', *ex.Peek());
|
||||
}
|
||||
|
||||
TEST_F(StringExtractorTest, GetNameColonValueSuccess)
|
||||
|
|
Loading…
Reference in New Issue