Index: configure =================================================================== --- configure (revision 66181) +++ configure (working copy) @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 65206 . +# From configure.in Revision: 65857 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.0. # @@ -24315,8 +24315,73 @@ fi +{ echo "$as_me:$LINENO: checking for broken mbstowcs" >&5 +echo $ECHO_N "checking for broken mbstowcs... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + ac_cv_broken_mbstowcs=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int main() { + size_t len = -1; + const char *str = "text"; + len = mbstowcs(NULL, str, 0); + return (len != 4); +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_broken_mbstowcs=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_broken_mbstowcs=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $ac_cv_broken_mbstowcs" >&5 +echo "${ECHO_T}$ac_cv_broken_mbstowcs" >&6; } +if test "$ac_cv_broken_mbstowcs" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_MBSTOWCS 1 +_ACEOF + +fi + + + for h in `(cd $srcdir;echo Python/thread_*.h)` do THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" Index: configure.in =================================================================== --- configure.in (revision 66181) +++ configure.in (working copy) @@ -3571,6 +3571,27 @@ #endif ]) +AC_MSG_CHECKING(for broken mbstowcs) +AC_TRY_RUN([ +#include +int main() { + size_t len = -1; + const char *str = "text"; + len = mbstowcs(NULL, str, 0); + return (len != 4); +} +], +ac_cv_broken_mbstowcs=no, +ac_cv_broken_mbstowcs=yes, +ac_cv_broken_mbstowcs=no) +AC_MSG_RESULT($ac_cv_broken_mbstowcs) +if test "$ac_cv_broken_mbstowcs" = yes +then + AC_DEFINE(HAVE_BROKEN_MBSTOWCS, 1, + [Define if mbstowcs(NULL, "text", 0) does not return the number of + wide chars that would be converted.]) +fi + AC_SUBST(THREADHEADERS) for h in `(cd $srcdir;echo Python/thread_*.h)` Index: pyconfig.h.in =================================================================== --- pyconfig.h.in (revision 66181) +++ pyconfig.h.in (working copy) @@ -803,6 +803,10 @@ /* Define to 1 if you have the `wcsxfrm' function. */ #undef HAVE_WCSXFRM +/* Define if mbstowcs(NULL, "text", 0) does not return the number of + wide chars that would be converted */ +#undef HAVE_BROKEN_MBSTOWCS + /* Define if tzset() actually switches the local timezone in a meaningful way. */ #undef HAVE_WORKING_TZSET Index: Python/frozenmain.c =================================================================== --- Python/frozenmain.c (revision 66181) +++ Python/frozenmain.c (working copy) @@ -45,7 +45,12 @@ oldloc = setlocale(LC_ALL, NULL); setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { +#ifdef HAVE_BROKEN_MBSTOWCS + size_t argsize = strlen(argv[i]); +#else size_t argsize = mbstowcs(NULL, argv[i], 0); +#endif + size_t count; if (argsize == (size_t)-1) { fprintf(stderr, "Could not convert argument %d to string", i); return 1; @@ -56,7 +61,11 @@ fprintf(stderr, "out of memory"); return 1; } - mbstowcs(argv_copy[i], argv[i], argsize+1); + count = mbstowcs(argv_copy[i], argv[i], argsize+1); + if (count == (size_t)-1) { + fprintf(stderr, "Could not convert argument %d to string", i); + return 1; + } } setlocale(LC_ALL, oldloc); Index: Modules/_localemodule.c =================================================================== --- Modules/_localemodule.c (revision 66181) +++ Modules/_localemodule.c (working copy) @@ -49,7 +49,11 @@ static PyObject* str2uni(const char* s) { +#ifdef HAVE_BROKEN_MBSTOWCS + size_t needed = strlen(s); +#else size_t needed = mbstowcs(NULL, s, 0); +#endif size_t res1; wchar_t smallbuf[30]; wchar_t *dest; @@ -67,7 +71,11 @@ } /* This shouldn't fail now */ res1 = mbstowcs(dest, s, needed+1); +#ifdef HAVE_BROKEN_MBSTOWCS + assert(res1 != (size_t)-1); +#else assert(res1 == needed); +#endif res2 = PyUnicode_FromWideChar(dest, res1); if (dest != smallbuf) PyMem_Free(dest); Index: Modules/python.c =================================================================== --- Modules/python.c (revision 66181) +++ Modules/python.c (working copy) @@ -40,7 +40,16 @@ oldloc = setlocale(LC_ALL, NULL); setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { +#ifdef HAVE_BROKEN_MBSTOWCS + /* Some platforms have a broken implementation of + * mbstowcs which does not count the characters that + * would result from conversion. Use an upper bound. + */ + size_t argsize = strlen(argv[i]); +#else size_t argsize = mbstowcs(NULL, argv[i], 0); +#endif + size_t count; if (argsize == (size_t)-1) { fprintf(stderr, "Could not convert argument %d to string", i); return 1; @@ -51,7 +60,11 @@ fprintf(stderr, "out of memory"); return 1; } - mbstowcs(argv_copy[i], argv[i], argsize+1); + count = mbstowcs(argv_copy[i], argv[i], argsize+1); + if (count == (size_t)-1) { + fprintf(stderr, "Could not convert argument %d to string", i); + return 1; + } } setlocale(LC_ALL, oldloc); res = Py_Main(argc, argv_copy);