Exemple #1
0
static void
randomly_set_extreme_ints (const DBusString *orig_data,
                           DBusString       *mutated)
{
  int i;
  int byte_order;
  const char *d;
  dbus_uint32_t orig;
  static int which = 0;
  unsigned int extreme_ints[] = {
    _DBUS_INT_MAX,
    _DBUS_UINT_MAX,
    _DBUS_INT_MAX - 1,
    _DBUS_UINT_MAX - 1,
    _DBUS_INT_MAX - 2,
    _DBUS_UINT_MAX - 2,
    _DBUS_INT_MAX - 17,
    _DBUS_UINT_MAX - 17,
    _DBUS_INT_MAX / 2,
    _DBUS_INT_MAX / 3,
    _DBUS_UINT_MAX / 2,
    _DBUS_UINT_MAX / 3,
    0, 1, 2, 3,
    (unsigned int) -1,
    (unsigned int) -2,
    (unsigned int) -3
  };
    
  if (orig_data != mutated)
    {
      _dbus_string_set_length (mutated, 0);
      
      if (!_dbus_string_copy (orig_data, 0, mutated, 0))
        _dbus_assert_not_reached ("out of mem");
    }

  if (_dbus_string_get_length (mutated) < 12)
    return;
  
  d = _dbus_string_get_const_data (mutated);

  if (!(*d == DBUS_LITTLE_ENDIAN ||
        *d == DBUS_BIG_ENDIAN))
    return;

  byte_order = *d;
  
  i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8);
  i = _DBUS_ALIGN_VALUE (i, 4);

  orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL);

  which = random_int_in_range (0, _DBUS_N_ELEMENTS (extreme_ints));

  _dbus_assert (which >= 0);
  _dbus_assert (which < _DBUS_N_ELEMENTS (extreme_ints));
  
  _dbus_marshal_set_uint32 (mutated, byte_order, i,
                            extreme_ints[which]);
}
/* this is a little fragile since it assumes the address doesn't
 * already have a guid, but it shouldn't
 */
static char*
copy_address_with_guid_appended (const DBusString *address,
                                 const DBusString *guid_hex)
{
    DBusString with_guid;
    char *retval;

    if (!_dbus_string_init (&with_guid))
        return NULL;

    if (!_dbus_string_copy (address, 0, &with_guid,
                            _dbus_string_get_length (&with_guid)) ||
            !_dbus_string_append (&with_guid, ",guid=") ||
            !_dbus_string_copy (guid_hex, 0,
                                &with_guid, _dbus_string_get_length (&with_guid)))
    {
        _dbus_string_free (&with_guid);
        return NULL;
    }

    retval = NULL;
    _dbus_string_steal_data (&with_guid, &retval);

    _dbus_string_free (&with_guid);

    return retval; /* may be NULL if steal_data failed */
}
/**
 * Tries loading the message in the given message file
 * and verifies that DBusMessageLoader can handle it.
 *
 * @param filename filename to load
 * @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,
                                           DBusValidity         expected_validity)
{
  DBusString data;
  dbus_bool_t retval;

  retval = FALSE;

  if (!_dbus_string_init (&data))
    _dbus_assert_not_reached ("could not allocate string\n");

  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);

 failed:

  if (!retval)
    {
      if (_dbus_string_get_length (&data) > 0)
        _dbus_verbose_bytes_of_string (&data, 0,
                                       _dbus_string_get_length (&data));

      _dbus_warn ("Failed message loader test on %s\n",
                  _dbus_string_get_const_data (filename));
    }

  _dbus_string_free (&data);

  return retval;
}
static dbus_bool_t
find_next_typecode (DBusMessageDataIter *iter,
                    DBusString          *data,
                    DBusValidity        *expected_validity)
{
  int body_seq;
  int byte_seq;
  int base_depth;

  base_depth = iter->depth;

 restart:
  _dbus_assert (iter->depth == (base_depth + 0));
  _dbus_string_set_length (data, 0);

  body_seq = iter_get_sequence (iter);
  
  if (!generate_many_bodies (iter, data, expected_validity))
    return FALSE;
  /* Undo the "next" in generate_many_bodies */
  iter_set_sequence (iter, body_seq);
  
  iter_recurse (iter);
  while (TRUE)
    {
      _dbus_assert (iter->depth == (base_depth + 1));
      
      byte_seq = iter_get_sequence (iter);

      _dbus_assert (byte_seq <= _dbus_string_get_length (data));
      
      if (byte_seq == _dbus_string_get_length (data))
        {
          /* reset byte count */
          iter_set_sequence (iter, 0);
          iter_unrecurse (iter);
          _dbus_assert (iter->depth == (base_depth + 0));
          iter_next (iter); /* go to the next body */
          goto restart;
        }

      _dbus_assert (byte_seq < _dbus_string_get_length (data));

      if (dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq)))
        break;
      else
        iter_next (iter);
    }

  _dbus_assert (byte_seq == iter_get_sequence (iter));
  _dbus_assert (byte_seq < _dbus_string_get_length (data));

  iter_unrecurse (iter);

  _dbus_assert (iter->depth == (base_depth + 0));
  
  return TRUE;
}
/**
 * Writes a struct of { byte, variant } with the given basic type.
 *
 * @param writer the writer (should be ready to write a struct)
 * @param type the type of the value
 * @param value the value as for _dbus_marshal_set_basic()
 * @returns #FALSE if no memory
 */
