From 94e6d2677bd3748b344aa5abccfc7284dbea8be0 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 19 Jul 2022 17:19:58 -0700 Subject: [PATCH] [ORC] Fix serialization / deserialization of default-constructed StringRef. Avoids accessing the data field on zero-length strings. This is the StringRef counterpart to the ArrayRef fix in 67220c2ad72e3. rdar://97285294 --- .../Orc/Shared/SimplePackedSerialization.h | 4 +++- .../Orc/SimplePackedSerializationTest.cpp | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h index 794c07b..c388259 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h @@ -479,6 +479,8 @@ public: static bool serialize(SPSOutputBuffer &OB, StringRef S) { if (!SPSArgList::serialize(OB, static_cast(S.size()))) return false; + if (S.empty()) // Empty StringRef may have null data, so bail out early. + return true; return OB.write(S.data(), S.size()); } @@ -490,7 +492,7 @@ public: Data = IB.data(); if (!IB.skip(Size)) return false; - S = StringRef(Data, Size); + S = StringRef(Size ? Data : nullptr, Size); return true; } }; diff --git a/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp b/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp index f5319e3..ee73614 100644 --- a/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp @@ -208,3 +208,24 @@ TEST(SimplePackedSerializationTest, ArrayRefEmpty) { EXPECT_EQ(AIn.data(), nullptr); EXPECT_EQ(AIn.size(), 0U); } + +TEST(SimplePackedSerializationTest, StringRefEmpty) { + // Make sure that empty StringRefs serialize and deserialize as expected. + // Empty StringRefs should not succeed even when the data field is null, and + // should deserialize to a default-constructed StringRef, not a pointer into + // the stream. + constexpr unsigned BufferSize = sizeof(uint64_t); + char Buffer[BufferSize]; + memset(Buffer, 0, BufferSize); + + StringRef SROut; + SPSOutputBuffer OB(Buffer, BufferSize); + EXPECT_TRUE(SPSArgList>::serialize(OB, SROut)); + + StringRef SRIn; + SPSInputBuffer IB(Buffer, BufferSize); + EXPECT_TRUE(SPSArgList>::deserialize(IB, SRIn)); + + EXPECT_EQ(SRIn.data(), nullptr); + EXPECT_EQ(SRIn.size(), 0U); +} -- 2.7.4