Skip to content

Commit

Permalink
Implement EOF1 (code & data sections) validation
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Apr 6, 2021
1 parent 9eeee32 commit fcea887
Showing 1 changed file with 94 additions and 3 deletions.
97 changes: 94 additions & 3 deletions test/experimental/eof_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ enum class error_code
invalid_eof_prefix,
eof_version_mismatch,
eof_version_unknown,

incomplete_section_size,
code_section_missing,
unknown_section_id,
zero_section_size,
section_headers_not_terminated,
invalid_section_bodies_size,

impossible,
};

error_code validate(bytes_view code, int expected_version);
Expand Down Expand Up @@ -53,7 +62,73 @@ error_code validate(bytes_view code, int expected_version)

error_code validate_eof1(bytes_view code_without_prefix)
{
(void)code_without_prefix;
enum class State
{
section_id,
section_size,
terminated
};

auto state = State::section_id;
uint8_t section_id;
int section_sizes[3] = {0, 0, 0};
auto it = code_without_prefix.begin();
while (it != code_without_prefix.end() && state != State::terminated)
{
switch (state)
{
case State::section_id:
{
section_id = *it;
switch (section_id)
{
case TERMINATOR:
if (section_sizes[CODE_SECTION] == 0)
return error_code::code_section_missing;
state = State::terminated;
break;
case DATA_SECTION:
if (section_sizes[CODE_SECTION] == 0)
return error_code::code_section_missing;
[[fallthrough]];
case CODE_SECTION:
state = State::section_size;
break;
default:
return error_code::unknown_section_id;
}
break;
}
case State::section_size:
{
const auto size_hi = *it;
++it;
if (it == code_without_prefix.end())
return error_code::incomplete_section_size;
const auto size_lo = *it;
const auto section_size = (size_hi << 8) | size_lo;
if (section_size == 0)
return error_code::zero_section_size;

section_sizes[section_id] = section_size;
state = State::section_id;
break;
}
case State::terminated:
return error_code::impossible;
}

++it;
}

if (state != State::terminated)
return error_code::section_headers_not_terminated;

const auto section_bodies_size = section_sizes[CODE_SECTION] + section_sizes[DATA_SECTION];
const auto remaining_code_size = code_without_prefix.end() - it;
if (section_bodies_size != remaining_code_size)
return error_code::invalid_section_bodies_size;

return error_code::success;
}
} // namespace eof
Expand All @@ -77,7 +152,7 @@ TEST_CASE("reject code starting with FORMAT in intermediate period")

TEST_CASE("validate EOF prefix")
{
CHECK(validate(from_hex("EFA61C01"), 1) == error_code::success);
CHECK(validate(from_hex("EFA61C01"), 1) == error_code::section_headers_not_terminated);

CHECK(validate(from_hex(""), 1) == error_code::invalid_eof_prefix);
CHECK(validate(from_hex("EF"), 1) == error_code::invalid_eof_prefix);
Expand All @@ -91,10 +166,26 @@ TEST_CASE("validate EOF prefix")

TEST_CASE("validate EOF version")
{
CHECK(validate(from_hex("EFA61C01"), 1) == error_code::success);
CHECK(validate(from_hex("EFA61C01"), 1) == error_code::section_headers_not_terminated);
CHECK(validate(from_hex("EFA61C02"), 2) == error_code::eof_version_unknown);
CHECK(validate(from_hex("EFA61CFF"), 0xff) == error_code::eof_version_unknown);

CHECK(validate(from_hex("EFA61C01"), 2) == error_code::eof_version_mismatch);
CHECK(validate(from_hex("EFA61C02"), 1) == error_code::eof_version_mismatch);
}

TEST_CASE("minimal valid EOF1 code")
{
CHECK(validate(from_hex("EFA61C01 010001 00 FE"), 1) == error_code::success);
}

TEST_CASE("minimal valid EOF1 code with data")
{
CHECK(validate(from_hex("EFA61C01 010001 020001 00 FE DA"), 1) == error_code::success);
}

TEST_CASE("EOF1 code section missing")
{
CHECK(validate(from_hex("EFA61C01 00"), 1) == error_code::code_section_missing);
CHECK(validate(from_hex("EFA61C01 020001 DA"), 1) == error_code::code_section_missing);
}

0 comments on commit fcea887

Please sign in to comment.