aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/ngx_string.c')
-rw-r--r--src/core/ngx_string.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 6a81984dd..3716df661 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -750,16 +750,82 @@ ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
}
+/*
+ * ngx_utf_decode() decodes two and more bytes UTF sequences only
+ * the return values:
+ * 0x80 - 0x10ffff valid character
+ * 0x10ffff - 0xfffffffd invalid sequence
+ * 0xfffffffe incomplete sequence
+ * 0xffffffff error
+ */
+
+uint32_t
+ngx_utf_decode(u_char **p, size_t n)
+{
+ size_t len;
+ uint32_t u, i, valid;
+
+ u = **p;
+
+ if (u > 0xf0) {
+
+ u &= 0x07;
+ valid = 0xffff;
+ len = 3;
+
+ } else if (u > 0xe0) {
+
+ u &= 0x0f;
+ valid = 0x7ff;
+ len = 2;
+
+ } else if (u > 0xc0) {
+
+ u &= 0x1f;
+ valid = 0x7f;
+ len = 1;
+
+ } else {
+ (*p)++;
+ return 0xffffffff;
+ }
+
+ if (n - 1 < len) {
+ return 0xfffffffe;
+ }
+
+ (*p)++;
+
+ while (len) {
+ i = *(*p)++;
+
+ if (i < 0x80) {
+ return 0xffffffff;
+ }
+
+ u = (u << 6) | (i & 0x3f);
+
+ len--;
+ }
+
+ if (u > valid) {
+ return u;
+ }
+
+ return 0xffffffff;
+}
+
+
size_t
-ngx_utf_length(ngx_str_t *utf)
+ngx_utf_length(u_char *p, size_t n)
{
u_char c;
size_t len;
ngx_uint_t i;
- for (len = 0, i = 0; i < utf->len; len++, i++) {
+ for (len = 0, i = 0; i < n; len++, i++) {
- c = utf->data[i];
+ c = p[i];
if (c < 0x80) {
continue;
@@ -775,7 +841,7 @@ ngx_utf_length(ngx_str_t *utf)
/* invalid utf */
- return utf->len;
+ return n;
}
return len;