Commit 175fa1aa authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #426 from dwrensha/fix-get-pointer-type

fix bug where PointerBuilder::getPointerType() can corrupt PointerBuilder::segment
parents 28e118d9 d1058e78
...@@ -264,7 +264,27 @@ TEST(Any, AnyStructListCapInSchema) { ...@@ -264,7 +264,27 @@ TEST(Any, AnyStructListCapInSchema) {
#endif #endif
} }
KJ_TEST("Builder::isStruct() does not corrupt segment pointer") {
MallocMessageBuilder builder(1); // small first segment
auto root = builder.getRoot<AnyPointer>();
// Do a lot of allocations so that there is likely a segment with a decent
// amount of free space.
initTestMessage(root.initAs<test::TestAllTypes>());
// This will probably get allocated in a segment that still has room for the
// Data allocation below.
root.initAs<test::TestAllTypes>();
// At one point, this caused root.builder.segment to point to the segment
// where the struct is allocated, rather than segment where the root pointer
// lives, i.e. segment zero.
EXPECT_TRUE(root.isStruct());
// If root.builder.segment points to the wrong segment and that segment has free
// space, then this triggers a DREQUIRE failure in WirePointer::setKindAndTarget().
root.initAs<Data>(1);
}
TEST(Any, Equals) { TEST(Any, Equals) {
MallocMessageBuilder builderA; MallocMessageBuilder builderA;
......
...@@ -2423,12 +2423,13 @@ void PointerBuilder::clear() { ...@@ -2423,12 +2423,13 @@ void PointerBuilder::clear() {
memset(pointer, 0, sizeof(WirePointer)); memset(pointer, 0, sizeof(WirePointer));
} }
PointerType PointerBuilder::getPointerType() { PointerType PointerBuilder::getPointerType() const {
if(pointer->isNull()) { if(pointer->isNull()) {
return PointerType::NULL_; return PointerType::NULL_;
} else { } else {
WirePointer* ptr = pointer; WirePointer* ptr = pointer;
WireHelpers::followFars(ptr, ptr->target(), segment); SegmentBuilder* sgmt = segment;
WireHelpers::followFars(ptr, ptr->target(), sgmt);
switch(ptr->kind()) { switch(ptr->kind()) {
case WirePointer::FAR: case WirePointer::FAR:
KJ_FAIL_ASSERT("far pointer not followed?"); KJ_FAIL_ASSERT("far pointer not followed?");
......
...@@ -318,7 +318,7 @@ public: ...@@ -318,7 +318,7 @@ public:
// location. // location.
inline bool isNull() { return getPointerType() == PointerType::NULL_; } inline bool isNull() { return getPointerType() == PointerType::NULL_; }
PointerType getPointerType(); PointerType getPointerType() const;
StructBuilder getStruct(StructSize size, const word* defaultValue); StructBuilder getStruct(StructSize size, const word* defaultValue);
ListBuilder getList(ElementSize elementSize, const word* defaultValue); ListBuilder getList(ElementSize elementSize, const word* defaultValue);
......
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