changeset 9940:0471a8660b70

Work around snprintf bug on Linux libc5.
author Bruno Haible <bruno@clisp.org>
date Sat, 19 Apr 2008 21:42:16 +0200
parents 11aa2931dfc7
children b1a61ff4ff40
files ChangeLog lib/vasnprintf.c m4/printf.m4 m4/snprintf-posix.m4 m4/snprintf.m4 m4/vsnprintf-posix.m4 m4/vsnprintf.m4 modules/snprintf modules/vsnprintf
diffstat 9 files changed, 120 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-04-19  Bruno Haible  <bruno@clisp.org>
+
+	Work around snprintf bug on Linux libc5.
+	* m4/printf.m4 (gl_SNPRINTF_SIZE1): New macro.
+	* m4/snprintf-posix.m4 (gl_FUNC_SNPRINTF_POSIX): Invoke
+	gl_SNPRINTF_SIZE1.
+	* m4/vsnprintf-posix.m4 (gl_FUNC_VSNPRINTF_POSIX): Likewise.
+	* m4/snprintf.m4 (gl_FUNC_SNPRINTF): Likewise. Replace snprintf if
+	that test failed.
+	* m4/vsnprintf.m4 (gl_FUNC_VSNPRINTF): Likewise.
+	* lib/vasnprintf.c (USE_SNPRINTF): Set to 0 on Linux libc5 systems.
+	* modules/snprintf (Files): Add m4/printf.m4.
+	* modules/vsnprintf (Files): Likewise.
+	* doc/posix-functions/snprintf.texi: Document Linux libc5 problem.
+	* doc/posix-functions/vsnprintf.texi: Likewise.
+
 2008-04-19  Bruno Haible  <bruno@clisp.org>
 
 	* lib/vasnprintf.c (floorlog10l, floorlog10): Reduce maximum error
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -177,10 +177,12 @@
 # endif
 #else
   /* TCHAR_T is char.  */
-# /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
+  /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
      But don't use it on BeOS, since BeOS snprintf produces no output if the
-     size argument is >= 0x3000000.  */
-# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__
+     size argument is >= 0x3000000.
+     Also don't use it on Linux libc5, since there snprintf with size = 1
+     writes any output without bounds, like sprintf.  */
+# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
 #  define USE_SNPRINTF 1
 # else
 #  define USE_SNPRINTF 0
--- a/m4/printf.m4
+++ b/m4/printf.m4
@@ -1,4 +1,4 @@
-# printf.m4 serial 22
+# printf.m4 serial 23
 dnl Copyright (C) 2003, 2007-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -1115,6 +1115,31 @@
     ])
 ])
 
+dnl Test whether the snprintf function, when passed a size = 1, writes any
+dnl output without bounds in this case, behaving like sprintf. This is the
+dnl case on Linux libc5.
+dnl Result is gl_cv_func_snprintf_size1.
+
+AC_DEFUN([gl_SNPRINTF_SIZE1],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_CACHE_CHECK([whether snprintf respects a size of 1],
+    [gl_cv_func_snprintf_size1],
+    [
+      AC_TRY_RUN([
+#include <stdio.h>
+int main()
+{
+  static char buf[8] = "DEADBEEF";
+  snprintf (buf, 1, "%d", 12345);
+  return buf[1] != 'E';
+}],
+      [gl_cv_func_snprintf_size1=yes],
+      [gl_cv_func_snprintf_size1=no],
+      [gl_cv_func_snprintf_size1="guessing yes"])
+    ])
+])
+
 dnl Test whether the vsnprintf function, when passed a zero size, produces no
 dnl output. (ISO C99, POSIX:2001)
 dnl For example, snprintf nevertheless writes a NUL byte in this case
@@ -1234,7 +1259,8 @@
 dnl 15 = gl_SNPRINTF_TRUNCATION_C99
 dnl 16 = gl_SNPRINTF_RETVAL_C99
 dnl 17 = gl_SNPRINTF_DIRECTIVE_N
