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