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

View File

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

View File

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