Perform RemoveCommentsChar, RemoveComments & ReplaceComments transformations in-place

This commit is contained in:
Eduardo Arias 2024-08-19 07:30:11 -07:00
parent da775eca81
commit 74d150c068
3 changed files with 76 additions and 86 deletions

View File

@ -19,41 +19,34 @@
namespace modsecurity::actions::transformations { namespace modsecurity::actions::transformations {
bool RemoveComments::transform(std::string &value, const Transaction *trans) const { static inline int inplace(std::string &value) {
std::string ret; auto input = reinterpret_cast<unsigned char*>(value.data());
unsigned char *input; const auto input_len = value.length();
bool changed = false, incomment = false;
std::string::size_type i = 0, j = 0;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * value.length()+1));
if (input == NULL) {
return "";
}
memcpy(input, value.c_str(), value.length()+1);
uint64_t input_len = value.size();
uint64_t i, j, incomment;
i = j = incomment = 0;
while (i < input_len) { while (i < input_len) {
if (incomment == 0) { if (!incomment) {
if ((input[i] == '/') && (i + 1 < input_len) if ((input[i] == '/') && (i + 1 < input_len)
&& (input[i + 1] == '*')) { && (input[i + 1] == '*')) {
incomment = 1; incomment = true;
changed = true;
i += 2; i += 2;
} else if ((input[i] == '<') && (i + 1 < input_len) } else if ((input[i] == '<') && (i + 1 < input_len)
&& (input[i + 1] == '!') && (i + 2 < input_len) && (input[i + 1] == '!') && (i + 2 < input_len)
&& (input[i+2] == '-') && (i + 3 < input_len) && (input[i+2] == '-') && (i + 3 < input_len)
&& (input[i + 3] == '-')) { && (input[i + 3] == '-')) {
incomment = 1; incomment = true;
changed = true;
i += 4; i += 4;
} else if ((input[i] == '-') && (i + 1 < input_len) } else if ((input[i] == '-') && (i + 1 < input_len)
&& (input[i + 1] == '-')) { && (input[i + 1] == '-')) {
input[i] = ' '; input[i] = ' ';
changed = true;
break; break;
} else if (input[i] == '#') { } else if (input[i] == '#') {
input[i] = ' '; input[i] = ' ';
changed = true;
break; break;
} else { } else {
input[j] = input[i]; input[j] = input[i];
@ -63,7 +56,7 @@ bool RemoveComments::transform(std::string &value, const Transaction *trans) con
} else { } else {
if ((input[i] == '*') && (i + 1 < input_len) if ((input[i] == '*') && (i + 1 < input_len)
&& (input[i + 1] == '/')) { && (input[i + 1] == '/')) {
incomment = 0; incomment = false;
i += 2; i += 2;
input[j] = input[i]; input[j] = input[i];
i++; i++;
@ -71,7 +64,7 @@ bool RemoveComments::transform(std::string &value, const Transaction *trans) con
} else if ((input[i] == '-') && (i + 1 < input_len) } else if ((input[i] == '-') && (i + 1 < input_len)
&& (input[i + 1] == '-') && (i + 2 < input_len) && (input[i + 1] == '-') && (i + 2 < input_len)
&& (input[i+2] == '>')) { && (input[i+2] == '>')) {
incomment = 0; incomment = false;
i += 3; i += 3;
input[j] = input[i]; input[j] = input[i];
i++; i++;
@ -86,13 +79,14 @@ bool RemoveComments::transform(std::string &value, const Transaction *trans) con
input[j++] = ' '; input[j++] = ' ';
} }
ret.assign(reinterpret_cast<char *>(input), j); value.resize(j);
free(input);
const auto changed = ret != value;
value = ret;
return changed; return changed;
} }
bool RemoveComments::transform(std::string &value, const Transaction *trans) const {
return inplace(value);
}
} // namespace modsecurity::actions::transformations } // namespace modsecurity::actions::transformations

View File

@ -23,43 +23,43 @@ RemoveCommentsChar::RemoveCommentsChar(const std::string &action)
this->action_kind = 1; this->action_kind = 1;
} }
bool RemoveCommentsChar::transform(std::string &val, const Transaction *trans) const { bool RemoveCommentsChar::transform(std::string &value, const Transaction *trans) const {
size_t i = 0; char *d = value.data();
std::string transformed_value; const char *s = d;
transformed_value.reserve(val.size()); const char *e = s + value.size();
while (i < val.size()) { while (s < e) {
if (val.at(i) == '/' if (*s == '/'
&& (i+1 < val.size()) && val.at(i+1) == '*') { && (s+1 < e) && *(s+1) == '*') {
i += 2; s += 2;
} else if (val.at(i) == '*' } else if (*s == '*'
&& (i+1 < val.size()) && val.at(i+1) == '/') { && (s+1 < e) && *(s+1) == '/') {
i += 2; s += 2;
} else if (val.at(i) == '<' } else if (*s == '<'
&& (i+1 < val.size()) && (s+1 < e)
&& val.at(i+1) == '!' && *(s+1) == '!'
&& (i+2 < val.size()) && (s+2 < e)
&& val.at(i+2) == '-' && *(s+2) == '-'
&& (i+3 < val.size()) && (s+3 < e)
&& val.at(i+3) == '-') { && *(s+3) == '-') {
i += 4; s += 4;
} else if (val.at(i) == '-' } else if (*s == '-'
&& (i+1 < val.size()) && val.at(i+1) == '-' && (s+1 < e) && *(s+1) == '-'
&& (i+2 < val.size()) && val.at(i+2) == '>') { && (s+2 < e) && *(s+2) == '>') {
i += 3; s += 3;
} else if (val.at(i) == '-' } else if (*s == '-'
&& (i+1 < val.size()) && val.at(i+1) == '-') { && (s+1 < e) && *(s+1) == '-') {
i += 2; s += 2;
} else if (val.at(i) == '#') { } else if (*s == '#') {
i += 1; s += 1;
} else { } else {
transformed_value += val.at(i); *d++ = *s++;
i++;
} }
} }
const auto changed = transformed_value != val; const auto changed = d != s;
val = transformed_value; const auto new_len = d - value.c_str();
value.resize(new_len);
return changed; return changed;
} }

View File

@ -19,36 +19,28 @@
namespace modsecurity::actions::transformations { namespace modsecurity::actions::transformations {
ReplaceComments::ReplaceComments(const std::string &action) static inline bool inplace(std::string &value) {
: Transformation(action) { auto input = reinterpret_cast<unsigned char*>(value.data());
this->action_kind = 1; const auto input_len = value.length();
} bool changed = false, incomment = false;
std::string::size_type i = 0, j = 0;
while (i < input_len) {
bool ReplaceComments::transform(std::string &value, const Transaction *trans) const { if (!incomment) {
uint64_t i, j, incomment; if ((input[i] == '/') && (i + 1 < input_len)
char *input = reinterpret_cast<char *>(
malloc(sizeof(char) * value.size() + 1));
memcpy(input, value.c_str(), value.size() + 1);
input[value.size()] = '\0';
i = j = incomment = 0;
while (i < value.size()) {
if (incomment == 0) {
if ((input[i] == '/') && (i + 1 < value.size())
&& (input[i + 1] == '*')) { && (input[i + 1] == '*')) {
incomment = 1; incomment = true;
i += 2; i += 2;
changed = true;
} else { } else {
input[j] = input[i]; input[j] = input[i];
i++; i++;
j++; j++;
} }
} else { } else {
if ((input[i] == '*') && (i + 1 < value.size()) if ((input[i] == '*') && (i + 1 < input_len)
&& (input[i + 1] == '/')) { && (input[i + 1] == '/')) {
incomment = 0; incomment = false;
i += 2; i += 2;
input[j] = ' '; input[j] = ' ';
j++; j++;
@ -62,16 +54,20 @@ bool ReplaceComments::transform(std::string &value, const Transaction *trans) co
input[j++] = ' '; input[j++] = ' ';
} }
value.resize(j);
std::string resp;
resp.append(reinterpret_cast<char *>(input), j);
free(input);
const auto changed = resp != value;
value = resp;
return changed; return changed;
} }
ReplaceComments::ReplaceComments(const std::string &action)
: Transformation(action) {
this->action_kind = 1;
}
bool ReplaceComments::transform(std::string &value, const Transaction *trans) const {
return inplace(value);
}
} // namespace modsecurity::actions::transformations } // namespace modsecurity::actions::transformations