OSDN Git Service

[lldb/Reproducers] Include string length in string (de)serialization.
authorJonas Devlieghere <jonas@devlieghere.com>
Sat, 1 Feb 2020 00:17:28 +0000 (16:17 -0800)
committerJonas Devlieghere <jonas@devlieghere.com>
Sat, 1 Feb 2020 01:40:49 +0000 (17:40 -0800)
This allows us to differentiate between an empty string and a nullptr.

(cherry picked from commit 53e206284fa715886020d6a5553bf791582850a3)

lldb/include/lldb/Utility/ReproducerInstrumentation.h
lldb/source/Utility/ReproducerInstrumentation.cpp
lldb/unittests/Utility/ReproducerInstrumentationTest.cpp

index e91eb7f..b0424e4 100644 (file)
@@ -602,8 +602,12 @@ private:
   }
 
   void Serialize(const char *t) {
-    m_stream << t;
-    m_stream.write(0x0);
+    const size_t size = t ? strlen(t) : std::numeric_limits<size_t>::max();
+    Serialize(size);
+    if (t) {
+      m_stream << t;
+      m_stream.write(0x0);
+    }
   }
 
   void Serialize(const char **t) {
@@ -620,11 +624,8 @@ private:
     Serialize(size);
 
     // Serialize the content of the array.
-    while (*t) {
-      m_stream << *t;
-      m_stream.write(0x0);
-      ++t;
-    }
+    while (*t)
+      Serialize(*t++);
   }
 
   /// Serialization stream.
index 1835e70..cfb77c0 100644 (file)
@@ -28,11 +28,12 @@ template <> char *Deserializer::Deserialize<char *>() {
 }
 
 template <> const char *Deserializer::Deserialize<const char *>() {
-  auto pos = m_buffer.find('\0');
-  if (pos == llvm::StringRef::npos)
+  const size_t size = Deserialize<size_t>();
+  if (size == std::numeric_limits<size_t>::max())
     return nullptr;
+  assert(HasData(size + 1));
   const char *str = m_buffer.data();
-  m_buffer = m_buffer.drop_front(pos + 1);
+  m_buffer = m_buffer.drop_front(size + 1);
 #ifdef LLDB_REPRO_INSTR_TRACE
   llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> \""
                << str << "\"\n";
@@ -41,7 +42,7 @@ template <> const char *Deserializer::Deserialize<const char *>() {
 }
 
 template <> const char **Deserializer::Deserialize<const char **>() {
-  size_t size = Deserialize<size_t>();
+  const size_t size = Deserialize<size_t>();
   if (size == 0)
     return nullptr;
   const char **r =
index e87c49f..490d188 100644 (file)
@@ -393,6 +393,21 @@ TEST(SerializationRountripTest, SerializeDeserializeCString) {
   EXPECT_STREQ(cstr, deserializer.Deserialize<const char *>());
 }
 
+TEST(SerializationRountripTest, SerializeDeserializeCStringNull) {
+  const char *cstr = nullptr;
+
+  std::string str;
+  llvm::raw_string_ostream os(str);
+
+  Serializer serializer(os);
+  serializer.SerializeAll(cstr);
+
+  llvm::StringRef buffer(os.str());
+  Deserializer deserializer(buffer);
+
+  EXPECT_EQ(nullptr, deserializer.Deserialize<const char *>());
+}
+
 TEST(SerializationRountripTest, SerializeDeserializeCStringArray) {
   const char *foo = "foo";
   const char *bar = "bar";