static dbus_bool_t
write_basic_field (DBusTypeWriter *writer,
                   int             field,
                   int             type,
                   const void     *value)
{
  DBusTypeWriter sub;
  DBusTypeWriter variant;
  int start;
  int padding;
  unsigned char field_byte;
  DBusString contained_type;
  char buf[2];

  start = writer->value_pos;
  padding = _dbus_string_get_length (writer->value_str) - start;

  if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
                                  NULL, 0, &sub))
    goto append_failed;

  field_byte = field;
  if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
                                      &field_byte))
    goto append_failed;

  buf[0] = type;
  buf[1] = '\0';
  _dbus_string_init_const_len (&contained_type, buf, 1);

  if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
                                  &contained_type, 0, &variant))
    goto append_failed;

  if (!_dbus_type_writer_write_basic (&variant, type, value))
    goto append_failed;

  if (!_dbus_type_writer_unrecurse (&sub, &variant))
    goto append_failed;

  if (!_dbus_type_writer_unrecurse (writer, &sub))
    goto append_failed;

  return TRUE;

 append_failed:
  _dbus_string_delete (writer->value_str,
                       start,
                       _dbus_string_get_length (writer->value_str) - start - padding);
  return FALSE;
}
/**
 * Checks that the given range of the string is a valid object path
 * name in the D-Bus protocol. Part of the validation ensures that
 * the object path contains only ASCII.
 *
 * @todo this is inconsistent with most of DBusString in that
 * it allows a start,len range that extends past the string end.
 *
 * @todo change spec to disallow more things, such as spaces in the
 * path name
 *
 * @param str the string
 * @param start first byte index to check
 * @param len number of bytes to check
 * @returns #TRUE if the byte range exists and is a valid name
 */
dbus_bool_t
_dbus_validate_path (const DBusString  *str,
                     int                start,
                     int                len)
{
  const unsigned char *s;
  const unsigned char *end;
  const unsigned char *last_slash;

  _dbus_assert (start >= 0);
  _dbus_assert (len >= 0);
  _dbus_assert (start <= _dbus_string_get_length (str));
  
  if (len > _dbus_string_get_length (str) - start)
    return FALSE;

  if (len == 0)
    return FALSE;

  s = _dbus_string_get_const_data (str) + start;
  end = s + len;

  if (*s != '/')
    return FALSE;
  last_slash = s;
  ++s;

  while (s != end)
    {
      if (*s == '/')
        {
          if ((s - last_slash) < 2)
            return FALSE; /* no empty path components allowed */

          last_slash = s;
        }
      else
        {
          if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
            return FALSE;
        }

      ++s;
    }

  if ((end - last_slash) < 2 &&
      len > 1)
    return FALSE; /* trailing slash not allowed unless the string is "/" */

  return TRUE;
}
/**
 * Checks that the given range of the string is a valid message type
 * signature in the D-Bus protocol.
 *
 * @todo this is inconsistent with most of DBusString in that
 * it allows a start,len range that extends past the string end.
 *
 * @param str the string
 * @param start first byte index to check
 * @param len number of bytes to check
 * @returns #TRUE if the byte range exists and is a valid signature
 */
