dbus/dbus dbus-message.c,1.112,1.113 dbus-string.c,1.43,1.44

Havoc Pennington hp@pdx.freedesktop.org
Tue, 28 Oct 2003 14:53:38 -0800


Update of /cvs/dbus/dbus/dbus
In directory pdx:/tmp/cvs-serv905/dbus

Modified Files:
	dbus-message.c dbus-string.c 
Log Message:
2003-10-28  Havoc Pennington  <hp@redhat.com>

	* dbus/dbus-message.c (_dbus_message_test): enable and fix the
	tests for set_path, set_interface, set_member, etc.

	* dbus/dbus-string.c (_dbus_string_insert_bytes): allow 0 bytes

	* dbus/dbus-message.c (set_string_field): always just delete and
	re-append the field; accept NULL for deletion
	(re_align_fields_recurse): reimplement
	


Index: dbus-message.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message.c,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -d -r1.112 -r1.113
--- dbus-message.c	22 Oct 2003 16:01:08 -0000	1.112
+++ dbus-message.c	28 Oct 2003 22:53:36 -0000	1.113
@@ -377,6 +377,7 @@
   return FALSE;
 }
 
+#define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 1 + 8)
 static dbus_bool_t
 append_string_field (DBusMessage *message,
                      int          field,
@@ -430,11 +431,14 @@
 get_next_field (DBusMessage *message,
 		int          field)
 {
-  int offset = message->header_fields[field].name_offset;
+  int offset;
   int closest;
   int i;
-  int retval = DBUS_HEADER_FIELD_INVALID;
+  int retval;
 
+  offset = message->header_fields[field].name_offset;
+  retval = DBUS_HEADER_FIELD_INVALID;
+  
   i = 0;
   closest = _DBUS_INT_MAX;
   while (i < DBUS_HEADER_FIELD_LAST)
@@ -451,183 +455,334 @@
   return retval;
 }
 
-static dbus_bool_t
-re_align_field_recurse (DBusMessage *message,
-			int          field,
-			int          offset)
+static int
+get_type_alignment (int type)
 {
-  int old_name_offset  = message->header_fields[field].name_offset;
-  int old_value_offset = message->header_fields[field].value_offset;
-  int prev_padding, padding, delta;
-  int type;
-  int next_field;
-  int pos = offset;
-
-  /* padding between the typecode byte and the value itself */
-  prev_padding = old_value_offset - old_name_offset + 2;
-
-  pos++;
-  type = _dbus_string_get_byte (&message->header, pos);
-
-  pos++;
+  int alignment;
+  
   switch (type)
     {
     case DBUS_TYPE_NIL:
     case DBUS_TYPE_BYTE:
     case DBUS_TYPE_BOOLEAN:
-      padding = 0;
+      alignment = 0;
       break;
+
     case DBUS_TYPE_INT32:
     case DBUS_TYPE_UINT32:
     case DBUS_TYPE_STRING:
     case DBUS_TYPE_OBJECT_PATH:
-      padding = _DBUS_ALIGN_VALUE (pos, 4) - pos;
+      /* These are aligned 4 because they have a length as the
+       * first field;
+       */
+    case DBUS_TYPE_CUSTOM:
+    case DBUS_TYPE_DICT:
+      alignment = 4;
       break;
+
     case DBUS_TYPE_INT64:
     case DBUS_TYPE_UINT64:
     case DBUS_TYPE_DOUBLE:
-      padding = _DBUS_ALIGN_VALUE (pos, 8) - pos;
+      alignment = 8;
       break;
-    case DBUS_TYPE_CUSTOM:
+
     case DBUS_TYPE_ARRAY:
-    case DBUS_TYPE_DICT:
-      /* FIXME This is no good; we have to handle undefined header fields
-       * also. SECURITY and spec compliance issue.
-       */
-      _dbus_assert_not_reached ("no defined header fields may contain a custom, array or dict value");
+      _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()");
       break;
+
     case DBUS_TYPE_INVALID:
     default:
-      _dbus_assert_not_reached ("invalid type in marshalled header");
+      _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()");
       break;
     }
 
-  delta = padding - prev_padding;
-  if (delta > 0)
+  return alignment;
+}
+
+static dbus_bool_t
+iterate_one_field (const DBusString *str,
+                   int               byte_order,
+                   int               name_offset,
+                   int              *next_offset_p,
+                   int              *field_name_p,
+                   DBusString       *append_copy_to,
+                   int              *copy_name_offset_p,
+                   int              *copy_value_offset_p)
+{
+  int name, type, array_type;
+  int alignment;
+  int type_len;
+  int type_pos;
+  int value_pos;
+  int value_len;
+  int value_end;
+  int pos;
+
+  _dbus_verbose ("%s: name_offset=%d, append to %p\n",
+                 _DBUS_FUNCTION_NAME, name_offset, append_copy_to);
+  
+  pos = name_offset;
+  
+  name = _dbus_string_get_byte (str, name_offset);
+  pos++;
+
+  type_pos = pos;
+  type = _dbus_string_get_byte (str, type_pos);
+  pos++;
+  type_len = 1;
+
+  array_type = type;
+  /* find out the type of our array */
+  while (array_type == DBUS_TYPE_ARRAY)
     {
-      if (!_dbus_string_insert_bytes (&message->header, pos, delta, 0))
-	return FALSE;
+      pos++;
+      type_len++;
+      array_type = _dbus_string_get_byte (str, pos);
     }
-  else if (delta < 0)
+
+  _dbus_verbose ("%s: name %d, type '%c' %d at %d len %d, array type '%c' %d\n",
+                 _DBUS_FUNCTION_NAME,
+                 name, type, type, type_pos, type_len, array_type, array_type);
+  
+#ifndef DBUS_DISABLE_ASSERT
+  if (!_dbus_type_is_valid (array_type))
     {
-      _dbus_string_delete (&message->header, pos, -delta);
+      _dbus_warn ("type '%c' %d is not valid in %s\n",
+                  array_type, array_type, _DBUS_FUNCTION_NAME);
+      _dbus_assert_not_reached ("invalid type");
     }
+#endif
+      
+  alignment = get_type_alignment (array_type);
+      
+  if (alignment > 0)
+    pos = _DBUS_ALIGN_VALUE (pos, alignment);
 
-  next_field = get_next_field (message, field);
-  if (next_field != DBUS_HEADER_FIELD_INVALID)
-    {
-      int next_offset = message->header_fields[next_field].name_offset;
+  _dbus_verbose ("%s: alignment %d value at pos %d\n",
+                 _DBUS_FUNCTION_NAME, alignment, pos);
+  
+  /* pos now points to our value */
+  if (!_dbus_marshal_get_arg_end_pos (str, byte_order,
+                                      type, pos, &value_end))
+    _dbus_assert_not_reached ("failed to get the byte after this header");
 
-      _dbus_assert (next_offset > 0);
+  value_pos = pos;
+  value_len = value_end - value_pos;
 
-      if (!re_align_field_recurse (message, field,
-				   pos + padding + (next_offset - old_value_offset)))
-	goto failed;
-    }
-  else
+  _dbus_verbose ("%s: value_pos %d value_len %d value_end %d\n",
+                 _DBUS_FUNCTION_NAME, value_pos, value_len, value_end);
+  
+  if (next_offset_p)
+    *next_offset_p = pos + value_len;
+
+  if (field_name_p)
+    *field_name_p = name;
+
+  if (append_copy_to)
     {
-      if (!append_header_padding (message))
-	goto failed;
-    }
+      int orig_len;
 
-  message->header_fields[field].name_offset  = offset;
-  message->header_fields[field].value_offset = pos + padding;
+      orig_len = _dbus_string_get_length (append_copy_to);
 
-  return TRUE;
+      if (copy_name_offset_p)
+        *copy_name_offset_p = orig_len;
+      
+      if (!_dbus_string_append_byte (append_copy_to, name))
+        goto failed_copy;
 
- failed:
-  if (delta > 0)
-    {
-      _dbus_string_delete (&message->header, pos, delta);
+      if (!_dbus_string_copy_len (str, type_pos, type_len,
+                                  append_copy_to,
+                                  _dbus_string_get_length (append_copy_to)))
+        goto failed_copy;
+
+      if (!_dbus_string_align_length (append_copy_to, alignment))
+        goto failed_copy;
+
+      if (copy_value_offset_p)
+        *copy_value_offset_p = _dbus_string_get_length (append_copy_to);
+      
+      if (!_dbus_string_copy_len (str, value_pos, value_len,
+                                  append_copy_to,
+                                  _dbus_string_get_length (append_copy_to)))
+        goto failed_copy;
+      
+      return TRUE;
+
+    failed_copy:
+      _dbus_verbose ("%s: Failed copying old fields to new string\n",
+                     _DBUS_FUNCTION_NAME);
+      _dbus_string_set_length (append_copy_to, orig_len);
+      return FALSE;
     }
-  else if (delta < 0)
+  else
+    return TRUE;
+}
+
+#ifndef DBUS_DISABLE_ASSERT
+static void
+verify_header_fields (DBusMessage *message)
+{
+  int i;
+  i = 0;
+  while (i < DBUS_HEADER_FIELD_LAST)
     {
-      /* this must succeed because it was allocated on function entry and
-       * DBusString doesn't ever realloc smaller
-       */
-      _dbus_string_insert_bytes (&message->header, pos, -delta, 0);
+      if (message->header_fields[i].name_offset >= 0)
+        _dbus_assert (_dbus_string_get_byte (&message->header,
+                                             message->header_fields[i].name_offset) ==
+                      i);
+      ++i;
     }
-
-  return FALSE;
 }
+#else /* DBUS_DISABLE_ASSERT */
+#define verify_header_fields(x)
+#endif /* DBUS_DISABLE_ASSERT */
 
+/* In this function we delete one field and re-align all the fields
+ * following it.
+ */
 static dbus_bool_t
-delete_field (DBusMessage *message,
-	      int          field)
+delete_one_and_re_align (DBusMessage *message,
+                         int          name_offset_to_delete)
 {
-  int offset = message->header_fields[field].name_offset;
-  int next_field;
+  DBusString copy;
+  int new_fields_front_padding;
+  int next_offset;
+  int field_name;
+  dbus_bool_t retval;
+  HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST];
+  
+  _dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header));
+  verify_header_fields (message);
 
