/src/avahi/avahi-common/utf8.c
Line | Count | Source |
1 | | /* This file is based on the GLIB utf8 validation functions. The |
2 | | * original license text follows. */ |
3 | | |
4 | | /* gutf8.c - Operations on UTF-8 strings. |
5 | | * |
6 | | * Copyright (C) 1999 Tom Tromey |
7 | | * Copyright (C) 2000 Red Hat, Inc. |
8 | | * |
9 | | * This library is free software; you can redistribute it and/or |
10 | | * modify it under the terms of the GNU Lesser General Public |
11 | | * License as published by the Free Software Foundation; either |
12 | | * version 2 of the License, or (at your option) any later version. |
13 | | * |
14 | | * This library is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | | * Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public |
20 | | * License along with this library; if not, write to the |
21 | | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
22 | | * Boston, MA 02111-1307, USA. |
23 | | */ |
24 | | |
25 | | #ifdef HAVE_CONFIG_H |
26 | | #include <config.h> |
27 | | #endif |
28 | | |
29 | | #include <stdlib.h> |
30 | | |
31 | | #include "utf8.h" |
32 | | |
33 | | #define UNICODE_VALID(Char) \ |
34 | 2.89k | ((Char) < 0x110000 && \ |
35 | 2.89k | (((Char) & 0xFFFFF800) != 0xD800) && \ |
36 | 2.89k | ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \ |
37 | 2.89k | ((Char) & 0xFFFE) != 0xFFFE) |
38 | | |
39 | | |
40 | | #define CONTINUATION_CHAR \ |
41 | 7.73k | do { \ |
42 | 7.73k | if ((*(const unsigned char *)p & 0xc0) != 0x80) /* 10xxxxxx */ \ |
43 | 7.73k | goto error; \ |
44 | 7.73k | val <<= 6; \ |
45 | 7.71k | val |= (*(const unsigned char *)p) & 0x3f; \ |
46 | 7.71k | } while(0) |
47 | | |
48 | | |
49 | | const char * |
50 | | avahi_utf8_valid (const char *str) |
51 | | |
52 | 148k | { |
53 | 148k | unsigned val = 0; |
54 | 148k | unsigned min = 0; |
55 | 148k | const char *p; |
56 | | |
57 | 2.17M | for (p = str; *p; p++) |
58 | 2.02M | { |
59 | 2.02M | if (*(const unsigned char *)p < 128) |
60 | 2.01M | /* done */; |
61 | 5.39k | else |
62 | 5.39k | { |
63 | 5.39k | if ((*(const unsigned char *)p & 0xe0) == 0xc0) /* 110xxxxx */ |
64 | 2.43k | { |
65 | 2.43k | if ( ((*(const unsigned char *)p & 0x1e) == 0)) |
66 | 4 | goto error; |
67 | 2.43k | p++; |
68 | 2.43k | if ( ((*(const unsigned char *)p & 0xc0) != 0x80)) /* 10xxxxxx */ |
69 | 8 | goto error; |
70 | 2.43k | } |
71 | 2.95k | else |
72 | 2.95k | { |
73 | 2.95k | if ((*(const unsigned char *)p & 0xf0) == 0xe0) /* 1110xxxx */ |
74 | 1.01k | { |
75 | 1.01k | min = (1 << 11); |
76 | 1.01k | val = *(const unsigned char *)p & 0x0f; |
77 | 1.01k | goto TWO_REMAINING; |
78 | 1.01k | } |
79 | 1.94k | else if ((*(const unsigned char *)p & 0xf8) == 0xf0) /* 11110xxx */ |
80 | 1.91k | { |
81 | 1.91k | min = (1 << 16); |
82 | 1.91k | val = *(const unsigned char *)p & 0x07; |
83 | 1.91k | } |
84 | 33 | else |
85 | 33 | goto error; |
86 | | |
87 | 1.91k | p++; |
88 | 1.91k | CONTINUATION_CHAR; |
89 | 2.92k | TWO_REMAINING: |
90 | 2.92k | p++; |
91 | 2.92k | CONTINUATION_CHAR; |
92 | 2.90k | p++; |
93 | 2.90k | CONTINUATION_CHAR; |
94 | | |
95 | 2.90k | if ( (val < min)) |
96 | 1 | goto error; |
97 | | |
98 | 2.89k | if ( (!UNICODE_VALID(val))) |
99 | 10 | goto error; |
100 | 2.89k | } |
101 | | |
102 | 5.31k | continue; |
103 | | |
104 | 5.31k | error: |
105 | 81 | return NULL; |
106 | 5.39k | } |
107 | 2.02M | } |
108 | | |
109 | 148k | return str; |
110 | 148k | } |