Remove unnecessary copying in transformations

In C++11, string data is always null-terminated[1], and can be
freely modified[2].

[1] https://stackoverflow.com/questions/6077189/will-stdstring-always-be-null-terminated-in-c11
[2] https://stackoverflow.com/questions/38875623/is-it-permitted-to-modify-the-internal-stdstring-buffer-returned-by-operator
This commit is contained in:
WGH 2020-07-22 03:14:51 +03:00 committed by Felipe Zimmerle
parent d7e9e0aa5b
commit 904fd030f9
16 changed files with 50 additions and 191 deletions

View File

@ -1,6 +1,8 @@
v3.x.y - YYYY-MMM-DD (to be released)
-------------------------------------
- Removed unnecessary while processing the transformations.
[#2368 - @WGH-, @zimmerle]
- auditlog: Computes whether or not to save while loading the rules.
[@zimmerle]
- actions: Computes Rule association while loading the rules given a

View File

@ -32,19 +32,10 @@ namespace transformations {
void CssDecode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
size_t s = in.size();
char *tmp = reinterpret_cast<char *>(
malloc(sizeof(char) * s + 1));
memcpy(tmp, in.c_str(), s + 1);
tmp[s] = '\0';
size_t r = CssDecode::css_decode_inplace(
reinterpret_cast<unsigned char *>(tmp),
s);
out.assign(tmp, r);
free(tmp);
out.assign(in);
auto size = CssDecode::css_decode_inplace(
reinterpret_cast<unsigned char *>(&out[0]), out.size());
out.resize(size);
}

View File

@ -135,14 +135,11 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input,
void EscapeSeqDecode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *tmp = (unsigned char *) malloc(sizeof(char)
* in.size() + 1);
memcpy(tmp, in.c_str(), in.size() + 1);
tmp[in.size()] = '\0';
int size = ansi_c_sequences_decode_inplace(tmp, in.size());
out.assign(reinterpret_cast<char *>(tmp), size);
free(tmp);
out.assign(in);
auto size = ansi_c_sequences_decode_inplace(
reinterpret_cast<unsigned char *>(&out[0]), out.size());
out.resize(size);
}
} // namespace transformations

View File

@ -34,22 +34,10 @@ namespace transformations {
void HexDecode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
int size = 0;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memcpy(input, in.c_str(), in.length()+1);
size = inplace(input, in.length());
out.assign(reinterpret_cast<char *>(input), size);
free(input);
out.assign(in);
auto size = inplace(reinterpret_cast<unsigned char *>(
&out[0]), out.length());
out.resize(size);
}

View File

@ -32,21 +32,10 @@ namespace transformations {
void HtmlEntityDecode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memcpy(input, in.c_str(), in.length()+1);
size_t i = inplace(input, in.length());
out.assign(reinterpret_cast<char *>(input), i);
free(input);
out.assign(in);
auto i = inplace(reinterpret_cast<unsigned char *>(
&out[0]), out.length());
out.resize(i);
}

View File

@ -32,21 +32,11 @@ namespace transformations {
void JsDecode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memcpy(input, in.c_str(), in.length()+1);
size_t i = inplace(input, in.length());
out.assign(reinterpret_cast<char *>(input), i);
free(input);
out.assign(in);
auto i = inplace(reinterpret_cast<unsigned char *>(
&out[0]), out.length());
out.resize(i);
}

View File

@ -31,18 +31,9 @@ void NormalisePath::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
int changed = 0;
char *tmp = reinterpret_cast<char *>(
malloc(sizeof(char) * in.size() + 1));
memcpy(tmp, in.c_str(), in.size() + 1);
tmp[in.size()] = '\0';
int i = normalize_path_inplace((unsigned char *)tmp,
in.size(), 0, &changed);
std::string ret("");
out.assign(tmp, i);
free(tmp);
out.assign(in);
auto size = normalize_path_inplace(reinterpret_cast<unsigned char *>(&out[0]), out.length(), 0, &changed);
out.resize(size);
}

View File

@ -36,18 +36,10 @@ void NormalisePathWin::execute(const Transaction *t,
ModSecString &out) noexcept {
int changed;
char *tmp = reinterpret_cast<char *>(
malloc(sizeof(char) * in.size() + 1));
memcpy(tmp, in.c_str(), in.size() + 1);
tmp[in.size()] = '\0';
int i = NormalisePath::normalize_path_inplace(
reinterpret_cast<unsigned char *>(tmp),
in.size(), 1, &changed);
std::string ret("");
out.assign(tmp, i);
free(tmp);
out.assign(in);
auto size = NormalisePath::normalize_path_inplace(
reinterpret_cast<unsigned char *>(&out[0]), out.length(), 1, &changed);
out.resize(size);
}

