| |
1 #include <glib.h> |
| |
2 |
| |
3 #include "account.h" |
| |
4 #include "conversation.h" |
| |
5 #include "xmlnode.h" |
| |
6 #include "protocols/jabber/jutil.h" |
| |
7 |
| |
8 typedef struct { |
| |
9 const gchar *input; |
| |
10 const gchar *output; |
| |
11 } TestStringData; |
| |
12 |
| |
13 typedef const gchar *(*test_string_func)(const gchar *); |
| |
14 typedef gchar *(*test_string_free_func)(const gchar *); |
| |
15 |
| |
16 static void |
| |
17 _test_string_compare_func(TestStringData data[], test_string_func func) { |
| |
18 gint i; |
| |
19 |
| |
20 for(i = 0; data[i].input; i++) |
| |
21 g_assert_cmpstr(data[i].output, ==, func(data[i].input)); |
| |
22 } |
| |
23 |
| |
24 static void |
| |
25 _test_string_compare_func_free(TestStringData data[], test_string_free_func func) { |
| |
26 gint i; |
| |
27 |
| |
28 for(i = 0; data[i].input; i++) { |
| |
29 gchar *got = func(data[i].input); |
| |
30 |
| |
31 g_assert_cmpstr(data[i].output, ==, got); |
| |
32 |
| |
33 g_free(got); |
| |
34 } |
| |
35 } |
| |
36 |
| |
37 static void |
| |
38 test_jabber_util_get_resource_exists(void) { |
| |
39 TestStringData data[] = { |
| |
40 { "foo@bar/baz", "baz" }, |
| |
41 { "bar/baz", "baz" }, |
| |
42 { "foo@bar/baz/bat", "baz/bat" }, |
| |
43 { "bar/baz/bat", "baz/bat" }, |
| |
44 { NULL, NULL }, |
| |
45 }; |
| |
46 |
| |
47 _test_string_compare_func_free(data, jabber_get_resource); |
| |
48 } |
| |
49 |
| |
50 static void |
| |
51 test_jabber_util_get_resource_none(void) { |
| |
52 TestStringData data[] = { |
| |
53 { "foo@bar", NULL }, |
| |
54 { "bar", NULL }, |
| |
55 { NULL, NULL }, |
| |
56 }; |
| |
57 |
| |
58 _test_string_compare_func_free(data, jabber_get_resource); |
| |
59 } |
| |
60 |
| |
61 static void |
| |
62 test_jabber_util_get_bare_jid(void) { |
| |
63 TestStringData data[] = { |
| |
64 { "foo@bar", "foo@bar" }, |
| |
65 { "foo@bar/baz", "foo@bar" }, |
| |
66 { "bar", "bar" }, |
| |
67 { "bar/baz", "bar" }, |
| |
68 { NULL, NULL }, |
| |
69 }; |
| |
70 |
| |
71 _test_string_compare_func_free(data, jabber_get_bare_jid); |
| |
72 } |
| |
73 |
| |
74 static void |
| |
75 test_jabber_util_nodeprep_validate(void) { |
| |
76 const gchar *data[] = { |
| |
77 "foo", |
| |
78 "%d", |
| |
79 "y\\z", |
| |
80 "a=", |
| |
81 "a,", |
| |
82 NULL, |
| |
83 }; |
| |
84 gchar *longnode; |
| |
85 gint i; |
| |
86 |
| |
87 for(i = 0; data[i]; i++) { |
| |
88 g_assert_true(jabber_nodeprep_validate(data[i])); |
| |
89 } |
| |
90 |
| |
91 longnode = g_strnfill(1023, 'a'); |
| |
92 g_assert_true(jabber_nodeprep_validate(longnode)); |
| |
93 g_free(longnode); |
| |
94 |
| |
95 longnode = g_strnfill(1024, 'a'); |
| |
96 g_assert_false(jabber_nodeprep_validate(longnode)); |
| |
97 g_free(longnode); |
| |
98 } |
| |
99 |
| |
100 static void |
| |
101 test_jabber_util_nodeprep_validate_illegal_chars(void) { |
| |
102 const gchar *data[] = { |
| |
103 "don't", |
| |
104 "m@ke", |
| |
105 "\"me\"", |
| |
106 "&ngry", |
| |
107 "c:", |
| |
108 "a/b", |
| |
109 "4>2", |
| |
110 "4<7", |
| |
111 NULL, |
| |
112 }; |
| |
113 gint i; |
| |
114 |
| |
115 for(i = 0; data[i]; i++) |
| |
116 g_assert_false(jabber_nodeprep_validate(data[i])); |
| |
117 } |
| |
118 |
| |
119 static void |
| |
120 test_jabber_util_nodeprep_validate_too_long(void) { |
| |
121 gchar *longnode = g_strnfill(1024, 'a'); |
| |
122 |
| |
123 g_assert_false(jabber_nodeprep_validate(longnode)); |
| |
124 |
| |
125 g_free(longnode); |
| |
126 } |
| |
127 |
| |
128 static void |
| |
129 test_jabber_util_jabber_id_new_valid(void) { |
| |
130 const gchar *jids[] = { |
| |
131 "gmail.com", |
| |
132 "gmail.com/Test", |
| |
133 "gmail.com/Test@", |
| |
134 "gmail.com/@", |
| |
135 "gmail.com/Test@alkjaweflkj", |
| |
136 "mark.doliner@gmail.com", |
| |
137 "mark.doliner@gmail.com/Test12345", |
| |
138 "mark.doliner@gmail.com/Test@12345", |
| |
139 "mark.doliner@gmail.com/Te/st@12@//345", |
| |
140 "わいど@conference.jabber.org", |
| |
141 "まりるーむ@conference.jabber.org", |
| |
142 "mark.doliner@gmail.com/まりるーむ", |
| |
143 "mark.doliner@gmail/stuff.org", |
| |
144 "stuart@nödåtXäYZ.se", |
| |
145 "stuart@nödåtXäYZ.se/まりるーむ", |
| |
146 "mark.doliner@わいど.org", |
| |
147 "nick@まつ.おおかみ.net", |
| |
148 "paul@10.0.42.230/s", |
| |
149 "paul@[::1]", /* IPv6 */ |
| |
150 "paul@[2001:470:1f05:d58::2]", |
| |
151 "paul@[2001:470:1f05:d58::2]/foo", |
| |
152 "pa=ul@10.0.42.230", |
| |
153 "pa,ul@10.0.42.230", |
| |
154 NULL |
| |
155 }; |
| |
156 gint i; |
| |
157 |
| |
158 for(i = 0; jids[i]; i++) { |
| |
159 JabberID *jid = jabber_id_new(jids[i]); |
| |
160 |
| |
161 g_assert_nonnull(jid); |
| |
162 |
| |
163 jabber_id_free(jid); |
| |
164 } |
| |
165 } |
| |
166 |
| |
167 static void |
| |
168 test_jabber_util_jabber_id_new_invalid(void) { |
| |
169 const gchar *jids[] = { |
| |
170 "@gmail.com", |
| |
171 "@@gmail.com", |
| |
172 "mark.doliner@@gmail.com/Test12345", |
| |
173 "mark@doliner@gmail.com/Test12345", |
| |
174 "@gmail.com/Test@12345", |
| |
175 "/Test@12345", |
| |
176 "mark.doliner@", |
| |
177 "mark.doliner/", |
| |
178 "mark.doliner@gmail_stuff.org", |
| |
179 "mark.doliner@gmail[stuff.org", |
| |
180 "mark.doliner@gmail\\stuff.org", |
| |
181 "paul@[::1]124", |
| |
182 "paul@2[::1]124/as", |
| |
183 "paul@まつ.おおかみ/\x01", |
| |
184 /* |
| |
185 * RFC 3454 Section 6 reads, in part, |
| |
186 * "If a string contains any RandALCat character, the |
| |
187 * string MUST NOT contain any LCat character." |
| |
188 * The character is U+066D (ARABIC FIVE POINTED STAR). |
| |
189 */ |
| |
190 "foo@example.com/٭simplexe٭", |
| |
191 NULL, |
| |
192 }; |
| |
193 gint i; |
| |
194 |
| |
195 for(i = 0; jids[i]; i++) |
| |
196 g_assert_null(jabber_id_new(jids[i])); |
| |
197 } |
| |
198 |
| |
199 #define assert_jid_parts(expect_node, expect_domain, str) G_STMT_START { \ |
| |
200 JabberID *jid = jabber_id_new(str); \ |
| |
201 g_assert_nonnull(jid); \ |
| |
202 g_assert_nonnull(jid->node); \ |
| |
203 g_assert_nonnull(jid->domain); \ |
| |
204 g_assert_null(jid->resource); \ |
| |
205 g_assert_cmpstr(expect_node, ==, jid->node); \ |
| |
206 g_assert_cmpstr(expect_domain, ==, jid->domain); \ |
| |
207 jabber_id_free(jid); \ |
| |
208 } G_STMT_END |
| |
209 |
| |
210 |
| |
211 static void |
| |
212 test_jabber_util_jid_parts(void) { |
| |
213 /* Ensure that jabber_id_new is properly lowercasing node and domains */ |
| |
214 assert_jid_parts("paul", "darkrain42.org", "PaUL@darkrain42.org"); |
| |
215 assert_jid_parts("paul", "darkrain42.org", "paul@DaRkRaIn42.org"); |
| |
216 |
| |
217 /* These case-mapping tests culled from examining RFC3454 B.2 */ |
| |
218 |
| |
219 /* Cyrillic capital EF (U+0424) maps to lowercase EF (U+0444) */ |
| |
220 assert_jid_parts("ф", "darkrain42.org", "Ф@darkrain42.org"); |
| |
221 |
| |
222 #ifdef USE_IDN |
| |
223 /* |
| |
224 * These character (U+A664 and U+A665) are not mapped to anything in |
| |
225 * RFC3454 B.2. This first test *fails* when not using IDN because glib's |
| |
226 * case-folding/utf8_strdown improperly (for XMPP) lowercases the character. |
| |
227 * |
| |
228 * This is known, but not (very?) likely to actually cause a problem, so |
| |
229 * this test is commented out when using glib's functions. |
| |
230 */ |
| |
231 assert_jid_parts("Ꙥ", "darkrain42.org", "Ꙥ@darkrain42.org"); |
| |
232 assert_jid_parts("ꙥ", "darkrain42.org", "ꙥ@darkrain42.org"); |
| |
233 #endif |
| |
234 |
| |
235 /* U+04E9 to U+04E9 */ |
| |
236 assert_jid_parts("paul", "өarkrain42.org", "paul@Өarkrain42.org"); |
| |
237 } |
| |
238 |
| |
239 static const gchar * |
| |
240 partial_jabber_normalize(const gchar *str) { |
| |
241 return jabber_normalize(NULL, str); |
| |
242 } |
| |
243 |
| |
244 static void |
| |
245 test_jabber_util_jabber_normalize(void) { |
| |
246 TestStringData data[] = { |
| |
247 { |
| |
248 "PaUL@DaRkRain42.org", |
| |
249 "paul@darkrain42.org", |
| |
250 }, { |
| |
251 "PaUL@DaRkRain42.org/", |
| |
252 "paul@darkrain42.org", |
| |
253 }, { |
| |
254 "PaUL@DaRkRain42.org/resource", |
| |
255 "paul@darkrain42.org", |
| |
256 }, { |
| |
257 NULL, |
| |
258 NULL, |
| |
259 } |
| |
260 }; |
| |
261 |
| |
262 _test_string_compare_func(data, partial_jabber_normalize); |
| |
263 } |
| |
264 |
| |
265 gint |
| |
266 main(gint argc, gchar **argv) { |
| |
267 g_test_init(&argc, &argv, NULL); |
| |
268 |
| |
269 g_test_add_func("/jabber/util/get_resource/exists", |
| |
270 test_jabber_util_get_resource_exists); |
| |
271 g_test_add_func("/jabber/util/get_resource/none", |
| |
272 test_jabber_util_get_resource_none); |
| |
273 |
| |
274 g_test_add_func("/jabber/util/get_bare_jid", |
| |
275 test_jabber_util_get_bare_jid); |
| |
276 |
| |
277 g_test_add_func("/jabber/util/nodeprep/validate/valid", |
| |
278 test_jabber_util_nodeprep_validate); |
| |
279 g_test_add_func("/jabber/util/nodeprep/validate/illegal_chars", |
| |
280 test_jabber_util_nodeprep_validate_illegal_chars); |
| |
281 g_test_add_func("/jabber/util/nodeprep/validate/too_long", |
| |
282 test_jabber_util_nodeprep_validate_too_long); |
| |
283 |
| |
284 g_test_add_func("/jabber/util/id_new/valid", |
| |
285 test_jabber_util_jabber_id_new_valid); |
| |
286 g_test_add_func("/jabber/util/id_new/invalid", |
| |
287 test_jabber_util_jabber_id_new_invalid); |
| |
288 g_test_add_func("/jabber/util/id_new/jid_parts", |
| |
289 test_jabber_util_jid_parts); |
| |
290 |
| |
291 g_test_add_func("/jabber/util/normalize", |
| |
292 test_jabber_util_jabber_normalize); |
| |
293 |
| |
294 return g_test_run(); |
| |
295 } |