Commit 63035efd authored by Kenton Varda's avatar Kenton Varda

Fix pointer corruption when using orphaned struct lists.

parent 359ea45a
......@@ -66,10 +66,7 @@ int main(int argc, char* argv[]) {
capnp::MallocMessageBuilder parserArena;
auto parsedFile = parserArena.initRoot<capnp::compiler::ParsedFile>();
capnp::compiler::parseFile(lexedFile.getStatements(), parsedFile, errorReporter);
capnp::MallocMessageBuilder parserArena2;
parserArena2.setRoot(parsedFile.asReader());
//KJ_DBG(parsedFile);
KJ_DBG(parsedFile);
return 0;
}
......@@ -2445,7 +2445,7 @@ OrphanBuilder OrphanBuilder::initStructList(
result.tagAsPtr(), result.segment, elementCount, elementSize);
KJ_ASSERT(builder.segment == result.segment,
"Orphan was unexpectedly allocated in a different segment.");
result.location = reinterpret_cast<word*>(builder.ptr);
result.location = reinterpret_cast<word*>(builder.ptr) - POINTER_SIZE_IN_WORDS;
return result;
}
}
......@@ -2563,7 +2563,7 @@ ListBuilder OrphanBuilder::asStructList(StructSize elementSize) {
if (tagAsPtr()->kind() == WirePointer::FAR) {
location = nullptr;
} else {
location = reinterpret_cast<word*>(result.ptr);
location = reinterpret_cast<word*>(result.ptr) - POINTER_SIZE_IN_WORDS;
}
return result;
......@@ -2592,7 +2592,11 @@ ObjectBuilder OrphanBuilder::asObject() {
location = reinterpret_cast<word*>(result.structBuilder.data);
break;
case ObjectKind::LIST:
location = reinterpret_cast<word*>(result.listBuilder.ptr);
if (tagAsPtr()->listRef.elementSize() == FieldSize::INLINE_COMPOSITE) {
location = reinterpret_cast<word*>(result.listBuilder.ptr) - POINTER_SIZE_IN_WORDS;
} else {
location = reinterpret_cast<word*>(result.listBuilder.ptr);
}
break;
case ObjectKind::NULL_POINTER:
location = nullptr;
......
......@@ -68,6 +68,31 @@ TEST(Orphans, Lists) {
checkList(root.asReader().getUInt32List(), {12u, 34u, 56u});
}
TEST(Orphans, StructLists) {
MallocMessageBuilder builder;
auto root = builder.initRoot<TestAllTypes>();
auto list = root.initStructList(2);
list[0].setTextField("foo");
list[1].setTextField("bar");
EXPECT_TRUE(root.hasStructList());
Orphan<List<TestAllTypes>> orphan = root.disownStructList();
EXPECT_FALSE(orphan == nullptr);
ASSERT_EQ(2u, orphan.get().size());
EXPECT_EQ("foo", orphan.get()[0].getTextField());
EXPECT_EQ("bar", orphan.get()[1].getTextField());
EXPECT_FALSE(root.hasStructList());
root.adoptStructList(kj::mv(orphan));
EXPECT_TRUE(orphan == nullptr);
EXPECT_TRUE(root.hasStructList());
ASSERT_EQ(2u, root.asReader().getStructList().size());
EXPECT_EQ("foo", root.asReader().getStructList()[0].getTextField());
EXPECT_EQ("bar", root.asReader().getStructList()[1].getTextField());
}
TEST(Orphans, Text) {
MallocMessageBuilder builder;
auto root = builder.initRoot<TestAllTypes>();
......@@ -321,6 +346,32 @@ TEST(Orphans, DynamicList) {
checkList(root.asReader().getObjectField<List<uint32_t>>(), {12u, 34u, 56u});
}
TEST(Orphans, DynamicStructList) {
MallocMessageBuilder builder;
auto root = builder.initRoot<test::TestObject>();
auto list = root.initObjectField<List<TestAllTypes>>(2);
list[0].setTextField("foo");
list[1].setTextField("bar");
EXPECT_TRUE(root.hasObjectField());
Orphan<DynamicList> orphan =
root.disownObjectField<DynamicList>(Schema::from<List<TestAllTypes>>());
EXPECT_FALSE(orphan == nullptr);
ASSERT_EQ(2u, orphan.get().size());
EXPECT_EQ("foo", orphan.get()[0].as<TestAllTypes>().getTextField());
EXPECT_EQ("bar", orphan.get()[1].as<TestAllTypes>().getTextField());
EXPECT_FALSE(root.hasObjectField());
root.adoptObjectField(kj::mv(orphan));
EXPECT_TRUE(orphan == nullptr);
EXPECT_TRUE(root.hasObjectField());
ASSERT_EQ(2u, root.asReader().getObjectField<List<TestAllTypes>>().size());
EXPECT_EQ("foo", root.asReader().getObjectField<List<TestAllTypes>>()[0].getTextField());
EXPECT_EQ("bar", root.asReader().getObjectField<List<TestAllTypes>>()[1].getTextField());
}
TEST(Orphans, OrphanageDynamicStruct) {
MallocMessageBuilder builder;
......
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