summaryrefslogtreecommitdiff
path: root/ufilter.c
diff options
context:
space:
mode:
authorBen Fuhrmannek2014-10-11 10:25:59 +0200
committerBen Fuhrmannek2014-10-11 10:25:59 +0200
commitc8724cde260e6c8bab4aefffffa1aa46f92a57ee (patch)
treefa71c2fd8f6c1e84ea2b23e5040253bf1ce93825 /ufilter.c
parent3159694378333c08c73d4fcd4b73725c02249750 (diff)
fixed utf8 detection + made feature experimental
Diffstat (limited to 'ufilter.c')
-rw-r--r--ufilter.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/ufilter.c b/ufilter.c
index 1669e88..f3c3054 100644
--- a/ufilter.c
+++ b/ufilter.c
@@ -149,19 +149,23 @@ return_failure:
149} 149}
150/* }}} */ 150/* }}} */
151 151
152static inline int suhosin_validate_utf8_multibyte(const char* cp) 152#ifdef SUHOSIN_EXPERIMENTAL
153static inline int suhosin_validate_utf8_multibyte(const char* cp, size_t maxlen)
153{ 154{
155 if (maxlen < 2 || !(*cp & 0x80)) { return 0; }
154 if ((*cp & 0xe0) == 0xc0 && // 1st byte is 110xxxxx 156 if ((*cp & 0xe0) == 0xc0 && // 1st byte is 110xxxxx
155 (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx 157 (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx
156 (*cp & 0x1e)) { // overlong check 110[xxxx]x 10xxxxxx 158 (*cp & 0x1e)) { // overlong check 110[xxxx]x 10xxxxxx
157 return 2; 159 return 2;
158 } 160 }
161 if (maxlen < 3) { return 0; }
159 if ((*cp & 0xf0) == 0xe0 && // 1st byte is 1110xxxx 162 if ((*cp & 0xf0) == 0xe0 && // 1st byte is 1110xxxx
160 (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx 163 (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx
161 (*(cp+2) & 0xc0) == 0x80 && // 3rd byte is 10xxxxxx 164 (*(cp+2) & 0xc0) == 0x80 && // 3rd byte is 10xxxxxx
162 ((*cp & 0x0f) | (*(cp+1) & 0x20))) { // 1110[xxxx] 10[x]xxxxx 10xxxxxx 165 ((*cp & 0x0f) | (*(cp+1) & 0x20))) { // 1110[xxxx] 10[x]xxxxx 10xxxxxx
163 return 3; 166 return 3;
164 } 167 }
168 if (maxlen < 4) { return 0; }
165 if ((*cp & 0xf8) == 0xf0 && // 1st byte is 11110xxx 169 if ((*cp & 0xf8) == 0xf0 && // 1st byte is 11110xxx
166 (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx 170 (*(cp+1) & 0xc0) == 0x80 && // 2nd byte is 10xxxxxx
167 (*(cp+2) & 0xc0) == 0x80 && // 3rd byte is 10xxxxxx 171 (*(cp+2) & 0xc0) == 0x80 && // 3rd byte is 10xxxxxx
@@ -171,6 +175,7 @@ static inline int suhosin_validate_utf8_multibyte(const char* cp)
171 } 175 }
172 return 0; 176 return 0;
173} 177}
178#endif
174 179
175int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TSRMLS_DC) 180int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TSRMLS_DC)
176{ 181{
@@ -236,14 +241,15 @@ int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TS
236 if (*cp >= 32 || isspace(*cp)) { 241 if (*cp >= 32 || isspace(*cp)) {
237 continue; 242 continue;
238 } 243 }
244#ifdef SUHOSIN_EXPERIMENTAL
239 if ((*cp & 0x80) && SUHOSIN_G(upload_allow_utf8)) { 245 if ((*cp & 0x80) && SUHOSIN_G(upload_allow_utf8)) {
240 SDEBUG("checking char %x", *cp); 246 SDEBUG("checking char %x", *cp);
241 if ((n = suhosin_validate_utf8_multibyte(cp))) { // valid UTF8 multibyte character 247 if ((n = suhosin_validate_utf8_multibyte(cp, cpend-cp))) { // valid UTF8 multibyte character
242 cp += n - 1; 248 cp += n - 1;
243 continue; 249 continue;
244 } 250 }
245 } 251 }
246 252#endif
247 suhosin_log(S_FILES, "uploaded file contains binary data - file dropped"); 253 suhosin_log(S_FILES, "uploaded file contains binary data - file dropped");
248 if (!SUHOSIN_G(simulation)) { 254 if (!SUHOSIN_G(simulation)) {
249 goto continue_with_failure; 255 goto continue_with_failure;
@@ -261,15 +267,17 @@ int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TS
261 for (i=0, j=0; i<mefd->length; i++) { 267 for (i=0, j=0; i<mefd->length; i++) {
262 if (mefd->data[i] >= 32 || isspace(mefd->data[i])) { 268 if (mefd->data[i] >= 32 || isspace(mefd->data[i])) {
263 mefd->data[j++] = mefd->data[i]; 269 mefd->data[j++] = mefd->data[i];
264 } else if (SUHOSIN_G(upload_allow_utf8) && mefd->data[i] & 0x80) { 270 }
265 n = suhosin_validate_utf8_multibyte(mefd->data + i); 271#ifdef SUHOSIN_EXPERIMENTAL
272 else if (SUHOSIN_G(upload_allow_utf8) && mefd->data[i] & 0x80) {
273 n = suhosin_validate_utf8_multibyte(mefd->data + i, mefd->length - i);
266 if (!n) { continue; } 274 if (!n) { continue; }
267 while (n) { 275 while (n--) {
268 mefd->data[j++] = mefd->data[i++]; 276 mefd->data[j++] = mefd->data[i++];
269 n--;
270 } 277 }
271 i--; 278 i--;
272 } 279 }
280#endif
273 } 281 }
274 mefd->data[j] = '\0'; 282 mefd->data[j] = '\0';
275 283