Skip to content

Commit

Permalink
fdt-v2: make parser validation local
Browse files Browse the repository at this point in the history
Signed-off-by: Bartłomiej Burdukiewicz <bartlomiej.burdukiewicz@gmail.com>
  • Loading branch information
dev-0x7C6 committed Mar 5, 2025
1 parent 2bb51bb commit f1cbbd4
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 61 deletions.
105 changes: 49 additions & 56 deletions src/fdt/fdt-parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,57 @@
#include <cstdint>
#include <cstring>
#include <expected>
#include <iostream>
#include <string_view>
#include <variant>

#include <iostream>

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 <class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};

auto validate(const fdt::parser::tokens &tokens) -> std::optional<fdt::parser::status> {
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 {
Expand Down Expand Up @@ -124,9 +163,15 @@ auto fdt::parser::parse(std::string_view view) -> std::expected<fdt::parser::res
}
}

const auto status = validate(tokens);

if (!status)
return std::unexpected(error::invalid_structure);

return fdt::parser::result{
.header = header,
.tokens = std::move(tokens),
.tokens = tokens,
.status = status.value(),
};
}

Expand Down Expand Up @@ -163,55 +208,3 @@ auto fdt::parser::rename_root(fdt::parser::tokens &tokens, std::string_view name

return false;
}

template <class... Ts>
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;
}
13 changes: 11 additions & 2 deletions src/fdt/fdt-parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<result, error>;
auto parse_multiple_offsets(std::string_view data) -> std::vector<std::expected<result, error>>;
auto validate(const result &) -> bool;
auto validate(const tokens &) -> bool;
auto rename_root(tokens &, std::string_view name) -> bool;

} // namespace fdt::parser
3 changes: 0 additions & 3 deletions src/fdt/fdt-view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit f1cbbd4

Please sign in to comment.