21
21
namespace modsecurity ::actions::transformations {
22
22
23
23
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
-
43
24
/* *
44
25
* Decode a string that contains CSS-escaped characters.
45
26
*
46
27
* References:
47
28
* http://www.w3.org/TR/REC-CSS2/syndata.html#q4
48
29
* http://www.unicode.org/roadmaps/
49
30
*/
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 ;
53
36
54
- if (input == NULL ) {
55
- return -1 ;
56
- }
57
-
58
- i = count = 0 ;
37
+ std::string::size_type i = 0 ;
59
38
while (i < input_len) {
60
39
/* Is the character a backslash? */
61
40
if (input[i] == ' \\ ' ) {
@@ -64,7 +43,7 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
64
43
i++; /* We are not going to need the backslash. */
65
44
66
45
/* Check for 1-6 hex characters following the backslash */
67
- j = 0 ;
46
+ std::string::size_type j = 0 ;
68
47
while ((j < 6 )
69
48
&& (i + j < input_len)
70
49
&& (VALID_HEX (input[i + j]))) {
@@ -146,37 +125,44 @@ int CssDecode::css_decode_inplace(unsigned char *input, int64_t input_len) {
146
125
}
147
126
148
127
/* Move over. */
149
- count++;
150
128
i += j;
129
+
130
+ changed = true ;
151
131
} else if (input[i] == ' \n ' ) {
152
132
/* No hexadecimal digits after backslash */
153
133
/* A newline character following backslash is ignored. */
154
134
i++;
135
+ changed = true ;
155
136
} else {
156
137
/* The character after backslash is not a hexadecimal digit,
157
138
* nor a newline. */
158
139
/* Use one character after backslash as is. */
159
140
*d++ = input[i++];
160
- count++;
161
141
}
162
142
} else {
163
143
/* No characters after backslash. */
164
144
/* Do not include backslash in output
165
145
*(continuation to nothing) */
166
146
i++;
147
+ changed = true ;
167
148
}
168
149
} else {
169
150
/* Character is not a backslash. */
170
151
/* Copy one normal character to output. */
171
152
*d++ = input[i++];
172
- count++;
173
153
}
174
154
}
175
155
176
156
/* Terminate output string. */
177
157
*d = ' \0 ' ;
178
158
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);
180
166
}
181
167
182
168
0 commit comments