[lldb/Reproducers] Include string length in string (de)serialization.
This allows us to differentiate between an empty string and a nullptr.
(cherry picked from commit 53e206284fa715886020d6a5553bf791582850a3)
diff --git a/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/lldb/include/lldb/Utility/ReproducerInstrumentation.h
index e91eb7f..b0424e4 100644
--- a/lldb/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/lldb/include/lldb/Utility/ReproducerInstrumentation.h
@@ -602,8 +602,12 @@
}
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 @@
Serialize(size);
// Serialize the content of the array.
- while (*t) {
- m_stream << *t;
- m_stream.write(0x0);
- ++t;
- }
+ while (*t)
+ Serialize(*t++);
}
/// Serialization stream.
diff --git a/lldb/source/Utility/ReproducerInstrumentation.cpp b/lldb/source/Utility/ReproducerInstrumentation.cpp
index 1835e70..cfb77c0 100644
--- a/lldb/source/Utility/ReproducerInstrumentation.cpp
+++ b/lldb/source/Utility/ReproducerInstrumentation.cpp
@@ -28,11 +28,12 @@
}
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 **>() {
- size_t size = Deserialize<size_t>();
+ const size_t size = Deserialize<size_t>();
if (size == 0)
return nullptr;
const char **r =
diff --git a/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp b/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp
index e87c49f..490d188 100644
--- a/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp
+++ b/lldb/unittests/Utility/ReproducerInstrumentationTest.cpp
@@ -393,6 +393,21 @@
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";