dbus_bool_t
_dbus_validate_signature (const DBusString  *str,
                          int                start,
                          int                len)
{
  _dbus_assert (start >= 0);
  _dbus_assert (start <= _dbus_string_get_length (str));
  _dbus_assert (len >= 0);

  if (len > _dbus_string_get_length (str) - start)
    return FALSE;

  return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
}
static void
test_hex_roundtrip (const unsigned char *data,
                    int                  len)
{
  DBusString orig;
  DBusString encoded;
  DBusString decoded;
  int end;

  if (len < 0)
    len = strlen (data);
  
  if (!_dbus_string_init (&orig))
    _dbus_assert_not_reached ("could not init string");

  if (!_dbus_string_init (&encoded))
    _dbus_assert_not_reached ("could not init string");
  
  if (!_dbus_string_init (&decoded))
    _dbus_assert_not_reached ("could not init string");

  if (!_dbus_string_append_len (&orig, data, len))
    _dbus_assert_not_reached ("couldn't append orig data");

  if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
    _dbus_assert_not_reached ("could not encode");

  if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
    _dbus_assert_not_reached ("could not decode");
    
  _dbus_assert (_dbus_string_get_length (&encoded) == end);

  if (!_dbus_string_equal (&orig, &decoded))
    {
      const char *s;
      
      printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
              _dbus_string_get_length (&orig),
              _dbus_string_get_length (&encoded),
              _dbus_string_get_length (&decoded));
      printf ("Original: %s\n", data);
      s = _dbus_string_get_const_data (&decoded);
      printf ("Decoded: %s\n", s);
      _dbus_assert_not_reached ("original string not the same as string decoded from hex");
    }
  
  _dbus_string_free (&orig);
  _dbus_string_free (&encoded);
  _dbus_string_free (&decoded);  
}
static void
correct_header_padding (DBusHeader *header)
{
  int unpadded_len;

  _dbus_assert (header->padding == 7);

  _dbus_string_shorten (&header->data, header->padding);
  unpadded_len = _dbus_string_get_length (&header->data);

  if (!_dbus_string_align_length (&header->data, 8))
    _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");

  header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
}
static void
run_validity_tests (const ValidityTest *tests,
                    int                 n_tests,
                    DBusValidity (* func) (const DBusString*,int,int))
{
  int i;

  for (i = 0; i < n_tests; i++)
    {
      DBusString str;
      DBusValidity v;

      _dbus_string_init_const (&str, tests[i].data);

      v = (*func) (&str, 0, _dbus_string_get_length (&str));

      if (v != tests[i].expected)
        {
          _dbus_warn ("Improper validation result %d for '%s'\n",
                      v, tests[i].data);
          _dbus_assert_not_reached ("test failed");
        }

      ++i;
    }
}
EXPORT_C
#endif
void
_dbus_marshal_byteswap (const DBusString *signature,
                        int               signature_start,
                        int               old_byte_order,
                        int               new_byte_order,
                        DBusString       *value_str,
                        int               value_pos)
{
  DBusTypeReader reader;

  _dbus_assert (value_pos >= 0);
  _dbus_assert (value_pos <= _dbus_string_get_length (value_str));

  if (old_byte_order == new_byte_order)
    return;
  
  _dbus_type_reader_init_types_only (&reader,
                                     signature, signature_start);

#ifndef __SYMBIAN32__
  byteswap_body_helper (&reader, TRUE,
                        old_byte_order, new_byte_order,
                        _dbus_string_get_data_len (value_str, value_pos, 0),
                        NULL);
#else
  byteswap_body_helper (&reader, TRUE,
                        old_byte_order, new_byte_order,
                        (unsigned char *)_dbus_string_get_data_len (value_str, value_pos, 0),
                        NULL);
#endif
                        
}
/**
 * Appends a double to a DBusString.
 * 
 * @param str the string
 * @param value the floating point value
 * @returns #FALSE if not enough memory or other failure.
 */
dbus_bool_t
_dbus_string_append_double (DBusString *str,
                            double      value)
{
#define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */
  int orig_len;
  char *buf;
  int i;
  
  orig_len = _dbus_string_get_length (str);

  if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
    return FALSE;

  buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);

  snprintf (buf, MAX_LONG_LEN, "%g", value);

  i = 0;
  while (*buf)
    {
      ++buf;
      ++i;
    }
  
  _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
  
  return TRUE;
}
/**
 * Generates the given number of random bytes, where the bytes are
 * chosen from the alphanumeric ASCII subset.
 *
 * @param str the string
 * @param n_bytes the number of random ASCII bytes to append to string
 * @param error location to store reason for failure
 * @returns #TRUE on success, #FALSE if no memory or other failure
 */
