OSDN Git Service

a patch from Yair K.
authorKeishi Suenaga <s_keishi@mutt.freemail.ne.jp>
Sun, 30 Mar 2008 22:08:08 +0000 (22:08 +0000)
committerKeishi Suenaga <s_keishi@mutt.freemail.ne.jp>
Sun, 30 Mar 2008 22:08:08 +0000 (22:08 +0000)
        * configure.in
          utils/support.c
          utils/support.h        fix-snprintf-crash

ChangeLog
config.h.in
configure
configure.in
utils/support.c
utils/support.h

index dce76c8..9dfa21a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-3-31  Keishi Suenaga <skeishi@yahoo.co.jp>
+        a patch from Yair K.
+       * configure.in
+         utils/support.c
+         utils/support.h        fix-snprintf-crash
+       
 2008-3-30  Keishi Suenaga <skeishi@yahoo.co.jp>
        patches from Yair K.
        * libarc/arc_tar.c       fix-archive-add-crash
index a92cd6e..e00cf07 100644 (file)
 /* Define to 1 if you use PDcurses */
 #undef USE_PDCURSES
 
+/* A 'va_copy' style function */
+#undef VA_COPY
+
+/* 'va_lists' cannot be copies as values */
+#undef VA_COPY_AS_ARRAY
+
 /* Version number of package */
 #undef VERSION
 
index 41e514b..5c56c00 100755 (executable)
--- a/configure
+++ b/configure
@@ -8155,6 +8155,7 @@ done
 
 
 
+
 for ac_header in \
   arpa/inet.h \
   errno.h \
@@ -8190,6 +8191,7 @@ for ac_header in \
   sys/param.h \
   sys/time.h \
   sys/types.h \
+  sys/stat.h \
   sys/sysctl.h \
   termios.h \
   unistd.h \
@@ -11573,6 +11575,246 @@ _ACEOF
 fi
 
 
+
+{ echo "$as_me:$LINENO: checking for an implementation of va_copy()" >&5
+echo $ECHO_N "checking for an implementation of va_copy()... $ECHO_C" >&6; }
+if test "${lib_cv_va_copy+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+       #include <stdarg.h>
+       void f (int i, ...) {
+       va_list args1, args2;
+       va_start (args1, i);
+       va_copy (args2, args1);
+       if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+         exit (1);
+       va_end (args1); va_end (args2);
+       }
+       int main() {
+         f (0, 42);
+         return 0;
+       }
+_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
+  lib_cv_va_copy=yes
+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 )
+lib_cv_va_copy=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+fi
+{ echo "$as_me:$LINENO: result: $lib_cv_va_copy" >&5
+echo "${ECHO_T}$lib_cv_va_copy" >&6; }
+
+{ echo "$as_me:$LINENO: checking for an implementation of __va_copy()" >&5
+echo $ECHO_N "checking for an implementation of __va_copy()... $ECHO_C" >&6; }
+if test "${lib_cv___va_copy+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+       #include <stdarg.h>
+       void f (int i, ...) {
+       va_list args1, args2;
+       va_start (args1, i);
+       __va_copy (args2, args1);
+       if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+         exit (1);
+       va_end (args1); va_end (args2);
+       }
+       int main() {
+         f (0, 42);
+         return 0;
+       }
+_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
+  lib_cv___va_copy=yes
+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 )
+lib_cv___va_copy=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+fi
+{ echo "$as_me:$LINENO: result: $lib_cv___va_copy" >&5
+echo "${ECHO_T}$lib_cv___va_copy" >&6; }
+
+if test "x$lib_cv_va_copy" = "xyes"; then
+  va_copy_func=va_copy
+else if test "x$lib_cv___va_copy" = "xyes"; then
+  va_copy_func=__va_copy
+fi
+fi
+
+if test -n "$va_copy_func"; then
+
+cat >>confdefs.h <<_ACEOF
+#define VA_COPY $va_copy_func
+_ACEOF
+
+fi
+
+{ echo "$as_me:$LINENO: checking whether va_lists can be copied by value" >&5
+echo $ECHO_N "checking whether va_lists can be copied by value... $ECHO_C" >&6; }
+if test "${lib_cv_va_val_copy+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+       #include <stdarg.h>
+       void f (int i, ...) {
+       va_list args1, args2;
+       va_start (args1, i);
+       args2 = args1;
+       if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+         exit (1);
+       va_end (args1); va_end (args2);
+       }
+       int main() {
+         f (0, 42);
+         return 0;
+       }
+_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
+  lib_cv_va_val_copy=yes
+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 )
+lib_cv_va_val_copy=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+fi
+{ echo "$as_me:$LINENO: result: $lib_cv_va_val_copy" >&5
+echo "${ECHO_T}$lib_cv_va_val_copy" >&6; }
+
+if test "x$lib_cv_va_val_copy" = "xno"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define VA_COPY_AS_ARRAY 1
+_ACEOF
+
+fi
+
 # Checks on cygnus and MSYS
 if test "x$MSYS" = xyes ; then
   case "$ac_cv_header_dirent_dirent_h$ac_cv_header_dirent_sys_ndir_h$ac_cv_header_dirent_sys_dir_h$ac_cv_header_dirent_ndir_h" in
