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[]) { ...@@ -66,10 +66,7 @@ int main(int argc, char* argv[]) {
capnp::MallocMessageBuilder parserArena; capnp::MallocMessageBuilder parserArena;
auto parsedFile = parserArena.initRoot<capnp::compiler::ParsedFile>(); auto parsedFile = parserArena.initRoot<capnp::compiler::ParsedFile>();
capnp::compiler::parseFile(lexedFile.getStatements(), parsedFile, errorReporter); capnp::compiler::parseFile(lexedFile.getStatements(), parsedFile, errorReporter);
KJ_DBG(parsedFile);
capnp::MallocMessageBuilder parserArena2;
parserArena2.setRoot(parsedFile.asReader());
//KJ_DBG(parsedFile);
return 0; return 0;
} }
...@@ -2445,7 +2445,7 @@ OrphanBuilder OrphanBuilder::initStructList( ...@@ -2445,7 +2445,7 @@ OrphanBuilder OrphanBuilder::initStructList(
result.tagAsPtr(), result.segment, elementCount, elementSize); result.tagAsPtr(), result.segment, elementCount, elementSize);
KJ_ASSERT(builder.segment == result.segment, KJ_ASSERT(builder.segment == result.segment,
"Orphan was unexpectedly allocated in a different 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; return result;
} }
} }
...@@ -2563,7 +2563,7 @@ ListBuilder OrphanBuilder::asStructList(StructSize elementSize) { ...@@ -2563,7 +2563,7 @@ ListBuilder OrphanBuilder::asStructList(StructSize elementSize) {
if (tagAsPtr()->kind() == WirePointer::FAR) { if (tagAsPtr()->kind() == WirePointer::FAR) {
location = nullptr; location = nullptr;
} else { } else {
location = reinterpret_cast<word*>(result.ptr); location = reinterpret_cast<word*>(result.ptr) - POINTER_SIZE_IN_WORDS;
} }
return result; return result;
...@@ -2592,7 +2592,11 @@ ObjectBuilder OrphanBuilder::asObject() { ...@@ -2592,7 +2592,11 @@ ObjectBuilder OrphanBuilder::asObject() {
location = reinterpret_cast<word*>(result.structBuilder.data); location = reinterpret_cast<word*>(result.structBuilder.data);
break; break;
case ObjectKind::LIST: 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; break;
case ObjectKind::NULL_POINTER: case ObjectKind::NULL_POINTER:
location = nullptr; location = nullptr;
......
...@@ -68,6 +68,31 @@ TEST(Orphans, Lists) { ...@@ -68,6 +68,31 @@ TEST(Orphans, Lists) {
checkList(root.asReader().getUInt32List(), {12u, 34u, 56u}); 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) { TEST(Orphans, Text) {
MallocMessageBuilder builder; MallocMessageBuilder builder;
auto root = builder.initRoot<TestAllTypes>(); auto root = builder.initRoot<TestAllTypes>();
...@@ -321,6 +346,32 @@ TEST(Orphans, DynamicList) { ...@@ -321,6 +346,32 @@ TEST(Orphans, DynamicList) {
checkList(root.asReader().getObjectField<List<uint32_t>>(), {12u, 34u, 56u}); 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) { TEST(Orphans, OrphanageDynamicStruct) {
MallocMessageBuilder builder; 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