|
|
978e96 |
The commit included in this patch only incidentally fixes the problem
|
|
|
978e96 |
reported in bug 1427734: In each of the IBM9xx character sets referenced in
|
|
|
978e96 |
this patch, the removal of the "break" statement means that the subsequent
|
|
|
978e96 |
increment of "inptr" is executed instead of being skipped. This allows
|
|
|
978e96 |
conversion to progress instead of hanging.
|
|
|
978e96 |
|
|
|
978e96 |
commit 692de4b3960dc90bdcfb871513ee4d81d314cf69
|
|
|
978e96 |
Author: Martin Sebor <msebor@redhat.com>
|
|
|
978e96 |
Date: Fri Jan 15 11:25:13 2016 -0700
|
|
|
978e96 |
|
|
|
978e96 |
Have iconv accept redundant escape sequences in IBM900, IBM903, IBM905,
|
|
|
978e96 |
IBM907, and IBM909.
|
|
|
978e96 |
|
|
|
978e96 |
Patch for bug #17197 changes the encoder to avoid generating redundant
|
|
|
978e96 |
shift sequences. However, those sequences may already be present in
|
|
|
978e96 |
data encododed by prior versions of the encoder. This change modifies
|
|
|
978e96 |
the decoder to also avoid rejecting redundant shift sequences.
|
|
|
978e96 |
|
|
|
978e96 |
[BZ #19432]
|
|
|
978e96 |
* iconvdata/Makefile: Add bug-iconv11.
|
|
|
978e96 |
* iconvdata/bug-iconv11.c: New test.
|
|
|
978e96 |
* iconvdata/ibm930.c: Do not reject redundant shift sequences.
|
|
|
978e96 |
* iconvdata/ibm933.c: Same.
|
|
|
978e96 |
* iconvdata/ibm935.c: Same.
|
|
|
978e96 |
* iconvdata/ibm937.c: Same.
|
|
|
978e96 |
* iconvdata/ibm939.c: Same.
|
|
|
978e96 |
|
|
|
978e96 |
# Conflicts:
|
|
|
978e96 |
# iconvdata/Makefile
|
|
|
978e96 |
|
|
|
978e96 |
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
|
|
|
978e96 |
index 0ec67554ca4c29ea..c4e6c510d7abc055 100644
|
|
|
978e96 |
--- a/iconvdata/Makefile
|
|
|
978e96 |
+++ b/iconvdata/Makefile
|
|
|
978e96 |
@@ -68,7 +68,7 @@ include ../Makeconfig
|
|
|
978e96 |
ifeq (yes,$(build-shared))
|
|
|
978e96 |
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
|
|
|
978e96 |
tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
|
|
|
978e96 |
- bug-iconv10 bug-iconv12
|
|
|
978e96 |
+ bug-iconv10 bug-iconv11 bug-iconv12
|
|
|
978e96 |
ifeq ($(have-thread-library),yes)
|
|
|
978e96 |
tests += bug-iconv3
|
|
|
978e96 |
endif
|
|
|
978e96 |
diff --git a/iconvdata/bug-iconv11.c b/iconvdata/bug-iconv11.c
|
|
|
978e96 |
new file mode 100644
|
|
|
978e96 |
index 0000000000000000..6cdc07d79883454d
|
|
|
978e96 |
--- /dev/null
|
|
|
978e96 |
+++ b/iconvdata/bug-iconv11.c
|
|
|
978e96 |
@@ -0,0 +1,114 @@
|
|
|
978e96 |
+/* bug 19432: iconv rejects redundant escape sequences in IBM903,
|
|
|
978e96 |
+ IBM905, IBM907, and IBM909
|
|
|
978e96 |
+
|
|
|
978e96 |
+ Copyright (C) 2016 Free Software Foundation, Inc.
|
|
|
978e96 |
+ This file is part of the GNU C Library.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ The GNU C Library is free software; you can redistribute it and/or
|
|
|
978e96 |
+ modify it under the terms of the GNU Lesser General Public
|
|
|
978e96 |
+ License as published by the Free Software Foundation; either
|
|
|
978e96 |
+ version 2.1 of the License, or (at your option) any later version.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
|
978e96 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
978e96 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
978e96 |
+ Lesser General Public License for more details.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ You should have received a copy of the GNU Lesser General Public
|
|
|
978e96 |
+ License along with the GNU C Library; if not, see
|
|
|
978e96 |
+ <http://www.gnu.org/licenses/>. */
|
|
|
978e96 |
+
|
|
|
978e96 |
+#include <iconv.h>
|
|
|
978e96 |
+#include <stdio.h>
|
|
|
978e96 |
+#include <stdlib.h>
|
|
|
978e96 |
+#include <string.h>
|
|
|
978e96 |
+#include <errno.h>
|
|
|
978e96 |
+
|
|
|
978e96 |
+// The longest test input sequence.
|
|
|
978e96 |
+#define MAXINBYTES 8
|
|
|
978e96 |
+#define MAXOUTBYTES (MAXINBYTES * MB_LEN_MAX)
|
|
|
978e96 |
+
|
|
|
978e96 |
+/* Verify that a conversion of the INPUT sequence consisting of
|
|
|
978e96 |
+ INBYTESLEFT bytes in the encoding specified by the codeset
|
|
|
978e96 |
+ named by FROM_SET is successful.
|
|
|
978e96 |
+ Return 0 on success, non-zero on iconv() failure. */
|
|
|
978e96 |
+
|
|
|
978e96 |
+static int
|
|
|
978e96 |
+test_ibm93x (const char *from_set, const char *input, size_t inbytesleft)
|
|
|
978e96 |
+{
|
|
|
978e96 |
+ const char to_set[] = "UTF-8";
|
|
|
978e96 |
+ iconv_t cd = iconv_open (to_set, from_set);
|
|
|
978e96 |
+ if (cd == (iconv_t) -1)
|
|
|
978e96 |
+ {
|
|
|
978e96 |
+ printf ("iconv_open(\"%s\", \"%s\"): %s\n",
|
|
|
978e96 |
+ from_set, to_set, strerror (errno));
|
|
|
978e96 |
+ return 1;
|
|
|
978e96 |
+ }
|
|
|
978e96 |
+
|
|
|
978e96 |
+ char output [MAXOUTBYTES];
|
|
|
978e96 |
+ size_t outbytesleft = sizeof output;
|
|
|
978e96 |
+
|
|
|
978e96 |
+ char *inbuf = (char*)input;
|
|
|
978e96 |
+ char *outbuf = output;
|
|
|
978e96 |
+
|
|
|
978e96 |
+ printf ("iconv(cd, %p, %zu, %p, %zu)\n",
|
|
|
978e96 |
+ inbuf, inbytesleft, outbuf, outbytesleft);
|
|
|
978e96 |
+
|
|
|
978e96 |
+ errno = 0;
|
|
|
978e96 |
+ size_t ret = iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
|
|
|
978e96 |
+ printf (" ==> %td: %s\n"
|
|
|
978e96 |
+ " inbuf%+td, inbytesleft=%zu, outbuf%+td, outbytesleft=%zu\n",
|
|
|
978e96 |
+ ret, strerror (errno),
|
|
|
978e96 |
+ inbuf - input, inbytesleft, outbuf - output, outbytesleft);
|
|
|
978e96 |
+
|
|
|
978e96 |
+ // Return 0 on success, non-zero on iconv() failure.
|
|
|
978e96 |
+ return ret == (size_t)-1 || errno;
|
|
|
978e96 |
+}
|
|
|
978e96 |
+
|
|
|
978e96 |
+static int
|
|
|
978e96 |
+do_test (void)
|
|
|
978e96 |
+{
|
|
|
978e96 |
+ // State-dependent encodings to exercise.
|
|
|
978e96 |
+ static const char* const to_code[] = {
|
|
|
978e96 |
+ "IBM930", "IBM933", "IBM935", "IBM937", "IBM939"
|
|
|
978e96 |
+ };
|
|
|
978e96 |
+
|
|
|
978e96 |
+ static const size_t ncodesets = sizeof to_code / sizeof *to_code;
|
|
|
978e96 |
+
|
|
|
978e96 |
+ static const struct {
|
|
|
978e96 |
+ char txt[MAXINBYTES];
|
|
|
978e96 |
+ size_t len;
|
|
|
978e96 |
+ } input[] = {
|
|
|
978e96 |
+#define DATA(s) { s, sizeof s - 1 }
|
|
|
978e96 |
+ /* <SI>: denotes the shift-in 1-byte escape sequence, changing
|
|
|
978e96 |
+ the encoder from a sigle-byte encoding to multibyte
|
|
|
978e96 |
+ <SO>: denotes the shift-out 1-byte escape sequence, switching
|
|
|
978e96 |
+ the encoder from a multibyte to a single-byte state */
|
|
|
978e96 |
+
|
|
|
978e96 |
+ DATA ("\x0e"), // <SI> (not redundant)
|
|
|
978e96 |
+ DATA ("\x0f"), // <S0> (redundant with initial state)
|
|
|
978e96 |
+ DATA ("\x0e\x0e"), // <SI><SI>
|
|
|
978e96 |
+ DATA ("\x0e\x0f\x0f"), // <SI><SO><SO>
|
|
|
978e96 |
+ DATA ("\x0f\x0f"), // <SO><SO>
|
|
|
978e96 |
+ DATA ("\x0f\x0e\x0e"), // <SO><SI><SI>
|
|
|
978e96 |
+ DATA ("\x0e\x0f\xc7\x0f"), // <SI><SO><G><SO>
|
|
|
978e96 |
+ DATA ("\xc7\x0f") // <G><SO> (redundant with initial state)
|
|
|
978e96 |
+ };
|
|
|
978e96 |
+
|
|
|
978e96 |
+ static const size_t ninputs = sizeof input / sizeof *input;
|
|
|
978e96 |
+
|
|
|
978e96 |
+ int ret = 0;
|
|
|
978e96 |
+
|
|
|
978e96 |
+ size_t i, j;
|
|
|
978e96 |
+
|
|
|
978e96 |
+ /* Iterate over the IBM93x codesets above and exercise each with
|
|
|
978e96 |
+ the input sequences above. */
|
|
|
978e96 |
+ for (i = 0; i != ncodesets; ++i)
|
|
|
978e96 |
+ for (j = 0; j != ninputs; ++j)
|
|
|
978e96 |
+ ret += test_ibm93x (to_code [i], input [i].txt, input [i].len);
|
|
|
978e96 |
+
|
|
|
978e96 |
+ return ret;
|
|
|
978e96 |
+}
|
|
|
978e96 |
+
|
|
|
978e96 |
+#define TEST_FUNCTION do_test ()
|
|
|
978e96 |
+#include "../test-skeleton.c"
|
|
|
978e96 |
diff --git a/iconvdata/ibm930.c b/iconvdata/ibm930.c
|
|
|
978e96 |
index 636141114f506985..88413ccfbabfdc35 100644
|
|
|
978e96 |
--- a/iconvdata/ibm930.c
|
|
|
978e96 |
+++ b/iconvdata/ibm930.c
|
|
|
978e96 |
@@ -105,24 +105,14 @@ enum
|
|
|
978e96 |
\
|
|
|
978e96 |
if (__builtin_expect (ch, 0) == SO) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift OUT, change to DBCS converter. */ \
|
|
|
978e96 |
- if (curcs == db) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift OUT, change to DBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = db; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
} \
|
|
|
978e96 |
else if (__builtin_expect (ch, 0) == SI) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift IN, change to SBCS converter */ \
|
|
|
978e96 |
- if (curcs == sb) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift IN, change to SBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = sb; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
|
|
|
978e96 |
index 8b9e5780a36a454a..335d385551fee86e 100644
|
|
|
978e96 |
--- a/iconvdata/ibm933.c
|
|
|
978e96 |
+++ b/iconvdata/ibm933.c
|
|
|
978e96 |
@@ -104,24 +104,14 @@ enum
|
|
|
978e96 |
\
|
|
|
978e96 |
if (__builtin_expect (ch, 0) == SO) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift OUT, change to DBCS converter. */ \
|
|
|
978e96 |
- if (curcs == db) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift OUT, change to DBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = db; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
} \
|
|
|
978e96 |
else if (__builtin_expect (ch, 0) == SI) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift IN, change to SBCS converter. */ \
|
|
|
978e96 |
- if (curcs == sb) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift IN, change to SBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = sb; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
diff --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
|
|
|
978e96 |
index 4e2d99ab56d7f0d2..520d28a4e9a690fc 100644
|
|
|
978e96 |
--- a/iconvdata/ibm935.c
|
|
|
978e96 |
+++ b/iconvdata/ibm935.c
|
|
|
978e96 |
@@ -104,24 +104,14 @@ enum
|
|
|
978e96 |
\
|
|
|
978e96 |
if (__builtin_expect(ch, 0) == SO) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift OUT, change to DBCS converter. */ \
|
|
|
978e96 |
- if (curcs == db) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift OUT, change to DBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = db; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
} \
|
|
|
978e96 |
else if (__builtin_expect (ch, 0) == SI) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift IN, change to SBCS converter. */ \
|
|
|
978e96 |
- if (curcs == sb) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift IN, change to SBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = sb; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
diff --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
|
|
|
978e96 |
index 1e468871b783e78d..64563bb8bf0441ff 100644
|
|
|
978e96 |
--- a/iconvdata/ibm937.c
|
|
|
978e96 |
+++ b/iconvdata/ibm937.c
|
|
|
978e96 |
@@ -104,24 +104,14 @@ enum
|
|
|
978e96 |
\
|
|
|
978e96 |
if (__builtin_expect (ch, 0) == SO) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift OUT, change to DBCS converter. */ \
|
|
|
978e96 |
- if (curcs == db) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift OUT, change to DBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = db; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
} \
|
|
|
978e96 |
else if (__builtin_expect (ch, 0) == SI) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift IN, change to SBCS converter. */ \
|
|
|
978e96 |
- if (curcs == sb) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift IN, change to SBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = sb; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
diff --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
|
|
|
978e96 |
index 2060b0c329df0c86..4f73e2e55c94972d 100644
|
|
|
978e96 |
--- a/iconvdata/ibm939.c
|
|
|
978e96 |
+++ b/iconvdata/ibm939.c
|
|
|
978e96 |
@@ -104,24 +104,14 @@ enum
|
|
|
978e96 |
\
|
|
|
978e96 |
if (__builtin_expect (ch, 0) == SO) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift OUT, change to DBCS converter. */ \
|
|
|
978e96 |
- if (curcs == db) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift OUT, change to DBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = db; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|
|
|
978e96 |
} \
|
|
|
978e96 |
else if (__builtin_expect (ch, 0) == SI) \
|
|
|
978e96 |
{ \
|
|
|
978e96 |
- /* Shift IN, change to SBCS converter. */ \
|
|
|
978e96 |
- if (curcs == sb) \
|
|
|
978e96 |
- { \
|
|
|
978e96 |
- result = __GCONV_ILLEGAL_INPUT; \
|
|
|
978e96 |
- break; \
|
|
|
978e96 |
- } \
|
|
|
978e96 |
+ /* Shift IN, change to SBCS converter (redundant escape okay). */ \
|
|
|
978e96 |
curcs = sb; \
|
|
|
978e96 |
++inptr; \
|
|
|
978e96 |
continue; \
|