dbus_bool_t
_dbus_generate_random_ascii (DBusString *str,
                             int         n_bytes,
                             DBusError  *error)
{
  static const char letters[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
  int i;
  int len;
  
  if (!_dbus_generate_random_bytes (str, n_bytes, error))
    return FALSE;
  
  len = _dbus_string_get_length (str);
  i = len - n_bytes;
  while (i < len)
    {
      _dbus_string_set_byte (str, i,
                             letters[_dbus_string_get_byte (str, i) %
                                     (sizeof (letters) - 1)]);

      ++i;
    }

  _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
                                             n_bytes));

  return TRUE;
}
/**
 * Appends an unsigned integer to a DBusString.
 * 
 * @param str the string
 * @param value the integer value
 * @returns #FALSE if not enough memory or other failure.
 */
dbus_bool_t
_dbus_string_append_uint (DBusString    *str,
                          unsigned long  value)
{
  /* this is wrong, but definitely on the high side. */
#define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
  int orig_len;
  int i;
  char *buf;
  
  orig_len = _dbus_string_get_length (str);

  if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
    return FALSE;

  buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);

  snprintf (buf, MAX_ULONG_LEN, "%lu", value);

  i = 0;
  while (*buf)
    {
      ++buf;
      ++i;
    }
  
  _dbus_string_shorten (str, MAX_ULONG_LEN - i);
  
  return TRUE;
}
/**
 * Parses an unsigned integer contained in a DBusString. Either return
 * parameter may be #NULL if you aren't interested in it. The integer
 * is parsed and stored in value_return. Return parameters are not
 * initialized if the function returns #FALSE.
 *
 * @param str the string
 * @param start the byte index of the start of the integer
 * @param value_return return location of the integer value or #NULL
 * @param end_return return location of the end of the integer, or #NULL
 * @returns #TRUE on success
 */
dbus_bool_t
_dbus_string_parse_uint (const DBusString *str,
                         int               start,
                         unsigned long    *value_return,
                         int              *end_return)
{
  unsigned long v;
  const char *p;
  char *end;

  p = _dbus_string_get_const_data_len (str, start,
                                       _dbus_string_get_length (str) - start);

  end = NULL;
  _dbus_set_errno_to_zero ();
  v = strtoul (p, &end, 0);
  if (end == NULL || end == p || errno != 0)
    return FALSE;

  if (value_return)
    *value_return = v;
  if (end_return)
    *end_return = start + (end - p);

  return TRUE;
}
/**
 * Parses a floating point number contained in a DBusString. Either
 * return parameter may be #NULL if you aren't interested in it. The
 * integer is parsed and stored in value_return. Return parameters are
 * not initialized if the function returns #FALSE.
 *
 * @param str the string
 * @param start the byte index of the start of the float
 * @param value_return return location of the float value or #NULL
 * @param end_return return location of the end of the float, or #NULL
 * @returns #TRUE on success
 */
dbus_bool_t
_dbus_string_parse_double (const DBusString *str,
                           int               start,
                           double           *value_return,
                           int              *end_return)
{
  double v;
  const char *p;
  char *end;

  p = _dbus_string_get_const_data_len (str, start,
                                       _dbus_string_get_length (str) - start);

  /* parsing hex works on linux but isn't portable, so intercept it
   * here to get uniform behavior.
   */
  if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
    return FALSE;
  
  end = NULL;
  errno = 0;
  v = ascii_strtod (p, &end);
  if (end == NULL || end == p || errno != 0)
    return FALSE;

  if (value_return)
    *value_return = v;
  if (end_return)
    *end_return = start + (end - p);

  return TRUE;
}
/**
 * Appends an integer to a DBusString.
 * 
 * @param str the string
 * @param value the integer value
 * @returns #FALSE if not enough memory or other failure.
 */
