Hi Eric, > I'm now getting failures on Solaris 10, at the same line, and traced it to a > call to the native: > > /* second byte uninitialized, and happens to be invalid character */ > wchar_t str[2] = { 'a', 0x65666768 }; > snprintf(buffer, 12, "%.*ls", 1, str); > > with a return of returns -1 with errno EILSEQ, instead of populating buffer > with "a" and returning 1. In short, Solaris parses too far into the wchar_t* > array, detects failure in converting str[1], and fails with EILSEQ, even > though > str[0] was sufficient to provide the requested precision. Random failures > due > to reading uninitialized memory are unacceptable, and while this was EILSEQ, > it > is also possible to trigger SIGSEGV.
This was somehow to be expected... This paragraph is ISO C 99 is hard to read and hard to implement. > This patch was sufficient to make the configure test detect the Solaris bug, > while still letting Linux defer to the (working) native version; okay to > apply, > or do you want to touch it up further? I removed the part of the test that should normally always fail: if (sprintf (buf, "%ls", wstring) != -1) return 2; because it does not fail on any known platform. Then refactored the code to keep different tests separate. Added comments and updated the doc: 2009-02-26 Eric Blake <e...@byu.net> Bruno Haible <br...@clisp.org> Work around a *printf bug with %ls on Solaris. * m4/printf.m4 (gl_PRINTF_DIRECTIVE_LS): Also test whether, when a precision is specified, sprintf stops converting the wide string argument when the number of bytes that have been produced by this conversion equals or exceeds the precision. * doc/posix-functions/fprintf.texi: Update. * doc/posix-functions/printf.texi: Update. * doc/posix-functions/snprintf.texi: Update. * doc/posix-functions/sprintf.texi: Update. * doc/posix-functions/vfprintf.texi: Update. * doc/posix-functions/vprintf.texi: Update. * doc/posix-functions/vsnprintf.texi: Update. * doc/posix-functions/vsprintf.texi: Update. * doc/glibc-functions/obstack_printf.texi: Update. * doc/glibc-functions/obstack_vprintf.texi: Update. --- m4/printf.m4.orig 2009-02-27 02:06:06.000000000 +0100 +++ m4/printf.m4 2009-02-27 01:59:44.000000000 +0100 @@ -1,4 +1,4 @@ -# printf.m4 serial 30 +# printf.m4 serial 31 dnl Copyright (C) 2003, 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -626,7 +626,10 @@ ]) dnl Test whether the *printf family of functions supports the %ls format -dnl directive. +dnl directive and in particular, when a precision is specified, whether +dnl the functions stop converting the wide string argument when the number +dnl of bytes that have been produced by this conversion equals or exceeds +dnl the precision. dnl Result is gl_cv_func_printf_directive_ls. AC_DEFUN([gl_PRINTF_DIRECTIVE_LS], @@ -646,19 +649,40 @@ #include <time.h> #include <wchar.h> #include <string.h> -static wchar_t wstring[] = { 'a', 'b', 'c', 0 }; int main () { char buf[100]; - buf[0] = '\0'; - sprintf (buf, "%ls", wstring); - return strcmp (buf, "abc") != 0; + /* Test whether %ls works at all. + This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. */ + { + static const wchar_t wstring[] = { 'a', 'b', 'c', 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%ls", wstring) < 0 + || strcmp (buf, "abc") != 0) + return 1; + } + /* Test whether precisions in %ls are supported as specified in ISO C 99 + section 7.19.6.1: + "If a precision is specified, no more than that many bytes are written + (including shift sequences, if any), and the array shall contain a + null wide character if, to equal the multibyte character sequence + length given by the precision, the function would need to access a + wide character one past the end of the array." + This test fails on Solaris 10. */ + { + static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%.2ls", wstring) < 0 + || strcmp (buf, "ab") != 0) + return 1; + } + return 0; }], [gl_cv_func_printf_directive_ls=yes], [gl_cv_func_printf_directive_ls=no], [ changequote(,)dnl case "$host_os" in openbsd*) gl_cv_func_printf_directive_ls="guessing no";; - solaris2.[1-6]*) gl_cv_func_printf_directive_ls="guessing no";; + solaris*) gl_cv_func_printf_directive_ls="guessing no";; irix*) gl_cv_func_printf_directive_ls="guessing no";; beos* | haiku*) gl_cv_func_printf_directive_ls="guessing no";; *) gl_cv_func_printf_directive_ls="guessing yes";; --- doc/glibc-functions/obstack_printf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/glibc-functions/obstack_printf.texi 2009-02-27 02:05:25.000000000 +0100 @@ -38,6 +38,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/glibc-functions/obstack_vprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/glibc-functions/obstack_vprintf.texi 2009-02-27 02:05:26.000000000 +0100 @@ -38,6 +38,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/fprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/fprintf.texi 2009-02-27 02:04:38.000000000 +0100 @@ -32,6 +32,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/printf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/printf.texi 2009-02-27 02:04:38.000000000 +0100 @@ -32,6 +32,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/snprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/snprintf.texi 2009-02-27 02:04:37.000000000 +0100 @@ -43,6 +43,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/sprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/sprintf.texi 2009-02-27 02:04:38.000000000 +0100 @@ -32,6 +32,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/vfprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/vfprintf.texi 2009-02-27 02:04:38.000000000 +0100 @@ -32,6 +32,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/vprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/vprintf.texi 2009-02-27 02:04:37.000000000 +0100 @@ -32,6 +32,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/vsnprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/vsnprintf.texi 2009-02-27 02:04:37.000000000 +0100 @@ -43,6 +43,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS. --- doc/posix-functions/vsprintf.texi.orig 2009-02-27 02:06:06.000000000 +0100 +++ doc/posix-functions/vsprintf.texi 2009-02-27 02:04:37.000000000 +0100 @@ -32,6 +32,10 @@ This function does not support the @samp{ls} directive on some platforms: OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku. @item +This function does not support precisions in the @samp{ls} directive correctly +on some platforms: +Solaris 10. +...@item This function does not support format directives that access arguments in an arbitrary order, such as @code{"%2$s"}, on some platforms: NetBSD 3.0, mingw, BeOS.