Perform RemoveNulls & RemoveWhitespace transformations in-place

- Refactored to share implementation.
This commit is contained in:
Eduardo Arias
2024-08-19 07:21:22 -07:00
parent 1236d9a7cd
commit 1505025990
3 changed files with 25 additions and 36 deletions

View File

@@ -19,23 +19,8 @@
namespace modsecurity::actions::transformations { namespace modsecurity::actions::transformations {
bool RemoveNulls::transform(std::string &val, const Transaction *trans) const { bool RemoveNulls::transform(std::string &value, const Transaction *trans) const {
size_t i = 0; return remove_if(value, [](const auto c) { return c == '\0'; });
std::string transformed_value;
transformed_value.reserve(val.size());
while (i < val.size()) {
if (val.at(i) == '\0') {
// do nothing; continue on to next char in original val
} else {
transformed_value += val.at(i);
}
i++;
}
const auto changed = transformed_value != val;
val = transformed_value;
return changed;
} }

View File

@@ -18,6 +18,8 @@
#include "transformation.h" #include "transformation.h"
#include <algorithm>
namespace modsecurity::actions::transformations { namespace modsecurity::actions::transformations {
class RemoveNulls : public Transformation { class RemoveNulls : public Transformation {
@@ -26,6 +28,18 @@ class RemoveNulls : public Transformation {
: Transformation(action) { } : Transformation(action) { }
bool transform(std::string &value, const Transaction *trans) const override; bool transform(std::string &value, const Transaction *trans) const override;
template<typename Pred>
static bool remove_if(std::string &val, Pred pred) {
const auto old_size = val.size();
val.erase(
std::remove_if(
val.begin(), val.end(), pred),
val.end());
return val.size() != old_size;
}
}; };
} // namespace modsecurity::actions::transformations } // namespace modsecurity::actions::transformations

View File

@@ -15,6 +15,8 @@
#include "remove_whitespace.h" #include "remove_whitespace.h"
#include "remove_nulls.h"
namespace modsecurity::actions::transformations { namespace modsecurity::actions::transformations {
@@ -23,30 +25,18 @@ RemoveWhitespace::RemoveWhitespace(const std::string &action)
this->action_kind = 1; this->action_kind = 1;
} }
bool RemoveWhitespace::transform(std::string &val, const Transaction *trans) const { bool RemoveWhitespace::transform(std::string &value, const Transaction *trans) const {
std::string transformed_value;
transformed_value.reserve(val.size());
size_t i = 0;
const char nonBreakingSpaces = 0xa0; const char nonBreakingSpaces = 0xa0;
const char nonBreakingSpaces2 = 0xc2; const char nonBreakingSpaces2 = 0xc2;
// loop through all the chars auto pred = [](const auto c) {
while (i < val.size()) {
// remove whitespaces and non breaking spaces (NBSP) // remove whitespaces and non breaking spaces (NBSP)
if (std::isspace(static_cast<unsigned char>(val[i])) return std::isspace(static_cast<unsigned char>(c))
|| (val[i] == nonBreakingSpaces) || c == nonBreakingSpaces
|| val[i] == nonBreakingSpaces2) { || c == nonBreakingSpaces2;
// don't copy; continue on to next char in original val };
} else {
transformed_value += val.at(i);
}
i++;
}
const auto changed = transformed_value != val; return RemoveNulls::remove_if(value, pred);
val = transformed_value;
return changed;
} }