dbus_bool_t
_dbus_string_append_int (DBusString *str,
                         long        value)
{
  /* this calculation is from comp.lang.c faq */
#define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)  /* +1 for '-' */
  int orig_len;
  int i;
  char *buf;
  
  orig_len = _dbus_string_get_length (str);

  if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
    return FALSE;

  buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);

  snprintf (buf, MAX_LONG_LEN, "%ld", value);

  i = 0;
  while (*buf)
    {
      ++buf;
      ++i;
    }
  
  _dbus_string_shorten (str, MAX_LONG_LEN - i);
  
  return TRUE;
}
Exemple #18
0
static dbus_bool_t print_install_root()
{
  DBusString runtime_prefix;

  if (!_dbus_string_init (&runtime_prefix))
    {
      _dbus_assert_not_reached ("out of memory");
      return FALSE;
    }

  if (!_dbus_get_install_root (&runtime_prefix))
    {
      _dbus_assert_not_reached ("out of memory");
      _dbus_string_free (&runtime_prefix);
      return FALSE;
    }

  if (_dbus_string_get_length (&runtime_prefix) == 0)
    {
      fprintf (stderr, "_dbus_get_install_root() failed\n");
      _dbus_string_free (&runtime_prefix);
      return FALSE;
    }

  fprintf (stdout, "_dbus_get_install_root() returned '%s'\n",
      _dbus_string_get_const_data (&runtime_prefix));
  _dbus_string_free (&runtime_prefix);
  return TRUE;
}
/**
 * Checks that the given range of the string is a valid member name
 * in the D-Bus protocol. This includes a length restriction, etc.,
 * see the specification.
 *
 * @todo this is inconsistent with most of DBusString in that
 * it allows a start,len range that extends past the string end.
 *
 * @param str the string
 * @param start first byte index to check
 * @param len number of bytes to check
 * @returns #TRUE if the byte range exists and is a valid name
 */
dbus_bool_t
_dbus_validate_member (const DBusString  *str,
                       int                start,
                       int                len)
{
  const unsigned char *s;
  const unsigned char *end;
  const unsigned char *member;

  _dbus_assert (start >= 0);
  _dbus_assert (len >= 0);
  _dbus_assert (start <= _dbus_string_get_length (str));

  if (len > _dbus_string_get_length (str) - start)
    return FALSE;

  if (len > DBUS_MAXIMUM_NAME_LENGTH)
    return FALSE;

  if (len == 0)
    return FALSE;

  member = _dbus_string_get_const_data (str) + start;
  end = member + len;
  s = member;

  /* check special cases of first char so it doesn't have to be done
   * in the loop. Note we know len > 0
   */

  if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
    return FALSE;
  else
    ++s;

  while (s != end)
    {
      if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
        {
          return FALSE;
        }

      ++s;
    }

  return TRUE;
}
static dbus_bool_t
create_unique_client_name (BusRegistry *registry,
                           DBusString  *str)
{
  /* We never want to use the same unique client name twice, because
   * we want to guarantee that if you send a message to a given unique
   * name, you always get the same application. So we use two numbers
   * for INT_MAX * INT_MAX combinations, should be pretty safe against
   * wraparound.
   */
  /* FIXME these should be in BusRegistry rather than static vars */
  static int next_major_number = 0;
  static int next_minor_number = 0;
  int len;
  
  len = _dbus_string_get_length (str);
  
  while (TRUE)
    {
      /* start out with 1-0, go to 1-1, 1-2, 1-3,
       * up to 1-MAXINT, then 2-0, 2-1, etc.
       */
      if (next_minor_number <= 0)
        {
          next_major_number += 1;
          next_minor_number = 0;
          if (next_major_number <= 0)
            _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
        }

      _dbus_assert (next_major_number > 0);
      _dbus_assert (next_minor_number >= 0);

      /* appname:MAJOR-MINOR */
      
      if (!_dbus_string_append (str, ":"))
        return FALSE;
      
      if (!_dbus_string_append_int (str, next_major_number))
        return FALSE;

      if (!_dbus_string_append (str, "."))
        return FALSE;
      
      if (!_dbus_string_append_int (str, next_minor_number))
        return FALSE;

      next_minor_number += 1;
      
      /* Check if a client with the name exists */
      if (bus_registry_lookup (registry, str) == NULL)
	break;

      /* drop the number again, try the next one. */
      _dbus_string_set_length (str, len);
    }

  return TRUE;
}
Exemple #21
0
/**
 * Hex-encode a UUID.
 *
 * @param uuid the uuid
 * @param encoded string to append hex uuid to
 * @returns #FALSE if no memory
 */
