diff options
| author | Ben Fuhrmannek | 2014-10-11 10:25:59 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2014-10-11 10:25:59 +0200 |
| commit | c8724cde260e6c8bab4aefffffa1aa46f92a57ee (patch) | |
| tree | fa71c2fd8f6c1e84ea2b23e5040253bf1ce93825 /ufilter.c | |
| parent | 3159694378333c08c73d4fcd4b73725c02249750 (diff) | |
fixed utf8 detection + made feature experimental
Diffstat (limited to 'ufilter.c')
| -rw-r--r-- | ufilter.c | 22 |
1 files changed, 15 insertions, 7 deletions
| @@ -149,19 +149,23 @@ return_failure: | |||
| 149 | } | 149 | } |
| 150 | /* }}} */ | 150 | /* }}} */ |
| 151 | 151 | ||
| 152 | static inline int suhosin_validate_utf8_multibyte(const char* cp) | 152 | #ifdef SUHOSIN_EXPERIMENTAL |
| 153 | static 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 | ||
| 175 | int suhosin_rfc1867_filter(unsigned int event, void *event_data, void **extra TSRMLS_DC) | 180 | int 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 | ||
