74 lines
1.9 KiB
C
74 lines
1.9 KiB
C
// SPDX-FileCopyrightText: 1999 Markus Kuhn <mgk25@cl.cam.ac.uk>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#include <ngx_config.h>
|
|
|
|
#include <naxsi.h>
|
|
|
|
/* @file naxsi_utf8.c
|
|
*
|
|
* Checks if the string is containing invalid utf8 codes.
|
|
*
|
|
* Original code from https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c
|
|
*/
|
|
|
|
unsigned char*
|
|
ngx_utf8_check(ngx_str_t* str)
|
|
{
|
|
unsigned int offset = 0;
|
|
unsigned char* s;
|
|
|
|
s = str->data;
|
|
|
|
while (offset < str->len && *s) {
|
|
if (*s < 0x80) {
|
|
/* 0xxxxxxx */
|
|
s++;
|
|
offset++;
|
|
} else if ((s[0] & 0xe0) == 0xc0) {
|
|
if (offset + 1 >= str->len) {
|
|
// not enough bytes
|
|
return s;
|
|
}
|
|
/* 110XXXXx 10xxxxxx */
|
|
if ((s[1] & 0xc0) != 0x80 || (s[0] & 0xfe) == 0xc0) { /* overlong? */
|
|
return s;
|
|
} else {
|
|
s += 2;
|
|
offset += 2;
|
|
}
|
|
} else if ((s[0] & 0xf0) == 0xe0) {
|
|
if (offset + 2 >= str->len) {
|
|
// not enough bytes
|
|
return s;
|
|
}
|
|
/* 1110XXXX 10Xxxxxx 10xxxxxx */
|
|
if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
|
|
(s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */
|
|
(s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */
|
|
(s[0] == 0xef && s[1] == 0xbf && (s[2] & 0xfe) == 0xbe)) { /* U+FFFE or U+FFFF? */
|
|
return s;
|
|
} else {
|
|
s += 3;
|
|
offset += 3;
|
|
}
|
|
} else if ((s[0] & 0xf8) == 0xf0) {
|
|
if (offset + 3 >= str->len) {
|
|
// not enough bytes
|
|
return s;
|
|
}
|
|
/* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
|
|
if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || (s[3] & 0xc0) != 0x80 ||
|
|
(s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */
|
|
(s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) { /* > U+10FFFF? */
|
|
return s;
|
|
} else {
|
|
s += 4;
|
|
offset += 4;
|
|
}
|
|
} else {
|
|
return s;
|
|
}
|
|
}
|
|
return NULL;
|
|
} |