index 05d0d3f..0e0c138 100644 (file)
@@ -433,6 +433,7 @@ AC_CHECK_HEADERS( \
   sys/param.h \
   sys/time.h \
   sys/types.h \
+  sys/stat.h \
   sys/sysctl.h \
   termios.h \
   unistd.h \
@@ -622,6 +623,82 @@ AC_CHECK_FUNC(open_memstream, [
         AC_DEFINE([HAVE_OPEN_MEMSTREAM],1,[Define to 1 if you have `open_memstream' function])
         ])
 
+dnl ***
+dnl *** va_copy checks (from GLIB)
+dnl ***
+
+AC_CACHE_CHECK([for an implementation of va_copy()],lib_cv_va_copy,[
+       AC_RUN_IFELSE([AC_LANG_SOURCE([[
+       #include <stdarg.h>
+       void f (int i, ...) {
+       va_list args1, args2;
+       va_start (args1, i);
+       va_copy (args2, args1);
+       if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+         exit (1);
+       va_end (args1); va_end (args2);
+       }
+       int main() {
+         f (0, 42);
+         return 0;
+       }]])],
+       [lib_cv_va_copy=yes],
+       [lib_cv_va_copy=no],[])
+])
+
+AC_CACHE_CHECK([for an implementation of __va_copy()],lib_cv___va_copy,[
+       AC_RUN_IFELSE([AC_LANG_SOURCE([[
+       #include <stdarg.h>
+       void f (int i, ...) {
+       va_list args1, args2;
+       va_start (args1, i);
+       __va_copy (args2, args1);
+       if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+         exit (1);
+       va_end (args1); va_end (args2);
+       }
+       int main() {
+         f (0, 42);
+         return 0;
+       }]])],
+       [lib_cv___va_copy=yes],
+       [lib_cv___va_copy=no],[])
+])
+
+if test "x$lib_cv_va_copy" = "xyes"; then
+  va_copy_func=va_copy
+else if test "x$lib_cv___va_copy" = "xyes"; then
+  va_copy_func=__va_copy
+fi
+fi
+
+if test -n "$va_copy_func"; then
+  AC_DEFINE_UNQUOTED(VA_COPY,$va_copy_func,[A 'va_copy' style function])
+fi
+
+AC_CACHE_CHECK([whether va_lists can be copied by value],lib_cv_va_val_copy,[
+       AC_RUN_IFELSE([AC_LANG_SOURCE([[
+       #include <stdarg.h>
+       void f (int i, ...) {
+       va_list args1, args2;
+       va_start (args1, i);
+       args2 = args1;
+       if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+         exit (1);
+       va_end (args1); va_end (args2);
+       }
+       int main() {
+         f (0, 42);
+         return 0;
+       }]])],
+       [lib_cv_va_val_copy=yes],
+       [lib_cv_va_val_copy=no],[])
+])
+
+if test "x$lib_cv_va_val_copy" = "xno"; then
+  AC_DEFINE(VA_COPY_AS_ARRAY,1, ['va_lists' cannot be copies as values])
+fi
+
 # Checks on cygnus and MSYS
 if test "x$MSYS" = xyes ; then
   case "$ac_cv_header_dirent_dirent_h$ac_cv_header_dirent_sys_ndir_h$ac_cv_header_dirent_sys_dir_h$ac_cv_header_dirent_ndir_h" in
index 5c11aae..f24f591 100644 (file)
 /* From glib-1.1.13:gstrfuncs.c
  * Modified by Masanao Izumo <mo@goice.co.jp>
  */
+#ifndef VA_COPY
+# if (defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (__WIN32__))) || defined (__WATCOMC__)
+#  define VA_COPY(ap1, ap2)      (*(ap1) = *(ap2))
+# elif defined (VA_COPY_AS_ARRAY)
+#  define VA_COPY(ap1, ap2)      memmove ((ap1), (ap2), sizeof (va_list))
+# else /* va_list is a pointer */
+#  define VA_COPY(ap1, ap2)      ((ap1) = (ap2))
+# endif /* va_list is a pointer */
+#endif /* !VA_COPY */
+
 static int printf_string_upper_bound (const char* format,
                             va_list      args)
 {
@@ -201,30 +211,38 @@ static int printf_string_upper_bound (const char* format,
   return len;
 }
 
-void vsnprintf(char *buff, size_t bufsiz, const char *fmt, va_list ap)
+int vsnprintf(char *buff, size_t bufsiz, const char *fmt, va_list ap)
 {
     MBlockList pool;
     char *tmpbuf = buff;
+    int ret;
+    va_list ap2;
 
+    VA_COPY(ap2, ap);
     init_mblock(&pool);
     tmpbuf = new_segment(&pool, printf_string_upper_bound(fmt, ap));
-    vsprintf(tmpbuf, fmt, ap);
-    strncpy(buff, tmpbuf, bufsiz-1);
+    ret = vsprintf(tmpbuf, fmt, ap2);
+    strncpy(buff, tmpbuf, bufsiz);
     buff[bufsiz-1] = '\0';
     reuse_mblock(&pool);
+    va_end(ap2);
+    return ret;
 }
 #endif /* HAVE_VSNPRINTF */
 
 
 #ifndef HAVE_SNPRINTF
-void snprintf(char *buff, size_t bufsiz, const char *fmt, ...)
+int snprintf(char *buff, size_t bufsiz, const char *fmt, ...)
 {
+    int ret;
     va_list ap;
+
     va_start(ap, fmt);
-    vsnprintf(buff, bufsiz, fmt, ap);
+    ret = vsnprintf(buff, bufsiz, fmt, ap);
     va_end(ap);
+    return ret;
 }
-#endif /* HAVE_VSNPRINTF */
+#endif /* HAVE_SNPRINTF */
 
 #ifndef HAVE_STRERROR
 #ifndef HAVE_ERRNO_H
index e29de3c..05a5034 100644 (file)
 
 #ifndef HAVE_VSNPRINTF
 #include <stdarg.h> /* for va_list */
-extern void vsnprintf(char *buff, size_t bufsiz, const char *fmt, va_list ap);
+extern int vsnprintf(char *buff, size_t bufsiz, const char *fmt, va_list ap);
 #endif
 
 #ifndef HAVE_SNPRINTF
-extern void snprintf(char *buff, size_t bufsiz, const char *fmt, ...);
+extern int snprintf(char *buff, size_t bufsiz, const char *fmt, ...);
 #endif /* HAVE_SNPRINTF */
 
 #ifndef HAVE_STRERROR