diff options
author | David Zeuthen <davidz@redhat.com> | 2004-03-05 14:05:33 +0000 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2004-03-05 14:05:33 +0000 |
commit | 868dd4b4b0be082b86354b1f89ed9cffd5b8e193 (patch) | |
tree | 73b59bb44eaab572d35ce55dc415d614f68a84fe | |
parent | 47d8e53bfeccc6f90475408bfbef9c0132a4122f (diff) |
2004-03-01 David Zeuthen <david@fubar.dk>
* dbus/dbus-string.c (_dbus_string_append_printf_valist): Fix a
bug where args were used twice. This bug resulted in a segfault
on a Debian/PPC system when starting the messagebus daemon. Include
dbus-sysdeps.h for DBUS_VA_COPY
* dbus/dbus-sysdeps.h: Define DBUS_VA_COPY if neccessary. From GLib
* configure.in: Check for va_copy; define DBUS_VA_COPY to the
appropriate va_copy implementation. From GLib
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | configure.in | 76 | ||||
-rw-r--r-- | dbus/dbus-string.c | 20 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.h | 14 |
4 files changed, 118 insertions, 4 deletions
@@ -1,3 +1,15 @@ +2004-03-01 David Zeuthen <david@fubar.dk> + + * dbus/dbus-string.c (_dbus_string_append_printf_valist): Fix a + bug where args were used twice. This bug resulted in a segfault + on a Debian/PPC system when starting the messagebus daemon. Include + dbus-sysdeps.h for DBUS_VA_COPY + + * dbus/dbus-sysdeps.h: Define DBUS_VA_COPY if neccessary. From GLib + + * configure.in: Check for va_copy; define DBUS_VA_COPY to the + appropriate va_copy implementation. From GLib + 2004-02-24 Joe Shaw <joe@ximian.com> * bus/services.c (bus_registry_acquire_service): We need to pass diff --git a/configure.in b/configure.in index 5d08f261..2e323155 100644 --- a/configure.in +++ b/configure.in @@ -293,6 +293,82 @@ AC_SUBST(DBUS_HAVE_INT64) ## byte order AC_C_BIGENDIAN + +dnl ********************************** +dnl *** va_copy checks (from GLib) *** +dnl ********************************** +dnl we currently check for all three va_copy possibilities, so we get +dnl all results in config.log for bug reports. +AC_CACHE_CHECK([for an implementation of va_copy()],dbus_cv_va_copy,[ + AC_LINK_IFELSE([#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; + }], + [dbus_cv_va_copy=yes], + [dbus_cv_va_copy=no]) +]) +AC_CACHE_CHECK([for an implementation of __va_copy()],dbus_cv___va_copy,[ + AC_LINK_IFELSE([#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; + }], + [dbus_cv___va_copy=yes], + [dbus_cv___va_copy=no]) +]) + +if test "x$dbus_cv_va_copy" = "xyes"; then + dbus_va_copy_func=va_copy +else if test "x$dbus_cv___va_copy" = "xyes"; then + dbus_va_copy_func=__va_copy +fi +fi + +if test -n "$dbus_va_copy_func"; then + AC_DEFINE_UNQUOTED(DBUS_VA_COPY,$dbus_va_copy_func,[A 'va_copy' style function]) +fi + +AC_CACHE_CHECK([whether va_lists can be copied by value],dbus_cv_va_val_copy,[ + AC_TRY_RUN([#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; + }], + [dbus_cv_va_val_copy=yes], + [dbus_cv_va_val_copy=no], + [dbus_cv_va_val_copy=yes]) +]) + +if test "x$dbus_cv_va_val_copy" = "xno"; then + AC_DEFINE(DBUS_VA_COPY_AS_ARRAY,1, ['va_lists' cannot be copies as values]) +fi + + #### Atomic integers (checks by Sebastian Wilhelmi for GLib) AC_MSG_CHECKING([whether to use inline assembler routines for atomic integers]) have_atomic_inc=no diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index f78d01c9..6a83398d 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -31,6 +31,8 @@ #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1 #include "dbus-string-private.h" #include "dbus-protocol.h" +/* for DBUS_VA_COPY */ +#include "dbus-sysdeps.h" /** * @defgroup DBusString string class @@ -1013,16 +1015,26 @@ _dbus_string_append_printf_valist (DBusString *str, { int len; char c; + va_list args_copy; + DBUS_STRING_PREAMBLE (str); - + + DBUS_VA_COPY (args_copy, args); + /* Measure the message length without terminating nul */ len = vsnprintf (&c, 1, format, args); if (!_dbus_string_lengthen (str, len)) - return FALSE; - + { + /* don't leak the copy */ + va_end (args_copy); + return FALSE; + } + vsprintf (real->str + (real->len - len), - format, args); + format, args_copy); + + va_end (args_copy); return TRUE; } diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index da71f99f..5febc6e6 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -306,6 +306,20 @@ void _dbus_set_signal_handler (int sig, DBusSignalHandler handler); +/* Define DBUS_VA_COPY() to do the right thing for copying va_list variables. + * config.h may have already defined DBUS_VA_COPY as va_copy or __va_copy. + */ +#if !defined (DBUS_VA_COPY) +# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32)) +# define DBUS_VA_COPY(ap1, ap2) (*(ap1) = *(ap2)) +# elif defined (DBUS_VA_COPY_AS_ARRAY) +# define DBUS_VA_COPY(ap1, ap2) memcpy ((ap1), (ap2), sizeof (va_list)) +# else /* va_list is a pointer */ +# define DBUS_VA_COPY(ap1, ap2) ((ap1) = (ap2)) +# endif /* va_list is a pointer */ +#endif /* !DBUS_VA_COPY */ + + DBUS_END_DECLS; #endif /* DBUS_SYSDEPS_H */ |