Perform ParityEven7bit, ParityOdd7bit & ParityZero7bit transformations in-place

- Refactored to share implementations of ParityEven7bit & ParityOdd7bit.
This commit is contained in:
Eduardo Arias 2024-08-19 01:48:38 +00:00
parent 5d39890783
commit 3ff72fbbc5
6 changed files with 33 additions and 117 deletions

View File

@ -15,53 +15,12 @@
#include "parity_even_7bit.h"
#include <cstring>
namespace modsecurity::actions::transformations {
bool ParityEven7bit::transform(std::string &value, const Transaction *trans) const {
if (value.empty()) return false;
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * value.length()+1));
if (input == NULL) {
return "";
}
std::memcpy(input, value.c_str(), value.length()+1);
const auto ret = inplace(input, value.length());
value.assign(reinterpret_cast<char *>(input), value.length());
free(input);
return ret;
}
bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) {
uint64_t i;
i = 0;
while (i < input_len) {
unsigned int x = input[i];
input[i] ^= input[i] >> 4;
input[i] &= 0xf;
if ((0x6996 >> input[i]) & 1) {
input[i] = x | 0x80;
} else {
input[i] = x & 0x7f;
}
i++;
}
return true;
return ParityEven7bit::inplace<true>(value);
}

View File

@ -26,7 +26,28 @@ class ParityEven7bit : public Transformation {
: Transformation(action) { }
bool transform(std::string &value, const Transaction *trans) const override;
static bool inplace(unsigned char *input, uint64_t input_len);
template<bool even>
static bool inplace(std::string &value) {
if (value.empty()) return false;
for(auto &c : value) {
auto &uc = reinterpret_cast<unsigned char&>(c);
unsigned int x = uc;
uc ^= uc >> 4;
uc &= 0xf;
const bool condition = (0x6996 >> uc) & 1;
if (even ? condition : !condition) {
uc = x | 0x80;
} else {
uc = x & 0x7f;
}
}
return true;
}
};
} // namespace modsecurity::actions::transformations

View File

@ -14,54 +14,14 @@
*/
#include "parity_odd_7bit.h"
#include <cstring>
#include "parity_even_7bit.h"
namespace modsecurity::actions::transformations {
bool ParityOdd7bit::transform(std::string &value, const Transaction *trans) const {
if (value.empty()) return false;
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * value.length()+1));
if (input == NULL) {
return "";
}
memcpy(input, value.c_str(), value.length()+1);
const auto ret = inplace(input, value.length());
value.assign(reinterpret_cast<char *>(input), value.length());
free(input);
return ret;
}
bool ParityOdd7bit::inplace(unsigned char *input, uint64_t input_len) {
uint64_t i;
i = 0;
while (i < input_len) {
unsigned int x = input[i];
input[i] ^= input[i] >> 4;
input[i] &= 0xf;
if ((0x6996 >> input[i]) & 1) {
input[i] = x & 0x7f;
} else {
input[i] = x | 0x80;
}
i++;
}
return true;
return ParityEven7bit::inplace<false>(value);
}

View File

@ -26,7 +26,6 @@ class ParityOdd7bit : public Transformation {
: Transformation(action) { }
bool transform(std::string &value, const Transaction *trans) const override;
static bool inplace(unsigned char *input, uint64_t input_len);
};
} // namespace modsecurity::actions::transformations

View File

@ -15,46 +15,24 @@
#include "parity_zero_7bit.h"
#include <cstring>
namespace modsecurity::actions::transformations {
bool ParityZero7bit::transform(std::string &value, const Transaction *trans) const {
static inline bool inplace(std::string &value) {
if (value.empty()) return false;
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * value.length()+1));
if (input == NULL) {
return "";
}
memcpy(input, value.c_str(), value.length()+1);
const auto ret = inplace(input, value.length());
value.assign(reinterpret_cast<char *>(input), value.length());
free(input);
return ret;
}
bool ParityZero7bit::inplace(unsigned char *input, uint64_t input_len) {
uint64_t i;
i = 0;
while (i < input_len) {
input[i] &= 0x7f;
i++;
for(auto &c : value) {
((unsigned char&)c) &= 0x7f;
}
return true;
}
bool ParityZero7bit::transform(std::string &value, const Transaction *trans) const {
return inplace(value);
}
} // namespace modsecurity::actions::transformations

View File

@ -26,7 +26,6 @@ class ParityZero7bit : public Transformation {
: Transformation(action) { }
bool transform(std::string &value, const Transaction *trans) const override;
static bool inplace(unsigned char *input, uint64_t input_len);
};
} // namespace modsecurity::actions::transformations