[Lldb-commits] [lldb] r243846 - GDBRemoteCommunication::DecompressPacket assumed that the buffer it was

Jason Molenda jmolenda at apple.com
Sat Aug 1 18:36:09 PDT 2015


Author: jmolenda
Date: Sat Aug  1 20:36:09 2015
New Revision: 243846

URL: http://llvm.org/viewvc/llvm-project?rev=243846&view=rev
Log:
GDBRemoteCommunication::DecompressPacket assumed that the buffer it was
working with (the Communication m_bytes ivar) contained a single packet.
Instead, it may contain multitudes.  Find the boundaries of the first packet
in the buffer and replace that with the decompressed version leaving the
rest of the buffer unmodified.
<rdar://problem/21841377> 

Modified:
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=243846&r1=243845&r2=243846&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Sat Aug  1 20:36:09 2015
@@ -574,15 +574,24 @@ GDBRemoteCommunication::DecompressPacket
         return true;
     if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
         return true;
-    if (m_bytes[pkt_size - 3] != '#')
+
+    size_t hash_mark_idx = m_bytes.find ('#');
+    if (hash_mark_idx == std::string::npos)
+        return true;
+    if (hash_mark_idx + 2 >= m_bytes.size())
         return true;
-    if (!::isxdigit (m_bytes[pkt_size - 2]) || !::isxdigit (m_bytes[pkt_size - 1]))
+
+    if (!::isxdigit (m_bytes[hash_mark_idx + 1]) || !::isxdigit (m_bytes[hash_mark_idx + 2]))
         return true;
 
-    size_t content_length = pkt_size - 5;   // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
-    size_t content_start = 2;               // The first character of the compressed/not-compressed text of the packet
-    size_t hash_mark_idx = pkt_size - 3;    // The '#' character marking the end of the packet
-    size_t checksum_idx = pkt_size - 2;     // The first character of the two hex checksum characters
+    size_t content_length = pkt_size - 5;    // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
+    size_t content_start = 2;                // The first character of the compressed/not-compressed text of the packet
+    size_t checksum_idx = hash_mark_idx + 1; // The first character of the two hex checksum characters
+
+    // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain multiple packets.
+    // size_of_first_packet is the size of the initial packet which we'll replace with the decompressed
+    // version of, leaving the rest of m_bytes unmodified.
+    size_t size_of_first_packet = hash_mark_idx + 3; 
 
     // Compressed packets ("$C") start with a base10 number which is the size of the uncompressed payload,
     // then a : and then the compressed data.  e.g. $C1024:<binary>#00
@@ -604,7 +613,7 @@ GDBRemoteCommunication::DecompressPacket
             decompressed_bufsize = ::strtoul (bufsize_str.c_str(), NULL, 10);
             if (errno != 0 || decompressed_bufsize == ULONG_MAX)
             {
-                m_bytes.erase (0, pkt_size);
+                m_bytes.erase (0, size_of_first_packet);
                 return false;
             }
         }
@@ -633,7 +642,7 @@ GDBRemoteCommunication::DecompressPacket
         if (!success)
         {
             SendNack();
-            m_bytes.erase (0, pkt_size);
+            m_bytes.erase (0, size_of_first_packet);
             return false;
         }
         else
@@ -677,7 +686,7 @@ GDBRemoteCommunication::DecompressPacket
         decompressed_buffer = (uint8_t *) malloc (decompressed_bufsize + 1);
         if (decompressed_buffer == nullptr)
         {
-            m_bytes.erase (0, pkt_size);
+            m_bytes.erase (0, size_of_first_packet);
             return false;
         }
 
@@ -751,7 +760,7 @@ GDBRemoteCommunication::DecompressPacket
     {
         if (decompressed_buffer)
             free (decompressed_buffer);
-        m_bytes.erase (0, pkt_size);
+        m_bytes.erase (0, size_of_first_packet);
         return false;
     }
 
@@ -773,7 +782,7 @@ GDBRemoteCommunication::DecompressPacket
         new_packet.push_back ('0');
     }
 
-    m_bytes = new_packet;
+    m_bytes.replace (0, size_of_first_packet, new_packet.data(), new_packet.size());
 
     free (decompressed_buffer);
     return true;





More information about the lldb-commits mailing list