patterns: Restore data offset for local variables / added array, nested structs and functions tests (#475)
* fix(eval): restore data offset for local variables * test(pattern_lang): add tests for arrays, nested structs and functions Co-authored-by: Dmitry Polshakov <dmitry.polshakov@dsr-corporation.com>
This commit is contained in:
parent
bc7c494316
commit
937ccbc5bd
@ -37,12 +37,13 @@ namespace hex::pl {
|
||||
auto startOffset = this->dataOffset();
|
||||
|
||||
std::unique_ptr<Pattern> pattern;
|
||||
this->dataOffset() = startOffset;
|
||||
|
||||
bool referenceType = false;
|
||||
|
||||
auto typePattern = type->createPatterns(this);
|
||||
|
||||
this->dataOffset() = startOffset;
|
||||
|
||||
if (typePattern.empty()) {
|
||||
// Handle auto variables
|
||||
if (!value.has_value())
|
||||
|
@ -19,6 +19,8 @@ set(AVAILABLE_TESTS
|
||||
Namespaces
|
||||
ExtraSemicolon
|
||||
Pointers
|
||||
Arrays
|
||||
NestedStructs
|
||||
)
|
||||
|
||||
|
||||
@ -42,4 +44,4 @@ add_custom_command(TARGET pattern_language_tests
|
||||
foreach (test IN LISTS AVAILABLE_TESTS)
|
||||
add_test(NAME "PatternLanguage/${test}" COMMAND pattern_language_tests "${test}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
endforeach ()
|
||||
add_dependencies(unit_tests ${PROJECT_NAME})
|
||||
add_dependencies(unit_tests ${PROJECT_NAME})
|
||||
|
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "test_pattern.hpp"
|
||||
|
||||
#include <hex/pattern_language/patterns/pattern_struct.hpp>
|
||||
#include <hex/pattern_language/patterns/pattern_array_dynamic.hpp>
|
||||
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace hex::test {
|
||||
|
||||
class TestPatternArrays : public TestPattern {
|
||||
public:
|
||||
TestPatternArrays() : TestPattern("Arrays") {
|
||||
auto first = create<PatternArrayStatic>("u8", "first", 0x0, sizeof(u8[4]));
|
||||
first->setEntries(create<PatternUnsigned>("u8", "", 0x0, sizeof(u8)), 4);
|
||||
|
||||
auto second = create<PatternArrayStatic>("u8", "second", 0x4, sizeof(u8[4]));
|
||||
second->setEntries(create<PatternUnsigned>("u8", "", 0x4, sizeof(u8)), 4);
|
||||
|
||||
auto testStruct = create<PatternStruct>("Signature", "sign", 0x0, sizeof(u8[8]));
|
||||
std::vector<std::shared_ptr<hex::pl::Pattern>> structMembers;
|
||||
{
|
||||
structMembers.push_back(std::move(first));
|
||||
structMembers.push_back(std::move(second));
|
||||
}
|
||||
testStruct->setMembers(std::move(structMembers));
|
||||
|
||||
addPattern(std::move(testStruct));
|
||||
}
|
||||
~TestPatternArrays() override = default;
|
||||
|
||||
[[nodiscard]] std::string getSourceCode() const override {
|
||||
return R"(
|
||||
fn end_of_signature() {
|
||||
return $ >= 8;
|
||||
};
|
||||
|
||||
struct Signature {
|
||||
u8 first[4];
|
||||
u8 second[while(!end_of_signature())];
|
||||
};
|
||||
|
||||
Signature sign @ 0x0;
|
||||
|
||||
std::assert(sign.first[0] == 0x89, "Invalid 1st byte of signature");
|
||||
std::assert(sign.first[1] == 0x50, "Invalid 2nd byte of signature");
|
||||
std::assert(sign.first[2] == 0x4E, "Invalid 3rd byte of signature");
|
||||
std::assert(sign.first[3] == 0x47, "Invalid 4th byte of signature");
|
||||
std::assert(sizeof(sign.second) == 4, "Invalid size of signature");
|
||||
std::assert(sign.second[0] == 0x0D, "Invalid 5th byte of signature");
|
||||
std::assert(sign.second[1] == 0x0A, "Invalid 6th byte of signature");
|
||||
std::assert(sign.second[2] == 0x1A, "Invalid 7th byte of signature");
|
||||
std::assert(sign.second[3] == 0x0A, "Invalid 8th byte of signature");
|
||||
)";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include "test_pattern.hpp"
|
||||
|
||||
#include <hex/pattern_language/patterns/pattern_struct.hpp>
|
||||
#include <hex/pattern_language/patterns/pattern_array_dynamic.hpp>
|
||||
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace hex::test {
|
||||
|
||||
class TestPatternNestedStructs : public TestPattern {
|
||||
public:
|
||||
TestPatternNestedStructs() : TestPattern("NestedStructs") {
|
||||
const size_t HEADER_START = 0x0;
|
||||
const size_t HEADER_SIZE = sizeof(u8);
|
||||
const size_t BODY_START = HEADER_SIZE;
|
||||
const size_t BODY_SIZE = 0x89 - 1;
|
||||
|
||||
auto data = create<PatternStruct>("Data", "data", HEADER_START, HEADER_SIZE + BODY_SIZE);
|
||||
{
|
||||
auto hdr = create<PatternStruct>("Header", "hdr", HEADER_START, HEADER_SIZE);
|
||||
{
|
||||
std::vector<std::shared_ptr<hex::pl::Pattern>> hdrMembers {
|
||||
std::shared_ptr(create<PatternUnsigned>("u8", "len", HEADER_START, sizeof(u8)))
|
||||
};
|
||||
hdr->setMembers(std::move(hdrMembers));
|
||||
}
|
||||
|
||||
auto body = create<PatternStruct>("Body", "body", BODY_START, BODY_SIZE);
|
||||
{
|
||||
auto bodyArray = create<PatternArrayStatic>("u8", "arr", BODY_START, BODY_SIZE);
|
||||
bodyArray->setEntries(create<PatternUnsigned>("u8", "", BODY_START, sizeof(u8)), BODY_SIZE);
|
||||
std::vector<std::shared_ptr<hex::pl::Pattern>> bodyMembers {
|
||||
std::shared_ptr(std::move(bodyArray))
|
||||
};
|
||||
body->setMembers(std::move(bodyMembers));
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<hex::pl::Pattern>> dataMembers {
|
||||
std::shared_ptr(std::move(hdr)),
|
||||
std::shared_ptr(std::move(body))
|
||||
};
|
||||
data->setMembers(std::move(dataMembers));
|
||||
}
|
||||
|
||||
addPattern(std::move(data));
|
||||
}
|
||||
~TestPatternNestedStructs() override = default;
|
||||
|
||||
[[nodiscard]] std::string getSourceCode() const override {
|
||||
return R"(
|
||||
fn end_of_body() {
|
||||
u32 start = addressof(parent.parent.hdr);
|
||||
u32 len = parent.parent.hdr.len;
|
||||
u32 end = start + len;
|
||||
|
||||
return $ >= end;
|
||||
};
|
||||
|
||||
struct Header {
|
||||
u8 len;
|
||||
};
|
||||
|
||||
struct Body {
|
||||
u8 arr[while(!end_of_body())];
|
||||
};
|
||||
|
||||
struct Data {
|
||||
Header hdr;
|
||||
Body body;
|
||||
};
|
||||
|
||||
Data data @ 0x0;
|
||||
|
||||
std::assert(data.hdr.len == 0x89, "Invalid length");
|
||||
std::assert(sizeof(data.body.arr) == 0x89 - 1, "Invalid size of body");
|
||||
)";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -14,6 +14,8 @@
|
||||
#include "test_patterns/test_pattern_namespaces.hpp"
|
||||
#include "test_patterns/test_pattern_extra_semicolon.hpp"
|
||||
#include "test_patterns/test_pattern_pointers.hpp"
|
||||
#include "test_patterns/test_pattern_arrays.hpp"
|
||||
#include "test_patterns/test_pattern_nested_structs.hpp"
|
||||
|
||||
std::array Tests = {
|
||||
TEST(Placement),
|
||||
@ -29,5 +31,7 @@ std::array Tests = {
|
||||
TEST(RValues),
|
||||
TEST(Namespaces),
|
||||
TEST(ExtraSemicolon),
|
||||
TEST(Pointers)
|
||||
TEST(Pointers),
|
||||
TEST(Arrays),
|
||||
TEST(NestedStructs),
|
||||
};
|
Loading…
Reference in New Issue
Block a user