Skip to content

Wrong offset sparse mask #9

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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