-  _dbus_assert (!message->locked);
+  _dbus_verbose ("%s: Deleting one field at offset %d\n",
+                 _DBUS_FUNCTION_NAME,
+                 name_offset_to_delete);
   
-  if (offset < 0)
-    return FALSE;
+  retval = FALSE;
 
   clear_header_padding (message);
-
-  next_field = get_next_field (message, field);
-  if (next_field == DBUS_HEADER_FIELD_INVALID)
+  
+  if (!_dbus_string_init_preallocated (&copy,
+                                       _dbus_string_get_length (&message->header) -
+                                       name_offset_to_delete + 8))
     {
-      _dbus_string_set_length (&message->header, offset);
-
-      message->header_fields[field].name_offset  = -1;
-      message->header_fields[field].value_offset = -1;
-      
-      /* this must succeed because it was allocated on function entry and
-       * DBusString doesn't ever realloc smaller
-       */
-      if (!append_header_padding (message))
-	_dbus_assert_not_reached ("failed to reappend header padding");
-
-      return TRUE;
+      _dbus_verbose ("%s: Failed to init string to hold copy of fields\n",
+                     _DBUS_FUNCTION_NAME);
+      goto out_0;
     }
-  else
-    {
-      DBusString deleted;
-      int next_offset = message->header_fields[next_field].name_offset;
-
-      _dbus_assert (next_offset > 0);
+  
+  /* Align the name offset of the first field in the same way it's
+   * aligned in the real header
+   */
+  new_fields_front_padding = name_offset_to_delete % 8;
 
-      if (!_dbus_string_init (&deleted))
-	goto failed;
+  if (!_dbus_string_insert_bytes (&copy, 0, new_fields_front_padding,
+                                  '\0'))
+    _dbus_assert_not_reached ("Should not have failed to insert bytes into preallocated string\n");
 
-      if (!_dbus_string_move_len (&message->header,
-				  offset, next_offset - offset,
-				  &deleted, 0))
-	{
-	  _dbus_string_free (&deleted);
-	  goto failed;
-	}
+  memcpy (new_header_fields, message->header_fields,
+          sizeof (new_header_fields));
+  
+  /* Now just re-marshal each field in the header to our temporary
+   * buffer, skipping the first one. The tricky part is that the
+   * fields are padded as if for previous_name_offset, but are in fact
+   * at unaligned_name_offset
+   */
 
-      /* appends the header padding */
-      if (!re_align_field_recurse (message, next_field, offset))
-	{
-	  /* this must succeed because it was allocated on function entry and
-	   * DBusString doesn't ever realloc smaller
-	   */
-	  if (!_dbus_string_copy (&deleted, 0, &message->header, offset))
-	    _dbus_assert_not_reached ("failed to revert to original field");
+  if (!iterate_one_field (&message->header,
+                          message->byte_order,
+                          name_offset_to_delete,
+                          &next_offset,
+                          &field_name, NULL, NULL, NULL))
+    _dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field");
 
-	  _dbus_string_free (&deleted);
-	  goto failed;
-	}
+  if (field_name < DBUS_HEADER_FIELD_LAST)
+    {
+      new_header_fields[field_name].name_offset = -1;
+      new_header_fields[field_name].value_offset = -1;
+    }
+  
+  while (next_offset < _dbus_string_get_length (&message->header))
+    {
+      int copy_name_offset;
+      int copy_value_offset;
 
-      _dbus_string_free (&deleted);
+      if (!iterate_one_field (&message->header,
+                              message->byte_order,
+                              next_offset,
+                              &next_offset,
+                              &field_name,
+                              &copy,
+                              &copy_name_offset,
+                              &copy_value_offset))
+        {
+          _dbus_verbose ("%s: OOM iterating one field\n",
+                         _DBUS_FUNCTION_NAME);
+          goto out_1;
+        }
       
-      message->header_fields[field].name_offset  = -1;
-      message->header_fields[field].value_offset = -1;
+      if (field_name < DBUS_HEADER_FIELD_LAST)
+        {
+          new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete;
+          new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete;
+        }
+    }
 
-      return TRUE;
+  if (!_dbus_string_replace_len (&copy,
+                                 new_fields_front_padding,
+                                 _dbus_string_get_length (&copy) - new_fields_front_padding,
+                                 &message->header,
+                                 name_offset_to_delete,
+                                 _dbus_string_get_length (&message->header) - name_offset_to_delete))
+    {
+      _dbus_verbose ("%s: OOM moving copy back into header\n",
+                     _DBUS_FUNCTION_NAME);
+      goto out_1;
+    }
+  
+  memcpy (message->header_fields, new_header_fields,
+          sizeof (new_header_fields));
+  verify_header_fields (message);
+  
+  retval = TRUE;
+  
+ out_1:
+  _dbus_string_free (&copy);
+  
+ out_0:
+  if (!append_header_padding (message))
+    _dbus_assert_not_reached ("Failed to re-append header padding in re_align_field_recurse()");
+  
+  return retval;
+}
 