dbus_bool_t
_dbus_uuid_encode (const DBusGUID *uuid,
                   DBusString     *encoded)
{
  DBusString binary;
  _dbus_string_init_const_len (&binary, uuid->as_bytes, DBUS_UUID_LENGTH_BYTES);
  return _dbus_string_hex_encode (&binary, 0, encoded, _dbus_string_get_length (encoded));
}
dbus_bool_t
_dbus_path_is_absolute (const DBusString *filename)
{
  if (_dbus_string_get_length (filename) > 0)
    return _dbus_string_get_byte (filename, 0) == '/';
  else
    return FALSE;
}
static dbus_bool_t
generate_byte_changed (DBusMessageDataIter *iter,
                       DBusString          *data,
                       DBusValidity        *expected_validity)
{
  int byte_seq;
  int v_BYTE;

  /* This is a little convoluted to make the bodies the
   * outer loop and each byte of each body the inner
   * loop
   */

 restart:
  if (!generate_many_bodies (iter, data, expected_validity))
    return FALSE;

  iter_recurse (iter);
  byte_seq = iter_get_sequence (iter);
  iter_next (iter);
  iter_unrecurse (iter);
  
  if (byte_seq == _dbus_string_get_length (data))
    {
      _dbus_string_set_length (data, 0);
      /* reset byte count */
      iter_recurse (iter);
      iter_set_sequence (iter, 0);
      iter_unrecurse (iter);
      goto restart;
    }
  else
    {
      /* Undo the "next" in generate_many_bodies */
      iter_set_sequence (iter, iter_get_sequence (iter) - 1);
    }

  _dbus_assert (byte_seq < _dbus_string_get_length (data));
  v_BYTE = _dbus_string_get_byte (data, byte_seq);
  v_BYTE += byte_seq; /* arbitrary but deterministic change to the byte */
  _dbus_string_set_byte (data, byte_seq, v_BYTE);
  *expected_validity = DBUS_VALIDITY_UNKNOWN;

  return TRUE;
}
Exemple #24
0
/**
 * sends the nonce over a given socket. Blocks while doing so.
 *
 * @param fd the file descriptor to write the nonce data to (usually a socket)
 * @param noncefile the noncefile location to read the nonce from
 * @param error contains error details if FALSE is returned
 * @return TRUE iff the nonce was successfully sent. Note that this does not
 * indicate whether the server accepted the nonce.
 */
dbus_bool_t
_dbus_send_nonce (DBusSocket        fd,
                  const DBusString *noncefile,
                  DBusError        *error)
{
  dbus_bool_t read_result;
  int send_result;
  DBusString nonce;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  if (_dbus_string_get_length (noncefile) == 0)
    return FALSE;

  if (!_dbus_string_init (&nonce))
    {
      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
      return FALSE;
    }

  read_result = _dbus_read_nonce (noncefile, &nonce, error);
  if (!read_result)
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      _dbus_string_free (&nonce);
      return FALSE;
    }
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  send_result = _dbus_write_socket (fd, &nonce, 0, _dbus_string_get_length (&nonce));

  _dbus_string_free (&nonce);

  if (send_result == -1)
    {
      dbus_set_error (error,
                      _dbus_error_from_system_errno (),
                      "Failed to send nonce (fd=%" DBUS_SOCKET_FORMAT "): %s",
                      _dbus_socket_printable (fd),
                      _dbus_strerror_from_errno ());
      return FALSE;
    }

  return TRUE;
}
static dbus_bool_t
generate_many_bodies_inner (DBusMessageDataIter *iter,
                            DBusMessage        **message_p)
{
  DBusMessage *message;
  DBusString signature;
  DBusString body;
  char byte_order;

  /* Keeping this small makes things go faster */
  message = dbus_message_new_method_call ("o.z.F",
                                          "/",
                                          "o.z.B",
                                          "Nah");
  if (message == NULL)
    _dbus_assert_not_reached ("oom");

  byte_order = _dbus_header_get_byte_order (&message->header);

  set_reply_serial (message);

  if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
    _dbus_assert_not_reached ("oom");
  
  if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter),
                                                byte_order,
                                                &signature, &body))
    {
      const char *v_SIGNATURE;

      v_SIGNATURE = _dbus_string_get_const_data (&signature);
      if (!_dbus_header_set_field_basic (&message->header,
                                         DBUS_HEADER_FIELD_SIGNATURE,
                                         DBUS_TYPE_SIGNATURE,
                                         &v_SIGNATURE))
        _dbus_assert_not_reached ("oom");

      if (!_dbus_string_move (&body, 0, &message->body, 0))
        _dbus_assert_not_reached ("oom");

      _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET,
                                _dbus_string_get_length (&message->body),
                                byte_order);
      
      *message_p = message;
    }
  else
    {
      dbus_message_unref (message);
      *message_p = NULL;
    }
  
  _dbus_string_free (&signature);
  _dbus_string_free (&body);

  return *message_p != NULL;
}
static dbus_bool_t
generate_typecode_changed (DBusMessageDataIter *iter,
                           DBusString          *data,
                           DBusValidity        *expected_validity)
{
  int byte_seq;
  int typecode_seq;
  int base_depth;

  base_depth = iter->depth;

 restart:
  _dbus_assert (iter->depth == (base_depth + 0));
  _dbus_string_set_length (data, 0);
  
  if (!find_next_typecode (iter, data, expected_validity))
    return FALSE;

  iter_recurse (iter);
  byte_seq = iter_get_sequence (iter);

  _dbus_assert (byte_seq < _dbus_string_get_length (data));
  
  iter_recurse (iter);
  typecode_seq = iter_get_sequence (iter);
  iter_next (iter);

  _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes));
  
  if (typecode_seq == _DBUS_N_ELEMENTS (typecodes))
    {
      _dbus_assert (iter->depth == (base_depth + 2));
      iter_set_sequence (iter, 0); /* reset typecode sequence */
      iter_unrecurse (iter);
      _dbus_assert (iter->depth == (base_depth + 1));
      iter_next (iter); /* go to the next byte_seq */
      iter_unrecurse (iter);
      _dbus_assert (iter->depth == (base_depth + 0));
      goto restart;
    }

  _dbus_assert (iter->depth == (base_depth + 2));
  iter_unrecurse (iter);
  _dbus_assert (iter->depth == (base_depth + 1));
  iter_unrecurse (iter);
  _dbus_assert (iter->depth == (base_depth + 0));