-dnl 18 = gl_VSNPRINTF_ZEROSIZE_C99
+dnl 18 = gl_SNPRINTF_SIZE1
+dnl 19 = gl_VSNPRINTF_ZEROSIZE_C99
 dnl
 dnl 1 = checking whether printf supports size specifiers as in C99...
 dnl 2 = checking whether printf supports 'long double' arguments...
@@ -1253,30 +1279,31 @@
 dnl 15 = checking whether snprintf truncates the result as in C99...
 dnl 16 = checking whether snprintf returns a byte count as in C99...
 dnl 17 = checking whether snprintf fully supports the 'n' directive...
-dnl 18 = checking whether vsnprintf respects a zero size as in C99...
+dnl 18 = checking whether snprintf respects a size of 1...
+dnl 19 = checking whether vsnprintf respects a zero size as in C99...
 dnl
 dnl . = yes, # = no.
 dnl
-dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18
-dnl   glibc 2.5                      .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
-dnl   glibc 2.3.6                    .  .  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .
-dnl   FreeBSD 5.4, 6.1               .  .  .  .  #  .  .  .  .  .  #  .  #  .  .  .  .  .
-dnl   MacOS X 10.3.9                 .  .  .  .  #  .  .  .  .  .  #  .  #  .  .  .  .  .
-dnl   OpenBSD 3.9, 4.0               .  .  #  #  #  #  .  .  #  .  #  .  #  .  .  .  .  .
-dnl   Cygwin 2007 (= Cygwin 1.5.24)  .  .  .  .  #  #  .  .  .  ?  #  ?  ?  .  .  .  .  .
-dnl   Cygwin 2006 (= Cygwin 1.5.19)  #  .  .  .  #  #  .  .  #  ?  #  ?  ?  .  .  .  .  .
-dnl   Solaris 10                     .  .  #  #  #  .  .  .  .  .  #  .  .  .  .  .  .  .
-dnl   Solaris 2.6 ... 9              #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  .  .  .
-dnl   Solaris 2.5.1                  #  .  #  #  #  #  .  .  .  .  #  .  .  #  #  #  #  #
-dnl   AIX 5.2                        .  .  #  #  #  .  .  .  .  .  #  .  .  .  .  .  .  .
-dnl   AIX 4.3.2, 5.1                 #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  .  .  .
-dnl   HP-UX 11.31                    .  .  .  .  #  .  .  .  .  .  #  .  .  .  .  #  #  .
-dnl   HP-UX 11.{00,11,23}            #  .  .  .  #  #  .  .  .  .  #  .  .  .  .  #  #  #
-dnl   HP-UX 10.20                    #  .  .  .  #  #  .  .  .  #  #  .  .  .  .  #  #  #
-dnl   IRIX 6.5                       #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  #  .  .
-dnl   OSF/1 5.1                      #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  #  .  #
-dnl   OSF/1 4.0d                     #  .  #  #  #  #  .  .  .  .  #  .  .  #  #  #  #  #
-dnl   NetBSD 4.0                     .  ?  ?  ?  ?  ?  .  .  ?  ?  ?  ?  ?  .  .  .  ?  ?
-dnl   NetBSD 3.0                     .  .  .  .  #  #  .  #  #  ?  #  .  #  .  .  .  .  .
-dnl   BeOS                           #  #  .  #  #  #  .  #  .  ?  .  #  ?  .  .  .  .  .
-dnl   mingw                          #  #  #  #  #  #  .  #  #  .  #  #  ?  .  #  #  #  .
+dnl                                  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
+dnl   glibc 2.5                      .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+dnl   glibc 2.3.6                    .  .  .  .  #  .  .  .  .  .  .  .  .  .  .  .  .  .  .
+dnl   FreeBSD 5.4, 6.1               .  .  .  .  #  .  .  .  .  .  #  .  #  .  .  .  .  .  .
+dnl   MacOS X 10.3.9                 .  .  .  .  #  .  .  .  .  .  #  .  #  .  .  .  .  .  .
+dnl   OpenBSD 3.9, 4.0               .  .  #  #  #  #  .  .  #  .  #  .  #  .  .  .  .  .  .
+dnl   Cygwin 2007 (= Cygwin 1.5.24)  .  .  .  .  #  #  .  .  .  ?  #  ?  ?  .  .  .  .  .  .
+dnl   Cygwin 2006 (= Cygwin 1.5.19)  #  .  .  .  #  #  .  .  #  ?  #  ?  ?  .  .  .  .  .  .
+dnl   Solaris 10                     .  .  #  #  #  .  .  .  .  .  #  .  .  .  .  .  .  .  .
+dnl   Solaris 2.6 ... 9              #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  .  .  .  .
+dnl   Solaris 2.5.1                  #  .  #  #  #  #  .  .  .  .  #  .  .  #  #  #  #  #  #
+dnl   AIX 5.2                        .  .  #  #  #  .  .  .  .  .  #  .  .  .  .  .  .  .  .
+dnl   AIX 4.3.2, 5.1                 #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  .  .  .  .
+dnl   HP-UX 11.31                    .  .  .  .  #  .  .  .  .  .  #  .  .  .  .  #  #  .  .
+dnl   HP-UX 11.{00,11,23}            #  .  .  .  #  #  .  .  .  .  #  .  .  .  .  #  #  .  #
+dnl   HP-UX 10.20                    #  .  .  .  #  #  .  .  .  #  #  .  .  .  .  #  #  ?  #
+dnl   IRIX 6.5                       #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  #  .  .  .
+dnl   OSF/1 5.1                      #  .  #  #  #  #  .  .  .  .  #  .  .  .  .  #  .  .  #
+dnl   OSF/1 4.0d                     #  .  #  #  #  #  .  .  .  .  #  .  .  #  #  #  #  #  #
+dnl   NetBSD 4.0                     .  ?  ?  ?  ?  ?  .  .  ?  ?  ?  ?  ?  .  .  .  ?  ?  ?
+dnl   NetBSD 3.0                     .  .  .  .  #  #  .  #  #  ?  #  .  #  .  .  .  .  .  .
+dnl   BeOS                           #  #  .  #  #  #  .  #  .  ?  .  #  ?  .  .  .  .  .  .
+dnl   mingw                          #  #  #  #  #  #  .  #  #  .  #  #  ?  .  #  #  #  .  .
--- a/m4/snprintf-posix.m4
+++ b/m4/snprintf-posix.m4
@@ -1,4 +1,4 @@
-# snprintf-posix.m4 serial 12
+# snprintf-posix.m4 serial 13
 dnl Copyright (C) 2007-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -25,6 +25,7 @@
     gl_SNPRINTF_TRUNCATION_C99
     gl_SNPRINTF_RETVAL_C99
     gl_SNPRINTF_DIRECTIVE_N
