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 {
bool RemoveNulls::transform(std::string &val, const Transaction *trans) const {
size_t i = 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;
bool RemoveNulls::transform(std::string &value, const Transaction *trans) const {
return remove_if(value, [](const auto c) { return c == '\0'; });
}

View File

@ -18,6 +18,8 @@
#include "transformation.h"
#include <algorithm>
namespace modsecurity::actions::transformations {
class RemoveNulls : public Transformation {
@ -26,6 +28,18 @@ class RemoveNulls : public Transformation {
: Transformation(action) { }
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

View File

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