|
15 | 15 |
|
16 | 16 | #include "src/operators/pm.h"
|
17 | 17 |
|
18 |
| -#include <string.h> |
19 |
| - |
20 |
| -#include <string> |
21 | 18 | #include <algorithm>
|
22 | 19 | #include <iterator>
|
23 | 20 | #include <sstream>
|
24 |
| -#include <vector> |
25 |
| -#include <list> |
26 |
| -#include <memory> |
27 | 21 |
|
28 |
| -#include "src/operators/operator.h" |
29 | 22 | #include "src/utils/acmp.h"
|
30 | 23 | #include "src/utils/string.h"
|
31 | 24 |
|
| 25 | + |
| 26 | +static inline std::string parse_pm_content(const std::string &op_parm) { |
| 27 | + auto offset = op_parm.find_first_not_of(" \t"); |
| 28 | + if (offset == std::string::npos) { |
| 29 | + return op_parm; |
| 30 | + } |
| 31 | + |
| 32 | + auto size = op_parm.size() - offset; |
| 33 | + if (size >= 2 && |
| 34 | + op_parm.at(offset) == '\"' && op_parm.back() == '\"') { |
| 35 | + offset++; |
| 36 | + size -= 2; |
| 37 | + } |
| 38 | + |
| 39 | + if (size == 0) { |
| 40 | + return op_parm; |
| 41 | + } |
| 42 | + |
| 43 | + std::string parsed_parm(op_parm.c_str() + offset, size); |
| 44 | + |
| 45 | + unsigned char bin_offset = 0; |
| 46 | + unsigned char bin_parm[3] = { 0 }; |
| 47 | + bool bin = false, esc = false; |
| 48 | + |
| 49 | + char *d = parsed_parm.data(); |
| 50 | + for(const char *s = d, *e = d + size; s != e; ++s) { |
| 51 | + if (*s == '|') { |
| 52 | + bin = !bin; |
| 53 | + } else if(!esc && *s == '\\') { |
| 54 | + esc = true; |
| 55 | + } else { |
| 56 | + if (bin) { |
| 57 | + if (*s == '0' || *s == '1' || *s == '2' || |
| 58 | + *s == '3' || *s == '4' || *s == '5' || |
| 59 | + *s == '6' || *s == '7' || *s == '8' || |
| 60 | + *s == '9' || |
| 61 | + *s == 'A' || *s == 'a' || |
| 62 | + *s == 'B' || *s == 'b' || |
| 63 | + *s == 'C' || *s == 'c' || |
| 64 | + *s == 'D' || *s == 'd' || |
| 65 | + *s == 'E' || *s == 'e' || |
| 66 | + *s == 'F' || *s == 'f') |
| 67 | + { |
| 68 | + bin_parm[bin_offset] = (char)*s; |
| 69 | + bin_offset++; |
| 70 | + if (bin_offset == 2) { |
| 71 | + unsigned char c = strtol((char *)bin_parm, (char **) nullptr, 16) & 0xFF; |
| 72 | + bin_offset = 0; |
| 73 | + *d++ = c; |
| 74 | + } |
| 75 | + } |
| 76 | + } else if (esc) { |
| 77 | + if (*s == ':' || |
| 78 | + *s == ';' || |
| 79 | + *s == '\\' || |
| 80 | + *s == '\"') |
| 81 | + { |
| 82 | + *d++ = *s; |
| 83 | + } else { |
| 84 | + // Unsupported escape sequence |
| 85 | + return op_parm; |
| 86 | + } |
| 87 | + esc = false; |
| 88 | + } else { |
| 89 | + *d++ = *s; |
| 90 | + } |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + parsed_parm.resize(d - parsed_parm.c_str()); |
| 95 | + return parsed_parm; |
| 96 | +} |
| 97 | + |
| 98 | + |
32 | 99 | namespace modsecurity {
|
33 | 100 | namespace operators {
|
34 | 101 |
|
@@ -105,36 +172,19 @@ bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,
|
105 | 172 |
|
106 | 173 |
|
107 | 174 | bool Pm::init(const std::string &file, std::string *error) {
|
108 |
| - std::vector<std::string> vec; |
109 |
| - std::istringstream *iss; |
110 |
| - const char *err = NULL; |
111 |
| - |
112 |
| - char *content = parse_pm_content(m_param.c_str(), m_param.length(), &err); |
113 |
| - if (content == NULL) { |
114 |
| - iss = new std::istringstream(m_param); |
115 |
| - } else { |
116 |
| - iss = new std::istringstream(content); |
117 |
| - } |
| 175 | + const auto op_parm = parse_pm_content(m_param); |
118 | 176 |
|
119 |
| - std::copy(std::istream_iterator<std::string>(*iss), |
| 177 | + std::istringstream iss{op_parm}; |
| 178 | + std::for_each(std::istream_iterator<std::string>(iss), |
120 | 179 | std::istream_iterator<std::string>(),
|
121 |
| - back_inserter(vec)); |
122 |
| - |
123 |
| - for (auto &a : vec) { |
124 |
| - acmp_add_pattern(m_p, a.c_str(), NULL, NULL, a.length()); |
125 |
| - } |
| 180 | + [this](const auto &a) { |
| 181 | + acmp_add_pattern(m_p, a.c_str(), NULL, NULL, a.length()); |
| 182 | + }); |
126 | 183 |
|
127 | 184 | while (m_p->is_failtree_done == 0) {
|
128 | 185 | acmp_prepare(m_p);
|
129 | 186 | }
|
130 | 187 |
|
131 |
| - if (content) { |
132 |
| - free(content); |
133 |
| - content = NULL; |
134 |
| - } |
135 |
| - |
136 |
| - delete iss; |
137 |
| - |
138 | 188 | return true;
|
139 | 189 | }
|
140 | 190 |
|
|
0 commit comments