mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-11-17 09:55:28 +03:00
Refactoring on `utils.cc' and adjacents
Completely removed the `utils.cc' by moving residual functions into sub-classes of `utils/'
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "modsecurity/transaction.h"
|
||||
#include "actions/transformations/transformation.h"
|
||||
#include "src/utils.h"
|
||||
#include "src/utils/msc_string.h"
|
||||
|
||||
|
||||
namespace modsecurity {
|
||||
@@ -42,13 +42,155 @@ std::string CssDecode::evaluate(std::string value,
|
||||
memcpy(tmp, value.c_str(), value.size() + 1);
|
||||
tmp[value.size()] = '\0';
|
||||
|
||||
css_decode_inplace(reinterpret_cast<unsigned char *>(tmp), value.size());
|
||||
CssDecode::css_decode_inplace(reinterpret_cast<unsigned char *>(tmp),
|
||||
value.size());
|
||||
|
||||
std::string ret(tmp, 0, value.size());
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode a string that contains CSS-escaped characters.
|
||||
*
|
||||
* References:
|
||||
* 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;
|
||||
|
||||
if (input == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = count = 0;
|
||||
while (i < input_len) {
|
||||
/* Is the character a backslash? */
|
||||
if (input[i] == '\\') {
|
||||
/* Is there at least one more byte? */
|
||||
if (i + 1 < input_len) {
|
||||
i++; /* We are not going to need the backslash. */
|
||||
|
||||
/* Check for 1-6 hex characters following the backslash */
|
||||
j = 0;
|
||||
while ((j < 6)
|
||||
&& (i + j < input_len)
|
||||
&& (VALID_HEX(input[i + j]))) {
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j > 0) {
|
||||
/* We have at least one valid hexadecimal character. */
|
||||
int fullcheck = 0;
|
||||
|
||||
/* For now just use the last two bytes. */
|
||||
switch (j) {
|
||||
/* Number of hex characters */
|
||||
case 1:
|
||||
*d++ = modsecurity::utils::xsingle2c(&input[i]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
/* Use the last two from the end. */
|
||||
*d++ = modsecurity::utils::x2c(&input[i + j - 2]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
/* Use the last two from the end, but request
|
||||
* a full width check.
|
||||
*/
|
||||
*d = modsecurity::utils::x2c(&input[i + j - 2]);
|
||||
fullcheck = 1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
/* Use the last two from the end, but request
|
||||
* a full width check if the number is greater
|
||||
* or equal to 0xFFFF.
|
||||
*/
|
||||
*d = modsecurity::utils::x2c(&input[i + j - 2]);
|
||||
/* Do full check if first byte is 0 */
|
||||
if (input[i] == '0') {
|
||||
fullcheck = 1;
|
||||
} else {
|
||||
d++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* Use the last two from the end, but request
|
||||
* a full width check if the number is greater
|
||||
* or equal to 0xFFFF.
|
||||
*/
|
||||
*d = modsecurity::utils::x2c(&input[i + j - 2]);
|
||||
|
||||
/* Do full check if first/second bytes are 0 */
|
||||
if ((input[i] == '0')
|
||||
&& (input[i + 1] == '0')) {
|
||||
fullcheck = 1;
|
||||
} else {
|
||||
d++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Full width ASCII (0xff01 - 0xff5e) needs 0x20 added */
|
||||
if (fullcheck) {
|
||||
if ((*d > 0x00) && (*d < 0x5f)
|
||||
&& ((input[i + j - 3] == 'f') ||
|
||||
(input[i + j - 3] == 'F'))
|
||||
&& ((input[i + j - 4] == 'f') ||
|
||||
(input[i + j - 4] == 'F'))) {
|
||||
(*d) += 0x20;
|
||||
}
|
||||
|
||||
d++;
|
||||
}
|
||||
|
||||
/* We must ignore a single whitespace after a hex escape */
|
||||
if ((i + j < input_len) && isspace(input[i + j])) {
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Move over. */
|
||||
count++;
|
||||
i += j;
|
||||
} else if (input[i] == '\n') {
|
||||
/* No hexadecimal digits after backslash */
|
||||
/* A newline character following backslash is ignored. */
|
||||
i++;
|
||||
} 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++;
|
||||
}
|
||||
} else {
|
||||
/* Character is not a backslash. */
|
||||
/* Copy one normal character to output. */
|
||||
*d++ = input[i++];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate output string. */
|
||||
*d = '\0';
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
} // namespace transformations
|
||||
} // namespace actions
|
||||
} // namespace modsecurity
|
||||
|
||||
Reference in New Issue
Block a user