Ejemplo n.º 1
0
static dbus_bool_t
generate_special (DBusMessageDataIter   *iter,
                  DBusString            *data,
                  DBusValidity          *expected_validity)
{
  int item_seq;
  DBusMessage *message;
  int pos;
  dbus_int32_t v_INT32;

  _dbus_assert (_dbus_string_get_length (data) == 0);
  
  message = NULL;
  pos = -1;
  v_INT32 = 42;
  item_seq = iter_get_sequence (iter);

  if (item_seq == 0)
    {
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");
                                     
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      /* set an invalid typecode */
      _dbus_string_set_byte (data, pos + 1, '$');

      *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
    }
  else if (item_seq == 1)
    {
      char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2];
      const char *v_STRING;
      int i;
      
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");

      i = 0;
      while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
        {
          long_sig[i] = DBUS_TYPE_ARRAY;
          ++i;
        }
      long_sig[i] = DBUS_TYPE_INVALID;

      v_STRING = long_sig;
      if (!_dbus_header_set_field_basic (&message->header,
                                         DBUS_HEADER_FIELD_SIGNATURE,
                                         DBUS_TYPE_SIGNATURE,
                                         &v_STRING))
        _dbus_assert_not_reached ("oom");
      
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
    }
  else if (item_seq == 2)
    {
      char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4];
      const char *v_STRING;
      int i;
      
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");

      i = 0;
      while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
        {
          long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
          ++i;
        }

      long_sig[i] = DBUS_TYPE_INT32;
      ++i;

      while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
        {
          long_sig[i] = DBUS_STRUCT_END_CHAR;
          ++i;
        }
      long_sig[i] = DBUS_TYPE_INVALID;
      
      v_STRING = long_sig;
      if (!_dbus_header_set_field_basic (&message->header,
                                         DBUS_HEADER_FIELD_SIGNATURE,
                                         DBUS_TYPE_SIGNATURE,
                                         &v_STRING))
        _dbus_assert_not_reached ("oom");
      
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
    }
  else if (item_seq == 3)
    {
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");
                                     
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
      
      *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
    }
  else if (item_seq == 4)
    {
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");
                                     
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
      
      *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
    }
  else if (item_seq == 5)
    {
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");
                                     
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
      _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
      
      *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
    }
  else if (item_seq == 6)
    {
      message = simple_method_call ();
      generate_from_message (data, expected_validity, message);
      
      _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
      
      *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
    }
  else if (item_seq == 7)
    {
      /* Messages of unknown type are considered valid */
      message = simple_method_call ();
      generate_from_message (data, expected_validity, message);
      
      _dbus_string_set_byte (data, TYPE_OFFSET, 100);
      
      *expected_validity = DBUS_VALID;
    }
  else if (item_seq == 8)
    {
      char byte_order;

      message = simple_method_call ();
      byte_order = _dbus_header_get_byte_order (&message->header);
      generate_from_message (data, expected_validity, message);
      
      _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
                                DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
                                byte_order);
      _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
                                DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
                                byte_order);
      *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
    }
  else if (item_seq == 9)
    {
      const char *v_STRING = "not a valid bus name";
      message = simple_method_call ();

      if (!_dbus_header_set_field_basic (&message->header,
                                         DBUS_HEADER_FIELD_SENDER,
                                         DBUS_TYPE_STRING, &v_STRING))
        _dbus_assert_not_reached ("oom");
      
      generate_from_message (data, expected_validity, message);

      *expected_validity = DBUS_INVALID_BAD_SENDER;
    }
  else if (item_seq == 10)
    {
      message = simple_method_call ();

      if (!dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL))
        _dbus_assert_not_reached ("oom");
      
      generate_from_message (data, expected_validity, message);

      *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
    }
  else if (item_seq == 11)
    {
      message = simple_method_call ();

      if (!dbus_message_set_path (message, DBUS_PATH_LOCAL))
        _dbus_assert_not_reached ("oom");
      
      generate_from_message (data, expected_validity, message);

      *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
    }
  else if (item_seq == 12)
    {
      /* Method calls don't have to have interface */
      message = simple_method_call ();

      if (!dbus_message_set_interface (message, NULL))
        _dbus_assert_not_reached ("oom");
      
      generate_from_message (data, expected_validity, message);
      
      *expected_validity = DBUS_VALID;
    }
  else if (item_seq == 13)
    {
      /* Signals require an interface */
      message = simple_signal ();

      if (!dbus_message_set_interface (message, NULL))
        _dbus_assert_not_reached ("oom");
      
      generate_from_message (data, expected_validity, message);
      
      *expected_validity = DBUS_INVALID_MISSING_INTERFACE;
    }
  else if (item_seq == 14)
    {
      message = simple_method_return ();

      if (!_dbus_header_delete_field (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL))
        _dbus_assert_not_reached ("oom");
      
      generate_from_message (data, expected_validity, message);
      
      *expected_validity = DBUS_INVALID_MISSING_REPLY_SERIAL;
    }
  else if (item_seq == 15)
    {
      message = simple_error ();

      if (!dbus_message_set_error_name (message, NULL))
        _dbus_assert_not_reached ("oom");
      
      generate_from_message (data, expected_validity, message);
      
      *expected_validity = DBUS_INVALID_MISSING_ERROR_NAME;
    }
  else if (item_seq == 16)
    {
      char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*4+10];
      const char *v_STRING;
      int i;
      int n_begins;
      
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");

      i = 0;
      while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*3 + 3))
        {
          long_sig[i] = DBUS_TYPE_ARRAY;
          ++i;
          long_sig[i] = DBUS_DICT_ENTRY_BEGIN_CHAR;
          ++i;
          long_sig[i] = DBUS_TYPE_INT32;
          ++i;
        }
      n_begins = i / 3;

      long_sig[i] = DBUS_TYPE_INT32;
      ++i;
      
      while (n_begins > 0)
        {
          long_sig[i] = DBUS_DICT_ENTRY_END_CHAR;
          ++i;
          n_begins -= 1;
        }
      long_sig[i] = DBUS_TYPE_INVALID;
      
      v_STRING = long_sig;
      if (!_dbus_header_set_field_basic (&message->header,
                                         DBUS_HEADER_FIELD_SIGNATURE,
                                         DBUS_TYPE_SIGNATURE,
                                         &v_STRING))
        _dbus_assert_not_reached ("oom");
      
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
    }
  else if (item_seq == 17)
    {
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");
                                     
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);

      _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
      _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
      
      *expected_validity = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
    }
  else if (item_seq == 18)
    {
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");
                                     
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);
      
      _dbus_string_set_byte (data, pos + 1, DBUS_DICT_ENTRY_END_CHAR);
      
      *expected_validity = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
    }
  else if (item_seq == 19)
    {
      message = simple_method_call ();
      if (!dbus_message_append_args (message,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INT32, &v_INT32,
                                     DBUS_TYPE_INVALID))
        _dbus_assert_not_reached ("oom");
                                     
      _dbus_header_get_field_raw (&message->header,
                                  DBUS_HEADER_FIELD_SIGNATURE,
                                  NULL, &pos);
      generate_from_message (data, expected_validity, message);

      _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
      _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
      _dbus_string_set_byte (data, pos + 3, DBUS_DICT_ENTRY_END_CHAR);
      
      *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
    }
  else if (item_seq == 20)
    {
      /* 64 levels of nesting is OK */
      message = message_with_nesting_levels(64);

      generate_from_message (data, expected_validity, message);

      *expected_validity = DBUS_VALID;
    }
  else if (item_seq == 21)
    {
      /* 65 levels of nesting is not OK */
      message = message_with_nesting_levels(65);

      generate_from_message (data, expected_validity, message);

      *expected_validity = DBUS_INVALID_NESTED_TOO_DEEPLY;
    }
  else
    {
      return FALSE;
    }

  if (message)
    dbus_message_unref (message);

  iter_next (iter);
  return TRUE;
}
Ejemplo n.º 2
0
static DBusValidity
load_and_validate_field (DBusHeader     *header,
                         int             field,
                         DBusTypeReader *variant_reader)
{
  int type;
  int expected_type;
  const DBusString *value_str;
  int value_pos;
  int str_data_pos;
  dbus_uint32_t v_UINT32;
  int bad_string_code;
  dbus_bool_t (* string_validation_func) (const DBusString *str,
                                          int start, int len);

  /* Supposed to have been checked already */
  _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
  _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);

  /* Before we can cache a field, we need to know it has the right type */
  type = _dbus_type_reader_get_current_type (variant_reader);

  _dbus_assert (_dbus_header_field_types[field].code == field);

  expected_type = EXPECTED_TYPE_OF_FIELD (field);
  if (type != expected_type)
    {
      _dbus_verbose ("Field %d should have type %d but has %d\n",
                     field, expected_type, type);
      return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
    }

  /* If the field was provided twice, we aren't happy */
  if (header->fields[field].value_pos >= 0)
    {
      _dbus_verbose ("Header field %d seen a second time\n", field);
      return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
    }

  /* Now we can cache and look at the field content */
  _dbus_verbose ("initially caching field %d\n", field);
  _dbus_header_cache_one (header, field, variant_reader);

  string_validation_func = NULL;

  /* make compiler happy that all this is initialized */
  v_UINT32 = 0;
  value_str = NULL;
  value_pos = -1;
  str_data_pos = -1;
  bad_string_code = DBUS_VALID;

  if (expected_type == DBUS_TYPE_UINT32)
    {
      _dbus_header_get_field_basic (header, field, expected_type,
                                    &v_UINT32);
    }
  else if (expected_type == DBUS_TYPE_STRING ||
           expected_type == DBUS_TYPE_OBJECT_PATH ||
           expected_type == DBUS_TYPE_SIGNATURE)
    {
      _dbus_header_get_field_raw (header, field,
                                  &value_str, &value_pos);
      str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
    }
  else
    {
      _dbus_assert_not_reached ("none of the known fields should have this type");
    }

  switch (field)
    {
    case DBUS_HEADER_FIELD_DESTINATION:
      string_validation_func = _dbus_validate_bus_name;
      bad_string_code = DBUS_INVALID_BAD_DESTINATION;
      break;
    case DBUS_HEADER_FIELD_INTERFACE:
      string_validation_func = _dbus_validate_interface;
      bad_string_code = DBUS_INVALID_BAD_INTERFACE;

      if (_dbus_string_equal_substring (&_dbus_local_interface_str,
                                        0,
                                        _dbus_string_get_length (&_dbus_local_interface_str),
                                        value_str, str_data_pos))
        {
          _dbus_verbose ("Message is on the local interface\n");
          return DBUS_INVALID_USES_LOCAL_INTERFACE;
        }
      break;

    case DBUS_HEADER_FIELD_MEMBER:
      string_validation_func = _dbus_validate_member;
      bad_string_code = DBUS_INVALID_BAD_MEMBER;
      break;

    case DBUS_HEADER_FIELD_ERROR_NAME:
      string_validation_func = _dbus_validate_error_name;
      bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
      break;

    case DBUS_HEADER_FIELD_SENDER:
      string_validation_func = _dbus_validate_bus_name;
      bad_string_code = DBUS_INVALID_BAD_SENDER;
      break;

    case DBUS_HEADER_FIELD_PATH:
      /* OBJECT_PATH was validated generically due to its type */
      string_validation_func = NULL;

      if (_dbus_string_equal_substring (&_dbus_local_path_str,
                                        0,
                                        _dbus_string_get_length (&_dbus_local_path_str),
                                        value_str, str_data_pos))
        {
          _dbus_verbose ("Message is from the local path\n");
          return DBUS_INVALID_USES_LOCAL_PATH;
        }
      break;

    case DBUS_HEADER_FIELD_REPLY_SERIAL:
      /* Can't be 0 */
      if (v_UINT32 == 0)
        {
          return DBUS_INVALID_BAD_SERIAL;
        }
      break;

    case DBUS_HEADER_FIELD_SIGNATURE:
      /* SIGNATURE validated generically due to its type */
      string_validation_func = NULL;
      break;

    default:
      _dbus_assert_not_reached ("unknown field shouldn't be seen here");
      break;
    }

  if (string_validation_func)
    {
      dbus_uint32_t len;

      _dbus_assert (bad_string_code != DBUS_VALID);

      len = _dbus_marshal_read_uint32 (value_str, value_pos,
                                       header->byte_order, NULL);

#if 0
      _dbus_verbose ("Validating string header field; code %d if fails\n",
                     bad_string_code);
#endif
      if (!(*string_validation_func) (value_str, str_data_pos, len))
        return bad_string_code;
    }

  return DBUS_VALID;
}