Branch data Line data Source code
1 : : /* context.c - check contextual rule on label
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 "tables.h"
23 : :
24 : : #include <unictype.h> /* uc_combining_class, UC_CCC_VR */
25 : :
26 : : #include "context.h"
27 : :
28 : : int
29 : 2631 : _idn2_contextj_rule (const uint32_t * label, size_t llen, size_t pos)
30 : : {
31 : : uint32_t cp;
32 : :
33 [ - + ]: 2631 : if (llen == 0)
34 : 0 : return IDN2_OK;
35 : :
36 : 2631 : cp = label[pos];
37 : :
38 [ + + ]: 2631 : if (!_idn2_contextj_p (cp))
39 : 2601 : return IDN2_OK;
40 : :
41 [ + + - ]: 30 : switch (cp)
42 : : {
43 : : case 0x200C: /* ZERO WIDTH NON-JOINER */
44 [ + + ]: 19 : if (pos > 0)
45 : : {
46 : : /* If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True; */
47 : 18 : uint32_t before_cp = label[pos - 1];
48 : 18 : int cc = uc_combining_class (before_cp);
49 [ + + ]: 18 : if (cc == UC_CCC_VR)
50 : 3 : return IDN2_OK;
51 : : }
52 : :
53 : : /* See http://permalink.gmane.org/gmane.ietf.idnabis/6980 for
54 : : clarified rule. */
55 : :
56 [ + + ][ - + ]: 16 : if (pos == 0 || pos == llen - 1)
57 : 1 : return IDN2_CONTEXTJ;
58 : :
59 : : {
60 : : int jt;
61 : : size_t tmp;
62 : :
63 : : /* Search backwards. */
64 : 15 : for (tmp = pos - 1;; tmp--)
65 : : {
66 : 20 : jt = uc_joining_type (label[tmp]);
67 [ + - + + ]: 20 : if (jt == UC_JOINING_TYPE_L || jt == UC_JOINING_TYPE_D)
68 : : break;
69 [ - + ]: 6 : if (tmp == 0)
70 : 0 : return IDN2_CONTEXTJ;
71 [ + + ]: 6 : if (jt == UC_JOINING_TYPE_T)
72 : 5 : continue;
73 : 1 : return IDN2_CONTEXTJ;
74 : 5 : }
75 : :
76 : : /* Search forward. */
77 [ + - ]: 21 : for (tmp = pos + 1; tmp < llen; tmp++)
78 : : {
79 : 21 : jt = uc_joining_type (label[tmp]);
80 [ + + + + ]: 21 : if (jt == UC_JOINING_TYPE_R || jt == UC_JOINING_TYPE_D)
81 : : break;
82 [ + + ]: 8 : if (tmp == llen - 1)
83 : 1 : return IDN2_CONTEXTJ;
84 [ + - ]: 7 : if (jt == UC_JOINING_TYPE_T)
85 : 7 : continue;
86 : 0 : return IDN2_CONTEXTJ;
87 : : }
88 : : }
89 : :
90 : 13 : return IDN2_OK;
91 : : break;
92 : :
93 : : case 0x200D: /* ZERO WIDTH JOINER */
94 [ + + ]: 11 : if (pos > 0)
95 : : {
96 : 10 : uint32_t before_cp = label[pos - 1];
97 : 10 : int cc = uc_combining_class (before_cp);
98 [ + + ]: 10 : if (cc == UC_CCC_VR)
99 : 9 : return IDN2_OK;
100 : : }
101 : 2 : return IDN2_CONTEXTJ;
102 : : }
103 : :
104 : 2631 : return IDN2_CONTEXTJ_NO_RULE;
105 : : }
106 : :
107 : : int
108 : 153 : _idn2_contexto_rule (const uint32_t * label, size_t llen, size_t pos)
109 : : {
110 : 153 : uint32_t cp = label[pos];
111 : :
112 [ + + ]: 153 : if (!_idn2_contexto_p (cp))
113 : 112 : return IDN2_OK;
114 : :
115 [ + + + + + : 41 : switch (cp)
+ - ]
116 : : {
117 : : case 0x00B7:
118 : : /* MIDDLE DOT */
119 [ + + ]: 6 : if (llen < 3)
120 : 3 : return IDN2_CONTEXTO;
121 [ + - ][ - + ]: 3 : if (pos == 0 || pos == llen - 1)
122 : 0 : return IDN2_CONTEXTO;
123 [ + + ][ + - ]: 3 : if (label[pos - 1] == 0x006C && label[pos + 1] == 0x006C)
124 : 2 : return IDN2_OK;
125 : 1 : return IDN2_CONTEXTO;
126 : : break;
127 : :
128 : : case 0x0375:
129 : : /* GREEK LOWER NUMERAL SIGN (KERAIA) */
130 [ + + ]: 8 : if (pos == llen - 1)
131 : 1 : return IDN2_CONTEXTO;
132 [ + + ]: 7 : if (strcmp (uc_script (label[pos + 1])->name, "Greek") == 0)
133 : 4 : return IDN2_OK;
134 : 3 : return IDN2_CONTEXTO;
135 : : break;
136 : :
137 : : case 0x05F3:
138 : : /* HEBREW PUNCTUATION GERESH */
139 : : case 0x05F4:
140 : : /* HEBREW PUNCTUATION GERSHAYIM */
141 [ + + ]: 12 : if (pos == 0)
142 : 2 : return IDN2_CONTEXTO;
143 [ + + ]: 10 : if (strcmp (uc_script (label[pos - 1])->name, "Hebrew") == 0)
144 : 5 : return IDN2_OK;
145 : 5 : return IDN2_CONTEXTO;
146 : : break;
147 : :
148 : : case 0x0660:
149 : : case 0x0661:
150 : : case 0x0662:
151 : : case 0x0663:
152 : : case 0x0664:
153 : : case 0x0665:
154 : : case 0x0666:
155 : : case 0x0667:
156 : : case 0x0668:
157 : : case 0x0669:
158 : : {
159 : : /* ARABIC-INDIC DIGITS */
160 : : size_t i;
161 [ + + ]: 21 : for (i = 0; i < llen; i++)
162 [ + + ][ + - ]: 18 : if (label[i] >= 0x6F0 && label[i] <= 0x06F9)
163 : 3 : return IDN2_CONTEXTO;
164 : 3 : return IDN2_OK;
165 : : break;
166 : : }
167 : :
168 : : case 0x06F0:
169 : : case 0x06F1:
170 : : case 0x06F2:
171 : : case 0x06F3:
172 : : case 0x06F4:
173 : : case 0x06F5:
174 : : case 0x06F6:
175 : : case 0x06F7:
176 : : case 0x06F8:
177 : : case 0x06F9:
178 : : {
179 : : /* EXTENDED ARABIC-INDIC DIGITS */
180 : : size_t i;
181 [ + + ]: 8 : for (i = 0; i < llen; i++)
182 [ + + ][ + + ]: 7 : if (label[i] >= 0x660 && label[i] <= 0x0669)
183 : 1 : return IDN2_CONTEXTO;
184 : 1 : return IDN2_OK;
185 : : break;
186 : : }
187 : : case 0x30FB:
188 : : {
189 : : /* KATAKANA MIDDLE DOT */
190 : : size_t i;
191 : 7 : bool script_ok = false;
192 : :
193 [ + + ][ + + ]: 51 : for (i = 0; !script_ok && i < llen; i++)
194 [ + + + + + : 129 : if (strcmp (uc_script (label[i])->name, "Hiragana") == 0
+ ]
195 : 43 : || strcmp (uc_script (label[i])->name, "Katakana") == 0
196 : 42 : || strcmp (uc_script (label[i])->name, "Han") == 0)
197 : 4 : script_ok = true;
198 : :
199 [ + + ]: 7 : if (script_ok)
200 : 4 : return IDN2_OK;
201 : 3 : return IDN2_CONTEXTO;
202 : : break;
203 : : }
204 : : }
205 : :
206 : 153 : return IDN2_CONTEXTO_NO_RULE;
207 : : }
208 : :
209 : : bool
210 : 26 : _idn2_contexto_with_rule (uint32_t cp)
211 : : {
212 [ + - ]: 26 : switch (cp)
213 : : {
214 : : case 0x00B7:
215 : : /* MIDDLE DOT */
216 : : case 0x0375:
217 : : /* GREEK LOWER NUMERAL SIGN (KERAIA) */
218 : : case 0x05F3:
219 : : /* HEBREW PUNCTUATION GERESH */
220 : : case 0x05F4:
221 : : /* HEBREW PUNCTUATION GERSHAYIM */
222 : : case 0x0660:
223 : : case 0x0661:
224 : : case 0x0662:
225 : : case 0x0663:
226 : : case 0x0664:
227 : : case 0x0665:
228 : : case 0x0666:
229 : : case 0x0667:
230 : : case 0x0668:
231 : : case 0x0669:
232 : : /* ARABIC-INDIC DIGITS */
233 : : case 0x06F0:
234 : : case 0x06F1:
235 : : case 0x06F2:
236 : : case 0x06F3:
237 : : case 0x06F4:
238 : : case 0x06F5:
239 : : case 0x06F6:
240 : : case 0x06F7:
241 : : case 0x06F8:
242 : : case 0x06F9:
243 : : /* EXTENDED ARABIC-INDIC DIGITS */
244 : : case 0x30FB:
245 : : /* KATAKANA MIDDLE DOT */
246 : 26 : return true;
247 : : break;
248 : : }
249 : :
250 : 26 : return false;
251 : : }
|