[ORC] Fix serialization / deserialization of default-constructed ArrayRef<char>.

Avoids a zero-length memcpy from a null src, which caused errors on some of the
sanitizer bots. Also uses null when deserializing an empty ArrayRef (rather
than pointing to a zero length range in the middle of the input buffer).
This commit is contained in:
Lang Hames
2022-07-18 20:36:17 -07:00
parent 58dfaaaace
commit 67220c2ad7
2 changed files with 25 additions and 1 deletions

View File

@@ -56,6 +56,7 @@ public:
SPSOutputBuffer(char *Buffer, size_t Remaining)
: Buffer(Buffer), Remaining(Remaining) {}
bool write(const char *Data, size_t Size) {
assert(Data && "Data must not be null");
if (Size > Remaining)
return false;
memcpy(Buffer, Data, Size);
@@ -349,6 +350,8 @@ public:
static bool serialize(SPSOutputBuffer &OB, const ArrayRef<char> &A) {
if (!SPSArgList<uint64_t>::serialize(OB, static_cast<uint64_t>(A.size())))
return false;
if (A.empty()) // Empty ArrayRef may have null data, so bail out early.
return true;
return OB.write(A.data(), A.size());
}
@@ -358,7 +361,7 @@ public:
return false;
if (Size > std::numeric_limits<size_t>::max())
return false;
A = {IB.data(), static_cast<size_t>(Size)};
A = {Size ? IB.data() : nullptr, static_cast<size_t>(Size)};
return IB.skip(Size);
}
};

View File

@@ -187,3 +187,24 @@ TEST(SimplePackedSerializationTest, ArrayRef) {
// Input should reference buffer.
EXPECT_LT(HelloIn.data() - Buffer, BufferSize);
}
TEST(SimplePackedSerializationTest, ArrayRefEmpty) {
// Make sure that empty ArrayRefs serialize and deserialize as expected.
// Empty ArrayRefs should not succeed even when the data field is null, and
// should deserialize to a default-constructed ArrayRef, not a pointer into
// the stream.
constexpr unsigned BufferSize = sizeof(uint64_t);
char Buffer[BufferSize];
memset(Buffer, 0, BufferSize);
ArrayRef<char> AOut;
SPSOutputBuffer OB(Buffer, BufferSize);
EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, AOut));
ArrayRef<char> AIn;
SPSInputBuffer IB(Buffer, BufferSize);
EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, AIn));
EXPECT_EQ(AIn.data(), nullptr);
EXPECT_EQ(AIn.size(), 0U);
}