diff options
| author | Havoc Pennington <hp@redhat.com> | 2005-01-23 06:10:07 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2005-01-23 06:10:07 +0000 | 
| commit | 9d21554dd3b560952cd5aa607c4ec07898c0b260 (patch) | |
| tree | 7a4f07715351a9de26bed3f99446b4da3e161ab9 | |
| parent | 487f13451d9f8c50858e9348b1e5f8612433132e (diff) | |
2005-01-23  Havoc Pennington  <hp@redhat.com>
	* dbus/dbus-message-factory.c, dbus/dbus-message-util.c:
	get this all working, not many tests in the framework yet though
| -rw-r--r-- | ChangeLog | 5 | ||||
| -rw-r--r-- | dbus/dbus-marshal-validate.h | 5 | ||||
| -rw-r--r-- | dbus/dbus-message-builder.c | 1283 | ||||
| -rw-r--r-- | dbus/dbus-message-builder.h | 40 | ||||
| -rw-r--r-- | dbus/dbus-message-factory.c | 98 | ||||
| -rw-r--r-- | dbus/dbus-message-factory.h | 1 | ||||
| -rw-r--r-- | dbus/dbus-message-private.h | 2 | ||||
| -rw-r--r-- | dbus/dbus-message-util.c | 205 | ||||
| -rw-r--r-- | dbus/dbus-message.c | 47 | ||||
| -rw-r--r-- | dbus/dbus-test.c | 4 | ||||
| -rw-r--r-- | dbus/dbus-test.h | 18 | ||||
| -rw-r--r-- | test/data/invalid-messages/boolean-array-length-too-long.message-raw | bin | 27 -> 0 bytes | 
12 files changed, 249 insertions, 1459 deletions
@@ -1,3 +1,8 @@ +2005-01-23  Havoc Pennington  <hp@redhat.com> + +	* dbus/dbus-message-factory.c, dbus/dbus-message-util.c:  +	get this all working, not many tests in the framework yet though +  2005-01-22  Havoc Pennington  <hp@redhat.com>  	* doc/dbus-faq.xml, doc/dbus-tutorial: add a FAQ and update diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h index 21d2e9e3..195f46da 100644 --- a/dbus/dbus-marshal-validate.h +++ b/dbus/dbus-marshal-validate.h @@ -49,6 +49,9 @@ typedef enum   */  typedef enum  { +  DBUS_INVALID_FOR_UNKNOWN_REASON = -3, +  DBUS_VALID_BUT_INCOMPLETE = -2, +  DBUS_VALIDITY_UNKNOWN = -1,    DBUS_VALID = 0,    DBUS_INVALID_UNKNOWN_TYPECODE = 1,    DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE = 2, @@ -98,7 +101,7 @@ typedef enum    DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES = 46,    DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL = 47,    DBUS_INVALID_STRING_MISSING_NUL = 48, -  DBUS_INVALID_SIGNATURE_MISSING_NUL = 49, +  DBUS_INVALID_SIGNATURE_MISSING_NUL = 49  } DBusValidity;  DBusValidity _dbus_validate_signature_with_reason (const DBusString *type_str, diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c deleted file mode 100644 index 83b37aff..00000000 --- a/dbus/dbus-message-builder.c +++ /dev/null @@ -1,1283 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-message-builder.c Build messages from text files for testing (internal to D-BUS implementation) - *  - * Copyright (C) 2003, 2004 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - *  - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - *  - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ -#include <config.h> - -#ifdef DBUS_BUILD_TESTS - -#include "dbus-message-builder.h" -#include "dbus-hash.h" -#include "dbus-internals.h" -#include "dbus-marshal.h" - -/** - * @defgroup DBusMessageBuilder code for loading test message data - * @ingroup  DBusInternals - * @brief code for loading up test data for unit tests - * - * The code in here is used for unit testing, it loads - * up message data from a description in a file. - * - * @{ - */ - -/** - * Saved length - */ -typedef struct -{ -  DBusString name; /**< Name of the length */ -  int start;  /**< Calculate length since here */ -  int length; /**< length to write */ -  int offset; /**< where to write it into the data */ -  int endian; /**< endianness to write with */ -} SavedLength; - -static void -free_saved_length (void *data) -{ -  SavedLength *sl = data; - -  if (sl == NULL) -    return; /* all hash free functions have to accept NULL */ -   -  _dbus_string_free (&sl->name); -  dbus_free (sl); -} - -static SavedLength* -ensure_saved_length (DBusHashTable    *hash, -                     const DBusString *name) -{ -  SavedLength *sl; -  const char *s; -   -  s = _dbus_string_get_const_data (name); - -  sl = _dbus_hash_table_lookup_string (hash, s); -  if (sl != NULL) -    return sl; -   -  sl = dbus_new0 (SavedLength, 1); - -  if (!_dbus_string_init (&sl->name)) -    { -      dbus_free (sl); -      return NULL; -    } - -  if (!_dbus_string_copy (name, 0, &sl->name, 0)) -    goto failed; - -  s = _dbus_string_get_const_data (&sl->name); - -  if (!_dbus_hash_table_insert_string (hash, (char*)s, sl)) -    goto failed; - -  sl->start = -1; -  sl->length = -1; -  sl->offset = -1; -  sl->endian = -1; -   -  return sl; -   - failed: -  free_saved_length (sl); -  return NULL; -} - -static dbus_bool_t -save_start (DBusHashTable    *hash, -            const DBusString *name, -            int               start) -{ -  SavedLength *sl; - -  sl = ensure_saved_length (hash, name); - -  if (sl == NULL) -    return FALSE; -  else if (sl->start >= 0) -    { -      _dbus_warn ("Same START_LENGTH given twice\n"); -      return FALSE; -    } -  else -    sl->start = start; - -  return TRUE; -} - -static dbus_bool_t -save_length (DBusHashTable    *hash, -             const DBusString *name, -             int               length) -{ -  SavedLength *sl; - -  sl = ensure_saved_length (hash, name); - -  if (sl == NULL) -    return FALSE; -  else if (sl->length >= 0) -    { -      _dbus_warn ("Same END_LENGTH given twice\n"); -      return FALSE; -    } -  else -    sl->length = length; - -  return TRUE; -} - -static dbus_bool_t -save_offset (DBusHashTable    *hash, -             const DBusString *name, -             int               offset, -             int               endian) -{ -  SavedLength *sl; - -  sl = ensure_saved_length (hash, name); - -  if (sl == NULL) -    return FALSE; -  else if (sl->offset >= 0) -    { -      _dbus_warn ("Same LENGTH given twice\n"); -      return FALSE; -    } -  else -    { -      sl->offset = offset; -      sl->endian = endian; -    } - -  return TRUE; -} - -/** Saves the segment to delete in order to unalign the next item */ -#define SAVE_FOR_UNALIGN(str, boundary)                                 \ -  int align_pad_start = _dbus_string_get_length (str);                  \ -  int align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, (boundary)) - -/** Deletes the alignment padding */ -#define PERFORM_UNALIGN(str)                                    \ -  if (unalign)                                                  \ -    {                                                           \ -      _dbus_string_delete ((str), align_pad_start,              \ -                           align_pad_end - align_pad_start);    \ -      unalign = FALSE;                                          \ -    } - - -static dbus_bool_t -append_quoted_string (DBusString       *dest, -                      const DBusString *quoted, -		      int               start_pos, -		      int              *new_pos) -{ -  dbus_bool_t in_quotes = FALSE; -  int i; - -  /* FIXME: We might want to add escaping in case we want to put ' -   * characters in our strings. -   */ -   -  i = start_pos; -  while (i < _dbus_string_get_length (quoted)) -    { -      unsigned char b; - -      b = _dbus_string_get_byte (quoted, i); -       -      if (in_quotes) -        { -          if (b == '\'') -	    break; -          else -            { -              if (!_dbus_string_append_byte (dest, b)) -                return FALSE; -            } -        } -      else -        { -          if (b == '\'') -            in_quotes = TRUE; -          else if (b == ' ' || b == '\n' || b == '\t') -            break; /* end on whitespace if not quoted */ -          else -            { -              if (!_dbus_string_append_byte (dest, b)) -                return FALSE; -            } -        } -       -      ++i; -    } - -  if (new_pos) -    *new_pos = i; -   -  if (!_dbus_string_append_byte (dest, '\0')) -    return FALSE; -  return TRUE; -} - -static dbus_bool_t -append_saved_length (DBusString       *dest, -                     DBusHashTable    *length_hash, -                     const DBusString *name, -                     int               offset, -                     int               endian) -{ -  if (!save_offset (length_hash, name, -                    offset, endian)) -    { -      _dbus_warn ("failed to save offset to LENGTH\n"); -      return FALSE; -    } -   -  if (!_dbus_marshal_uint32 (dest, endian, -                             -1)) -    { -      _dbus_warn ("failed to append a length\n"); -      return FALSE; -    } - -  return TRUE; -} - -static int -message_type_from_string (const DBusString *str, -                          int               start) -{ -  const char *s; - -  s = _dbus_string_get_const_data_len (str, start, -                                       _dbus_string_get_length (str) - start); - -  if (strncmp (s, "method_call", strlen ("method_call")) == 0) -    return DBUS_MESSAGE_TYPE_METHOD_CALL; -  else if (strncmp (s, "method_return", strlen ("method_return")) == 0) -    return DBUS_MESSAGE_TYPE_METHOD_RETURN; -  else if (strncmp (s, "signal", strlen ("signal")) == 0) -    return DBUS_MESSAGE_TYPE_SIGNAL; -  else if (strncmp (s, "error", strlen ("error")) == 0) -    return DBUS_MESSAGE_TYPE_ERROR; -  else if (strncmp (s, "invalid", strlen ("invalid")) == 0) -    return DBUS_MESSAGE_TYPE_INVALID; -  else -    return -1; -} - -static dbus_bool_t -append_string_field (DBusString *dest, -                     int         endian, -                     int         field, -                     int         type, -                     const char *value) -{ -  int len; -   -  if (!_dbus_string_append_byte (dest, field)) -    { -      _dbus_warn ("couldn't append field name byte\n"); -      return FALSE; -    } -   -  if (!_dbus_string_append_byte (dest, type)) -    { -      _dbus_warn ("could not append typecode byte\n"); -      return FALSE; -    } - -  len = strlen (value); - -  if (!_dbus_marshal_uint32 (dest, endian, len)) -    { -      _dbus_warn ("couldn't append string length\n"); -      return FALSE; -    } -   -  if (!_dbus_string_append (dest, value)) -    { -      _dbus_warn ("couldn't append field value\n"); -      return FALSE; -    } - -  if (!_dbus_string_append_byte (dest, 0)) -    { -      _dbus_warn ("couldn't append string nul term\n"); -      return FALSE; -    } - -  return TRUE; -} - -#ifdef DBUS_BUILD_TESTS -/** - * Parses a basic type defined by type contained in a DBusString. The - * end_return parameter may be #NULL if you aren't interested in it. The - * type is parsed and stored in value_return. Return parameters are not - * initialized if the function returns #FALSE. - * - * @param str the string - * @param type the type of the basic type - * @param start the byte index of the start of the type - * @param value_return return location of the value or #NULL - * @param end_return return location of the end of the type, or #NULL - * @returns #TRUE on success - */ -static dbus_bool_t -_dbus_string_parse_basic_type (const DBusString  *str, -			       char               type, -			       int                start, -			       void              *value, -			       int               *end_return) -{ -  int end = start; - -  switch (type) -    { -    case DBUS_TYPE_BOOLEAN: -      { -	int len = _dbus_string_get_length (str) - start; -	if (len >= 5 && _dbus_string_find_to (str, start, start + 5, "false", NULL)) -	  { -	    end += 5; -	    *(unsigned char *) value = TRUE; -	  } -	else if (len >= 4 && _dbus_string_find_to (str, start, start + 4, "true", NULL)) -	  { -	    end += 4; -	    *(unsigned char *) value = FALSE; -	  } -	else -	  _dbus_warn ("could not parse BOOLEAN\n"); -	break; -      } -    case DBUS_TYPE_BYTE: -      { -	long val = 0; - -	if (_dbus_string_get_byte (str, start) == '\'' && -	    _dbus_string_get_length (str) >= start + 4 && -	    _dbus_string_get_byte (str, start + 1) == '\\' && -	    _dbus_string_get_byte (str, start + 2) == '\'' && -	    _dbus_string_get_byte (str, start + 3) == '\'') -	  { -	    val = '\''; -	    end += 4; -	  } -	else if (_dbus_string_get_byte (str, start) == '\'' && -		 _dbus_string_get_length (str) >= start + 3 && -		 _dbus_string_get_byte (str, start + 2) == '\'') -	  { -	    val = _dbus_string_get_byte (str, start + 1); -	    end += 3; -	  } -	else -	  { -	    if (!_dbus_string_parse_int (str, start, &val, &end))  -	      _dbus_warn ("Failed to parse integer for BYTE\n"); -	  } - -	if (val > 255) -	  _dbus_warn ("A byte must be in range 0-255 not %ld\n", val); - -	*(unsigned char *) value = val; -	break; -      } -    case DBUS_TYPE_INT32: -      { -	long val; -	if (_dbus_string_parse_int (str, start, &val, &end)) -	  *(dbus_int32_t *)value = val; -	break; -      } -    case DBUS_TYPE_UINT32: -      { -	unsigned long val; -	if (_dbus_string_parse_uint (str, start, &val, &end)) -	  *(dbus_uint32_t *)value = val; -	break; -      } -#ifdef DBUS_HAVE_INT64 -    case DBUS_TYPE_INT64: -    case DBUS_TYPE_UINT64:  -      /* use stroll oull */ -      _dbus_assert_not_reached ("string -> [u]int64 not supported yet"); -      break; -#endif /* DBUS_HAVE_INT64 */ -    case DBUS_TYPE_DOUBLE: -      _dbus_string_parse_double (str, start, value, &end); -      break; -    default: -      _dbus_assert_not_reached ("not a basic type"); -      break; -    } -  if (end_return) -    *end_return = end; - -  return end != start; -} -#endif /* DBUS_BUILD_TESTS */ - -static dbus_bool_t -parse_basic_type (DBusString *src, char type, -		  DBusString *dest, dbus_bool_t *unalign, -		  int endian) -{ -  int align; -  int align_pad_start, align_pad_end; -  unsigned char data[16]; - -  switch (type) -    { -    case DBUS_TYPE_BYTE: -      align = 1; -      break; -    case DBUS_TYPE_BOOLEAN: -    case DBUS_TYPE_UINT32: -    case DBUS_TYPE_INT32: -      align = 4; -      break; -    case DBUS_TYPE_DOUBLE: -      align = 8; -      break; -    default: -      _dbus_assert_not_reached ("not a basic type"); -      break; -    } - -  align_pad_start = _dbus_string_get_length (dest); -  align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, align); - -  _dbus_string_delete_first_word (src); - -  if (!_dbus_string_parse_basic_type (src, type, 0, data, NULL)) -    { -      _dbus_verbose ("failed to parse type '%c'", type); -      return FALSE; -    } - -  if (!_dbus_marshal_basic_type (dest, type, data, endian)) -    { -      _dbus_verbose ("failed to marshal type '%c'", type); -      return FALSE; -    } - -  if (*unalign) -    { -      _dbus_string_delete (dest, align_pad_start, -                           align_pad_end - align_pad_start); -      *unalign = FALSE; -    } - -  return TRUE; -} - -static dbus_bool_t -parse_basic_array (DBusString *src, char type, -		   DBusString *dest, dbus_bool_t *unalign, -		   int endian) -{ -  int array_align, elem_size; -  int i, len, allocated; -  unsigned char *values, b; -  int values_offset; -  int align_pad_start, align_pad_end; -  dbus_bool_t retval = FALSE; - -  array_align = 4; /* length */ -  switch (type) -    { -    case DBUS_TYPE_BYTE: -      elem_size = 1; -      break; -    case DBUS_TYPE_BOOLEAN: -    case DBUS_TYPE_UINT32: -    case DBUS_TYPE_INT32: -      elem_size = 4; -      break; -    case DBUS_TYPE_DOUBLE: -      array_align = 8; -      elem_size = 8; -      break; -    default: -      _dbus_assert_not_reached ("not a basic type"); -      break; -    } - -  align_pad_start = _dbus_string_get_length (dest); -  align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, array_align); - -  len = 0; -  allocated = 2; -  values = NULL; -  values_offset = 0; -	   -  _dbus_string_delete_first_word (src); -  _dbus_string_skip_blank (src, 0, &i); -  b = _dbus_string_get_byte (src, i++); - -  if (b != '{') -    goto failed; - -  while (i < _dbus_string_get_length (src)) -    { -      _dbus_string_skip_blank (src, i, &i); - -      if (!values || len == allocated - 1) -	{ -	  allocated *= 2; -	  values = dbus_realloc (values, allocated * elem_size); -	  if (!values) -	    { -	      _dbus_warn ("could not allocate memory for '%c' ARRAY\n", type); -	      goto failed; -	    } -	} - -      if (!_dbus_string_parse_basic_type (src, type, i, values + values_offset, &i)) -	{ -	  _dbus_warn ("could not parse integer element %d of '%c' ARRAY\n", len, type); -	  goto failed; -	} - -      values_offset += elem_size; -      len++; -	       -      _dbus_string_skip_blank (src, i, &i); - -      b = _dbus_string_get_byte (src, i++); - -      if (b == '}') -	break; -      else if (b != ',') -	goto failed; -    } - -  if (!_dbus_marshal_basic_type_array (dest, type, values, len, endian)) -    { -      _dbus_warn ("failed to append '%c' ARRAY\n", type); -      goto failed; -    } - -  if (*unalign) -    { -      _dbus_string_delete (dest, align_pad_start, -                           align_pad_end - align_pad_start); -      *unalign = FALSE; -    } - -  retval = TRUE; - - failed: -  dbus_free (values); -  return retval; -} - -static char -lookup_basic_type (const DBusString *str, dbus_bool_t *is_array) -{ -  int i; -  char type = DBUS_TYPE_INVALID; -  static struct { -    const char *name; -    char        type; -  } name_to_type[] = { -    { "BYTE",    DBUS_TYPE_BYTE }, -    { "BOOLEAN", DBUS_TYPE_BOOLEAN }, -    { "INT32",   DBUS_TYPE_INT32 }, -    { "UINT32",  DBUS_TYPE_UINT32 }, -    { "DOUBLE",  DBUS_TYPE_DOUBLE } -  }; - -  for (i = 0; i < _DBUS_N_ELEMENTS(name_to_type); i++) -    { -      const char *name = name_to_type[i].name; -      if (_dbus_string_starts_with_c_str (str, name))  -	{ -	  int offset = strlen (name); -	  type = name_to_type[i].type; -	  if (is_array) -	    *is_array = _dbus_string_find (str, offset, "_ARRAY", NULL); -	  break; -	} -    } - -  return type; -} - -/** - * Reads the given filename, which should be in "message description - * language" (look at some examples), and builds up the message data - * from it.  The message data may be invalid, or valid. - * - * The parser isn't very strict, it's just a hack for test programs. - *  - * The file format is: - * @code - *   VALID_HEADER <type> normal header; byte order, type, padding, header len, body len, serial - *   REQUIRED_FIELDS add required fields with placeholder values - *   BIG_ENDIAN switch to big endian - *   LITTLE_ENDIAN switch to little endian - *   OPPOSITE_ENDIAN switch to opposite endian - *   ALIGN <N> aligns to the given value - *   UNALIGN skips alignment for the next marshal - *   BYTE <N> inserts the given integer in [0,255] or char in 'a' format - *   START_LENGTH <name> marks the start of a length to measure - *   END_LENGTH <name> records the length since START_LENGTH under the given name - *                     (or if no START_LENGTH, absolute length) - *   LENGTH <name> inserts the saved length of the same name - *   CHOP <N> chops last N bytes off the data - *   HEADER_FIELD <fieldname> inserts a header field name byte - *   TYPE <typename> inserts a typecode byte  - * @endcode - *  - * Following commands insert aligned data unless - * preceded by "UNALIGN": - * @code - *   INT32 <N> marshals an INT32 - *   UINT32 <N> marshals a UINT32 - *   INT64 <N> marshals an INT64 - *   UINT64 <N> marshals a UINT64 - *   DOUBLE <N> marshals a double - *   STRING 'Foo' marshals a string - *   OBJECT_PATH '/foo/bar' marshals an object path - *   BYTE_ARRAY { 'a', 3, 4, 5, 6} marshals a BYTE array - *   BOOLEAN_ARRAY { false, true, false} marshals a BOOLEAN array - *   INT32_ARRAY { 3, 4, 5, 6} marshals an INT32 array - *   UINT32_ARRAY { 3, 4, 5, 6} marshals an UINT32 array - *   DOUBLE_ARRAY { 1.0, 2.0, 3.0, 4.0} marshals a DOUBLE array   - *   STRING_ARRAY { "foo", "bar", "gazonk"} marshals a STRING array   - * @endcode - * - * @todo add support for array types INT32_ARRAY { 3, 4, 5, 6 } - * and so forth. - *  - * @param dest the string to append the message data to - * @param filename the filename to load - * @returns #TRUE on success - */ -dbus_bool_t -_dbus_message_data_load (DBusString       *dest, -                         const DBusString *filename) -{ -  DBusString file; -  DBusError error; -  DBusString line; -  dbus_bool_t retval; -  int line_no; -  dbus_bool_t unalign; -  DBusHashTable *length_hash; -  int endian; -  DBusHashIter iter; -  char type; -  dbus_bool_t is_array; -   -  retval = FALSE; -  length_hash = NULL; -   -  if (!_dbus_string_init (&file)) -    return FALSE; - -  if (!_dbus_string_init (&line)) -    { -      _dbus_string_free (&file); -      return FALSE; -    } - -  _dbus_verbose ("Loading %s\n", _dbus_string_get_const_data (filename)); - -  dbus_error_init (&error); -  if (!_dbus_file_get_contents (&file, filename, &error)) -    { -      _dbus_warn ("Getting contents of %s failed: %s\n", -                  _dbus_string_get_const_data (filename), error.message); -      dbus_error_free (&error); -      goto out; -    } - -  length_hash = _dbus_hash_table_new (DBUS_HASH_STRING, -                                      NULL, -                                      free_saved_length); -  if (length_hash == NULL) -    goto out; -   -  endian = DBUS_COMPILER_BYTE_ORDER; -  unalign = FALSE; -  line_no = 0; - next_iteration: -  while (_dbus_string_pop_line (&file, &line)) -    { -      dbus_bool_t just_set_unalign; - -      just_set_unalign = FALSE; -      line_no += 1; - -      _dbus_string_delete_leading_blanks (&line); - -      if (_dbus_string_get_length (&line) == 0) -        { -          /* empty line */ -          goto next_iteration; -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "#")) -        { -          /* Ignore this comment */ -          goto next_iteration; -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "VALID_HEADER")) -        { -          int i; -          DBusString name; -          int message_type; - -          if (_dbus_string_get_length (&line) < (int) strlen ("VALID_HEADER ")) -            { -              _dbus_warn ("no args to VALID_HEADER\n"); -              goto parse_failed; -            } -           -          if (!_dbus_string_append_byte (dest, endian)) -            { -              _dbus_warn ("could not append endianness\n"); -              goto parse_failed; -            } - -          message_type = message_type_from_string (&line, -                                                   strlen ("VALID_HEADER ")); -          if (message_type < 0) -            { -              _dbus_warn ("VALID_HEADER not followed by space then known message type\n"); -              goto parse_failed; -            } -           -          if (!_dbus_string_append_byte (dest, message_type)) -            { -              _dbus_warn ("could not append message type\n"); -              goto parse_failed; -            } -           -          i = 0; -          while (i < 2) -            { -              if (!_dbus_string_append_byte (dest, '\0')) -                { -                  _dbus_warn ("could not append nul pad\n"); -                  goto parse_failed; -                } -              ++i; -            } - -          _dbus_string_init_const (&name, "Header"); -          if (!append_saved_length (dest, length_hash, -                                    &name, _dbus_string_get_length (dest), -                                    endian)) -            goto parse_failed; - -          _dbus_string_init_const (&name, "Body"); -          if (!append_saved_length (dest, length_hash, -                                    &name, _dbus_string_get_length (dest), -                                    endian)) -            goto parse_failed; -           -          /* client serial */ -          if (!_dbus_marshal_uint32 (dest, endian, 1)) -            { -              _dbus_warn ("couldn't append client serial\n"); -              goto parse_failed; -            } -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "REQUIRED_FIELDS")) -        { -          if (!append_string_field (dest, endian, -                                    DBUS_HEADER_FIELD_INTERFACE, -                                    DBUS_TYPE_STRING, -                                    "org.freedesktop.BlahBlahInterface")) -            goto parse_failed; -          if (!append_string_field (dest, endian, -                                    DBUS_HEADER_FIELD_MEMBER, -                                    DBUS_TYPE_STRING, -                                    "BlahBlahMethod")) -            goto parse_failed; -          if (!append_string_field (dest, endian, -                                    DBUS_HEADER_FIELD_PATH, -                                    DBUS_TYPE_OBJECT_PATH, -                                    "/blah/blah/path")) -            goto parse_failed; - -          /* FIXME later we'll validate this, and then it will break -           * and the .message files will have to include the right thing -           */ -          if (!append_string_field (dest, endian, -                                    DBUS_HEADER_FIELD_SIGNATURE, -                                    DBUS_TYPE_STRING, -                                    "iii")) -            goto parse_failed; -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "BIG_ENDIAN")) -        { -          endian = DBUS_BIG_ENDIAN; -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "LITTLE_ENDIAN")) -        { -          endian = DBUS_LITTLE_ENDIAN; -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "OPPOSITE_ENDIAN")) -        { -          if (endian == DBUS_BIG_ENDIAN) -            endian = DBUS_LITTLE_ENDIAN; -          else -            endian = DBUS_BIG_ENDIAN; -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "ALIGN")) -        { -          long val; -          int end; -          int orig_len; -           -          _dbus_string_delete_first_word (&line); - -          if (!_dbus_string_parse_int (&line, 0, &val, &end)) -            { -              _dbus_warn ("Failed to parse integer\n"); -              goto parse_failed; -            } - -          if (val > 8) -            { -              _dbus_warn ("Aligning to %ld boundary is crack\n", -                          val); -              goto parse_failed; -            } - -          orig_len = _dbus_string_get_length (dest); -           -          if (!_dbus_string_align_length (dest, val)) -            goto parse_failed; - -          if (_dbus_string_parse_int (&line, end, &val, NULL)) -            { -              /* If there's an optional second int argument, -               * fill in align padding with that value -               */ -              if (val < 0 || val > 255) -                { -                  _dbus_warn ("can't fill align padding with %ld, must be a byte value\n", val); -                  goto parse_failed; -                } - -              end = orig_len; -              while (end < _dbus_string_get_length (dest)) -                { -                  _dbus_string_set_byte (dest, end, val); -                  ++end; -                } -            } -        } -      else if (_dbus_string_starts_with_c_str (&line, "UNALIGN")) -        { -          unalign = TRUE; -          just_set_unalign = TRUE; -        } -      else if (_dbus_string_starts_with_c_str (&line, "CHOP")) -        { -          long val; - -          /* FIXME if you CHOP the offset for a LENGTH -           * command, we segfault. -           */ -           -          _dbus_string_delete_first_word (&line); - -          if (!_dbus_string_parse_int (&line, 0, &val, NULL)) -            { -              _dbus_warn ("Failed to parse integer to chop\n"); -              goto parse_failed; -            } - -          if (val > _dbus_string_get_length (dest)) -            { -              _dbus_warn ("Trying to chop %ld bytes but we only have %d\n", -                          val, -                          _dbus_string_get_length (dest)); -              goto parse_failed; -            } -           -          _dbus_string_shorten (dest, val); -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "START_LENGTH")) -        { -          _dbus_string_delete_first_word (&line); - -          if (!save_start (length_hash, &line, -                           _dbus_string_get_length (dest))) -            { -              _dbus_warn ("failed to save length start\n"); -              goto parse_failed; -            } -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "END_LENGTH")) -        { -          _dbus_string_delete_first_word (&line); - -          if (!save_length (length_hash, &line, -                            _dbus_string_get_length (dest))) -            { -              _dbus_warn ("failed to save length end\n"); -              goto parse_failed; -            } -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "LENGTH")) -        { -          SAVE_FOR_UNALIGN (dest, 4); -           -          _dbus_string_delete_first_word (&line); - -          if (!append_saved_length (dest, length_hash, -                                    &line, -                                    unalign ? align_pad_start : align_pad_end, -                                    endian)) -            { -              _dbus_warn ("failed to add LENGTH\n"); -              goto parse_failed; -            } - -          PERFORM_UNALIGN (dest); -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "HEADER_FIELD")) -        { -	  int field; - -          _dbus_string_delete_first_word (&line); - -          if (_dbus_string_starts_with_c_str (&line, "INVALID")) -            field = DBUS_HEADER_FIELD_INVALID; -          else if (_dbus_string_starts_with_c_str (&line, "PATH")) -	    field = DBUS_HEADER_FIELD_PATH; -          else if (_dbus_string_starts_with_c_str (&line, "INTERFACE")) -	    field = DBUS_HEADER_FIELD_INTERFACE; -          else if (_dbus_string_starts_with_c_str (&line, "MEMBER")) -	    field = DBUS_HEADER_FIELD_MEMBER; -          else if (_dbus_string_starts_with_c_str (&line, "ERROR_NAME")) -	    field = DBUS_HEADER_FIELD_ERROR_NAME; -          else if (_dbus_string_starts_with_c_str (&line, "REPLY_SERIAL")) -	    field = DBUS_HEADER_FIELD_REPLY_SERIAL; -          else if (_dbus_string_starts_with_c_str (&line, "DESTINATION")) -	    field = DBUS_HEADER_FIELD_DESTINATION; -          else if (_dbus_string_starts_with_c_str (&line, "SENDER")) -	    field = DBUS_HEADER_FIELD_SENDER; -          else if (_dbus_string_starts_with_c_str (&line, "SIGNATURE")) -	    field = DBUS_HEADER_FIELD_SIGNATURE; -	  else if (_dbus_string_starts_with_c_str (&line, "UNKNOWN")) -	    field = 22; /* random unknown header field */ -          else -            { -              _dbus_warn ("%s is not a valid header field name\n", -			  _dbus_string_get_const_data (&line)); -              goto parse_failed; -            } - -          if (!_dbus_string_append_byte (dest, field)) -	    { -              _dbus_warn ("could not append header field name byte\n"); -	      goto parse_failed; -	    } -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                               "TYPE")) -        { -          int code; -           -          _dbus_string_delete_first_word (&line);           - -          if (_dbus_string_starts_with_c_str (&line, "INVALID")) -            code = DBUS_TYPE_INVALID; -          else if (_dbus_string_starts_with_c_str (&line, "NIL")) -            code = DBUS_TYPE_NIL; -	  else if ((code = lookup_basic_type (&line, NULL)) != DBUS_TYPE_INVALID) -	    ; -          else if (_dbus_string_starts_with_c_str (&line, "STRING")) -            code = DBUS_TYPE_STRING; -          else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH")) -            code = DBUS_TYPE_OBJECT_PATH; -          else if (_dbus_string_starts_with_c_str (&line, "CUSTOM")) -            code = DBUS_TYPE_CUSTOM; -          else if (_dbus_string_starts_with_c_str (&line, "ARRAY")) -            code = DBUS_TYPE_ARRAY; -          else if (_dbus_string_starts_with_c_str (&line, "DICT")) -            code = DBUS_TYPE_DICT; -          else -            { -              _dbus_warn ("%s is not a valid type name\n", _dbus_string_get_const_data (&line)); -              goto parse_failed; -            } - -          if (!_dbus_string_append_byte (dest, code)) -            { -              _dbus_warn ("could not append typecode byte\n"); -              goto parse_failed; -            } -        } -      else if (_dbus_string_starts_with_c_str (&line, -					       "STRING_ARRAY")) -	{ -	  SAVE_FOR_UNALIGN (dest, 4); -	  int i, len, allocated; -	  char **values; -	  char *val; -	  DBusString val_str; -	  unsigned char b; - -	  allocated = 4; -	  values = dbus_new (char *, allocated); -	  if (!values) -	    { -	      _dbus_warn ("could not allocate memory for STRING_ARRAY\n"); -	      goto parse_failed; -	    } -	   -	  len = 0; -	   -	  _dbus_string_delete_first_word (&line); -	  _dbus_string_skip_blank (&line, 0, &i); -	  b = _dbus_string_get_byte (&line, i++); - -	  if (b != '{') -	    goto parse_failed; - -	  _dbus_string_init (&val_str); -	  while (i < _dbus_string_get_length (&line)) -	    { -	      _dbus_string_skip_blank (&line, i, &i); - -	      if (!append_quoted_string (&val_str, &line, i, &i)) -		{ -		  _dbus_warn ("could not parse quoted string for STRING_ARRAY\n"); -		  goto parse_failed; -		} -	      i++; - -	      if (!_dbus_string_steal_data (&val_str, &val)) -		{ -		  _dbus_warn ("could not allocate memory for STRING_ARRAY string\n"); -		  goto parse_failed; -		} -	       -	      values[len++] = val; -	      if (len == allocated) -		{ -		  allocated *= 2; -		  values = dbus_realloc (values, allocated * sizeof (char *)); -		  if (!values) -		    { -		      _dbus_warn ("could not allocate memory for STRING_ARRAY\n"); -		      goto parse_failed; -		    } -		} -	       -	      _dbus_string_skip_blank (&line, i, &i); -	       -	      b = _dbus_string_get_byte (&line, i++); - -	      if (b == '}') -		break; -	      else if (b != ',') -		{ -		  _dbus_warn ("missing comma when parsing STRING_ARRAY\n"); -		  goto parse_failed; -		} -	    } -	  _dbus_string_free (&val_str); -	   -          if (!_dbus_marshal_string_array (dest, endian, (const char **)values, len)) -            { -              _dbus_warn ("failed to append STRING_ARRAY\n"); -              goto parse_failed; -            } - -	  values[len] = NULL; -	  dbus_free_string_array (values); -	   -	  PERFORM_UNALIGN (dest); -	} -      else if (_dbus_string_starts_with_c_str (&line, -                                               "STRING")) -        { -          SAVE_FOR_UNALIGN (dest, 4); -          int size_offset; -          int old_len; -           -          _dbus_string_delete_first_word (&line); - -          size_offset = _dbus_string_get_length (dest); -          size_offset = _DBUS_ALIGN_VALUE (size_offset, 4); -          if (!_dbus_marshal_uint32 (dest, endian, 0)) -            { -              _dbus_warn ("Failed to append string size\n"); -              goto parse_failed; -            } - -          old_len = _dbus_string_get_length (dest); -          if (!append_quoted_string (dest, &line, 0, NULL)) -            { -              _dbus_warn ("Failed to append quoted string\n"); -              goto parse_failed; -            } - -          _dbus_marshal_set_uint32 (dest, size_offset, -                                    /* subtract 1 for nul */ -                                    _dbus_string_get_length (dest) - old_len - 1, -                                    endian); -           -          PERFORM_UNALIGN (dest); -        } -      else if ((type = lookup_basic_type (&line, &is_array)) != DBUS_TYPE_INVALID) -	{ -	  if (is_array) -	    { -	      if (!parse_basic_array (&line, type, dest, &unalign, endian)) -		goto parse_failed; -	    } -	  else -	    { -	      if (!parse_basic_type (&line, type, dest, &unalign, endian)) -		goto parse_failed; -	    } -        } -      else if (_dbus_string_starts_with_c_str (&line, -                                              "OBJECT_PATH")) -        { -          SAVE_FOR_UNALIGN (dest, 4); -          int size_offset; -          int old_len; -           -          _dbus_string_delete_first_word (&line); -           -          size_offset = _dbus_string_get_length (dest); -          size_offset = _DBUS_ALIGN_VALUE (size_offset, 4); -          if (!_dbus_marshal_uint32 (dest, endian, 0)) -            { -              _dbus_warn ("Failed to append string size\n"); -              goto parse_failed; -            } - -          old_len = _dbus_string_get_length (dest); -          if (!append_quoted_string (dest, &line, 0, NULL)) -            { -              _dbus_warn ("Failed to append quoted string\n"); -              goto parse_failed; -            } - -          _dbus_marshal_set_uint32 (dest, size_offset, -                                    /* subtract 1 for nul */ -                                    _dbus_string_get_length (dest) - old_len - 1, -                                    endian); -           -          PERFORM_UNALIGN (dest); -        }       -      else -        goto parse_failed; -       -      if (!just_set_unalign && unalign) -        { -          _dbus_warn ("UNALIGN prior to something that isn't aligned\n"); -          goto parse_failed; -        } - -      goto next_iteration; /* skip parse_failed */ -       -    parse_failed: -      { -        _dbus_warn ("couldn't process line %d \"%s\"\n", -                    line_no, _dbus_string_get_const_data (&line)); -        goto out; -      } -    } - -  _dbus_hash_iter_init (length_hash, &iter); -  while (_dbus_hash_iter_next (&iter)) -    { -      SavedLength *sl = _dbus_hash_iter_get_value (&iter); -      const char *s; - -      s = _dbus_string_get_const_data (&sl->name); -       -      if (sl->length < 0) -        { -          _dbus_warn ("Used LENGTH %s but never did END_LENGTH\n", -                      s); -          goto out; -        } -      else if (sl->offset < 0) -        { -          _dbus_warn ("Did END_LENGTH %s but never used LENGTH\n", -                      s); -          goto out; -        } -      else -        { -          if (sl->start < 0) -            sl->start = 0; -           -          _dbus_verbose ("Filling in length %s endian = %d offset = %d start = %d length = %d\n", -                         s, sl->endian, sl->offset, sl->start, sl->length); -          _dbus_marshal_set_int32 (dest, -                                   sl->endian, -                                   sl->offset, -                                   sl->length - sl->start); -        } - -      _dbus_hash_iter_remove_entry (&iter); -    } -   -  retval = TRUE; - -  _dbus_verbose_bytes_of_string (dest, 0, _dbus_string_get_length (dest)); -   - out: -  if (length_hash != NULL) -    _dbus_hash_table_unref (length_hash); -   -  _dbus_string_free (&file); -  _dbus_string_free (&line); -  return retval; -} - -/** @} */ -#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-message-builder.h b/dbus/dbus-message-builder.h deleted file mode 100644 index cb2c594a..00000000 --- a/dbus/dbus-message-builder.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-message-builder.h Build messages from text files for testing (internal to D-BUS implementation) - *  - * Copyright (C) 2003 Red Hat, Inc. - * - * Licensed under the Academic Free License version 2.1 - *  - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - *  - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA - * - */ - -#ifndef DBUS_MESSAGE_BUILDER_H -#define DBUS_MESSAGE_BUILDER_H - -#include <config.h> - -#include <dbus/dbus-memory.h> -#include <dbus/dbus-types.h> -#include <dbus/dbus-string.h> - -DBUS_BEGIN_DECLS - -dbus_bool_t _dbus_message_data_load (DBusString       *dest, -                                     const DBusString *filename); - -DBUS_END_DECLS - -#endif /* DBUS_MESSAGE_BUILDER_H */ diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c index 41d40137..d4b89565 100644 --- a/dbus/dbus-message-factory.c +++ b/dbus/dbus-message-factory.c @@ -20,14 +20,17 @@   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   *   */ +#include <config.h>  #ifdef DBUS_BUILD_TESTS -  #include "dbus-message-factory.h"  #include "dbus-message-private.h" -typedef dbus_bool_t (* DBusMessageGeneratorFunc) (int           sequence, +typedef dbus_bool_t (* DBusInnerGeneratorFunc)   (int           sequence,                                                    DBusMessage **message_p); +typedef dbus_bool_t (* DBusMessageGeneratorFunc) (int           sequence, +                                                  DBusString   *data, +                                                  DBusValidity *expected_validity);  static void  set_reply_serial (DBusMessage *message) @@ -39,8 +42,8 @@ set_reply_serial (DBusMessage *message)  }  static dbus_bool_t -generate_trivial (int           sequence, -                  DBusMessage **message_p) +generate_trivial_inner (int           sequence, +                        DBusMessage **message_p)  {    DBusMessage *message; @@ -63,6 +66,22 @@ generate_trivial (int           sequence,        break;      case 3:        message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); + +      if (!dbus_message_set_error_name (message, +                                        "org.freedesktop.TestErrorName")) +        _dbus_assert_not_reached ("oom"); +       +      { +        DBusMessageIter iter; +        const char *v_STRING = "This is an error"; +         +        dbus_message_iter_init_append (message, &iter); +        if (!dbus_message_iter_append_basic (&iter, +                                             DBUS_TYPE_STRING, +                                             &v_STRING)) +          _dbus_assert_not_reached ("oom"); +      } +              set_reply_serial (message);        break;      default: @@ -77,6 +96,48 @@ generate_trivial (int           sequence,    return TRUE;  } +static dbus_bool_t +generate_outer (int                    sequence, +                DBusString            *data, +                DBusValidity          *expected_validity, +                DBusInnerGeneratorFunc func) +{ +  DBusMessage *message; + +  message = NULL; +  if (!(*func)(sequence, &message)) +    return FALSE; + +  _dbus_assert (message != NULL); + +  _dbus_message_set_serial (message, 1); +  _dbus_message_lock (message); +   +  *expected_validity = DBUS_VALID; + +  /* move for efficiency, since we'll nuke the message anyway */ +  if (!_dbus_string_move (&message->header.data, 0, +                          data, 0)) +    _dbus_assert_not_reached ("oom"); + +  if (!_dbus_string_copy (&message->body, 0, +                          data, _dbus_string_get_length (data))) +    _dbus_assert_not_reached ("oom"); + +  dbus_message_unref (message); + +  return TRUE; +} + +static dbus_bool_t +generate_trivial (int                    sequence, +                  DBusString            *data, +                  DBusValidity          *expected_validity) +{ +  return generate_outer (sequence, data, expected_validity, +                         generate_trivial_inner); +} +  static const DBusMessageGeneratorFunc generators[] = {    generate_trivial  }; @@ -99,36 +160,25 @@ _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,                                        DBusMessageData     *data)  {    DBusMessageGeneratorFunc func; -  DBusMessage *message; -   + + restart:    if (iter->generator == _DBUS_N_ELEMENTS (generators))      return FALSE; - +      func = generators[iter->generator]; -  if ((*func)(iter->sequence, &message)) +  if (!_dbus_string_init (&data->data)) +    _dbus_assert_not_reached ("oom"); +   +  if ((*func)(iter->sequence, &data->data, &data->expected_validity))      iter->sequence += 1;    else      {        iter->generator += 1;        iter->sequence = 0; +      _dbus_string_free (&data->data); +      goto restart;      } - -  _dbus_assert (message != NULL); - -  if (!_dbus_string_init (&data->data)) -    _dbus_assert_not_reached ("oom"); - -  /* move for efficiency, since we'll nuke the message anyway */ -  if (!_dbus_string_move (&message->header.data, 0, -                          &data->data, 0)) -    _dbus_assert_not_reached ("oom"); - -  if (!_dbus_string_copy (&message->body, 0, -                          &data->data, _dbus_string_get_length (&data->data))) -    _dbus_assert_not_reached ("oom"); - -  dbus_message_unref (message);    return TRUE;  } diff --git a/dbus/dbus-message-factory.h b/dbus/dbus-message-factory.h index 28a169b9..fb97ab84 100644 --- a/dbus/dbus-message-factory.h +++ b/dbus/dbus-message-factory.h @@ -34,7 +34,6 @@ DBUS_BEGIN_DECLS  typedef struct  { -  dbus_bool_t  validity_known;    DBusValidity expected_validity;    DBusString data; diff --git a/dbus/dbus-message-private.h b/dbus/dbus-message-private.h index 60b0daea..5f727ae1 100644 --- a/dbus/dbus-message-private.h +++ b/dbus/dbus-message-private.h @@ -70,6 +70,8 @@ struct DBusMessageLoader    unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */    unsigned int corrupted : 1; /**< We got broken data, and are no longer working */ + +  DBusValidity corruption_reason; /**< why we were corrupted */  }; diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index 2d90cc83..5d503a98 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -78,6 +78,19 @@ dbus_message_iter_get_args (DBusMessageIter *iter,  #include <stdio.h>  #include <stdlib.h> +static void +check_memleaks (void) +{ +  dbus_shutdown (); + +  if (_dbus_get_malloc_blocks_outstanding () != 0) +    { +      _dbus_warn ("%d dbus_malloc blocks were not freed in %s\n", +                  _dbus_get_malloc_blocks_outstanding (), __FILE__); +      _dbus_assert_not_reached ("memleaks"); +    } +} +  static dbus_bool_t  check_have_valid_message (DBusMessageLoader *loader)  { @@ -87,12 +100,10 @@ check_have_valid_message (DBusMessageLoader *loader)    message = NULL;    retval = FALSE; -  if (!_dbus_message_loader_queue_messages (loader)) -    _dbus_assert_not_reached ("no memory to queue messages"); -    if (_dbus_message_loader_get_is_corrupted (loader))      { -      _dbus_warn ("loader corrupted on message that was expected to be valid\n"); +      _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d\n", +                  loader->corruption_reason);        goto failed;      } @@ -129,21 +140,27 @@ check_have_valid_message (DBusMessageLoader *loader)  }  static dbus_bool_t -check_invalid_message (DBusMessageLoader *loader) +check_invalid_message (DBusMessageLoader *loader, +                       DBusValidity       expected_validity)  {    dbus_bool_t retval;    retval = FALSE; -  if (!_dbus_message_loader_queue_messages (loader)) -    _dbus_assert_not_reached ("no memory to queue messages"); -    if (!_dbus_message_loader_get_is_corrupted (loader))      {        _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");        goto failed;      } +  if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON && +      loader->corruption_reason != expected_validity) +    { +      _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead\n", +                  expected_validity, loader->corruption_reason); +      goto failed; +    } +    retval = TRUE;   failed: @@ -159,12 +176,10 @@ check_incomplete_message (DBusMessageLoader *loader)    message = NULL;    retval = FALSE; -  if (!_dbus_message_loader_queue_messages (loader)) -    _dbus_assert_not_reached ("no memory to queue messages"); -    if (_dbus_message_loader_get_is_corrupted (loader))      { -      _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n"); +      _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d\n", +                  loader->corruption_reason);        goto failed;      } @@ -185,70 +200,51 @@ check_incomplete_message (DBusMessageLoader *loader)  static dbus_bool_t  check_loader_results (DBusMessageLoader      *loader, -                      DBusMessageValidity     validity) +                      DBusValidity            expected_validity)  {    if (!_dbus_message_loader_queue_messages (loader))      _dbus_assert_not_reached ("no memory to queue messages"); -  switch (validity) +  if (expected_validity == DBUS_VALID) +    return check_have_valid_message (loader); +  else if (expected_validity == DBUS_VALID_BUT_INCOMPLETE) +    return check_incomplete_message (loader); +  else if (expected_validity == DBUS_VALIDITY_UNKNOWN)      { -    case _DBUS_MESSAGE_VALID: -      return check_have_valid_message (loader); -    case _DBUS_MESSAGE_INVALID: -      return check_invalid_message (loader); -    case _DBUS_MESSAGE_INCOMPLETE: -      return check_incomplete_message (loader); -    case _DBUS_MESSAGE_UNKNOWN: +      /* here we just know we didn't segfault and that was the +       * only test +       */        return TRUE;      } - -  _dbus_assert_not_reached ("bad DBusMessageValidity"); -  return FALSE; +  else +    return check_invalid_message (loader, expected_validity);  } -  /**   * Loads the message in the given message file.   *   * @param filename filename to load - * @param is_raw if #TRUE load as binary data, if #FALSE as message builder language   * @param data string to load message into   * @returns #TRUE if the message was loaded   */  dbus_bool_t  dbus_internal_do_not_use_load_message_file (const DBusString    *filename, -                                            dbus_bool_t          is_raw,                                              DBusString          *data)  {    dbus_bool_t retval; - +  DBusError error; +      retval = FALSE; -  if (is_raw) -    { -      DBusError error; - -      _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename)); -      dbus_error_init (&error); -      if (!_dbus_file_get_contents (data, filename, &error)) -        { -          _dbus_warn ("Could not load message file %s: %s\n", -                      _dbus_string_get_const_data (filename), -                      error.message); -          dbus_error_free (&error); -          goto failed; -        } -    } -  else +  _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename)); +  dbus_error_init (&error); +  if (!_dbus_file_get_contents (data, filename, &error))      { -      if (FALSE) /* Message builder disabled, probably permanently, -                  * I want to do it another way -                  */ -        { -          _dbus_warn ("Could not load message file %s\n", -                      _dbus_string_get_const_data (filename)); -          goto failed; -        } +      _dbus_warn ("Could not load message file %s: %s\n", +                  _dbus_string_get_const_data (filename), +                  error.message); +      dbus_error_free (&error); +      goto failed;      }    retval = TRUE; @@ -263,14 +259,12 @@ dbus_internal_do_not_use_load_message_file (const DBusString    *filename,   * and verifies that DBusMessageLoader can handle it.   *   * @param filename filename to load - * @param is_raw if #TRUE load as binary data, if #FALSE as message builder language   * @param expected_validity what the message has to be like to return #TRUE   * @returns #TRUE if the message has the expected validity   */  dbus_bool_t  dbus_internal_do_not_use_try_message_file (const DBusString    *filename, -                                           dbus_bool_t          is_raw, -                                           DBusMessageValidity  expected_validity) +                                           DBusValidity         expected_validity)  {    DBusString data;    dbus_bool_t retval; @@ -280,8 +274,7 @@ dbus_internal_do_not_use_try_message_file (const DBusString    *filename,    if (!_dbus_string_init (&data))      _dbus_assert_not_reached ("could not allocate string\n"); -  if (!dbus_internal_do_not_use_load_message_file (filename, is_raw, -                                                   &data)) +  if (!dbus_internal_do_not_use_load_message_file (filename, &data))      goto failed;    retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity); @@ -313,7 +306,7 @@ dbus_internal_do_not_use_try_message_file (const DBusString    *filename,   */  dbus_bool_t  dbus_internal_do_not_use_try_message_data (const DBusString    *data, -                                           DBusMessageValidity  expected_validity) +                                           DBusValidity         expected_validity)  {    DBusMessageLoader *loader;    dbus_bool_t retval; @@ -405,7 +398,7 @@ dbus_internal_do_not_use_try_message_data (const DBusString    *data,  static dbus_bool_t  process_test_subdir (const DBusString          *test_base_dir,                       const char                *subdir, -                     DBusMessageValidity        validity, +                     DBusValidity               expected_validity,                       DBusForeachMessageFileFunc function,                       void                      *user_data)  { @@ -451,7 +444,6 @@ process_test_subdir (const DBusString          *test_base_dir,    while (_dbus_directory_get_next_file (dir, &filename, &error))      {        DBusString full_path; -      dbus_bool_t is_raw;        if (!_dbus_string_init (&full_path))          _dbus_assert_not_reached ("couldn't init string"); @@ -462,12 +454,16 @@ process_test_subdir (const DBusString          *test_base_dir,        if (!_dbus_concat_dir_and_file (&full_path, &filename))          _dbus_assert_not_reached ("couldn't concat file to dir"); -      if (_dbus_string_ends_with_c_str (&filename, ".message")) -        is_raw = FALSE; -      else if (_dbus_string_ends_with_c_str (&filename, ".message-raw")) -        is_raw = TRUE; +      if (_dbus_string_ends_with_c_str (&filename, ".message-raw")) +        ;        else          { +          if (_dbus_string_ends_with_c_str (&filename, ".message")) +            { +              _dbus_warn ("Could not load %s, message builder language no longer supported\n", +                          _dbus_string_get_const_data (&filename)); +            } +                      _dbus_verbose ("Skipping non-.message file %s\n",                           _dbus_string_get_const_data (&filename));  	  _dbus_string_free (&full_path); @@ -477,13 +473,8 @@ process_test_subdir (const DBusString          *test_base_dir,        printf ("    %s\n",                _dbus_string_get_const_data (&filename)); -      _dbus_verbose (" expecting %s for %s\n", -                     validity == _DBUS_MESSAGE_VALID ? "valid" : -                     (validity == _DBUS_MESSAGE_INVALID ? "invalid" : -                      (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")), -                     _dbus_string_get_const_data (&filename)); - -      if (! (*function) (&full_path, is_raw, validity, user_data)) +      if (! (*function) (&full_path, +                         expected_validity, user_data))          {            _dbus_string_free (&full_path);            goto failed; @@ -533,21 +524,27 @@ dbus_internal_do_not_use_foreach_message_file (const char                *test_d    retval = FALSE;    _dbus_string_init_const (&test_directory, test_data_dir); - +      if (!process_test_subdir (&test_directory, "valid-messages", -                            _DBUS_MESSAGE_VALID, func, user_data)) +                            DBUS_VALID, func, user_data))      goto failed; +  check_memleaks (); +      if (!process_test_subdir (&test_directory, "invalid-messages", -                            _DBUS_MESSAGE_INVALID, func, user_data)) +                            DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data))      goto failed; +  check_memleaks (); +      if (!process_test_subdir (&test_directory, "incomplete-messages", -                            _DBUS_MESSAGE_INCOMPLETE, func, user_data)) +                            DBUS_VALID_BUT_INCOMPLETE, func, user_data))      goto failed; +  check_memleaks (); +      retval = TRUE; - +     failed:    _dbus_string_free (&test_directory); @@ -660,11 +657,12 @@ verify_test_message (DBusMessage *message)    DBusMessageIter iter;    DBusError error;    dbus_int32_t our_int; +  dbus_uint32_t our_uint;    const char *our_str;    double our_double; +  double v_DOUBLE;    dbus_bool_t our_bool;    unsigned char our_byte_1, our_byte_2; -  dbus_uint32_t our_uint32;    const dbus_int32_t *our_uint32_array = (void*)0xdeadbeef;    int our_uint32_array_len;    dbus_int32_t *our_int32_array = (void*)0xdeadbeef; @@ -689,6 +687,7 @@ verify_test_message (DBusMessage *message)    dbus_error_init (&error);    if (!dbus_message_iter_get_args (&iter, &error,  				   DBUS_TYPE_INT32, &our_int, +                                   DBUS_TYPE_UINT32, &our_uint,  #ifdef DBUS_HAVE_INT64                                     DBUS_TYPE_INT64, &our_int64,                                     DBUS_TYPE_UINT64, &our_uint64, @@ -724,6 +723,9 @@ verify_test_message (DBusMessage *message)    if (our_int != -0x12345678)      _dbus_assert_not_reached ("integers differ!"); +  if (our_uint != 0x12300042) +    _dbus_assert_not_reached ("uints differ!"); +  #ifdef DBUS_HAVE_INT64    if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))      _dbus_assert_not_reached ("64-bit integers differ!"); @@ -731,7 +733,8 @@ verify_test_message (DBusMessage *message)      _dbus_assert_not_reached ("64-bit unsigned integers differ!");  #endif -  if (our_double != 3.14159) +  v_DOUBLE = 3.14159; +  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE))      _dbus_assert_not_reached ("doubles differ!");    if (strcmp (our_str, "Test string") != 0) @@ -782,9 +785,14 @@ verify_test_message (DBusMessage *message)    /* On all IEEE machines (i.e. everything sane) exact equality     * should be preserved over the wire     */ -  if (our_double_array[0] != 0.1234 || -      our_double_array[1] != 9876.54321 || -      our_double_array[2] != -300.0) +  v_DOUBLE = 0.1234; +  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE)) +    _dbus_assert_not_reached ("double array had wrong values"); +  v_DOUBLE = 9876.54321; +  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE)) +    _dbus_assert_not_reached ("double array had wrong values"); +  v_DOUBLE = -300.0; +  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE))      _dbus_assert_not_reached ("double array had wrong values");    if (our_byte_array_len != 4) @@ -821,7 +829,6 @@ _dbus_message_test (const char *test_data_dir)  {    DBusMessage *message;    DBusMessageLoader *loader; -  DBusMessageIter iter, child_iter, child_iter2, child_iter3;    int i;    const char *data;    DBusMessage *copy; @@ -851,8 +858,6 @@ _dbus_message_test (const char *test_data_dir)    const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array;    char sig[64];    const char *s; -  char *t; -  DBusError error;    const char *v_STRING;    double v_DOUBLE;    dbus_int32_t v_INT32; @@ -967,8 +972,10 @@ _dbus_message_test (const char *test_data_dir)                                            "Foo.TestInterface",                                            "TestMethod");    _dbus_message_set_serial (message, 1); +  dbus_message_set_reply_serial (message, 5678);    v_INT32 = -0x12345678; +  v_UINT32 = 0x12300042;  #ifdef DBUS_HAVE_INT64    v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd);    v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); @@ -981,6 +988,7 @@ _dbus_message_test (const char *test_data_dir)    dbus_message_append_args (message,  			    DBUS_TYPE_INT32, &v_INT32, +                            DBUS_TYPE_UINT32, &v_UINT32,  #ifdef DBUS_HAVE_INT64                              DBUS_TYPE_INT64, &v_INT64,                              DBUS_TYPE_UINT64, &v_UINT64, @@ -1010,6 +1018,7 @@ _dbus_message_test (const char *test_data_dir)    i = 0;    sig[i++] = DBUS_TYPE_INT32; +  sig[i++] = DBUS_TYPE_UINT32;  #ifdef DBUS_HAVE_INT64    sig[i++] = DBUS_TYPE_INT64;    sig[i++] = DBUS_TYPE_UINT64; @@ -1125,7 +1134,7 @@ _dbus_message_test (const char *test_data_dir)    if (!message)      _dbus_assert_not_reached ("received a NULL message"); -  if (dbus_message_get_reply_serial (message) != 0x12345678) +  if (dbus_message_get_reply_serial (message) != 5678)      _dbus_assert_not_reached ("reply serial fields differ");    verify_test_message (message); @@ -1133,7 +1142,33 @@ _dbus_message_test (const char *test_data_dir)    dbus_message_unref (message);    _dbus_message_loader_unref (loader); +  check_memleaks (); +  /* Load all the sample messages from the message factory */ +  { +    DBusMessageDataIter diter; +    DBusMessageData mdata; + +    _dbus_message_data_iter_init (&diter); +     +    while (_dbus_message_data_iter_get_and_next (&diter, +                                                 &mdata)) +      { +        if (!dbus_internal_do_not_use_try_message_data (&mdata.data, +                                                        mdata.expected_validity)) +          { +            _dbus_warn ("expected validity %d and did not get it; generator %d sequence %d\n", +                        mdata.expected_validity, +                        diter.generator, diter.sequence); +            _dbus_assert_not_reached ("message data failed"); +          } + +        _dbus_message_data_free (&mdata); +      } +  } +   +  check_memleaks (); +      /* Now load every message in test_data_dir if we have one */    if (test_data_dir == NULL)      return TRUE; diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 2ed9cf2f..eca2a3c4 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -570,7 +570,7 @@ dbus_message_cache_or_finalize (DBusMessage *message)  {    dbus_bool_t was_cached;    int i; - +      _dbus_assert (message->refcount.value == 0);    /* This calls application code and has to be done first thing @@ -654,7 +654,7 @@ dbus_message_new_empty_header (void)        message->generation = _dbus_current_generation;  #endif      } - +      message->refcount.value = 1;    message->byte_order = DBUS_COMPILER_BYTE_ORDER;    message->locked = FALSE; @@ -2881,9 +2881,12 @@ _dbus_message_loader_new (void)    loader = dbus_new0 (DBusMessageLoader, 1);    if (loader == NULL)      return NULL; - +      loader->refcount = 1; +  loader->corrupted = FALSE; +  loader->corruption_reason = DBUS_VALID; +      /* Try to cap message size at something that won't *totally* hose     * the system if we have a couple of them.     */ @@ -3018,7 +3021,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,   * loader->data and only delete it occasionally, instead of after   * each message is loaded.   * - * load_message() returns FALSE if not enough memory + * load_message() returns FALSE if not enough memory OR the loader was corrupted   */  static dbus_bool_t  load_message (DBusMessageLoader *loader, @@ -3059,6 +3062,11 @@ load_message (DBusMessageLoader *loader,        _dbus_verbose ("Failed to load header for new message code %d\n", validity);        if (validity == DBUS_VALID)          oom = TRUE; +      else +        { +          loader->corrupted = TRUE; +          loader->corruption_reason = validity; +        }        goto failed;      } @@ -3084,6 +3092,10 @@ load_message (DBusMessageLoader *loader,        if (validity != DBUS_VALID)          {            _dbus_verbose ("Failed to validate message body code %d\n", validity); + +          loader->corrupted = TRUE; +          loader->corruption_reason = validity; +                      goto failed;          }      } @@ -3117,6 +3129,8 @@ load_message (DBusMessageLoader *loader,    _dbus_assert (!oom);    _dbus_assert (!loader->corrupted); +  _dbus_assert (loader->messages != NULL); +  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);    return TRUE; @@ -3126,13 +3140,15 @@ load_message (DBusMessageLoader *loader,    /* does nothing if the message isn't in the list */    _dbus_list_remove_last (&loader->messages, message); - -  if (!oom) -    loader->corrupted = TRUE; +   +  if (oom) +    _dbus_assert (!loader->corrupted); +  else +    _dbus_assert (loader->corrupted);    _dbus_verbose_bytes_of_string (&loader->data, 0, _dbus_string_get_length (&loader->data)); -  return !oom; +  return FALSE;  }  /** @@ -3180,15 +3196,24 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader)                               header_len, body_len))              {                dbus_message_unref (message); -              return FALSE; +              /* load_message() returns false if corrupted or OOM; if +               * corrupted then return TRUE for not OOM +               */ +              return loader->corrupted;              } + +          _dbus_assert (loader->messages != NULL); +          _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);  	}        else          {            _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",                           validity);            if (validity != DBUS_VALID) -            loader->corrupted = TRUE; +            { +              loader->corrupted = TRUE; +              loader->corruption_reason = validity; +            }            return TRUE;          }      } @@ -3265,6 +3290,8 @@ _dbus_message_loader_putback_message_link (DBusMessageLoader  *loader,  dbus_bool_t  _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)  { +  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) || +                (!loader->corrupted && loader->corruption_reason == DBUS_VALID));    return loader->corrupted;  } diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index 7fae00d4..5f51832c 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -118,7 +118,7 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir)    check_memleaks (); -#if 1 +#if 0    printf ("%s: running recursive marshalling tests\n", "dbus-test");    if (!_dbus_marshal_recursive_test ())      die ("recursive marshal"); @@ -134,11 +134,13 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir)    check_memleaks (); +#if 0    printf ("%s: running memory pool tests\n", "dbus-test");    if (!_dbus_mem_pool_test ())      die ("memory pools");    check_memleaks (); +#endif    printf ("%s: running linked list tests\n", "dbus-test");    if (!_dbus_list_test ()) diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index b9865f09..06d368fa 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -26,14 +26,7 @@  #include <dbus/dbus-types.h>  #include <dbus/dbus-string.h> - -typedef enum -{ -  _DBUS_MESSAGE_VALID, -  _DBUS_MESSAGE_INVALID, -  _DBUS_MESSAGE_INCOMPLETE, -  _DBUS_MESSAGE_UNKNOWN -} DBusMessageValidity; +#include <dbus/dbus-marshal-validate.h>  dbus_bool_t _dbus_hash_test              (void);  dbus_bool_t _dbus_dict_test              (void); @@ -61,19 +54,16 @@ dbus_bool_t _dbus_pending_call_test      (const char *test_data_dir);  void        dbus_internal_do_not_use_run_tests         (const char          *test_data_dir);  dbus_bool_t dbus_internal_do_not_use_try_message_file  (const DBusString    *filename, -                                                        dbus_bool_t          is_raw, -                                                        DBusMessageValidity  expected_validity); +                                                        DBusValidity         expected_validity);  dbus_bool_t dbus_internal_do_not_use_try_message_data  (const DBusString    *data, -                                                        DBusMessageValidity  expected_validity); +                                                        DBusValidity         expected_validity);  dbus_bool_t dbus_internal_do_not_use_load_message_file (const DBusString    *filename, -                                                        dbus_bool_t          is_raw,                                                          DBusString          *data);  /* returns FALSE on fatal failure */  typedef dbus_bool_t (* DBusForeachMessageFileFunc) (const DBusString   *filename, -                                                    dbus_bool_t         is_raw, -                                                    DBusMessageValidity expected_validity, +                                                    DBusValidity        expected_validity,                                                      void               *data);  dbus_bool_t dbus_internal_do_not_use_foreach_message_file (const char                 *test_data_dir, diff --git a/test/data/invalid-messages/boolean-array-length-too-long.message-raw b/test/data/invalid-messages/boolean-array-length-too-long.message-raw Binary files differdeleted file mode 100644 index 07d4b341..00000000 --- a/test/data/invalid-messages/boolean-array-length-too-long.message-raw +++ /dev/null  | 
