[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:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user