Skip to content

Wrong offset sparse mask #9

@mrexodia

Description

@mrexodia

Repro

#include <Pattern16.h>

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using u8 = std::uint8_t;

static std::string to_signature(const std::vector<u8>& pattern, const std::string& mask)
{
    std::ostringstream oss;
    for (size_t i = 0; i < mask.size(); ++i)
    {
        if (i) oss << ' ';
        if (mask[i] == 'x')
            oss << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned>(pattern[i]);
        else
            oss << "??";
    }
    return oss.str();
}

static size_t reference_find_first(const std::vector<u8>& data, const std::vector<u8>& pattern, const std::string& mask)
{
    for (size_t off = 0; off + pattern.size() <= data.size(); ++off)
    {
        bool match = true;
        for (size_t i = 0; i < pattern.size(); ++i)
        {
            if (mask[i] == 'x' && data[off + i] != pattern[i]) { match = false; break; }
        }
        if (match) return off;
    }
    return static_cast<size_t>(-1);
}

static size_t run_case(const std::vector<u8>& pattern, const std::string& mask, size_t length)
{
    std::vector<u8> data(length, 0x11);
    for (size_t base = 0; base + pattern.size() <= data.size(); base += 64)
    {
        for (size_t i = 0; i < pattern.size(); ++i)
            if (mask[i] == 'x') data[base + i] = pattern[i];
    }

    const std::string signature = to_signature(pattern, mask);
    const u8* found = static_cast<const u8*>(Pattern16::scan(data.data(), data.size(), signature));
    return found ? static_cast<size_t>(found - data.data()) : static_cast<size_t>(-1);
}

int main()
{
    const std::vector<u8> warmup_pattern = {0x00, 0x00, 0xBE, 0x00, 0xD9};
    const std::string warmup_mask = "??x?x";

    std::cout << "warmup_1024=" << run_case(warmup_pattern, warmup_mask, 1024) << "\n";
    std::cout << "warmup_2048=" << run_case(warmup_pattern, warmup_mask, 2048) << "\n";

    const std::vector<u8> pattern = {0x96, 0x00, 0x00, 0x00, 0x00};
    const std::string mask = "x????";

    std::vector<u8> data(2048, 0x11);
    for (size_t base = 0; base + pattern.size() <= data.size(); base += 64)
        data[base] = pattern[0];

    const size_t expected = reference_find_first(data, pattern, mask);
    const std::string signature = to_signature(pattern, mask);
    const u8* found = static_cast<const u8*>(Pattern16::scan(data.data(), data.size(), signature));
    const size_t got = found ? static_cast<size_t>(found - data.data()) : static_cast<size_t>(-1);

    std::cout << "expected=" << expected << " got=" << got << "\n";
}

Expected

  • warmup_1024=0
  • warmup_2048=0
  • expected=0 got=0

Actual

  • warmup_1024=0
  • warmup_2048=1920
  • expected=0 got=1920

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions