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]); }
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; }
/** * Fills in the correct body length. * * @param header the header * @param body_len the length of the body */ void _dbus_header_update_lengths (DBusHeader *header, int body_len) { _dbus_marshal_set_uint32 (&header->data, BODY_LENGTH_OFFSET, body_len, header->byte_order); }
/** * Sets the serial number of a header. This can only be done once on * a header. * * @param header the header * @param serial the serial */ void _dbus_header_set_serial (DBusHeader *header, dbus_uint32_t serial) { /* we use this function to set the serial on outgoing * messages, and to reset the serial in dbus_message_copy; * this assertion should catch a double-set on outgoing. */ _dbus_assert (_dbus_header_get_serial (header) == 0 || serial == 0); _dbus_marshal_set_uint32 (&header->data, SERIAL_OFFSET, serial, header->byte_order); }
static void randomly_modify_length (const DBusString *orig_data, DBusString *mutated) { int i; int byte_order; const char *d; dbus_uint32_t orig; int delta; 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); delta = random_int_in_range (-10, 10); _dbus_marshal_set_uint32 (mutated, byte_order, i, (unsigned) (orig + delta)); }
static dbus_bool_t generate_wrong_length (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { int lengths[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 }; int adjust; int len_seq; restart: len_seq = iter_get_sequence (iter); if (len_seq == _DBUS_N_ELEMENTS (lengths)) return FALSE; _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths)); iter_recurse (iter); if (!generate_many_bodies (iter, data, expected_validity)) { iter_set_sequence (iter, 0); /* reset to first body */ iter_unrecurse (iter); iter_next (iter); /* next length adjustment */ goto restart; } iter_unrecurse (iter); adjust = lengths[len_seq]; if (adjust < 0) { if ((_dbus_string_get_length (data) + adjust) < DBUS_MINIMUM_HEADER_SIZE) _dbus_string_set_length (data, DBUS_MINIMUM_HEADER_SIZE); else _dbus_string_shorten (data, - adjust); *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON; } else { if (!_dbus_string_lengthen (data, adjust)) _dbus_assert_not_reached ("oom"); *expected_validity = DBUS_INVALID_TOO_MUCH_DATA; } /* Fixup lengths */ { int old_body_len; int new_body_len; int byte_order; _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE); byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET); old_body_len = _dbus_marshal_read_uint32 (data, BODY_LENGTH_OFFSET, byte_order, NULL); _dbus_assert (old_body_len < _dbus_string_get_length (data)); new_body_len = old_body_len + adjust; if (new_body_len < 0) { new_body_len = 0; /* we just munged the header, and aren't sure how */ *expected_validity = DBUS_VALIDITY_UNKNOWN; } _dbus_verbose ("changing body len from %u to %u by adjust %d\n", old_body_len, new_body_len, adjust); _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET, new_body_len, byte_order); } return TRUE; }
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; }
static dbus_bool_t generate_uint32_changed (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { int body_seq; int byte_seq; int change_seq; dbus_uint32_t v_UINT32; int byte_order; const UIntChange *change; int base_depth; /* Outer loop is each body, next loop is each change, * inner loop is each change location */ base_depth = iter->depth; next_body: _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; _dbus_assert (iter->depth == (base_depth + 0)); iter_set_sequence (iter, body_seq); /* undo the "next" from generate_many_bodies */ iter_recurse (iter); next_change: _dbus_assert (iter->depth == (base_depth + 1)); change_seq = iter_get_sequence (iter); if (change_seq == _DBUS_N_ELEMENTS (uint32_changes)) { /* Reset change count */ iter_set_sequence (iter, 0); iter_unrecurse (iter); iter_next (iter); goto next_body; } _dbus_assert (iter->depth == (base_depth + 1)); iter_recurse (iter); _dbus_assert (iter->depth == (base_depth + 2)); byte_seq = iter_get_sequence (iter); /* skip 4 bytes at a time */ iter_next (iter); iter_next (iter); iter_next (iter); iter_next (iter); iter_unrecurse (iter); _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq, 4) == (unsigned) byte_seq); if (byte_seq >= (_dbus_string_get_length (data) - 4)) { /* reset byte count */ _dbus_assert (iter->depth == (base_depth + 1)); iter_recurse (iter); _dbus_assert (iter->depth == (base_depth + 2)); iter_set_sequence (iter, 0); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 1)); iter_next (iter); goto next_change; } _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4)); byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET); v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL); change = &uint32_changes[change_seq]; if (change->type == CHANGE_TYPE_ADJUST) { v_UINT32 += (int) change->value; } else { v_UINT32 = change->value; } #if 0 printf ("body %d change %d pos %d ", body_seq, change_seq, byte_seq); if (change->type == CHANGE_TYPE_ADJUST) printf ("adjust by %d", (int) change->value); else printf ("set to %u", change->value); printf (" \t%u -> %u\n", _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL), v_UINT32); #endif _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order); *expected_validity = DBUS_VALIDITY_UNKNOWN; _dbus_assert (iter->depth == (base_depth + 1)); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); return TRUE; }