Branch data Line data Source code
1 : : /* idna.c - implementation of high-level IDNA processing function
2 : : Copyright (C) 2011 Simon Josefsson
3 : :
4 : : This program is free software: you can redistribute it and/or modify
5 : : it under the terms of the GNU General Public License as published by
6 : : the Free Software Foundation, either version 3 of the License, or
7 : : (at your option) any later version.
8 : :
9 : : This program is distributed in the hope that it will be useful,
10 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : : GNU General Public License for more details.
13 : :
14 : : You should have received a copy of the GNU General Public License
15 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
16 : : */
17 : :
18 : : #include <config.h>
19 : :
20 : : #include "idn2.h"
21 : :
22 : : #include <stdlib.h> /* free */
23 : : #include <errno.h> /* errno */
24 : :
25 : : #include "bidi.h"
26 : : #include "tables.h"
27 : : #include "context.h"
28 : :
29 : : #include <unictype.h> /* uc_is_general_category, UC_CATEGORY_M */
30 : : #include <uninorm.h> /* u32_normalize */
31 : : #include <unistr.h> /* u8_to_u32 */
32 : :
33 : : #include "idna.h"
34 : :
35 : : int
36 : 489 : _idn2_u8_to_u32_nfc (const uint8_t * src, size_t srclen,
37 : : uint32_t ** out, size_t * outlen, int nfc)
38 : : {
39 : : uint32_t *p;
40 : : size_t plen;
41 : :
42 : 489 : p = u8_to_u32 (src, srclen, NULL, &plen);
43 [ + + ]: 489 : if (p == NULL)
44 : : {
45 [ - + ]: 12 : if (errno == ENOMEM)
46 : 0 : return IDN2_MALLOC;
47 : 12 : return IDN2_ENCODING_ERROR;
48 : : }
49 : :
50 [ - + ]: 477 : if (nfc)
51 : : {
52 : : size_t tmplen;
53 : 0 : uint32_t *tmp = u32_normalize (UNINORM_NFC, p, plen, NULL, &tmplen);
54 : 0 : free (p);
55 [ # # ]: 0 : if (tmp == NULL)
56 : : {
57 [ # # ]: 0 : if (errno == ENOMEM)
58 : 0 : return IDN2_MALLOC;
59 : 0 : return IDN2_NFC;
60 : : }
61 : :
62 : 0 : p = tmp;
63 : 0 : plen = tmplen;
64 : : }
65 : :
66 : 477 : *out = p;
67 : 477 : *outlen = plen;
68 : 489 : return IDN2_OK;
69 : : }
70 : :
71 : : bool
72 : 638 : _idn2_ascii_p (const uint8_t * src, size_t srclen)
73 : : {
74 : : size_t i;
75 : 638 : bool ascii = true;
76 : :
77 [ + + ]: 8462 : for (i = 0; i < srclen; i++)
78 [ + + ]: 7824 : if (src[i] >= 0x80)
79 : 4280 : ascii = false;
80 : :
81 : 638 : return ascii;
82 : : }
83 : :
84 : : int
85 : 477 : _idn2_label_test (int what, const uint32_t * label, size_t llen)
86 : : {
87 [ + - ]: 477 : if (what & TEST_NFC)
88 : : {
89 : : size_t plen;
90 : 477 : uint32_t *p = u32_normalize (UNINORM_NFC, label, llen,
91 : 477 : NULL, &plen);
92 : : int ok;
93 [ - + ]: 477 : if (p == NULL)
94 : : {
95 [ # # ]: 0 : if (errno == ENOMEM)
96 : 0 : return IDN2_MALLOC;
97 : 0 : return IDN2_NFC;
98 : : }
99 [ + + ][ + + ]: 477 : ok = llen == plen && memcmp (label, p, plen * sizeof (*label)) == 0;
100 : 477 : free (p);
101 [ + + ]: 477 : if (!ok)
102 : 11 : return IDN2_NOT_NFC;
103 : : }
104 : :
105 [ + - ]: 466 : if (what & TEST_2HYPHEN)
106 : : {
107 [ + + ][ + + ]: 466 : if (llen >= 4 && label[2] == '-' && label[3] == '-')
[ + - ]
108 : 2 : return IDN2_2HYPHEN;
109 : : }
110 : :
111 [ + + ]: 464 : if (what & TEST_HYPHEN_STARTEND)
112 : : {
113 [ + - ][ + - ]: 42 : if (llen > 0 && (label[0] == '-' || label[llen - 1] == '-'))
[ - + ]
114 : 0 : return IDN2_HYPHEN_STARTEND;
115 : : }
116 : :
117 [ + - ]: 464 : if (what & TEST_LEADING_COMBINING)
118 : : {
119 [ + - ][ + + ]: 464 : if (llen > 0 && uc_is_general_category (label[0], UC_CATEGORY_M))
120 : 5 : return IDN2_LEADING_COMBINING;
121 : : }
122 : :
123 [ + - ]: 459 : if (what & TEST_DISALLOWED)
124 : : {
125 : : size_t i;
126 [ + + ]: 3231 : for (i = 0; i < llen; i++)
127 [ + + ]: 2826 : if (_idn2_disallowed_p (label[i]))
128 : 54 : return IDN2_DISALLOWED;
129 : : }
130 : :
131 [ - + ]: 405 : if (what & TEST_CONTEXTJ)
132 : : {
133 : : size_t i;
134 [ # # ]: 0 : for (i = 0; i < llen; i++)
135 [ # # ]: 0 : if (_idn2_contextj_p (label[i]))
136 : 0 : return IDN2_CONTEXTJ;
137 : : }
138 : :
139 [ + - ]: 405 : if (what & TEST_CONTEXTJ_RULE)
140 : : {
141 : : size_t i;
142 : : int rc;
143 : :
144 [ + + ]: 3031 : for (i = 0; i < llen; i++)
145 : : {
146 : 2631 : rc = _idn2_contextj_rule (label, llen, i);
147 [ + + ]: 2631 : if (rc != IDN2_OK)
148 : 5 : return rc;
149 : : }
150 : : }
151 : :
152 [ - + ]: 400 : if (what & TEST_CONTEXTO)
153 : : {
154 : : size_t i;
155 [ # # ]: 0 : for (i = 0; i < llen; i++)
156 [ # # ]: 0 : if (_idn2_contexto_p (label[i]))
157 : 0 : return IDN2_CONTEXTO;
158 : : }
159 : :
160 [ + + ]: 400 : if (what & TEST_CONTEXTO_WITH_RULE)
161 : : {
162 : : size_t i;
163 [ + + ]: 2795 : for (i = 0; i < llen; i++)
164 [ + + - + ]: 2437 : if (_idn2_contexto_p (label[i])
165 : 2437 : && !_idn2_contexto_with_rule (label[i]))
166 : 0 : return IDN2_CONTEXTO_NO_RULE;
167 : : }
168 : :
169 [ + + ]: 400 : if (what & TEST_CONTEXTO_RULE)
170 : : {
171 : : size_t i;
172 : : int rc;
173 : :
174 [ + + ]: 173 : for (i = 0; i < llen; i++)
175 : : {
176 : 153 : rc = _idn2_contexto_rule (label, llen, i);
177 [ + + ]: 153 : if (rc != IDN2_OK)
178 : 22 : return rc;
179 : : }
180 : : }
181 : :
182 [ + - ]: 378 : if (what & TEST_UNASSIGNED)
183 : : {
184 : : size_t i;
185 [ + + ]: 2917 : for (i = 0; i < llen; i++)
186 [ + + ]: 2544 : if (_idn2_unassigned_p (label[i]))
187 : 5 : return IDN2_UNASSIGNED;
188 : : }
189 : :
190 [ + - ]: 373 : if (what & TEST_BIDI)
191 : : {
192 : 373 : int rc = _idn2_bidi (label, llen);
193 [ + + ]: 373 : if (rc != IDN2_OK)
194 : 9 : return rc;
195 : : }
196 : :
197 : 477 : return IDN2_OK;
198 : : }
|