+    gl_SNPRINTF_SIZE1
     gl_VSNPRINTF_ZEROSIZE_C99
     case "$gl_cv_func_printf_sizes_c99" in
       *yes)
@@ -58,11 +59,15 @@
                                                               *yes)
                                                                 case "$gl_cv_func_snprintf_directive_n" in
                                                                   *yes)
-                                                                    case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                    case "$gl_cv_func_snprintf_size1" in
                                                                       *yes)
-                                                                        # snprintf exists and is
-                                                                        # already POSIX compliant.
-                                                                        gl_cv_func_snprintf_posix=yes
+                                                                        case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                          *yes)
+                                                                            # snprintf exists and is
+                                                                            # already POSIX compliant.
+                                                                            gl_cv_func_snprintf_posix=yes
+                                                                            ;;
+                                                                        esac
                                                                         ;;
                                                                     esac
                                                                     ;;
--- a/m4/snprintf.m4
+++ b/m4/snprintf.m4
@@ -1,5 +1,5 @@
-# snprintf.m4 serial 4
-dnl Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+# snprintf.m4 serial 5
+dnl Copyright (C) 2002-2004, 2007-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -7,8 +7,17 @@
 AC_DEFUN([gl_FUNC_SNPRINTF],
 [
   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  gl_cv_func_snprintf_usable=no
   AC_CHECK_FUNCS([snprintf])
-  if test $ac_cv_func_snprintf = no; then
+  if test $ac_cv_func_snprintf = yes; then
+    gl_SNPRINTF_SIZE1
+    case "$gl_cv_func_snprintf_size1" in
+      *yes)
+        gl_cv_func_snprintf_usable=yes
+        ;;
+    esac
+  fi
+  if test $gl_cv_func_snprintf_usable = no; then
     gl_REPLACE_SNPRINTF
   fi
   AC_CHECK_DECLS_ONCE([snprintf])
--- a/m4/vsnprintf-posix.m4
+++ b/m4/vsnprintf-posix.m4
@@ -1,4 +1,4 @@
-# vsnprintf-posix.m4 serial 12
+# vsnprintf-posix.m4 serial 13
 dnl Copyright (C) 2007-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -26,6 +26,7 @@
     gl_SNPRINTF_TRUNCATION_C99
     gl_SNPRINTF_RETVAL_C99
     gl_SNPRINTF_DIRECTIVE_N
+    gl_SNPRINTF_SIZE1
     gl_VSNPRINTF_ZEROSIZE_C99
     case "$gl_cv_func_printf_sizes_c99" in
       *yes)
