summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2004-03-05 14:05:33 +0000
committerDavid Zeuthen <davidz@redhat.com>2004-03-05 14:05:33 +0000
commit868dd4b4b0be082b86354b1f89ed9cffd5b8e193 (patch)
tree73b59bb44eaab572d35ce55dc415d614f68a84fe
parent47d8e53bfeccc6f90475408bfbef9c0132a4122f (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--ChangeLog12
-rw-r--r--configure.in76
-rw-r--r--dbus/dbus-string.c20
-rw-r--r--dbus/dbus-sysdeps.h14
4 files changed, 118 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index af872a97..f099f0ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 */