Rainer Tammer wrote: > # ./testme > res = 0 > outptr-buf = 2, outbytesleft = -1, buf = { 0xC3, 0x84 }
This is a buffer overrun bug: Although an outbytesleft argument of 1 is given, the iconv() function writes 2 bytes into memory. This kind of bug, if not worked around, can crash any program that uses iconv. I'm adding this detection to gnulib. It will have the effect that the iconv() function is not used in this case, which is better than using a function that can crash the program. 2010-07-31 Bruno Haible <br...@clisp.org> iconv: Work around AIX 6.1..7.1 bug. * doc/posix-functions/iconv.texi: Mention AIX 6.1, 7.1 bug. * m4/iconv.m4 (AM_ICONV_LINK): Test against AIX 6.1, 7.1 bug. When cross-compiling, guess no on all versions of AIX. Reported by Rainer Tammer. --- doc/posix-functions/iconv.texi.orig Sat Jul 31 13:30:52 2010 +++ doc/posix-functions/iconv.texi Sat Jul 31 13:24:05 2010 @@ -13,6 +13,9 @@ @item Failures are not distinguishable from successful returns on some platforms: AIX 5.1, Solaris 10. +...@item +A buffer overrun can occur on some platforms: +AIX 6.1..7.1. @end itemize Portability problems not fixed by Gnulib: --- m4/iconv.m4.orig Sat Jul 31 13:30:52 2010 +++ m4/iconv.m4 Sat Jul 31 13:29:09 2010 @@ -1,4 +1,4 @@ -# iconv.m4 serial 11a +# iconv.m4 serial 11b dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -58,7 +58,8 @@ ]) if test "$am_cv_func_iconv" = yes; then AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ - dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10. + dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, + dnl Solaris 10. am_save_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" @@ -106,6 +107,24 @@ return 1; } } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + const char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + return 1; + } + } #if 0 /* This bug could be worked around by the caller. */ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ { @@ -142,8 +161,8 @@ [ changequote(,)dnl case "$host_os" in - aix | aix[3-6]* | hpux*) am_cv_func_iconv_works="guessing no" ;; - *) am_cv_func_iconv_works="guessing yes" ;; + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; esac changequote([,])dnl ])