-    failed:
-      /* this must succeed because it was allocated on function entry and
-       * DBusString doesn't ever realloc smaller
-       */
-      if (!append_header_padding (message))
-	_dbus_assert_not_reached ("failed to reappend header padding");
+static dbus_bool_t
+delete_field (DBusMessage *message,
+	      int          field,
+              int          prealloc_header_space)
+{
+  int offset;
+
+  _dbus_assert (!message->locked);
 
+  /* Prealloc */
+  if (!_dbus_string_lengthen (&message->header, prealloc_header_space))
+    {
+      _dbus_verbose ("failed to prealloc %d bytes header space\n",
+                     prealloc_header_space);
       return FALSE;
     }
+  _dbus_string_shorten (&message->header, prealloc_header_space);
+
+  /* Delete */
+  offset = message->header_fields[field].name_offset;
+  if (offset < 0)
+    {
+      _dbus_verbose ("header field didn't exist, no need to delete\n");
+      return TRUE; /* field didn't exist */
+    }
+
+  return delete_one_and_re_align (message, offset);
 }
 
 #ifdef DBUS_BUILD_TESTS
@@ -686,78 +841,29 @@
                   int          type,
                   const char  *value)
 {
-  int offset = message->header_fields[field].value_offset;
-
-  _dbus_assert (!message->locked);
-  _dbus_assert (value != NULL);
+  int prealloc;
   
-  if (offset < 0)
-    {      
-      /* need to append the field */
-      return append_string_field (message, field, type, value);
-    }
-  else
-    {
-      DBusString v;
-      char *old_value;
-      int next_field;
-      int next_offset;
-      int len;
-      
-      clear_header_padding (message);
-
-      old_value = _dbus_demarshal_string (&message->header,
-					  message->byte_order,
-					  offset,
-					  &next_offset);
-      if (!old_value)
-	goto failed;
-
-      len = strlen (value);
-
-      _dbus_string_init_const_len (&v, value,
-				   len + 1); /* include nul */
-      if (!_dbus_marshal_set_string (&message->header,
-                                     message->byte_order,
-                                     offset, &v, len))
-	{
-	  dbus_free (old_value);
-	  goto failed;
-	}
-
-      next_field = get_next_field (message, field);
-      if (next_field != DBUS_HEADER_FIELD_INVALID)
-	{
-	  /* re-appends the header padding */
-	  if (!re_align_field_recurse (message, next_field, next_offset))
-	    {
-	      len = strlen (old_value);
-
-	      _dbus_string_init_const_len (&v, old_value,
-                                           len + 1); /* include nul */
-	      if (!_dbus_marshal_set_string (&message->header,
-					     message->byte_order,
-					     offset, &v, len))
-		_dbus_assert_not_reached ("failed to revert to original string");
-
-	      dbus_free (old_value);
-	      goto failed;
-	    }
-	}
+  _dbus_assert (!message->locked);
 
-      dbus_free (old_value);
-      
-      return TRUE;
+  /* the prealloc is so the append_string_field()
+   * below won't fail, leaving us in inconsistent state
+   */
+  prealloc = (value ? strlen (value) : 0) + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
 
-    failed:
-      /* this must succeed because it was allocated on function entry and
-       * DBusString doesn't ever realloc smaller
-       */
-      if (!append_header_padding (message))
-	_dbus_assert_not_reached ("failed to reappend header padding");
+  _dbus_verbose ("set_string_field() field %d prealloc %d\n",
+                 field, prealloc);
+  
+  if (!delete_field (message, field, prealloc))
+    return FALSE;
 
-      return FALSE;
+  if (value != NULL)
+    {
+      /* need to append the field */
+      if (!append_string_field (message, field, type, value))
+        _dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation");
     }
+  
+  return TRUE;
 }
 
 /**
@@ -1522,19 +1628,11 @@
 {
   _dbus_return_val_if_fail (message != NULL, FALSE);
   _dbus_return_val_if_fail (!message->locked, FALSE);
-  
-  if (object_path == NULL)
-    {
-      delete_field (message, DBUS_HEADER_FIELD_PATH);
-      return TRUE;
-    }
-  else
-    {
-      return set_string_field (message,
-                               DBUS_HEADER_FIELD_PATH,
-                               DBUS_TYPE_OBJECT_PATH,
-                               object_path);
-    }
+
+  return set_string_field (message,
+                           DBUS_HEADER_FIELD_PATH,
+                           DBUS_TYPE_OBJECT_PATH,
+                           object_path);
 }
 
 /**
@@ -1596,19 +1694,11 @@
 {
   _dbus_return_val_if_fail (message != NULL, FALSE);
   _dbus_return_val_if_fail (!message->locked, FALSE);
-  
-  if (interface == NULL)
-    {
-      delete_field (message, DBUS_HEADER_FIELD_INTERFACE);
-      return TRUE;
-    }
-  else
-    {
-      return set_string_field (message,
-                               DBUS_HEADER_FIELD_INTERFACE,
-                               DBUS_TYPE_STRING,
-                               interface);
-    }
+
+  return set_string_field (message,
+                           DBUS_HEADER_FIELD_INTERFACE,
+                           DBUS_TYPE_STRING,
+                           interface);
 }
 
 /**
@@ -1644,19 +1734,11 @@
 {
   _dbus_return_val_if_fail (message != NULL, FALSE);
   _dbus_return_val_if_fail (!message->locked, FALSE);
-  
-  if (member == NULL)
-    {
-      delete_field (message, DBUS_HEADER_FIELD_MEMBER);
-      return TRUE;
-    }
-  else
-    {
-      return set_string_field (message,
-                               DBUS_HEADER_FIELD_MEMBER,
-                               DBUS_TYPE_STRING,
-                               member);
-    }
+
+  return set_string_field (message,
+                           DBUS_HEADER_FIELD_MEMBER,
+                           DBUS_TYPE_STRING,
+                           member);
 }
 
 /**
@@ -1691,19 +1773,11 @@
 {
   _dbus_return_val_if_fail (message != NULL, FALSE);
   _dbus_return_val_if_fail (!message->locked, FALSE);
-  
-  if (error_name == NULL)
-    {
-      delete_field (message, DBUS_HEADER_FIELD_ERROR_NAME);
-      return TRUE;
-    }
-  else
-    {
-      return set_string_field (message,
-                               DBUS_HEADER_FIELD_ERROR_NAME,
-                               DBUS_TYPE_STRING,
-                               error_name);
-    }
+
+  return set_string_field (message,
+                           DBUS_HEADER_FIELD_ERROR_NAME,
+                           DBUS_TYPE_STRING,
+                           error_name);
 }
 
 /**
@@ -1735,19 +1809,11 @@
 {
   _dbus_return_val_if_fail (message != NULL, FALSE);
   _dbus_return_val_if_fail (!message->locked, FALSE);
-  
-  if (destination == NULL)
-    {
-      delete_field (message, DBUS_HEADER_FIELD_SERVICE);
-      return TRUE;
-    }
-  else
-    {
-      return set_string_field (message,
-                               DBUS_HEADER_FIELD_SERVICE,
-                               DBUS_TYPE_STRING,
-                               destination);
-    }
+
+  return set_string_field (message,
+                           DBUS_HEADER_FIELD_SERVICE,
+                           DBUS_TYPE_STRING,
+                           destination);
 }
 
 /**
@@ -4314,18 +4380,10 @@
   _dbus_return_val_if_fail (message != NULL, FALSE);
   _dbus_return_val_if_fail (!message->locked, FALSE);
 
-  if (sender == NULL)
-    {
-      delete_field (message, DBUS_HEADER_FIELD_SENDER_SERVICE);
-      return TRUE;
-    }
-  else
-    {
-      return set_string_field (message,
-                               DBUS_HEADER_FIELD_SENDER_SERVICE,
-                               DBUS_TYPE_STRING,
-                               sender);
-    }
+  return set_string_field (message,
+                           DBUS_HEADER_FIELD_SENDER_SERVICE,
+                           DBUS_TYPE_STRING,
+                           sender);
 }
 
 /**
@@ -5182,7 +5240,7 @@
   message = NULL;
   oom = FALSE;
   
-#if 1
+#if 0
   _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
 #endif	  
 
@@ -6673,9 +6731,9 @@
     _dbus_assert_not_reached ("integers differ!");
 
 #ifdef DBUS_HAVE_INT64
-  if (our_int64 != -0x123456789abcd)
+  if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
     _dbus_assert_not_reached ("64-bit integers differ!");
-  if (our_uint64 != 0x123456789abcd)
+  if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
     _dbus_assert_not_reached ("64-bit unsigned integers differ!");
 #endif
   
@@ -6877,7 +6935,6 @@
   dbus_message_set_no_reply (message, FALSE);
   _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
 
-#if 0
   /* Set/get some header fields */
   
   if (!dbus_message_set_path (message, "/foo"))
@@ -6927,7 +6984,6 @@
     _dbus_assert_not_reached ("out of memory");
   _dbus_assert (strcmp (dbus_message_get_member (message),
                         "Bar") == 0);
-#endif
   
   dbus_message_unref (message);
   
@@ -6940,8 +6996,8 @@
   dbus_message_append_args (message,
 			    DBUS_TYPE_INT32, -0x12345678,
 #ifdef DBUS_HAVE_INT64
-                            DBUS_TYPE_INT64, -0x123456789abcd,
-                            DBUS_TYPE_UINT64, 0x123456789abcd,
+                            DBUS_TYPE_INT64, DBUS_INT64_CONSTANT (-0x123456789abcd),
+                            DBUS_TYPE_UINT64, DBUS_UINT64_CONSTANT (0x123456789abcd),
 #endif
 			    DBUS_TYPE_STRING, "Test string",
 			    DBUS_TYPE_DOUBLE, 3.14159,

Index: dbus-string.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- dbus-string.c	21 Oct 2003 05:46:51 -0000	1.43
+++ dbus-string.c	28 Oct 2003 22:53:36 -0000	1.44
@@ -582,7 +582,10 @@
   DBUS_STRING_PREAMBLE (str);
   _dbus_assert (i <= real->len);
   _dbus_assert (i >= 0);
-  _dbus_assert (n_bytes > 0);
+  _dbus_assert (n_bytes >= 0);
+
+  if (n_bytes == 0)
+    return TRUE;
   
   if (!open_gap (n_bytes, real, i))
     return FALSE;