Commit 4d4f831a authored by Kenton Varda's avatar Kenton Varda

Fix message corruption bug introduced in 2c9c5c83.

As of that change, adopting an empty struct into a pointer that already had some other value fails to overwrite the upper 32 bits of the pointer, thus resulting in a struct pointer with totally bogus bounds. Normally this will either cause a bounds check exception to be thrown when that pointer is later accessed, or lead to a struct containing bogus data (but if teh struct was expected to be empty, probably that data is never accessed).
parent dd854d87
......@@ -897,14 +897,14 @@ struct WireHelpers {
if (dstSegment == srcSegment) {
// Same segment, so create a direct pointer.
if (srcTag->kind() == WirePointer::STRUCT && srcTag->structRef.wordSize() == 0) {
if (srcTag->kind() == WirePointer::STRUCT && srcTag->structRef.wordSize() == 0 * WORDS) {
dst->setKindAndTargetForEmptyStruct();
} else {
dst->setKindAndTarget(srcTag->kind(), srcPtr, dstSegment);
// We can just copy the upper 32 bits. (Use memcpy() to comply with aliasing rules.)
memcpy(&dst->upper32Bits, &srcTag->upper32Bits, sizeof(srcTag->upper32Bits));
}
// We can just copy the upper 32 bits. (Use memcpy() to comply with aliasing rules.)
memcpy(&dst->upper32Bits, &srcTag->upper32Bits, sizeof(srcTag->upper32Bits));
} else {
// Need to create a far pointer. Try to allocate it in the same segment as the source, so
// that it doesn't need to be a double-far.
......
......@@ -55,6 +55,19 @@ TEST(Orphans, EmptyStruct) {
EXPECT_TRUE(anyPointer.isNull());
auto orphan = builder.getOrphanage().newOrphan<test::TestEmptyStruct>();
anyPointer.adopt(kj::mv(orphan));
EXPECT_EQ(0, anyPointer.targetSize().wordCount);
EXPECT_FALSE(anyPointer.isNull());
}
TEST(Orphans, EmptyStructOverwrite) {
MallocMessageBuilder builder;
auto root = builder.initRoot<test::TestAnyPointer>();
auto anyPointer = root.getAnyPointerField();
EXPECT_TRUE(anyPointer.isNull());
anyPointer.initAs<TestAllTypes>();
auto orphan = builder.getOrphanage().newOrphan<test::TestEmptyStruct>();
anyPointer.adopt(kj::mv(orphan));
EXPECT_EQ(0, anyPointer.targetSize().wordCount);
EXPECT_FALSE(anyPointer.isNull());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment