mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-15 23:55:03 +03:00
Remove unnecessary heap-allocation & copy in Transaction::extractArguments
- utils::urldecode_nonstrict_inplace decodes inplace so key & value, which are values returned by utils::string::ssplit_pair can be just be modified and do not need to be copied. - Updated signature of utils::urldecode_nonstrict_inplace, as its two callers already have std::string values.
This commit is contained in:
parent
021d0caa33
commit
b647dbd905
@ -27,16 +27,8 @@ UrlDecode::UrlDecode(const std::string &action)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool UrlDecode::transform(std::string &value, const Transaction *trans) const {
|
bool UrlDecode::transform(std::string &value, const Transaction *trans) const {
|
||||||
int invalid_count = 0;
|
int invalid_count;
|
||||||
int changed;
|
return utils::urldecode_nonstrict_inplace(value, invalid_count);
|
||||||
const auto new_len = utils::urldecode_nonstrict_inplace(
|
|
||||||
(unsigned char*)value.data(),
|
|
||||||
value.length(),
|
|
||||||
&invalid_count,
|
|
||||||
&changed);
|
|
||||||
|
|
||||||
value.resize(new_len);
|
|
||||||
return changed != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -348,46 +348,22 @@ bool Transaction::extractArguments(const std::string &orig,
|
|||||||
if (m_rules->m_secArgumentSeparator.m_set) {
|
if (m_rules->m_secArgumentSeparator.m_set) {
|
||||||
sep1 = m_rules->m_secArgumentSeparator.m_value.at(0);
|
sep1 = m_rules->m_secArgumentSeparator.m_value.at(0);
|
||||||
}
|
}
|
||||||
std::vector<std::string> key_value_sets = utils::string::ssplit(buf, sep1);
|
const auto key_value_sets = utils::string::ssplit(buf, sep1);
|
||||||
|
|
||||||
for (std::string t : key_value_sets) {
|
for (const auto &t : key_value_sets) {
|
||||||
char sep2 = '=';
|
const auto sep2 = '=';
|
||||||
size_t key_s = 0;
|
auto [key, value] = utils::string::ssplit_pair(t, sep2);
|
||||||
size_t value_s = 0;
|
|
||||||
int invalid = 0;
|
|
||||||
int changed = 0;
|
|
||||||
|
|
||||||
std::string key;
|
int invalid_count;
|
||||||
std::string value;
|
utils::urldecode_nonstrict_inplace(key, invalid_count);
|
||||||
std::pair<std::string, std::string> key_value_pair = utils::string::ssplit_pair(t, sep2);
|
utils::urldecode_nonstrict_inplace(value, invalid_count);
|
||||||
key = key_value_pair.first;
|
|
||||||
value = key_value_pair.second;
|
|
||||||
|
|
||||||
key_s = (key.length() + 1);
|
if (invalid_count > 0) {
|
||||||
value_s = (value.length() + 1);
|
|
||||||
unsigned char *key_c = reinterpret_cast<unsigned char *>(
|
|
||||||
calloc(sizeof(char), key_s));
|
|
||||||
unsigned char *value_c = reinterpret_cast<unsigned char *>(
|
|
||||||
calloc(sizeof(char), value_s));
|
|
||||||
|
|
||||||
memcpy(key_c, key.c_str(), key_s);
|
|
||||||
memcpy(value_c, value.c_str(), value_s);
|
|
||||||
|
|
||||||
key_s = utils::urldecode_nonstrict_inplace(key_c, key_s,
|
|
||||||
&invalid, &changed);
|
|
||||||
value_s = utils::urldecode_nonstrict_inplace(value_c, value_s,
|
|
||||||
&invalid, &changed);
|
|
||||||
|
|
||||||
if (invalid) {
|
|
||||||
m_variableUrlEncodedError.set("1", m_variableOffset);
|
m_variableUrlEncodedError.set("1", m_variableOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
addArgument(orig, std::string(reinterpret_cast<char *>(key_c), key_s-1),
|
addArgument(orig, key, value, offset);
|
||||||
std::string(reinterpret_cast<char *>(value_c), value_s-1), offset);
|
|
||||||
offset = offset + t.size() + 1;
|
offset = offset + t.size() + 1;
|
||||||
|
|
||||||
free(key_c);
|
|
||||||
free(value_c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -22,63 +22,55 @@ namespace modsecurity {
|
|||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
|
||||||
int urldecode_nonstrict_inplace(unsigned char *input,
|
bool urldecode_nonstrict_inplace(std::string &val,
|
||||||
uint64_t input_len, int *invalid_count, int *changed) {
|
int &invalid_count) {
|
||||||
unsigned char *d = (unsigned char *)input;
|
unsigned char *d = (unsigned char *)val.data();
|
||||||
uint64_t i, count;
|
unsigned char *s = d;
|
||||||
|
const unsigned char *e = s + val.size();
|
||||||
|
|
||||||
*changed = 0;
|
invalid_count = 0;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
if (input == NULL) {
|
while (s != e) {
|
||||||
return -1;
|
if (*s == '%') {
|
||||||
}
|
|
||||||
|
|
||||||
i = count = 0;
|
|
||||||
while (i < input_len) {
|
|
||||||
if (input[i] == '%') {
|
|
||||||
/* Character is a percent sign. */
|
/* Character is a percent sign. */
|
||||||
|
|
||||||
/* Are there enough bytes available? */
|
/* Are there enough bytes available? */
|
||||||
if (i + 2 < input_len) {
|
if (s + 2 < e) {
|
||||||
char c1 = input[i + 1];
|
const auto c1 = *(s + 1);
|
||||||
char c2 = input[i + 2];
|
const auto c2 = *(s + 2);
|
||||||
if (VALID_HEX(c1) && VALID_HEX(c2)) {
|
if (VALID_HEX(c1) && VALID_HEX(c2)) {
|
||||||
uint64_t uni = string::x2c(&input[i + 1]);
|
const auto uni = string::x2c(s + 1);
|
||||||
|
|
||||||
*d++ = (wchar_t)uni;
|
*d++ = uni;
|
||||||
count++;
|
s += 3;
|
||||||
i += 3;
|
changed = true;
|
||||||
*changed = 1;
|
|
||||||
} else {
|
} else {
|
||||||
/* Not a valid encoding, skip this % */
|
/* Not a valid encoding, skip this % */
|
||||||
*d++ = input[i++];
|
*d++ = *s++;
|
||||||
count++;
|
invalid_count++;
|
||||||
(*invalid_count)++;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Not enough bytes available, copy the raw bytes. */
|
/* Not enough bytes available, copy the raw bytes. */
|
||||||
*d++ = input[i++];
|
*d++ = *s++;
|
||||||
count++;
|
invalid_count++;
|
||||||
(*invalid_count)++;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Character is not a percent sign. */
|
/* Character is not a percent sign. */
|
||||||
if (input[i] == '+') {
|
if (*s == '+') {
|
||||||
*d++ = ' ';
|
*d++ = ' ';
|
||||||
*changed = 1;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
*d++ = input[i];
|
*d++ = *s;
|
||||||
}
|
}
|
||||||
count++;
|
s++;
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
if (changed)
|
||||||
*d = '\0';
|
val.resize((char*) d - val.c_str());
|
||||||
#endif
|
|
||||||
|
|
||||||
return count;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ namespace modsecurity {
|
|||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
|
||||||
int urldecode_nonstrict_inplace(unsigned char *input,
|
bool urldecode_nonstrict_inplace(std::string &val,
|
||||||
uint64_t input_len, int *invalid_count, int *changed);
|
int &invalid_count);
|
||||||
std::string uri_decode(const std::string & sSrc);
|
std::string uri_decode(const std::string & sSrc);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user