2121namespace modsecurity ::actions::transformations {
2222
2323
24- bool CssDecode::transform (std::string &value, const Transaction *trans) const {
25-
26- char *tmp = reinterpret_cast <char *>(
27- malloc (sizeof (char ) * value.size () + 1 ));
28- memcpy (tmp, value.c_str (), value.size () + 1 );
29- tmp[value.size ()] = ' \0 ' ;
30-
31- CssDecode::css_decode_inplace (reinterpret_cast <unsigned char *>(tmp),
32- value.size ());
33-
34- std::string ret (tmp, 0 , value.size ());
35- free (tmp);
36-
37- const auto changed = ret != value;
38- value = ret;
39- return changed;
40- }
41-
42-
4324/* *
4425 * Decode a string that contains CSS-escaped characters.
4526 *
4627 * References:
4728 * http://www.w3.org/TR/REC-CSS2/syndata.html#q4
4829 * http://www.unicode.org/roadmaps/
4930 */
50- int CssDecode::css_decode_inplace (unsigned char *input, int64_t input_len) {
51- unsigned char *d = (unsigned char *)input;
52- int64_t i, j, count;
31+ static inline bool css_decode_inplace (std::string &val) {
32+ const auto input_len = val.length ();
33+ auto input = reinterpret_cast <unsigned char *>(val.data ());
34+ auto d = input;
35+ bool changed = false ;
5336
54- if (input == NULL ) {
55- return -1 ;
56- }
57-
58- i = count = 0 ;
37+ std::string::size_type i = 0 ;
5938 while (i < input_len) {
6039 /* Is the character a backslash? */
6140 if (input[i] == ' \\ ' ) {
@@ -64,7 +43,7 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
6443 i++; /* We are not going to need the backslash. */
6544
6645 /* Check for 1-6 hex characters following the backslash */
67- j = 0 ;
46+ std::string::size_type j = 0 ;
6847 while ((j < 6 )
6948 && (i + j < input_len)
7049 && (VALID_HEX (input[i + j]))) {
@@ -146,37 +125,44 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
146125 }
147126
148127 /* Move over. */
149- count++;
150128 i += j;
129+
130+ changed = true ;
151131 } else if (input[i] == ' \n ' ) {
152132 /* No hexadecimal digits after backslash */
153133 /* A newline character following backslash is ignored. */
154134 i++;
135+ changed = true ;
155136 } else {
156137 /* The character after backslash is not a hexadecimal digit,
157138 * nor a newline. */
158139 /* Use one character after backslash as is. */
159140 *d++ = input[i++];
160- count++;
161141 }
162142 } else {
163143 /* No characters after backslash. */
164144 /* Do not include backslash in output
165145 *(continuation to nothing) */
166146 i++;
147+ changed = true ;
167148 }
168149 } else {
169150 /* Character is not a backslash. */
170151 /* Copy one normal character to output. */
171152 *d++ = input[i++];
172- count++;
173153 }
174154 }
175155
176156 /* Terminate output string. */
177157 *d = ' \0 ' ;
178158
179- return count;
159+ val.resize (d - input);
160+ return changed;
161+ }
162+
163+
164+ bool CssDecode::transform (std::string &value, const Transaction *trans) const {
165+ return css_decode_inplace (value);
180166}
181167
182168
0 commit comments