1 /* Assertion in ISO-2022-JP-3 due to two-character sequence (bug 27256).
2    Copyright (C) 2021-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 <string.h>
21 #include <errno.h>
22 #include <support/check.h>
23 
24 /* Use an escape sequence to return to the initial state.  */
25 static void
with_escape_sequence(void)26 with_escape_sequence (void)
27 {
28   iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
29   TEST_VERIFY_EXIT (c != (iconv_t) -1);
30 
31   char in[] = "\e$(O+D\e(B";
32   char *inbuf = in;
33   size_t inleft = strlen (in);
34   char out[3];                  /* Space for one output character.  */
35   char *outbuf;
36   size_t outleft;
37 
38   outbuf = out;
39   outleft = sizeof (out);
40   TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
41   TEST_COMPARE (errno, E2BIG);
42   TEST_COMPARE (inleft, 3);
43   TEST_COMPARE (inbuf - in, strlen (in) - 3);
44   TEST_COMPARE (outleft, sizeof (out) - 2);
45   TEST_COMPARE (outbuf - out, 2);
46   TEST_COMPARE (out[0] & 0xff, 0xc3);
47   TEST_COMPARE (out[1] & 0xff, 0xa6);
48 
49   /* Return to the initial shift state, producing the pending
50      character.  */
51   outbuf = out;
52   outleft = sizeof (out);
53   TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), 0);
54   TEST_COMPARE (inleft, 0);
55   TEST_COMPARE (inbuf - in, strlen (in));
56   TEST_COMPARE (outleft, sizeof (out) - 2);
57   TEST_COMPARE (outbuf - out, 2);
58   TEST_COMPARE (out[0] & 0xff, 0xcc);
59   TEST_COMPARE (out[1] & 0xff, 0x80);
60 
61   /* Nothing should be flushed the second time.  */
62   outbuf = out;
63   outleft = sizeof (out);
64   TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
65   TEST_COMPARE (outleft, sizeof (out));
66   TEST_COMPARE (outbuf - out, 0);
67   TEST_COMPARE (out[0] & 0xff, 0xcc);
68   TEST_COMPARE (out[1] & 0xff, 0x80);
69 
70   TEST_COMPARE (iconv_close (c), 0);
71 }
72 
73 /* Use an explicit flush to return to the initial state.  */
74 static void
with_flush(void)75 with_flush (void)
76 {
77   iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
78   TEST_VERIFY_EXIT (c != (iconv_t) -1);
79 
80   char in[] = "\e$(O+D";
81   char *inbuf = in;
82   size_t inleft = strlen (in);
83   char out[3];                  /* Space for one output character.  */
84   char *outbuf;
85   size_t outleft;
86 
87   outbuf = out;
88   outleft = sizeof (out);
89   TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
90   TEST_COMPARE (errno, E2BIG);
91   TEST_COMPARE (inleft, 0);
92   TEST_COMPARE (inbuf - in, strlen (in));
93   TEST_COMPARE (outleft, sizeof (out) - 2);
94   TEST_COMPARE (outbuf - out, 2);
95   TEST_COMPARE (out[0] & 0xff, 0xc3);
96   TEST_COMPARE (out[1] & 0xff, 0xa6);
97 
98   /* Flush the pending character.  */
99   outbuf = out;
100   outleft = sizeof (out);
101   TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
102   TEST_COMPARE (outleft, sizeof (out) - 2);
103   TEST_COMPARE (outbuf - out, 2);
104   TEST_COMPARE (out[0] & 0xff, 0xcc);
105   TEST_COMPARE (out[1] & 0xff, 0x80);
106 
107   /* Nothing should be flushed the second time.  */
108   outbuf = out;
109   outleft = sizeof (out);
110   TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
111   TEST_COMPARE (outleft, sizeof (out));
112   TEST_COMPARE (outbuf - out, 0);
113   TEST_COMPARE (out[0] & 0xff, 0xcc);
114   TEST_COMPARE (out[1] & 0xff, 0x80);
115 
116   TEST_COMPARE (iconv_close (c), 0);
117 }
118 
119 static int
do_test(void)120 do_test (void)
121 {
122   with_escape_sequence ();
123   with_flush ();
124   return 0;
125 }
126 
127 #include <support/test-driver.c>
128