Commit fae34de9 authored by David Renshaw's avatar David Renshaw

teach isCanonical() to validate inlineCompositeWordCount

parent cc4611d3
......@@ -202,6 +202,34 @@ KJ_TEST("isCanonical accepts empty inline composite list of zero-sized structs")
KJ_ASSERT(message.isCanonical());
}
KJ_TEST("isCanonical rejects inline composite list with inaccurate word-length") {
AlignedData<6> segment = {{
// Struct pointer, no offset, pointer section has two entries
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
// List pointer, offset of one, inline composite, two words long
// (The list only needs to be one word long to hold its actual elements;
// therefore this message is not canonical.)
0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
// Struct pointer, offset two, data section has one word
0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
// Tag word, struct, one element, one word data section
0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
// Data section of struct element of list
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
// Data section of struct field in top-level struct
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
}};
kj::ArrayPtr<const word> segments[1] = {kj::arrayPtr(segment.words, 6)};
SegmentArrayMessageReader message(kj::arrayPtr(segments, 1));
KJ_ASSERT(!message.isCanonical());
}
KJ_TEST("upgraded lists can be canonicalized") {
AlignedData<7> upgradedList = {{
//Struct pointer, data immediately follows, 4 pointer fields, no data
......
......@@ -2608,7 +2608,7 @@ bool PointerReader::isCanonical(const word **readHead) {
}
}
case PointerType::LIST:
return this->getListAnySize(nullptr).isCanonical(readHead);
return this->getListAnySize(nullptr).isCanonical(readHead, pointer);
case PointerType::CAPABILITY:
KJ_FAIL_ASSERT("Capabilities are not positional");
}
......@@ -2951,7 +2951,7 @@ ListReader ListReader::imbue(CapTableReader* capTable) const {
return result;
}
bool ListReader::isCanonical(const word **readHead) {
bool ListReader::isCanonical(const word **readHead, const WirePointer *ref) {
switch (this->getElementSize()) {
case ElementSize::INLINE_COMPOSITE: {
*readHead += 1;
......@@ -2965,6 +2965,9 @@ bool ListReader::isCanonical(const word **readHead) {
}
auto structSize = (this->structDataSize / BITS_PER_WORD) +
(this->structPointerCount * WORDS_PER_POINTER);
if (structSize * this->elementCount != ref->listRef.inlineCompositeWordCount()) {
return false;
}
if (structSize == 0 * WORDS) {
return true;
}
......
......@@ -769,7 +769,7 @@ public:
ListReader imbue(CapTableReader* capTable) const;
// Return a copy of this reader except using the given capability context.
bool isCanonical(const word **readHead);
bool isCanonical(const word **readHead, const WirePointer* ref);
// Validate this pointer's canonicity, subject to the conditions:
// * All data to the left of readHead has been read thus far (for pointer
// ordering)
......
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