diff --git a/src/fdt/fdt-parser.cpp b/src/fdt/fdt-parser.cpp index 7d7c2c0..6d074be 100644 --- a/src/fdt/fdt-parser.cpp +++ b/src/fdt/fdt-parser.cpp @@ -8,18 +8,57 @@ #include #include #include -#include #include #include -#include - auto align(const std::size_t size) { const auto q = size % sizeof(u32); const auto w = size / sizeof(u32); return w + (q ? 1u : 0u); }; +template +struct overloaded : Ts... { + using Ts::operator()...; +}; + +auto validate(const fdt::parser::tokens &tokens) -> std::optional { + fdt::parser::status ret; + bool valid_depth_test = true; + + using namespace fdt::parser; + + for (auto &&token : tokens) { + std::visit(overloaded{ + [&](const token_types::node_begin &) { + ret.node_begin_count++; + ret.node_scope_depth++; + }, + [&](const token_types::node_end &) { + ret.node_end_count++; + ret.node_scope_depth--; + }, + [&](const token_types::property &) { + ret.property_count++; + }, + [&](const token_types::nop &) { ret.nop_count++; }, + [&](const token_types::end &) { ret.end_count++; }, + }, + token); + + // check that we never go below 0 + valid_depth_test &= (ret.node_scope_depth >= 0); + } + + if (!valid_depth_test) + return {}; + + if (ret.node_begin_count != ret.node_end_count) + return {}; + + return ret; +} + namespace fdt::parser { auto parse(token_types::node_begin &&token, context &ctx) -> fdt::parser::token { @@ -124,9 +163,15 @@ auto fdt::parser::parse(std::string_view view) -> std::expected -struct overloaded : Ts... { - using Ts::operator()...; -}; - -auto fdt::parser::validate(const fdt::parser::result &fdt) -> bool { - return validate(fdt.tokens); -} - -auto fdt::parser::validate(const fdt::parser::tokens &tokens) -> bool { - using namespace fdt::parser; - - bool valid_depth_test{true}; - std::int32_t node_scope_depth{}; - std::int32_t node_begin_count{}; - std::int32_t node_end_count{}; - std::int32_t property_count{}; - std::int32_t nop_count{}; - std::int32_t end_count{}; - - for (auto &&token : tokens) { - std::visit(overloaded{ - [&](const token_types::node_begin &) { - node_begin_count++; - node_scope_depth++; - }, - [&](const token_types::node_end &) { - node_end_count++; - node_scope_depth--; - }, - [&](const token_types::property &) { - property_count++; - }, - [&](const token_types::nop &) { nop_count++; }, - [&](const token_types::end &) { end_count++; }, - }, - token); - - // check that we never go below 0 - valid_depth_test &= (node_scope_depth >= 0); - } - - std::cout << "node depth validation: " << valid_depth_test << std::endl; - std::cout << "node begin: " << node_begin_count << std::endl; - std::cout << "node end : " << node_end_count << std::endl; - std::cout << "property : " << property_count << std::endl; - std::cout << "nop : " << nop_count << std::endl; - std::cout << "end : " << end_count << std::endl; - - return valid_depth_test && node_begin_count == node_end_count; -} diff --git a/src/fdt/fdt-parser.hpp b/src/fdt/fdt-parser.hpp index 74d9dd3..aeb59cf 100644 --- a/src/fdt/fdt-parser.hpp +++ b/src/fdt/fdt-parser.hpp @@ -14,21 +14,30 @@ enum class error { invalid_header, invalid_magic, invalid_token, + invalid_structure, data_truncated, data_unaligned, unsupported_version, }; +struct status { + std::int64_t node_scope_depth{}; + std::int64_t node_begin_count{}; + std::int64_t node_end_count{}; + std::int64_t property_count{}; + std::int64_t nop_count{}; + std::int64_t end_count{}; +}; + struct result { std::uint64_t offset{}; fdt::decode::header header; fdt::parser::tokens tokens; + fdt::parser::status status; }; auto parse(std::string_view data) -> std::expected; auto parse_multiple_offsets(std::string_view data) -> std::vector>; -auto validate(const result &) -> bool; -auto validate(const tokens &) -> bool; auto rename_root(tokens &, std::string_view name) -> bool; } // namespace fdt::parser diff --git a/src/fdt/fdt-view.cpp b/src/fdt/fdt-view.cpp index 7531d7a..4cd744e 100644 --- a/src/fdt/fdt-view.cpp +++ b/src/fdt/fdt-view.cpp @@ -109,9 +109,6 @@ bool fdt::viewer::load(QByteArray &&data, QString &&name, QString &&id) { if (!result) return false; - if (!validate(result.value())) - return false; - auto &&tokens = result.value().tokens; QString root_id = id;