From 74d150c068cceaca76300f0003be6e2d152d975f Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 07:30:11 -0700 Subject: [PATCH] Perform RemoveCommentsChar, RemoveComments & ReplaceComments transformations in-place --- .../transformations/remove_comments.cc | 46 ++++++------- .../transformations/remove_comments_char.cc | 64 +++++++++---------- .../transformations/replace_comments.cc | 52 +++++++-------- 3 files changed, 76 insertions(+), 86 deletions(-) diff --git a/src/actions/transformations/remove_comments.cc b/src/actions/transformations/remove_comments.cc index 1515675c..5f3edaef 100644 --- a/src/actions/transformations/remove_comments.cc +++ b/src/actions/transformations/remove_comments.cc @@ -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(value.data()); + const auto input_len = value.length(); + bool changed = false, incomment = false; + std::string::size_type i = 0, j = 0; - input = reinterpret_cast - (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(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 diff --git a/src/actions/transformations/remove_comments_char.cc b/src/actions/transformations/remove_comments_char.cc index 7a4763d3..2eeb86f6 100644 --- a/src/actions/transformations/remove_comments_char.cc +++ b/src/actions/transformations/remove_comments_char.cc @@ -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; } diff --git a/src/actions/transformations/replace_comments.cc b/src/actions/transformations/replace_comments.cc index b1aeecf9..a6bab972 100644 --- a/src/actions/transformations/replace_comments.cc +++ b/src/actions/transformations/replace_comments.cc @@ -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(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( - 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(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