#if 0
  printf ("Changing byte %d in message %d to %c\n",
          byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]);
#endif
  
  _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]);
  *expected_validity = DBUS_VALIDITY_UNKNOWN;
  return TRUE;
}
Exemple #27
0
static void
check_two_pid_descriptors (const DBusString *pid_fd,
                           const char       *extra_arg)
{
  if (_dbus_string_get_length (pid_fd) > 0)
    {
      fprintf (stderr, "--%s specified but printing pid to %s already requested\n",
               extra_arg, _dbus_string_get_const_data (pid_fd));
      exit (1);
    }
}
Exemple #28
0
static void
check_two_config_files (const DBusString *config_file,
                        const char       *extra_arg)
{
  if (_dbus_string_get_length (config_file) > 0)
    {
      fprintf (stderr, "--%s specified but configuration file %s already requested\n",
               extra_arg, _dbus_string_get_const_data (config_file));
      exit (1);
    }
}
Exemple #29
0
static void
check_two_addresses (const DBusString *address,
                     const char       *extra_arg)
{
  if (_dbus_string_get_length (address) > 0)
    {
      fprintf (stderr, "--%s specified but address %s already requested\n",
               extra_arg, _dbus_string_get_const_data (address));
      exit (1);
    }
}
dbus_bool_t
_dbus_string_get_dirname  (const DBusString *filename,
                           DBusString       *dirname)
{
  int sep;
  
  _dbus_assert (filename != dirname);
  _dbus_assert (filename != NULL);
  _dbus_assert (dirname != NULL);

  /* Ignore any separators on the end */
  sep = _dbus_string_get_length (filename);
  if (sep == 0)
    return _dbus_string_append (dirname, "."); /* empty string passed in */
    
  while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
    --sep;

  _dbus_assert (sep >= 0);
  
  if (sep == 0)
    return _dbus_string_append (dirname, "/");
  
  /* Now find the previous separator */
  _dbus_string_find_byte_backward (filename, sep, '/', &sep);
  if (sep < 0)
    return _dbus_string_append (dirname, ".");
  
  /* skip multiple separators */
  while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
    --sep;

  _dbus_assert (sep >= 0);
  
  if (sep == 0 &&
      _dbus_string_get_byte (filename, 0) == '/')
    return _dbus_string_append (dirname, "/");
  else
    return _dbus_string_copy_len (filename, 0, sep - 0,
                                  dirname, _dbus_string_get_length (dirname));
}