View File

@ -30,21 +30,8 @@ namespace transformations {
void ParityEven7bit::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
std::memcpy(input, in.c_str(), in.length()+1);
inplace(input, in.length());
out.assign(reinterpret_cast<char *>(input), in.length());
free(input);
out.assign(in);
inplace(reinterpret_cast<unsigned char*>(&out[0]), out.size());
}

View File

@ -30,21 +30,8 @@ namespace transformations {
void ParityOdd7bit::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memcpy(input, in.c_str(), in.length()+1);
inplace(input, in.length());
out.assign(reinterpret_cast<char *>(input), in.length());
free(input);
out.assign(in);
inplace(reinterpret_cast<unsigned char *>(&out[0]), out.length());
}

View File

@ -30,21 +30,8 @@ namespace transformations {
void ParityZero7bit::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memcpy(input, in.c_str(), in.length()+1);
inplace(input, in.length());
out.assign(reinterpret_cast<char *>(input), in.length());
free(input);
out.assign(in);
inplace(reinterpret_cast<unsigned char *>(&out[0]), out.length());
}

View File

@ -32,22 +32,9 @@ namespace transformations {
void SqlHexDecode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
int size = 0;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memcpy(input, in.c_str(), in.length()+1);
size = inplace(input, in.length());
out.assign(reinterpret_cast<char *>(input), size);
free(input);
out.assign(in);
auto size = inplace(reinterpret_cast<unsigned char*>(&out[0]), out.size());
out.resize(size);
}

View File

@ -32,19 +32,14 @@ namespace transformations {
void UrlDecode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *val(NULL);
int invalid_count = 0;
int changed;
val = (unsigned char *) malloc(sizeof(char) * in.size() + 1);
memcpy(val, in.c_str(), in.size() + 1);
val[in.size()] = '\0';
int size = utils::urldecode_nonstrict_inplace(val, in.size(),
out.assign(in);
int size = utils::urldecode_nonstrict_inplace(
reinterpret_cast<unsigned char *>(&out[0]), out.size(),
&invalid_count, &changed);
out.append((const char *)val, size);
free(val);
out.resize(size);
}

View File

@ -33,21 +33,9 @@ namespace transformations {
void UrlDecodeUni::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memcpy(input, in.c_str(), in.length()+1);
size_t i = inplace(input, in.length(), t);
out.assign(reinterpret_cast<char *>(input), i);
free(input);
out.assign(in);
size_t i = inplace(reinterpret_cast<unsigned char *>(&out[0]), out.length(), t);
out.resize(i);
}

View File

@ -32,31 +32,19 @@ namespace transformations {
void Utf8ToUnicode::execute(const Transaction *t,
const ModSecString &in,
ModSecString &out) noexcept {
unsigned char *input;
int changed = 0;
char *out2;
input = reinterpret_cast<unsigned char *>
(malloc(sizeof(char) * in.length()+1));
if (input == NULL) {
return;
}
memset(input, '\0', in.length()+1);
memcpy(input, in.c_str(), in.length()+1);
out2 = inplace(input, in.size() + 1, &changed);
out2 = inplace(reinterpret_cast<const unsigned char *>(&in[0]), in.size() + 1, &changed);
if (out2 != NULL) {
out.assign(reinterpret_cast<char *>(out2),
strlen(reinterpret_cast<char *>(out2)));
free(out2);
}
free(input);
}
char *Utf8ToUnicode::inplace(unsigned char *input,
char *Utf8ToUnicode::inplace(const unsigned char *input,
uint64_t input_len, int *changed) {
unsigned int count = 0;
char *data;
@ -84,7 +72,7 @@ char *Utf8ToUnicode::inplace(unsigned char *input,
int unicode_len = 0;
unsigned int d = 0;
unsigned char c;
unsigned char *utf = (unsigned char *)&input[i];
const unsigned char *utf = &input[i];
c = *utf;

View File

@ -50,7 +50,7 @@ class Utf8ToUnicode : public Transformation {
UNICODE_ERROR_DECODING_ERROR = -5
};
static char *inplace(unsigned char *input, uint64_t input_len,
static char *inplace(const unsigned char *input, uint64_t input_len,
int *changed);
};