1
0
mirror of synced 2024-11-12 02:00:52 +01:00

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:
Polshakov Dmitry 2022-03-20 23:42:21 +03:00 committed by GitHub
parent bc7c494316
commit 937ccbc5bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 153 additions and 3 deletions

View File

@ -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())

View File

@ -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})

View File

@ -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");
)";
}
};
}

View File

@ -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");
)";
}
};
}

View File

@ -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),
};