Perform CssDecode transformation in-place

- Removed inplace helper function from the class, as it's only
  referenced by the implementation.
This commit is contained in:
Eduardo Arias 2024-08-19 08:24:31 -07:00
parent e687140d05
commit 727f2bf840
2 changed files with 18 additions and 34 deletions

View File

@ -21,25 +21,6 @@
namespace modsecurity::actions::transformations {
bool CssDecode::transform(std::string &value, const Transaction *trans) const {
char *tmp = reinterpret_cast<char *>(
malloc(sizeof(char) * value.size() + 1));
memcpy(tmp, value.c_str(), value.size() + 1);
tmp[value.size()] = '\0';
CssDecode::css_decode_inplace(reinterpret_cast<unsigned char *>(tmp),
value.size());
std::string ret(tmp, 0, value.size());
free(tmp);
const auto changed = ret != value;
value = ret;
return changed;
}
/**
* Decode a string that contains CSS-escaped characters.
*
@ -47,15 +28,13 @@ bool CssDecode::transform(std::string &value, const Transaction *trans) const {
* http://www.w3.org/TR/REC-CSS2/syndata.html#q4
* http://www.unicode.org/roadmaps/
*/
int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
unsigned char *d = (unsigned char *)input;
int64_t i, j, count;
static inline bool css_decode_inplace(std::string &val) {
const auto input_len = val.length();
auto input = reinterpret_cast<unsigned char *>(val.data());
auto d = input;
bool changed = false;
if (input == NULL) {
return -1;
}
i = count = 0;
std::string::size_type i = 0;
while (i < input_len) {
/* Is the character a backslash? */
if (input[i] == '\\') {
@ -64,7 +43,7 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
i++; /* We are not going to need the backslash. */
/* Check for 1-6 hex characters following the backslash */
j = 0;
std::string::size_type j = 0;
while ((j < 6)
&& (i + j < input_len)
&& (VALID_HEX(input[i + j]))) {
@ -146,37 +125,44 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
}
/* Move over. */
count++;
i += j;
changed = true;
} else if (input[i] == '\n') {
/* No hexadecimal digits after backslash */
/* A newline character following backslash is ignored. */
i++;
changed = true;
} else {
/* The character after backslash is not a hexadecimal digit,
* nor a newline. */
/* Use one character after backslash as is. */
*d++ = input[i++];
count++;
}
} else {
/* No characters after backslash. */
/* Do not include backslash in output
*(continuation to nothing) */
i++;
changed = true;
}
} else {
/* Character is not a backslash. */
/* Copy one normal character to output. */
*d++ = input[i++];
count++;
}
}
/* Terminate output string. */
*d = '\0';
return count;
val.resize(d - input);
return changed;
}
bool CssDecode::transform(std::string &value, const Transaction *trans) const {
return css_decode_inplace(value);
}

View File

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