/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 | 989 | ((Char) < 0x110000 && \ |
35 | 989 | (((Char) & 0xFFFFF800) != 0xD800) && \ |
36 | 989 | ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \ |
37 | 989 | ((Char) & 0xFFFE) != 0xFFFE) |
38 | | |
39 | | |
40 | | #define CONTINUATION_CHAR \ |
41 | 2.42k | do { \ |
42 | 2.42k | if ((*(const unsigned char *)p & 0xc0) != 0x80) /* 10xxxxxx */ \ |
43 | 2.42k | goto error; \ |
44 | 2.42k | val <<= 6; \ |
45 | 2.40k | val |= (*(const unsigned char *)p) & 0x3f; \ |
46 | 2.40k | } while(0) |
47 | | |
48 | | |
49 | | const char * |
50 | | avahi_utf8_valid (const char *str) |
51 | | |
52 | 42.5k | { |
53 | 42.5k | unsigned val = 0; |
54 | 42.5k | unsigned min = 0; |
55 | 42.5k | const char *p; |
56 | | |
57 | 145k | for (p = str; *p; p++) |
58 | 103k | { |
59 | 103k | if (*(const unsigned char *)p < 128) |
60 | 101k | /* done */; |
61 | 1.46k | else |
62 | 1.46k | { |
63 | 1.46k | if ((*(const unsigned char *)p & 0xe0) == 0xc0) /* 110xxxxx */ |
64 | 428 | { |
65 | 428 | if ( ((*(const unsigned char *)p & 0x1e) == 0)) |
66 | 15 | goto error; |
67 | 413 | p++; |
68 | 413 | if ( ((*(const unsigned char *)p & 0xc0) != 0x80)) /* 10xxxxxx */ |
69 | 8 | goto error; |
70 | 413 | } |
71 | 1.03k | else |
72 | 1.03k | { |
73 | 1.03k | if ((*(const unsigned char *)p & 0xf0) == 0xe0) /* 1110xxxx */ |
74 | 581 | { |
75 | 581 | min = (1 << 11); |
76 | 581 | val = *(const unsigned char *)p & 0x0f; |
77 | 581 | goto TWO_REMAINING; |
78 | 581 | } |
79 | 456 | else if ((*(const unsigned char *)p & 0xf8) == 0xf0) /* 11110xxx */ |
80 | 426 | { |
81 | 426 | min = (1 << 16); |
82 | 426 | val = *(const unsigned char *)p & 0x07; |
83 | 426 | } |
84 | 30 | else |
85 | 30 | goto error; |
86 | | |
87 | 426 | p++; |
88 | 426 | CONTINUATION_CHAR; |
89 | 1.00k | TWO_REMAINING: |
90 | 1.00k | p++; |
91 | 1.00k | CONTINUATION_CHAR; |
92 | 994 | p++; |
93 | 994 | CONTINUATION_CHAR; |
94 | | |
95 | 991 | if ( (val < min)) |
96 | 2 | goto error; |
97 | | |
98 | 989 | if ( (!UNICODE_VALID(val))) |
99 | 9 | goto error; |
100 | 989 | } |
101 | | |
102 | 1.38k | continue; |
103 | | |
104 | 1.38k | error: |
105 | 80 | return NULL; |
106 | 1.46k | } |
107 | 103k | } |
108 | | |
109 | 42.4k | return str; |
110 | 42.5k | } |