1#ifndef lint
2static char *rcsid = "$Id: converter.tsy,v 1.1 2003/06/04 00:26:53 marka Exp $";
3#endif
4
5/*
6 * Copyright (c) 2002 Japan Network Information Center.
7 * All rights reserved.
8 *
9 * By using this file, you agree to the terms and conditions set forth bellow.
10 *
11 * 			LICENSE TERMS AND CONDITIONS
12 *
13 * The following License Terms and Conditions apply, unless a different
14 * license is obtained from Japan Network Information Center ("JPNIC"),
15 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
16 * Chiyoda-ku, Tokyo 101-0047, Japan.
17 *
18 * 1. Use, Modification and Redistribution (including distribution of any
19 *    modified or derived work) in source and/or binary forms is permitted
20 *    under this License Terms and Conditions.
21 *
22 * 2. Redistribution of source code must retain the copyright notices as they
23 *    appear in each source code file, this License Terms and Conditions.
24 *
25 * 3. Redistribution in binary form must reproduce the Copyright Notice,
26 *    this License Terms and Conditions, in the documentation and/or other
27 *    materials provided with the distribution.  For the purposes of binary
28 *    distribution the "Copyright Notice" refers to the following language:
29 *    "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
30 *
31 * 4. The name of JPNIC may not be used to endorse or promote products
32 *    derived from this Software without specific prior written approval of
33 *    JPNIC.
34 *
35 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
36 *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
38 *    PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JPNIC BE LIABLE
39 *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42 *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
43 *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
44 *    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
45 *    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
46 */
47
48#include <stddef.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <idn/converter.h>
53#include <idn/log.h>
54
55#include "codeset.h"
56#include "testutil.h"
57
58
59#ifndef IDN_PUNYCODE_ENCODING_NAME
60#define IDN_PUNYCODE_ENCODING_NAME "Punycode"
61#endif
62
63#ifndef IDN_UTF8_ENCODING_NAME
64#define IDN_UTF8_ENCODING_NAME "UTF-8"		/* by IANA */
65#endif
66
67#ifndef EUCJP_ENCODING_NAME
68#define EUCJP_ENCODING_NAME	"eucJP"
69#endif
70
71#ifndef SJIS_ENCODING_NAME
72#define SJIS_ENCODING_NAME	"SJIS"
73#endif
74
75#define CONF_FILENAME	"testalias.conf"
76#define LINEBUF_SIZE	2001
77
78#define SIZEOFUCS4(x)	(sizeof(x) / sizeof(unsigned long))
79
80/*
81 * U+1820: mongorian letter a
82 */
83#define UCS4_INVALID_NAME_FOR_EUCJP	0x1820
84
85/*
86 * A4AC: hiragana letter GA (in EUC-JP)
87 */
88#define EUCJP_NAME	"\xa4\xac"
89#define EUCJP_NAME_SIZE	3
90
91/*
92 * U+304C: hiragana letter GA
93 */
94#define UCS4_NAME		0x304C
95
96/*
97 * Conversion result of "U+304C"
98 */
99#define PUNYCODE_NAME	"xn--v8j"
100#define PUNYCODE_NAME_SIZE	8
101
102#define BUF_SIZE	128
103
104idn_result_t
105idn_test_encode(idn_converter_t ctx, void *privdata,
106		const unsigned long *from, char *to, size_t tolen)
107{
108	idn_result_t r;
109
110	if (tolen >= EUCJP_NAME_SIZE) {
111		strcpy(to, EUCJP_NAME);
112		r = idn_success;
113	} else {
114		r = idn_buffer_overflow;
115	}
116	return (r);
117
118}
119
120idn_result_t
121idn_test_decode(idn_converter_t ctx, void *privdata,
122		const char *from, unsigned long *to, size_t tolen)
123{
124	idn_result_t r;
125
126	if (tolen >= 2) {
127		to[0] = UCS4_NAME;
128		to[1] = 0x0000;
129		r = idn_success;
130	} else {
131		r = idn_buffer_overflow;
132	}
133	return (r);
134}
135
136
137//--------------------------------------------------------------------
138// Setups and Teardowns.
139//--------------------------------------------------------------------
140
141//# SETUP
142//	group: noinit
143//--
144//	Do nothing
145{
146	idn_result_t r;
147}
148
149//# SETUP
150//	group: generic
151//--
152//	Initialize the module.
153{
154	idn_result_t r;
155	idn_converter_t ctx = NULL;
156	const char *name;
157
158	r = idn_converter_initialize();
159	ASSERT_RESULT(r, idn_success);
160	r = idn_converter_resetalias();
161	ASSERT_RESULT(r, idn_success);
162}
163
164//# SETUP
165//	group: localencoding
166//--
167//	Initialize the module and load alias file.
168{
169	idn_result_t r;
170	idn_converter_t ctx = NULL;
171	const char *name;
172
173	r = idn_converter_initialize();
174	ASSERT_RESULT(r, idn_success);
175	r = idn_converter_resetalias();
176	ASSERT_RESULT(r, idn_success);
177	create_conf_file(CONF_FILENAME, 0,
178			 "*.KOI8-R KOI8-R",
179			 "*.ISO_8859-1 ISO-8859-1",
180			 "*.ISO_8859-2 ISO-8859-1",
181			 "*.UTF-8 UTF-8",
182			 "ja_JP.EUC eucJP",
183			 "japanese eucJP",
184			 NULL);
185	r = idn_converter_aliasfile(CONF_FILENAME);
186	ASSERT_RESULT(r, idn_success);
187}
188
189//# TEARDOWN
190//	group: localencoding
191//--
192//	reset alias information.
193{
194	idn_converter_resetalias();
195}
196
197//# SETUP
198//	group: conversion
199//--
200//	Initialize the module and create contexts.
201{
202	idn_result_t r;
203	idn_converter_t punycode_ctx = NULL;
204	idn_converter_t utf8_ctx = NULL;
205#ifndef WITHOUT_ICONV
206	idn_converter_t eucjp_ctx = NULL;
207#endif
208
209	r = idn_converter_initialize();
210	ASSERT_RESULT(r, idn_success);
211	r = idn_converter_create(IDN_PUNYCODE_ENCODING_NAME, &punycode_ctx,
212				 0);
213	ASSERT_RESULT(r, idn_success);
214	r = idn_converter_create(IDN_UTF8_ENCODING_NAME, &utf8_ctx,
215				 IDN_CONVERTER_DELAYEDOPEN);
216	ASSERT_RESULT(r, idn_success);
217#ifndef WITHOUT_ICONV
218	r = idn_converter_create(EUCJP_ENCODING_NAME, &eucjp_ctx,
219				 IDN_CONVERTER_DELAYEDOPEN);
220	ASSERT_RESULT(r, idn_success);
221#endif
222}
223
224//# TEARDOWN
225//	group: conversion
226//--
227//	Destroy contexts.
228{
229	if (punycode_ctx != NULL) {
230		idn_converter_destroy(punycode_ctx);
231	}
232	if (utf8_ctx != NULL) {
233		idn_converter_destroy(utf8_ctx);
234	}
235#ifndef WITHOUT_ICONV
236	if (eucjp_ctx != NULL) {
237		idn_converter_destroy(eucjp_ctx);
238	}
239#endif
240}
241
242//# SETUP
243//	group: quiet
244//--
245//	Set log level to `fatal' to supress log messages.
246{
247	int saved_log_level;
248
249	saved_log_level = idn_log_getlevel();
250	idn_log_setlevel(idn_log_level_fatal);
251}
252
253//# TEARDOWN
254//	group: quiet
255//--
256//	Restore log level.
257{
258	idn_log_setlevel(saved_log_level);
259}
260
261//--------------------------------------------------------------------
262// Testcases.
263//--------------------------------------------------------------------
264
265//# TESTCASE
266//	title: idn_converter_addalias() test - without initialization
267//	group: noinit quiet
268{
269	r = idn_converter_addalias("a", "b", 0);
270	ASSERT_RESULT(r, idn_failure);
271}
272
273//# TESTCASE
274//	title: idn_converter_aliasfile() - without initialization
275//	group: noinit quiet
276{
277	r = idn_converter_aliasfile("a");
278	ASSERT_RESULT(r, idn_failure);
279}
280
281//# TESTCASE
282//	title: idn_converter_resetalias() - without initialization
283//	group: noinit quiet
284{
285	r = idn_converter_resetalias();
286	ASSERT_RESULT(r, idn_failure);
287}
288
289//# TESTCASE
290//	title: idn_converter_getrealname() - without initialization
291//	group: noinit quiet
292{
293	const char *name;
294
295	name = idn_converter_getrealname("test");
296	ASSERT_STRING(name, "test");
297}
298
299//# TESTCASE
300//	title: idn_converter_create()
301//	group: generic quiet
302{
303#ifdef WITHOUT_ICONV
304	r = idn_converter_addalias("*pc", "Punycode", 0);
305	ASSERT_RESULT(r, idn_success);
306	r = idn_converter_addalias("*ej", EUCJP_ENCODING_NAME, 0);
307	ASSERT_RESULT(r, idn_success);
308	r = idn_converter_addalias("*sj", SJIS_ENCODING_NAME, 0);
309	ASSERT_RESULT(r, idn_success);
310
311	r = idn_converter_create("abcsj", &ctx, 0);
312	ASSERT_RESULT(r, idn_invalid_name);
313
314	r = idn_converter_create("notresolved", &ctx, 0);
315	ASSERT_RESULT(r, idn_invalid_name);
316	r = idn_converter_create("notresolved", &ctx,
317				 IDN_CONVERTER_DELAYEDOPEN);
318	ASSERT_RESULT(r, idn_invalid_name);
319#else
320	r = idn_converter_addalias("*pc", IDN_PUNYCODE_ENCODING_NAME, 0);
321	ASSERT_RESULT(r, idn_success);
322	r = idn_converter_addalias("*ej", EUCJP_ENCODING_NAME, 0);
323	ASSERT_RESULT(r, idn_success);
324	r = idn_converter_addalias("*sj", SJIS_ENCODING_NAME, 0);
325	ASSERT_RESULT(r, idn_success);
326
327	r = idn_converter_create("abcsj", &ctx, 0);
328	ASSERT_RESULT(r, idn_success);
329	idn_converter_destroy(ctx);
330
331	r = idn_converter_create("notresolved", &ctx, 0);
332	ASSERT_RESULT(r, idn_invalid_name);
333	r = idn_converter_create("notresolved", &ctx,
334				 IDN_CONVERTER_DELAYEDOPEN);
335	ASSERT_RESULT(r, idn_success);
336    {
337	    unsigned long ucs4_to[BUF_SIZE];
338
339	    r = idn_converter_convtoucs4(ctx, "a", ucs4_to, BUF_SIZE);
340	    ASSERT_RESULT(r, idn_invalid_name);
341	    idn_converter_destroy(ctx);
342    }
343#endif /* WITHOUT_ICONV */
344}
345
346//# TESTCASE
347//	title: idn_converter_addalias() - #1
348//	group: generic
349{
350	r = idn_converter_addalias("test", "result-a", 0);
351	ASSERT_RESULT(r, idn_success);
352	name = idn_converter_getrealname("test");
353	ASSERT_STRING(name, "result-a");
354}
355
356//# TESTCASE
357//	title: idn_converter_addalias() - #2
358//	group: generic
359{
360	r = idn_converter_addalias("test", "result-b", 1);
361	ASSERT_RESULT(r, idn_success);
362	name = idn_converter_getrealname("test");
363	ASSERT_STRING(name, "result-b");
364}
365
366//# TESTCASE
367//	title: idn_converter_addalias() - #3
368//	group: generic
369{
370	r = idn_converter_addalias("test", "result-a", 0);
371	ASSERT_RESULT(r, idn_success);
372	r = idn_converter_addalias("test", "result-b", 0);
373	ASSERT_RESULT(r, idn_success);
374	name = idn_converter_getrealname("test");
375	ASSERT_STRING(name, "result-a");
376}
377
378//# TESTCASE
379//	title: idn_converter_addalias() - #4
380//	group: generic
381{
382	r = idn_converter_addalias("test", "result-a", 0);
383	ASSERT_RESULT(r, idn_success);
384	r = idn_converter_addalias("test", "result-b", 1);
385	ASSERT_RESULT(r, idn_success);
386	name = idn_converter_getrealname("test");
387	ASSERT_STRING(name, "result-b");
388}
389
390//# TESTCASE
391//	title: idn_converter_addalias() - #5
392//	group: generic
393{
394	r = idn_converter_addalias("test", "result-a", 0);
395	ASSERT_RESULT(r, idn_success);
396	r = idn_converter_addalias("test", "result-b", 0);
397	ASSERT_RESULT(r, idn_success);
398	r = idn_converter_addalias("test", "result-c", 0);
399	ASSERT_RESULT(r, idn_success);
400	r = idn_converter_addalias("test", "result-d", 0);
401	ASSERT_RESULT(r, idn_success);
402	r = idn_converter_addalias("test", "result-e", 0);
403	ASSERT_RESULT(r, idn_success);
404	r = idn_converter_addalias("test", "result-f", 0);
405	ASSERT_RESULT(r, idn_success);
406	r = idn_converter_addalias("test", "result-g", 0);
407	ASSERT_RESULT(r, idn_success);
408	r = idn_converter_addalias("test", "result-h", 0);
409	ASSERT_RESULT(r, idn_success);
410	r = idn_converter_addalias("test", "result-i", 0);
411	ASSERT_RESULT(r, idn_success);
412	name = idn_converter_getrealname("test");
413	ASSERT_STRING(name, "result-a");
414}
415
416//# TESTCASE
417//	title: idn_converter_addalias() - #6
418//	group: generic
419{
420	r = idn_converter_addalias("test", "result-a", 0);
421	ASSERT_RESULT(r, idn_success);
422	r = idn_converter_addalias("test", "result-b", 0);
423	ASSERT_RESULT(r, idn_success);
424	r = idn_converter_addalias("test", "result-c", 0);
425	ASSERT_RESULT(r, idn_success);
426	r = idn_converter_addalias("test", "result-d", 0);
427	ASSERT_RESULT(r, idn_success);
428	r = idn_converter_addalias("test", "result-e", 0);
429	ASSERT_RESULT(r, idn_success);
430	r = idn_converter_addalias("test", "result-f", 0);
431	ASSERT_RESULT(r, idn_success);
432	r = idn_converter_addalias("test", "result-g", 0);
433	ASSERT_RESULT(r, idn_success);
434	r = idn_converter_addalias("test", "result-h", 0);
435	ASSERT_RESULT(r, idn_success);
436	r = idn_converter_addalias("test", "result-i", 1);
437	ASSERT_RESULT(r, idn_success);
438	name = idn_converter_getrealname("test");
439	ASSERT_STRING(name, "result-i");
440}
441
442//# TESTCASE
443//	title: idn_converter_addalias() - null character
444//	group: generic
445{
446	r = idn_converter_addalias("", "result", 0);
447	ASSERT_RESULT(r, idn_invalid_syntax);
448	r = idn_converter_addalias("test", "", 0);
449	ASSERT_RESULT(r, idn_invalid_syntax);
450	r = idn_converter_addalias("", "", 0);
451	ASSERT_RESULT(r, idn_invalid_syntax);
452}
453
454//# TESTCASE
455//	title: idn_converter_resetalias() - no alias added
456//	group: generic
457{
458	r = idn_converter_resetalias();
459	ASSERT_RESULT(r, idn_success);
460	name = idn_converter_getrealname("test");
461	ASSERT_STRING(name, "test");
462
463}
464
465//# TESTCASE
466//	title: idn_converter_resetalias() - one alias added
467//	group: generic
468{
469	r = idn_converter_addalias("test", "result-a", 0);
470	ASSERT_RESULT(r, idn_success);
471	r = idn_converter_resetalias();
472	ASSERT_RESULT(r, idn_success);
473	name = idn_converter_getrealname("test");
474	ASSERT_STRING(name, "test");
475
476}
477
478//# TESTCASE
479//	title: idn_converter_resetalias() - many aliases added
480//	group: generic
481{
482	r = idn_converter_addalias("test", "result-a", 1);
483	ASSERT_RESULT(r, idn_success);
484	r = idn_converter_addalias("test", "result-b", 1);
485	ASSERT_RESULT(r, idn_success);
486	r = idn_converter_addalias("test", "result-c", 0);
487	ASSERT_RESULT(r, idn_success);
488	r = idn_converter_addalias("test", "result-d", 1);
489	ASSERT_RESULT(r, idn_success);
490	r = idn_converter_addalias("test", "result-e", 1);
491	ASSERT_RESULT(r, idn_success);
492	r = idn_converter_addalias("test", "result-f", 1);
493	ASSERT_RESULT(r, idn_success);
494	r = idn_converter_addalias("test", "result-g", 0);
495	ASSERT_RESULT(r, idn_success);
496	r = idn_converter_addalias("test", "result-h", 0);
497	ASSERT_RESULT(r, idn_success);
498	r = idn_converter_addalias("test", "result-i", 1);
499	ASSERT_RESULT(r, idn_success);
500	r = idn_converter_resetalias();
501	ASSERT_RESULT(r, idn_success);
502	name = idn_converter_getrealname("test");
503	ASSERT_STRING(name, "test");
504}
505
506//# TESTCASE
507//	title: idn_converter_aliasfile() - boundary condition
508//	group: generic quiet
509{
510	r = idn_converter_aliasfile("");
511	ASSERT_RESULT(r, idn_nofile);
512
513	r = idn_converter_aliasfile("idnalias-not-found.conf");
514	ASSERT_RESULT(r, idn_nofile);
515}
516
517//# TESTCASE
518//	title: idn_converter_aliasfile() - long line
519//	group: generic quiet
520{
521	char line[LINEBUF_SIZE];
522	const char *entry = "aaaaaaaaaa";
523	int i;
524	int len;
525
526	len = strlen(entry);
527	for (i = 0; i < LINEBUF_SIZE - len; i += len) {
528		memcpy(line + i, entry, len);
529	}
530	*(line + (LINEBUF_SIZE / 2)) = ' ';
531	*(line + i) = '\0';
532	create_conf_file(CONF_FILENAME, 0, line, NULL);
533	r = idn_converter_aliasfile(CONF_FILENAME);
534	ASSERT_RESULT(r, idn_invalid_syntax);
535}
536
537//# TESTCASE
538//	title: idn_converter_aliasfile() - no new line at end of file
539//	group: generic quiet
540{
541	create_conf_file(CONF_FILENAME, CONF_NO_EOF_NEWLINE,
542			 "*.ISO_8859-1 ISO-8859-1",
543			 "*.ISO_8859-2 ISO-8859-1",
544			 "*.SJIS Shift_JIS",
545			 "*.Shift_JIS Shift_JIS",
546			 "ja_JP.EUC eucJP",
547			 "japanese eucJP",
548			 NULL);
549	r = idn_converter_aliasfile(CONF_FILENAME);
550	ASSERT_RESULT(r, idn_success);
551	name = idn_converter_getrealname("japanese");
552	ASSERT_STRING(name, "eucJP");
553
554}
555
556//# TESTCASE
557//	title: idn_converter_aliasfile() - invalid entries
558//	group: generic quiet
559{
560	create_conf_file(CONF_FILENAME, 0,
561			 "*.ISO_8859-1 ISO-8859-1",
562			 "*.ISO_8859-2 ISO-8859-1",
563			 "*.SJIS",
564			 "*.Shift_JIS",
565			 "ja_JP.EUC eucJP",
566			 "japanese eucJP",
567			 NULL);
568	r = idn_converter_aliasfile(CONF_FILENAME);
569	ASSERT_RESULT(r, idn_invalid_syntax);
570}
571
572//# TESTCASE
573//	title: idn_converter_aliasfile() - more then two items in one line
574//	group: generic quiet
575{
576	create_conf_file(CONF_FILENAME, 0,
577			 "*.ISO_8859-1 ISO-8859-1",
578			 "*.ISO_8859-2 ISO-8859-1",
579			 "*.SJIS Shift_JIS ko_KR.EUC",
580			 "*.Shift_JIS Shift_JIS",
581			 "*.big5 Big5 *.big5 *.big5",
582			 "ja_JP.EUC eucJP",
583			 "japanese eucJP",
584			 NULL);
585	r = idn_converter_aliasfile(CONF_FILENAME);
586	ASSERT_RESULT(r, idn_success);
587	name = idn_converter_getrealname("japanese");
588	ASSERT_STRING(name, "eucJP");
589}
590
591//# TESTCASE
592//	title: idn_converter_localencoding() - #1
593//	group: localencoding
594{
595	r = idn_converter_create("test.UTF-8", &ctx,
596				 IDN_CONVERTER_DELAYEDOPEN);
597	ASSERT_RESULT(r, idn_success);
598	name = idn_converter_localencoding(ctx);
599	ASSERT_STRING(name, "UTF-8");
600	idn_converter_destroy(ctx);
601}
602
603//# TESTCASE
604//	title: idn_converter_localencoding() - #2
605//	group: localencoding
606{
607	r = idn_converter_create("test.KOI8-R", &ctx,
608				 IDN_CONVERTER_DELAYEDOPEN);
609#ifdef WITHOUT_ICONV
610	ASSERT_RESULT(r, idn_invalid_name);
611#else
612	ASSERT_RESULT(r, idn_success);
613	name = idn_converter_localencoding(ctx);
614	ASSERT_STRING(name, "KOI8-R");
615	idn_converter_destroy(ctx);
616#endif
617}
618
619//# TESTCASE
620//	title: idn_converter_localencoding() - #3
621//	group: localencoding
622{
623	r = idn_converter_create("unresolvedname", &ctx,
624				 IDN_CONVERTER_DELAYEDOPEN);
625#ifdef WITHOUT_ICONV
626	ASSERT_RESULT(r, idn_invalid_name);
627#else
628	ASSERT_RESULT(r, idn_success);
629	name = idn_converter_localencoding(ctx);
630	ASSERT_STRING(name, "unresolvedname");
631	idn_converter_destroy(ctx);
632#endif
633}
634
635//# TESTCASE
636//	title: idn_converter_encodingtype()
637//	group: conversion
638{
639	ASSERT_INT(idn_converter_encodingtype(punycode_ctx),
640		   IDN_ACE_STRICTCASE);
641	ASSERT_INT(idn_converter_encodingtype(utf8_ctx),
642		   IDN_NONACE);
643#ifndef WITHOUT_ICONV
644	ASSERT_INT(idn_converter_encodingtype(eucjp_ctx),
645		   IDN_NONACE);
646#endif
647}
648
649//# TESTCASE
650//	title: idn_converter_isasciicompatible()
651//	group: conversion
652{
653	ASSERT_INT(idn_converter_isasciicompatible(punycode_ctx), 1);
654	ASSERT_INT(idn_converter_isasciicompatible(utf8_ctx), 0);
655#ifndef WITHOUT_ICONV
656	ASSERT_INT(idn_converter_isasciicompatible(eucjp_ctx), 0);
657#endif
658}
659
660//# TESTCASE
661//	title: idn_converter_convfromucs4()
662//	group: conversion quiet
663{
664	unsigned long from_nullchar = 0x0000;
665	unsigned long from[2] = { UCS4_NAME, 0x0000 };
666	char to[1];
667	char to_punycode[PUNYCODE_NAME_SIZE];
668#ifndef WITHOUT_ICONV
669	char to_eucjp[EUCJP_NAME_SIZE];
670#endif
671
672	r = idn_converter_convfromucs4(punycode_ctx, &from_nullchar, to, 0);
673	ASSERT_RESULT(r, idn_buffer_overflow);
674
675	r = idn_converter_convfromucs4(punycode_ctx, &from_nullchar, to, 1);
676	ASSERT_RESULT(r, idn_success);
677	ASSERT_STRING(to, "");
678
679	r = idn_converter_convfromucs4(punycode_ctx, from, to_punycode, 0);
680	ASSERT_RESULT(r, idn_buffer_overflow);
681
682	r = idn_converter_convfromucs4(punycode_ctx, from, to_punycode,
683				       PUNYCODE_NAME_SIZE - 1);
684	ASSERT_RESULT(r, idn_buffer_overflow);
685	r = idn_converter_convfromucs4(punycode_ctx, from, to_punycode,
686				       PUNYCODE_NAME_SIZE);
687	ASSERT_RESULT(r, idn_success);
688	ASSERT_STRING(to_punycode, PUNYCODE_NAME);
689
690#ifndef WITHOUT_ICONV
691	r = idn_converter_convfromucs4(eucjp_ctx, &from_nullchar, to, 0);
692	ASSERT_RESULT(r, idn_buffer_overflow);
693
694	r = idn_converter_convfromucs4(eucjp_ctx, &from_nullchar, to, 1);
695	ASSERT_RESULT(r, idn_success);
696	ASSERT_STRING(to, "");
697
698	r = idn_converter_convfromucs4(eucjp_ctx, from, to_eucjp, 0);
699	ASSERT_RESULT(r, idn_buffer_overflow);
700
701	r = idn_converter_convfromucs4(eucjp_ctx, from, to_eucjp,
702				       EUCJP_NAME_SIZE - 1);
703	ASSERT_RESULT(r, idn_buffer_overflow);
704
705	r = idn_converter_convfromucs4(eucjp_ctx, from, to_eucjp,
706				       EUCJP_NAME_SIZE);
707	ASSERT_RESULT(r, idn_success);
708	ASSERT_STRING(to_eucjp, EUCJP_NAME);
709
710	from[0] = 0x80000000;
711	r = idn_converter_convfromucs4(eucjp_ctx, from, to_eucjp,
712				       EUCJP_NAME_SIZE);
713	ASSERT_RESULT(r, idn_invalid_encoding);
714
715	from[0] = UCS4_INVALID_NAME_FOR_EUCJP;
716	r = idn_converter_convfromucs4(eucjp_ctx, from, to_eucjp,
717				       EUCJP_NAME_SIZE);
718	ASSERT_RESULT(r, idn_nomapping);
719#endif
720}
721
722//# TESTCASE
723//	title: idn_converter_convtoucs4()
724//	group: conversion
725{
726	unsigned long to_nullchar = 0x0000;
727	unsigned long to[1];
728	unsigned long punycode_to[2];
729#ifndef WITHOUT_ICONV
730	unsigned long eucjp_to[2];
731#endif
732	unsigned long ucs4_name[2] = { UCS4_NAME, 0x0000 };
733
734	r = idn_converter_convtoucs4(punycode_ctx, "", to, 0);
735	ASSERT_RESULT(r, idn_buffer_overflow);
736
737	r = idn_converter_convtoucs4(punycode_ctx, "", to, 1);
738	ASSERT_RESULT(r, idn_success);
739	ASSERT_UCS4STRING(to, &to_nullchar);
740
741	r = idn_converter_convtoucs4(punycode_ctx, PUNYCODE_NAME,
742				     punycode_to, 0);
743	ASSERT_RESULT(r, idn_buffer_overflow);
744
745	r = idn_converter_convtoucs4(punycode_ctx, PUNYCODE_NAME,
746				     punycode_to, 1);
747	ASSERT_RESULT(r, idn_buffer_overflow);
748	r = idn_converter_convtoucs4(punycode_ctx, PUNYCODE_NAME, punycode_to,
749				     2);
750	ASSERT_RESULT(r, idn_success);
751	ASSERT_UCS4STRING_THRU(punycode_to, ucs4_name);
752
753#ifndef WITHOUT_ICONV
754	r = idn_converter_convtoucs4(eucjp_ctx, "", to, 0);
755	ASSERT_RESULT(r, idn_buffer_overflow);
756
757	r = idn_converter_convtoucs4(eucjp_ctx, "", to, 1);
758	ASSERT_RESULT(r, idn_success);
759	ASSERT_UCS4STRING(to, &to_nullchar);
760
761	r = idn_converter_convtoucs4(eucjp_ctx, EUCJP_NAME, eucjp_to, 0);
762	ASSERT_RESULT(r, idn_buffer_overflow);
763
764	r = idn_converter_convtoucs4(eucjp_ctx, EUCJP_NAME, eucjp_to, 1);
765	ASSERT_RESULT(r, idn_buffer_overflow);
766
767	r = idn_converter_convtoucs4(eucjp_ctx, EUCJP_NAME, eucjp_to, 2);
768	ASSERT_RESULT(r, idn_success);
769	ASSERT_UCS4STRING(to, &to_nullchar);
770
771	r = idn_converter_convtoucs4(eucjp_ctx, "\xFF\xFF", eucjp_to, 2);
772	ASSERT_RESULT(r, idn_invalid_encoding);
773#endif
774}
775
776//# TESTCASE
777//	title: idn_converter_destroy(), idn_converter_incrref()
778//	group: generic
779{
780	idn_converter_t ctx2;
781
782	r = idn_converter_create(IDN_UTF8_ENCODING_NAME, &ctx, 0);
783	ASSERT_RESULT(r, idn_success);
784	idn_converter_destroy(ctx);
785
786	r = idn_converter_create(IDN_UTF8_ENCODING_NAME, &ctx2, 0);
787	ASSERT_RESULT(r, idn_success);
788	idn_converter_incrref(ctx2);
789	ASSERT_RESULT(r, idn_success);
790	idn_converter_destroy(ctx2);
791	idn_converter_destroy(ctx2);
792}
793
794//# TESTCASE
795//	title: idn_converter_register()
796//	group: generic
797{
798	char eucjp_to[3];
799	unsigned long ucs4_to[2];
800	unsigned long ucs4_name[2] = { UCS4_NAME, 0x0000 };
801
802	r = idn_converter_register("test",
803				   NULL,
804				   NULL,
805				   idn_test_encode,
806				   idn_test_decode,
807				   NULL,
808				   IDN_ACE_STRICTCASE);
809	ASSERT_RESULT(r, idn_success);
810	r = idn_converter_create("test", &ctx, 0);
811	ASSERT_RESULT(r, idn_success);
812
813	r = idn_converter_convfromucs4(ctx, ucs4_name, eucjp_to, sizeof(eucjp_to));
814	ASSERT_RESULT(r, idn_success);
815	ASSERT_STRING(eucjp_to, EUCJP_NAME);
816
817	r = idn_converter_convtoucs4(ctx, "", ucs4_to, SIZEOFUCS4(ucs4_to));
818	ASSERT_RESULT(r, idn_success);
819	ASSERT_UCS4STRING(ucs4_to, ucs4_name);
820
821	idn_converter_destroy(ctx);
822}
823