1/* bug 17197: check that iconv doesn't emit invalid extra shift character
2 Copyright (C) 2015-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <iconv.h>
20#include <locale.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <errno.h>
25
26static int
27do_test (void)
28{
29 static const char *charsets[] =
30 { "IBM930", "IBM933", "IBM935", "IBM937", "IBM939" };
31 static const char *expects[] =
32 { "\016\x44\x4d\017", "\016\x41\x63\017", "\016\x44\x4d\017",
33 "\016\x44\x4d\017", "\016\x44\x4d\017" };
34 int ret = 0;
35
36 for (int i = 0; i < sizeof (charsets) / sizeof (*charsets); i++)
37 {
38 const char *charset = charsets[i];
39 iconv_t cd = iconv_open (tocode: charset, fromcode: "UTF-8");
40 if (cd == (iconv_t) -1)
41 {
42 printf (format: "iconv_open failed (%s)\n", charset);
43 ret = 1;
44 continue;
45 }
46
47 char input[] = "\xe2\x88\x9e.";
48 const char *expect1 = expects[i];
49 const char expect2[] = "\x4b";
50 size_t input_len = sizeof (input);
51 char output[4];
52 size_t inlen = input_len;
53 size_t outlen = sizeof (output);
54 char *inptr = input;
55 char *outptr = output;
56 /* First round: expect conversion to stop before ".". */
57 size_t r = iconv (cd: cd, inbuf: &inptr, inbytesleft: &inlen, outbuf: &outptr, outbytesleft: &outlen);
58 if (r != -1
59 || errno != E2BIG
60 || inlen != 2
61 || inptr != input + input_len - 2
62 || outlen != 0
63 || memcmp (s1: output, s2: expect1, n: sizeof (output)) != 0)
64 {
65 printf (format: "wrong first conversion (%s)", charset);
66 ret = 1;
67 goto do_close;
68 }
69
70 outlen = sizeof (output);
71 outptr = output;
72 r = iconv (cd: cd, inbuf: &inptr, inbytesleft: &inlen, outbuf: &outptr, outbytesleft: &outlen);
73 if (r != 0
74 || inlen != 0
75 || outlen != sizeof (output) - sizeof (expect2)
76 || memcmp (s1: output, s2: expect2, n: sizeof (expect2)) != 0)
77 {
78 printf (format: "wrong second conversion (%s)\n", charset);
79 ret = 1;
80 }
81
82 do_close:
83 if (iconv_close (cd: cd) != 0)
84 {
85 printf (format: "iconv_close failed (%s)\n", charset);
86 ret = 1;
87 continue;
88 }
89 }
90 return ret;
91}
92
93#define TEST_FUNCTION do_test ()
94#include "../test-skeleton.c"
95

source code of glibc/iconvdata/bug-iconv10.c