Skip to content

Commit fbdf0b0

Browse files
authored
Merge commit from fork
Fix utf8toUnicode string truncate issue on i386
2 parents c3979ed + edcd010 commit fbdf0b0

2 files changed

Lines changed: 59 additions & 16 deletions

File tree

src/actions/transformations/utf8_to_unicode.cc

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ static inline bool encode(std::string &value) {
3434
bool changed = false;
3535
std::string::size_type count = 0;
3636
auto bytes_left = input_len;
37-
unsigned char unicode[8];
37+
char unicode[8] = {0}; /* 5 or 6 bytes for OLD standard unicode character and 1 byte for null terminator */
38+
/* 4 bytes are enough for standard UTF8 + '\0' */
39+
/* result can be only signed char array, so no need to cast later */
3840

3941
/* RFC3629 states that UTF-8 are encoded using sequences of 1 to 4 octets. */
4042
/* Max size per character should fit in 4 bytes */
@@ -81,10 +83,7 @@ static inline bool encode(std::string &value) {
8183
d = ((c & 0x1F) << 6) | (*(utf + 1) & 0x3F);
8284
*data++ = '%';
8385
*data++ = 'u';
84-
snprintf(reinterpret_cast<char *>(unicode),
85-
sizeof(reinterpret_cast<char *>(unicode)),
86-
"%x", d);
87-
length = strlen(reinterpret_cast<char *>(unicode));
86+
length = snprintf(unicode, sizeof(unicode), "%x", d);
8887

8988
switch (length) {
9089
case 1:
@@ -104,7 +103,7 @@ static inline bool encode(std::string &value) {
104103
break;
105104
}
106105

107-
for (std::string::size_type j = 0; j < length; j++) {
106+
for (int j = 0; j < length; j++) {
108107
*data++ = unicode[j];
109108
}
110109

@@ -133,10 +132,7 @@ static inline bool encode(std::string &value) {
133132
| (*(utf + 2) & 0x3F);
134133
*data++ = '%';
135134
*data++ = 'u';
136-
snprintf(reinterpret_cast<char *>(unicode),
137-
sizeof(reinterpret_cast<char *>(unicode)),
138-
"%x", d);
139-
length = strlen(reinterpret_cast<char *>(unicode));
135+
length = snprintf(unicode, sizeof(unicode), "%x", d);
140136

141137
switch (length) {
142138
case 1:
@@ -156,7 +152,7 @@ static inline bool encode(std::string &value) {
156152
break;
157153
}
158154

159-
for (std::string::size_type j = 0; j < length; j++) {
155+
for (int j = 0; j < length; j++) {
160156
*data++ = unicode[j];
161157
}
162158

@@ -195,10 +191,7 @@ static inline bool encode(std::string &value) {
195191
| (*(utf + 3) & 0x3F);
196192
*data++ = '%';
197193
*data++ = 'u';
198-
snprintf(reinterpret_cast<char *>(unicode),
199-
sizeof(reinterpret_cast<char *>(unicode)),
200-
"%x", d);
201-
length = strlen(reinterpret_cast<char *>(unicode));
194+
length = snprintf(unicode, sizeof(unicode), "%x", d);
202195

203196
switch (length) {
204197
case 1:
@@ -218,7 +211,7 @@ static inline bool encode(std::string &value) {
218211
break;
219212
}
220213

221-
for (std::string::size_type j = 0; j < length; j++) {
214+
for (int j = 0; j < length; j++) {
222215
*data++ = unicode[j];
223216
}
224217

test/test-cases/regression/transformations.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,55 @@
118118
"SecRuleEngine On",
119119
"SecRule ARGS \"@contains test \" \"id:1,pass,t:trim,t:lowercase\""
120120
]
121+
},
122+
{
123+
"enabled": 1,
124+
"version_min": 300000,
125+
"version_max": 0,
126+
"title": "Testing transformations :: none,utf8toUnicode,urlDecodeUni,htmlEntityDecode,jsDecode,cssDecode,removeNulls",
127+
"client": {
128+
"ip": "200.249.12.31",
129+
"port": 2313
130+
},
131+
"server": {
132+
"ip": "200.249.12.31",
133+
"port": 80
134+
},
135+
"request": {
136+
"headers": {
137+
"Host": "www.modsecurity.org",
138+
"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)",
139+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
140+
"Accept-Language": "en-us,en;q=0.5",
141+
"Accept-Encoding": "gzip,deflate",
142+
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
143+
"Keep-Alive": "300",
144+
"Connection": "keep-alive",
145+
"Pragma": "no-cache",
146+
"Cache-Control": "no-cache",
147+
"Content-Length": "0"
148+
},
149+
"uri": "/?var=%ef%bc%9cscript%20%ef%bc%9ealert%281%29%ef%bc%9c/script%ef%bc%9e",
150+
"method": "GET",
151+
"http_version": 1.1,
152+
"body": [
153+
""
154+
]
155+
},
156+
"response": {
157+
"headers": {
158+
"Content-Length": "0"
159+
},
160+
"body": [
161+
""
162+
]
163+
},
164+
"expected": {
165+
"http_code": 403
166+
},
167+
"rules": [
168+
"SecRuleEngine On",
169+
"SecRule ARGS \"@rx (?i)<script[^>]*>[\\s\\S]*?\" \"id:941110,phase:2,deny,capture,t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls\""
170+
]
121171
}
122172
]

0 commit comments

Comments
 (0)