@@ -59,11 +60,15 @@
                                                               *yes)
                                                                 case "$gl_cv_func_snprintf_directive_n" in
                                                                   *yes)
-                                                                    case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                    case "$gl_cv_func_snprintf_size1" in
                                                                       *yes)
-                                                                        # vsnprintf exists and is
-                                                                        # already POSIX compliant.
-                                                                        gl_cv_func_vsnprintf_posix=yes
+                                                                        case "$gl_cv_func_vsnprintf_zerosize_c99" in
+                                                                          *yes)
+                                                                            # vsnprintf exists and is
+                                                                            # already POSIX compliant.
+                                                                            gl_cv_func_vsnprintf_posix=yes
+                                                                            ;;
+                                                                        esac
                                                                         ;;
                                                                     esac
                                                                     ;;
--- a/m4/vsnprintf.m4
+++ b/m4/vsnprintf.m4
@@ -1,5 +1,5 @@
-# vsnprintf.m4 serial 4
-dnl Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+# vsnprintf.m4 serial 5
+dnl Copyright (C) 2002-2004, 2007-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -7,8 +7,17 @@
 AC_DEFUN([gl_FUNC_VSNPRINTF],
 [
   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  gl_cv_func_vsnprintf_usable=no
   AC_CHECK_FUNCS([vsnprintf])
-  if test $ac_cv_func_vsnprintf = no; then
+  if test $ac_cv_func_vsnprintf = yes; then
+    gl_SNPRINTF_SIZE1
+    case "$gl_cv_func_snprintf_size1" in
+      *yes)
+        gl_cv_func_vsnprintf_usable=yes
+        ;;
+    esac
+  fi
+  if test $gl_cv_func_snprintf_usable = no; then
     gl_REPLACE_VSNPRINTF
   fi
   AC_CHECK_DECLS_ONCE([vsnprintf])
--- a/modules/snprintf
+++ b/modules/snprintf
@@ -4,6 +4,7 @@
 Files:
 lib/snprintf.c
 m4/snprintf.m4
+m4/printf.m4
 
 Depends-on:
 stdio
--- a/modules/vsnprintf
+++ b/modules/vsnprintf
@@ -5,6 +5,7 @@
 Files:
 lib/vsnprintf.c
 m4/vsnprintf.m4
+m4/printf.m4
 
 Depends-on:
 stdio