1/* Copyright (C) 2008 Free Software Foundation, Inc.
2   This file is part of the GNU LIBICONV Library.
3
4   The GNU LIBICONV Library is free software; you can redistribute it
5   and/or modify it under the terms of the GNU Library General Public
6   License as published by the Free Software Foundation; either version 2
7   of the License, or (at your option) any later version.
8
9   The GNU LIBICONV Library is distributed in the hope that it will be
10   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Library General Public License for more details.
13
14   You should have received a copy of the GNU Library General Public
15   License along with the GNU LIBICONV Library; see the file COPYING.LIB.
16   If not, write to the Free Software Foundation, Inc., 51 Franklin Street,
17   Fifth Floor, Boston, MA 02110-1301, USA.  */
18
19#include "config.h"
20
21#include <stdlib.h>
22#include <iconv.h>
23#include <errno.h>
24
25/* This test checks that the behaviour of iconv() in the situation of an
26   invalid multibyte character after a shift sequence is consistent whether
27   the entire buffer is passed at once, or whether it is passed in two
28   subsequent calls.  Based on a bug report from
29   Roman Rybalko <roman_rybalko@users.sourceforge.net>
30   at <http://savannah.gnu.org/bugs/?24216>.  */
31
32void main1 (void)
33{
34  static const char input[] = "+2D/YQNhB";
35  iconv_t cd;
36  char buf[20];
37
38  const char * inptr;
39  size_t inleft;
40  char * outptr;
41  size_t outleft;
42
43  cd = iconv_open ("UTF-8", "UTF-7");
44  {
45    size_t r;
46
47    inptr = input;
48    inleft = 9;
49    outptr = buf;
50    outleft = sizeof (buf);
51    r = iconv (cd, (ICONV_CONST char **) &inptr, &inleft, &outptr, &outleft);
52    /*
53    printf ("r = %d  errno = %d  inconsumed = %d outproduced = %d\n",
54            r, errno, inptr - input, outptr - buf);
55    // glibc:
56    //   r = -1  errno = 84  inconsumed = 4 outproduced = 0
57    // libiconv:
58    //   r = -1  errno = 84  inconsumed = 1 outproduced = 0
59    */
60    if (!(r == (size_t)(-1) && errno == EILSEQ
61          && inptr - input == 1 && outptr - buf == 0))
62      abort();
63  }
64}
65
66void main2 (void)
67{
68  static const char input[] = "+2D/YQNhB";
69  iconv_t cd;
70  char buf[20];
71
72  const char * inptr;
73  size_t inleft;
74  char * outptr;
75  size_t outleft;
76
77  cd = iconv_open ("UTF-8", "UTF-7");
78  {
79    size_t r;
80
81    inptr = input;
82    inleft = 5;
83    outptr = buf;
84    outleft = sizeof (buf);
85    r = iconv (cd, (ICONV_CONST char **) &inptr, &inleft, &outptr, &outleft);
86    /*
87    printf ("r = %d  errno = %d  inconsumed = %d outproduced = %d\n",
88            r, errno, inptr - input, outptr - buf);
89    // glibc:
90    //   r = -1  errno = 84 (EILSEQ)  inconsumed = 4 outproduced = 0
91    // libiconv:
92    //   r = -1  errno = 22 (EINVAL)  inconsumed = 1 outproduced = 0
93    */
94    if (!(r == (size_t)(-1) && errno == EINVAL
95          && inptr - input == 1 && outptr - buf == 0))
96      abort();
97
98    inleft = input + 20 - inptr;
99    r = iconv (cd, (ICONV_CONST char **) &inptr, &inleft, &outptr, &outleft);
100    /*
101    printf ("r = %d  errno = %d  inconsumed = %d outproduced = %d\n",
102            r, errno, inptr - input, outptr - buf);
103    // glibc:
104    //   r = -1  errno = 84 (EILSEQ)  inconsumed = 4 outproduced = 0
105    // libiconv:
106    //   r = -1  errno = 84 (EILSEQ)  inconsumed = 1 outproduced = 0
107    */
108    if (!(r == (size_t)(-1) && errno == EILSEQ
109          && inptr - input == 1 && outptr - buf == 0))
110      abort();
111  }
112}
113
114int main ()
115{
116  main1 ();
117  main2 ();
118  return 0;
119}
120