pattern.cpp (6875B)
1 #include "pattern_parse.hpp" 2 3 #include <libshit/doctest.hpp> 4 5 namespace Neptools::Test 6 { 7 TEST_SUITE_BEGIN("Neptools::Pattern"); 8 9 // static test... 10 auto fuck_you_cpp_committee = NEPTOOLS_PATTERN("01 02 03 04"); 11 static_assert(std::is_same_v< 12 decltype(fuck_you_cpp_committee), 13 PatternParse::Pattern< 14 PatternParse::ByteSequence<1,2,3,4>, 15 PatternParse::ByteSequence<0xff,0xff,0xff,0xff>>>, 16 "simple pattern"); 17 18 auto why_cant_I_use_fucking_lambdas = NEPTOOLS_PATTERN("11 05 f3 14"); 19 static_assert(std::is_same_v< 20 decltype(why_cant_I_use_fucking_lambdas), 21 PatternParse::Pattern< 22 PatternParse::ByteSequence<0x11,0x05,0xf3,0x14>, 23 PatternParse::ByteSequence<0xff,0xff,0xff,0xff>>>, 24 "multi digit"); 25 26 auto in_an_unevaluated_context_like_decltype = NEPTOOLS_PATTERN("11 5 f3 4"); 27 static_assert(std::is_same_v< 28 decltype(in_an_unevaluated_context_like_decltype), 29 PatternParse::Pattern< 30 PatternParse::ByteSequence<0x11,0x05,0xf3,0x04>, 31 PatternParse::ByteSequence<0xff,0xff,0xff,0xff>>>, 32 "shortcuts"); 33 34 auto or_why_cant_you_add_a_sane_way_to_use = NEPTOOLS_PATTERN("11 ?? f3 04"); 35 static_assert(std::is_same_v< 36 decltype(or_why_cant_you_add_a_sane_way_to_use), 37 PatternParse::Pattern< 38 PatternParse::ByteSequence<0x11,0x00,0xf3,0x04>, 39 PatternParse::ByteSequence<0xff,0x00,0xff,0xff>>>, 40 "placeholder"); 41 42 auto fucking_strings_as_template_arguments = NEPTOOLS_PATTERN("11 ? f3 04"); 43 static_assert(std::is_same_v< 44 decltype(fucking_strings_as_template_arguments), 45 PatternParse::Pattern< 46 PatternParse::ByteSequence<0x11,0x00,0xf3,0x04>, 47 PatternParse::ByteSequence<0xff,0x00,0xff,0xff>>>, 48 "short placeholder"); 49 // PS. you should add ctr instead of shit like a wrapper around cairo 50 51 auto with_mask = NEPTOOLS_PATTERN("11 22/ff 33/f0 44/77 55/00"); 52 static_assert(std::is_same_v< 53 decltype(with_mask), 54 PatternParse::Pattern< 55 PatternParse::ByteSequence<0x11, 0x22, 0x30, 0x44, 0x00>, 56 PatternParse::ByteSequence<0xff, 0xff, 0xf0, 0x77, 0x00>>>); 57 58 Byte data[] = { 59 /* 00 */ 0xff, 0xf0, 0x64, 0x22, 0x50, 0xca, 0x9f, 0x23, 60 /* 08 */ 0x92, 0xf7, 0xb3, 0x8f, 0xb1, 0x30, 0x8a, 0xd6, 61 /* 10 */ 0x1e, 0x38, 0xd8, 0xf3, 0xa7, 0xfa, 0x98, 0xee, 62 /* 18 */ 0x58, 0xec, 0x21, 0xa8, 0xfe, 0x00, 0x1c, 0xfb, 63 /* 20 */ 0x5e, 0x0a, 0x48, 0x38, 0xc5, 0x64, 0xb5, 0xbe, 64 /* 28 */ 0xc1, 0x48, 0xdd, 0x7f, 0x3e, 0x58, 0xec, 0x21, 65 /* 30 */ 0x82, 0xf4, 0xca, 0x11, 0x47, 0x22, 0xcf, 0x98, 66 /* 38 */ 0x40, 0xfe, 0x18, 0x0e, 0x2e, 0xb9, 0xfc, 0xce, 67 }; 68 TEST_CASE("simple patterns") 69 { 70 Pattern p = NEPTOOLS_PATTERN("a8 fe 0 1c"); //middle 71 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x1b); 72 CHECK(p.Find({data, sizeof(data)}) == data + 0x1b); 73 74 p = NEPTOOLS_PATTERN("ff f0 64"); //beginning 75 CHECK(p.MaybeFind({data, sizeof(data)}) == data); 76 CHECK(p.Find({data, sizeof(data)}) == data); 77 78 p = NEPTOOLS_PATTERN("18 e 2e b9 fc ce"); //end 79 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x3a); 80 CHECK(p.Find({data, sizeof(data)}) == data + 0x3a); 81 } 82 TEST_CASE("simple not match") 83 { 84 auto p = NEPTOOLS_PATTERN("12 34 56 76"); 85 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 86 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 87 } 88 TEST_CASE("multiple match") 89 { 90 auto p = NEPTOOLS_PATTERN("58 ec 21"); 91 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 92 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 93 } 94 95 TEST_CASE("wildcards") 96 { 97 Pattern p = NEPTOOLS_PATTERN("48 ? c5 ? ? be"); // mid 98 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x22); 99 CHECK(p.Find({data, sizeof(data)}) == data + 0x22); 100 101 p = NEPTOOLS_PATTERN("ff ? ? 22 50"); // begin 102 CHECK(p.MaybeFind({data, sizeof(data)}) == data); 103 CHECK(p.Find({data, sizeof(data)}) == data); 104 105 106 p = NEPTOOLS_PATTERN("e ? b9 ? ce"); // end 107 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x3b); 108 CHECK(p.Find({data, sizeof(data)}) == data + 0x3b); 109 110 p = NEPTOOLS_PATTERN("? ? fe 00 ?"); // mid 111 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x1a); 112 CHECK(p.Find({data, sizeof(data)}) == data + 0x1a); 113 114 p = NEPTOOLS_PATTERN("? ? 64 22 ?"); // begin 115 CHECK(p.MaybeFind({data, sizeof(data)}) == data); 116 CHECK(p.Find({data, sizeof(data)}) == data); 117 118 p = NEPTOOLS_PATTERN("? 2e b9 ? ?"); // end 119 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x3b); 120 CHECK(p.Find({data, sizeof(data)}) == data + 0x3b); 121 } 122 TEST_CASE("wildcards not match") 123 { 124 Pattern p = NEPTOOLS_PATTERN("12 34 ?? 56 ?? 78"); 125 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 126 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 127 128 p = NEPTOOLS_PATTERN("? ? 12 34 56"); 129 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 130 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 131 132 p = NEPTOOLS_PATTERN("12 34 ? 56 ? ? ?"); 133 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 134 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 135 } 136 TEST_CASE("wildcards multiple match") 137 { 138 Pattern p = NEPTOOLS_PATTERN("58 ? 21"); 139 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 140 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 141 142 p = NEPTOOLS_PATTERN("? 58 ? ?"); 143 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 144 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 145 146 p = NEPTOOLS_PATTERN("? ? ? ?"); 147 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 148 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 149 } 150 151 TEST_CASE("mask") 152 { 153 Byte pat[] = { 0x58, 0xe0, 0x21, 0x28, 0x3e }; 154 Byte mask[] = { 0xff, 0xf0, 0xff, 0x2f, 0x3f }; 155 auto p = Pattern{pat, mask, 5}; 156 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x18); 157 CHECK(p.Find({data, sizeof(data)}) == data + 0x18); 158 } 159 160 TEST_CASE("mask no match") 161 { 162 Byte pat[] = { 0x58, 0xe0, 0x21, 0x18, 0x3e }; 163 Byte mask[] = { 0xff, 0xf0, 0xff, 0x1f, 0x3f }; 164 auto p = Pattern{pat, mask, 5}; 165 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 166 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 167 } 168 169 TEST_CASE("mask no 0xff") 170 { 171 Byte pat[] = { 0x58, 0xe0, 0x20, 0x28, 0x3e }; 172 Byte mask[] = { 0x5f, 0xf0, 0xf2, 0x2f, 0x3f }; 173 auto p = Pattern{pat, mask, 5}; 174 CHECK(p.MaybeFind({data, sizeof(data)}) == data + 0x18); 175 CHECK(p.Find({data, sizeof(data)}) == data + 0x18); 176 177 Byte pat2[] = { 0x58, 0xe0, 0x20, 0x18, 0x3e }; 178 Byte mask2[] = { 0x5f, 0xf0, 0xf2, 0x1f, 0x3f }; 179 p = Pattern{pat2, mask2, 5}; 180 CHECK(p.MaybeFind({data, sizeof(data)}) == nullptr); 181 CHECK_THROWS_AS(p.Find({data, sizeof(data)}), std::runtime_error); 182 } 183 184 TEST_SUITE_END(); 185 }