diff --git a/iconv/Makefile b/iconv/Makefile index b0fa550141..29e4f280ec 100644 --- a/iconv/Makefile +++ b/iconv/Makefile @@ -61,6 +61,10 @@ test-srcs := \ tst-translit-mchar \ # test-srcs +tests-internal = \ + tst-iconv-sticky-input-error \ + # tests-internal + others = iconv_prog iconvconfig install-others-programs = $(inst_bindir)/iconv install-sbin = iconvconfig diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 9fece3ea14..cd452d94cc 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -331,4 +331,34 @@ extern wint_t __gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c); __END_DECLS +/* Internal extensions for . */ + +/* Internal flags for __flags in struct __gconv_step_data. Overlaps + with flags for __gconv_open. */ +enum + { + /* The conversion encountered an illegal input character at one + point. */ + __GCONV_ENCOUNTERED_ILLEGAL_INPUT = 1U << 30, + }; + +/* Mark *STEP_DATA as having seen illegal input, and return + __GCONV_ILLEGAL_INPUT. */ +static inline int +__gconv_mark_illegal_input (struct __gconv_step_data *step_data) +{ + step_data->__flags |= __GCONV_ENCOUNTERED_ILLEGAL_INPUT; + return __GCONV_ILLEGAL_INPUT; +} + +/* Returns true if any of the conversion steps encountered illegal input. */ +static _Bool __attribute__ ((unused)) +__gconv_has_illegal_input (__gconv_t cd) +{ + for (size_t i = 0; i < cd->__nsteps; ++i) + if (cd->__data[i].__flags & __GCONV_ENCOUNTERED_ILLEGAL_INPUT) + return true; + return false; +} + #endif /* gconv_int.h */ diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c index 257be2f8ff..f22002cf81 100644 --- a/iconv/gconv_simple.c +++ b/iconv/gconv_simple.c @@ -207,7 +207,7 @@ ucs4_internal_loop (struct __gconv_step *step, UCS4 does not allow such values. */ if (irreversible == NULL) /* We are transliterating, don't try to correct anything. */ - return __GCONV_ILLEGAL_INPUT; + return __gconv_mark_illegal_input (step_data); if (flags & __GCONV_IGNORE_ERRORS) { @@ -218,7 +218,7 @@ ucs4_internal_loop (struct __gconv_step *step, *inptrp = inptr; *outptrp = outptr; - return __GCONV_ILLEGAL_INPUT; + return __gconv_mark_illegal_input (step_data); } put32 (outptr, inval); @@ -276,7 +276,7 @@ ucs4_internal_loop_single (struct __gconv_step *step, if (!(flags & __GCONV_IGNORE_ERRORS)) { *inptrp -= cnt - (state->__count & 7); - return __GCONV_ILLEGAL_INPUT; + return __gconv_mark_illegal_input (step_data); } } else @@ -453,7 +453,7 @@ ucs4le_internal_loop (struct __gconv_step *step, UCS4 does not allow such values. */ if (irreversible == NULL) /* We are transliterating, don't try to correct anything. */ - return __GCONV_ILLEGAL_INPUT; + return __gconv_mark_illegal_input (step_data); if (flags & __GCONV_IGNORE_ERRORS) { @@ -464,7 +464,7 @@ ucs4le_internal_loop (struct __gconv_step *step, *inptrp = inptr; *outptrp = outptr; - return __GCONV_ILLEGAL_INPUT; + return __gconv_mark_illegal_input (step_data); } put32 (outptr, inval); @@ -523,7 +523,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, represent the result. This is a genuine bug in the input since UCS4 does not allow such values. */ if (!(flags & __GCONV_IGNORE_ERRORS)) - return __GCONV_ILLEGAL_INPUT; + return __gconv_mark_illegal_input (step_data); } else { @@ -969,7 +969,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, surrogates pass through, attackers could make a security \ hole exploit by synthesizing any desired plane 1-16 \ character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ if (! ignore_errors_p ()) \ break; \ inptr += 4; \ @@ -1012,7 +1012,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, them. (Catching this here is not security relevant.) */ \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ inptr += 2; \ @@ -1061,7 +1061,7 @@ ucs4le_internal_loop_single (struct __gconv_step *step, character. */ \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ inptr += 4; \ diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c index 44f0fd849a..54c4f3a100 100644 --- a/iconv/gconv_trans.c +++ b/iconv/gconv_trans.c @@ -232,6 +232,6 @@ __gconv_transliterate (struct __gconv_step *step, } /* Haven't found a match. */ - return __GCONV_ILLEGAL_INPUT; + return __gconv_mark_illegal_input (step_data); } libc_hidden_def (__gconv_transliterate) diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c index 88a928557e..5fe4fe7a6c 100644 --- a/iconv/iconv_prog.c +++ b/iconv/iconv_prog.c @@ -291,6 +291,11 @@ conversions from `%s' and to `%s' are not supported"), } while (++remaining < argc); + /* Ensure that iconv -c still exits with failure if iconv (the + function) has failed with E2BIG instead of EILSEQ. */ + if (__gconv_has_illegal_input (cd)) + status = EXIT_FAILURE; + /* Close the output file now. */ if (output != NULL && fclose (output)) error (EXIT_FAILURE, errno, _("error while closing output file")); diff --git a/iconv/loop.c b/iconv/loop.c index 5340dafc70..199fb28326 100644 --- a/iconv/loop.c +++ b/iconv/loop.c @@ -123,8 +123,7 @@ `continue' must reach certain points. */ #define STANDARD_FROM_LOOP_ERR_HANDLER(Incr) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ - \ + result = __gconv_mark_illegal_input (step_data); \ if (! ignore_errors_p ()) \ break; \ \ @@ -142,7 +141,7 @@ points. */ #define STANDARD_TO_LOOP_ERR_HANDLER(Incr) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ \ if (irreversible == NULL) \ /* This means we are in call from __gconv_transliterate. In this \ diff --git a/iconv/tst-iconv-sticky-input-error.c b/iconv/tst-iconv-sticky-input-error.c new file mode 100644 index 0000000000..34a245f185 --- /dev/null +++ b/iconv/tst-iconv-sticky-input-error.c @@ -0,0 +1,135 @@ +/* Test __GCONV_ENCOUNTERED_ILLEGAL_INPUT, as used by iconv -c (bug 32046). + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* FROM is the input character set, TO the output character set. If + IGNORE is true, the iconv descriptor is set up in the same way as + iconv -c would. INPUT is the input string, EXPECTED_OUTPUT the + output. OUTPUT_LIMIT is a byte count, specifying how many input + bytes are passed to the iconv function on each invocation. */ +static void +one_direction (const char *from, const char *to, bool ignore, + const char *input, const char *expected_output, + size_t output_limit) +{ + if (test_verbose) + { + char *quoted_input = support_quote_string (input); + char *quoted_output = support_quote_string (expected_output); + printf ("info: testing from=\"%s\" to=\"%s\" ignore=%d input=\"%s\"" + " expected_output=\"%s\" output_limit=%zu\n", + from, to, (int) ignore, quoted_input, + quoted_output, output_limit); + free (quoted_output); + free (quoted_input); + } + + __gconv_t cd; + if (ignore) + { + struct gconv_spec conv_spec; + TEST_VERIFY_EXIT (__gconv_create_spec (&conv_spec, from, to) + == &conv_spec); + conv_spec.ignore = true; + cd = (iconv_t) -1; + TEST_COMPARE (__gconv_open (&conv_spec, &cd, 0), __GCONV_OK); + __gconv_destroy_spec (&conv_spec); + } + else + cd = iconv_open (to, from); + TEST_VERIFY_EXIT (cd != (iconv_t) -1); + + char *input_ptr = (char *) input; + size_t input_len = strlen (input); + char output_buf[20]; + char *output_ptr = output_buf; + size_t output_len; + do + { + output_len = array_end (output_buf) - output_ptr; + if (output_len > output_limit) + /* Limit the buffer size as requested by the caller. */ + output_len = output_limit; + TEST_VERIFY_EXIT (output_len > 0); + if (input_len == 0) + /* Trigger final flush. */ + input_ptr = NULL; + char *old_input_ptr = input_ptr; + size_t ret = iconv (cd, &input_ptr, &input_len, + &output_ptr, &output_len); + if (ret == (size_t) -1) + { + if (errno != EILSEQ) + TEST_COMPARE (errno, E2BIG); + } + + if (input_ptr == old_input_ptr) + /* Avoid endless loop if stuck on an invalid input character. */ + break; + } + while (input_ptr != NULL); + + /* Test the sticky illegal input bit. */ + TEST_VERIFY (__gconv_has_illegal_input (cd)); + + TEST_COMPARE_BLOB (expected_output, strlen (expected_output), + output_buf, output_ptr - output_buf); + + TEST_COMPARE (iconv_close (cd), 0); +} + +static int +do_test (void) +{ + static const char charsets[][14] = + { + "ASCII", + "ASCII//IGNORE", + "UTF-8", + "UTF-8//IGNORE", + }; + + for (size_t from_idx = 0; from_idx < array_length (charsets); ++from_idx) + for (size_t to_idx = 0; to_idx < array_length (charsets); ++to_idx) + for (int do_ignore = 0; do_ignore < 2; ++do_ignore) + for (int limit = 1; limit < 5; ++limit) + for (int skip = 0; skip < 3; ++skip) + { + const char *expected_output; + if (do_ignore || strstr (charsets[to_idx], "//IGNORE") != NULL) + expected_output = "ABXY" + skip; + else + expected_output = "AB" + skip; + one_direction (charsets[from_idx], charsets[to_idx], do_ignore, + "AB\xffXY" + skip, expected_output, limit); + } + + return 0; +} + +#include diff --git a/iconv/tst-iconv_prog-buffer.sh b/iconv/tst-iconv_prog-buffer.sh index a27107f02b..5ff99a02a3 100644 --- a/iconv/tst-iconv_prog-buffer.sh +++ b/iconv/tst-iconv_prog-buffer.sh @@ -150,9 +150,8 @@ expect_exit 1 \ ! test -s "$tmp/err" expect_files abc def -# FIXME: This is not correct, -c should not change the exit status. cp "$tmp/out-template" "$tmp/out" -run_iconv -c -o "$tmp/out" \ +expect_exit 1 run_iconv -c -o "$tmp/out" \ "$tmp/abc" "$tmp/0xff-wrapped" "$tmp/def" 2>"$tmp/err" ! test -s "$tmp/err" expect_files abc xy zt def diff --git a/iconvdata/cp932.c b/iconvdata/cp932.c index bf7297b114..3def70a70b 100644 --- a/iconvdata/cp932.c +++ b/iconvdata/cp932.c @@ -4559,7 +4559,7 @@ static const char from_ucs4_extra[229][2] = if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ \ @@ -4599,7 +4599,7 @@ static const char from_ucs4_extra[229][2] = if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ \ @@ -4634,7 +4634,7 @@ static const char from_ucs4_extra[229][2] = if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ \ diff --git a/iconvdata/euc-jp-ms.c b/iconvdata/euc-jp-ms.c index d03a0e05bb..96c5325e9d 100644 --- a/iconvdata/euc-jp-ms.c +++ b/iconvdata/euc-jp-ms.c @@ -4659,7 +4659,7 @@ static const unsigned char from_ucs4_extra[229][2] = /* This is illegal. */ \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ \ @@ -4689,7 +4689,7 @@ static const unsigned char from_ucs4_extra[229][2] = /* This is an illegal character. */ \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ \ @@ -4709,7 +4709,7 @@ static const unsigned char from_ucs4_extra[229][2] = if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ } \ @@ -4820,7 +4820,7 @@ static const unsigned char from_ucs4_extra[229][2] = if (! ignore_errors_p ()) \ { \ /* This is an illegal character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ \ diff --git a/iconvdata/gbbig5.c b/iconvdata/gbbig5.c index f05deeeb1a..b15a2ef932 100644 --- a/iconvdata/gbbig5.c +++ b/iconvdata/gbbig5.c @@ -4831,7 +4831,7 @@ const char __from_big5_to_gb2312 [13973][2] = { \ /* We do not have a mapping for this character. \ If ignore errors, map it to 0xa1bc - big5 box character */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ if (! ignore_errors_p ()) \ break; \ \ @@ -4922,7 +4922,7 @@ const char __from_big5_to_gb2312 [13973][2] = { \ /* We do not have a mapping for this character. \ If ignore errors, map it to 0xa1f5 - gb box character */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ if (! ignore_errors_p ()) \ break; \ \ diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c index 4c37f30e98..d6c8ce7f68 100644 --- a/iconvdata/ibm1364.c +++ b/iconvdata/ibm1364.c @@ -179,7 +179,7 @@ enum /* This is an illegal character. */ \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ ++*irreversible; \ @@ -219,7 +219,7 @@ enum /* This is an illegal character. */ \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ ++*irreversible; \ @@ -300,7 +300,7 @@ enum \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ ++*irreversible; \ @@ -332,7 +332,7 @@ enum /* This is an illegal character. */ \ if (! ignore_errors_p ()) \ { \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ break; \ } \ ++*irreversible; \ diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c index d96e5f86b9..ba7e23f8ac 100644 --- a/iconvdata/iso646.c +++ b/iconvdata/iso646.c @@ -313,7 +313,7 @@ gconv_end (struct __gconv_step *data) ch = 0xf9; \ else if (var == JP_OCR_B) \ /* Illegal character. */ \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ else if (var == YU) \ ch = 0x17e; \ else if (var == HU) \ @@ -387,7 +387,7 @@ gconv_end (struct __gconv_step *data) ch = 0xec; \ else if (var == JP_OCR_B) \ /* Illegal character. */ \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ else if (var == YU) \ ch = 0x10d; \ else if (var == HU) \ @@ -403,7 +403,7 @@ gconv_end (struct __gconv_step *data) break; \ case 0x80 ... 0xff: \ /* Illegal character. */ \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ } \ \ @@ -440,17 +440,17 @@ gconv_end (struct __gconv_step *data) case 0x23: \ if (var == GB || var == ES || var == IT || var == FR || var == FR1 \ || var == NO2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x24: \ if (var == CN || var == HU || var == CU || var == SE || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x40: \ if (var == CA || var == CA2 || var == DE || var == ES || var == ES2 \ || var == IT || var == YU || var == HU || var == FR || var == FR1 \ || var == PT || var == PT2 || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x5b: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ @@ -458,7 +458,7 @@ gconv_end (struct __gconv_step *data) || var == HU || var == FR || var == FR1 || var == NO \ || var == NO2 || var == PT || var == PT2 || var == SE \ || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ else if (var == CU) \ ch = 0x7d; \ break; \ @@ -468,7 +468,7 @@ gconv_end (struct __gconv_step *data) || var == YU || var == KR || var == HU || var == CU || var == FR \ || var == FR1 || var == NO || var == NO2 || var == PT \ || var == PT2 || var == SE || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x5d: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ @@ -476,17 +476,17 @@ gconv_end (struct __gconv_step *data) || var == HU || var == FR || var == FR1 || var == NO \ || var == NO2 || var == PT || var == PT2 || var == SE \ || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x5e: \ if (var == CA || var == CA2 || var == ES2 || var == YU || var == CU \ || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x60: \ if (var == CA || var == CA2 || var == IT || var == JP_OCR_B \ || var == YU || var == HU || var == FR || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x7b: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ @@ -494,14 +494,14 @@ gconv_end (struct __gconv_step *data) || var == CU || var == FR || var == FR1 || var == NO \ || var == NO2 || var == PT || var == PT2 || var == SE \ || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x7c: \ if (var == CA || var == CA2 || var == DE || var == DK || var == ES \ || var == ES2 || var == IT || var == YU || var == HU || var == CU \ || var == FR || var == FR1 || var == NO || var == PT \ || var == PT2 || var == SE || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ else if (var == NO2) \ ch = 0x7e; \ break; \ @@ -510,7 +510,7 @@ gconv_end (struct __gconv_step *data) || var == ES2 || var == IT || var == YU || var == HU || var == CU \ || var == FR || var == FR1 || var == NO || var == NO2 \ || var == PT || var == PT2 || var == SE || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x7e: \ if (var == GB || var == CA || var == CA2 || var == DE || var == ES2 \ @@ -518,21 +518,21 @@ gconv_end (struct __gconv_step *data) || var == YU || var == HU || var == CU || var == FR || var == FR1 \ || var == NO || var == NO2 || var == PT || var == SE \ || var == SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xa1: \ if (var != ES && var != ES2 && var != CU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5b; \ break; \ case 0xa3: \ if (var != GB && var != ES && var != IT && var != FR && var != FR1) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x23; \ break; \ case 0xa4: \ if (var != HU && var != CU && var != SE && var != SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x24; \ break; \ case 0xa5: \ @@ -541,7 +541,7 @@ gconv_end (struct __gconv_step *data) else if (var == JP || var == JP_OCR_B) \ ch = 0x5c; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xa7: \ if (var == DE || var == ES || var == IT || var == PT) \ @@ -551,11 +551,11 @@ gconv_end (struct __gconv_step *data) else if (var == NO2) \ ch = 0x23; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xa8: \ if (var != ES2 && var != CU && var != FR && var != FR1) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7e; \ break; \ case 0xb0: \ @@ -566,7 +566,7 @@ gconv_end (struct __gconv_step *data) else if (var == PT) \ ch = 0x7e; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xb4: \ if (var == ES2 || var == CU) \ @@ -574,11 +574,11 @@ gconv_end (struct __gconv_step *data) else if (var == PT2) \ ch = 0x40; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xb5: \ if (var != FR) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x60; \ break; \ case 0xbf: \ @@ -587,31 +587,31 @@ gconv_end (struct __gconv_step *data) else if (var == ES2 || var == CU) \ ch = 0x5e; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xc1: \ if (var != HU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x40; \ break; \ case 0xc3: \ if (var != PT && var != PT2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5b; \ break; \ case 0xc4: \ if (var != DE && var != SE && var != SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5b; \ break; \ case 0xc5: \ if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5d; \ break; \ case 0xc6: \ if (var != DK && var != NO && var != NO2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5b; \ break; \ case 0xc7: \ @@ -620,7 +620,7 @@ gconv_end (struct __gconv_step *data) else if (var == PT || var == PT2) \ ch = 0x5c; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xc9: \ if (var == CA2) \ @@ -630,26 +630,26 @@ gconv_end (struct __gconv_step *data) else if (var == SE2) \ ch = 0x40; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xd1: \ if (var != ES && var != ES2 && var != CU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5c; \ break; \ case 0xd5: \ if (var != PT && var != PT2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5d; \ break; \ case 0xd6: \ if (var != DE && var != HU && var != SE && var != SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5c; \ break; \ case 0xd8: \ if (var != DK && var != NO && var != NO2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5c; \ break; \ case 0xdc: \ @@ -658,11 +658,11 @@ gconv_end (struct __gconv_step *data) else if (var == SE2) \ ch = 0x5e; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xdf: \ if (var != DE) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7e; \ break; \ case 0xe0: \ @@ -671,36 +671,36 @@ gconv_end (struct __gconv_step *data) else if (var == IT) \ ch = 0x7b; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xe1: \ if (var != HU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x60; \ break; \ case 0xe2: \ if (var != CA && var != CA2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5b; \ break; \ case 0xe3: \ if (var != PT && var != PT2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7b; \ break; \ case 0xe4: \ if (var != DE && var != SE && var != SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7b; \ break; \ case 0xe5: \ if (var != DK && var != NO && var != NO2 && var != SE && var != SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7d; \ break; \ case 0xe6: \ if (var != DK && var != NO && var != NO2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7b; \ break; \ case 0xe7: \ @@ -711,11 +711,11 @@ gconv_end (struct __gconv_step *data) else if (var == PT || var == PT2) \ ch = 0x7c; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xe8: \ if (var != CA && var != CA2 && var != IT && var != FR && var != FR1) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7d; \ break; \ case 0xe9: \ @@ -726,51 +726,51 @@ gconv_end (struct __gconv_step *data) else if (var == SE2) \ ch = 0x60; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xea: \ if (var != CA && var != CA2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5d; \ break; \ case 0xec: \ if (var != IT) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7e; \ break; \ case 0xee: \ if (var != CA) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5e; \ break; \ case 0xf1: \ if (var != ES && var != ES2 && var != CU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7c; \ break; \ case 0xf2: \ if (var != IT) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7c; \ break; \ case 0xf4: \ if (var != CA && var != CA2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x60; \ break; \ case 0xf5: \ if (var != PT && var != PT2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7d; \ break; \ case 0xf6: \ if (var != DE && var != HU && var != SE && var != SE2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7c; \ break; \ case 0xf8: \ if (var != DK && var != NO && var != NO2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7c; \ break; \ case 0xf9: \ @@ -779,11 +779,11 @@ gconv_end (struct __gconv_step *data) else if (var == IT) \ ch = 0x60; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0xfb: \ if (var != CA && var != CA2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7e; \ break; \ case 0xfc: \ @@ -792,93 +792,93 @@ gconv_end (struct __gconv_step *data) else if (var == SE2) \ ch = 0x7e; \ else \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ break; \ case 0x160: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5b; \ break; \ case 0x106: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5d; \ break; \ case 0x107: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7d; \ break; \ case 0x10c: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5e; \ break; \ case 0x10d: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7e; \ break; \ case 0x110: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5c; \ break; \ case 0x111: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7c; \ break; \ case 0x161: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7b; \ break; \ case 0x17d: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x40; \ break; \ case 0x17e: \ if (var != YU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x60; \ break; \ case 0x2dd: \ if (var != HU) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7e; \ break; \ case 0x2022: \ if (var != ES2) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x40; \ break; \ case 0x203e: \ if (var != GB && var != CN && var != JP && var != NO && var != SE) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x7e; \ break; \ case 0x20a9: \ if (var != KR) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5c; \ break; \ case 0x2329: \ if (var != JP_OCR_B) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5b; \ break; \ case 0x232a: \ if (var != JP_OCR_B) \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ ch = 0x5d; \ break; \ default: \ if (__glibc_unlikely (ch > 0x7f)) \ { \ UNICODE_TAG_HANDLER (ch, 4); \ - failure = __GCONV_ILLEGAL_INPUT; \ + failure = __gconv_mark_illegal_input (step_data); \ } \ break; \ } \ diff --git a/iconvdata/unicode.c b/iconvdata/unicode.c index d69c9887a1..79bb9886e5 100644 --- a/iconvdata/unicode.c +++ b/iconvdata/unicode.c @@ -163,7 +163,7 @@ gconv_end (struct __gconv_step *data) surrogates pass through, attackers could make a security \ hole exploit by synthesizing any desired plane 1-16 \ character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ if (! ignore_errors_p ()) \ break; \ inptr += 4; \ diff --git a/iconvdata/utf-16.c b/iconvdata/utf-16.c index a869353f20..9d9fd2a2a3 100644 --- a/iconvdata/utf-16.c +++ b/iconvdata/utf-16.c @@ -206,7 +206,7 @@ gconv_end (struct __gconv_step *data) We must catch this. If we let surrogates pass through, \ attackers could make a security hole exploit by \ synthesizing any desired plane 1-16 character. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ if (! ignore_errors_p ()) \ break; \ inptr += 4; \ diff --git a/iconvdata/utf-32.c b/iconvdata/utf-32.c index 5693b48975..139eefb6d8 100644 --- a/iconvdata/utf-32.c +++ b/iconvdata/utf-32.c @@ -207,7 +207,7 @@ gconv_end (struct __gconv_step *data) We must catch this. If we let surrogates pass through, \ attackers could make a security hole exploit by \ generating "irregular UTF-32" sequences. */ \ - result = __GCONV_ILLEGAL_INPUT; \ + result = __gconv_mark_illegal_input (step_data); \ if (! ignore_errors_p ()) \ break; \ inptr += 4; \