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