/** * 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; }
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; }
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; }
static void randomly_change_one_byte (const DBusString *orig_data, DBusString *mutated) { int i; 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) == 0) return; i = random_int_in_range (0, _dbus_string_get_length (mutated)); _dbus_string_set_byte (mutated, i, random_int_in_range (0, 256)); }
static void randomly_shorten_or_lengthen (const DBusString *orig_data, DBusString *mutated) { 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) == 0) delta = random_int_in_range (0, 10); else delta = random_int_in_range (- _dbus_string_get_length (mutated), _dbus_string_get_length (mutated) * 3); if (delta < 0) _dbus_string_shorten (mutated, - delta); else if (delta > 0) { int i = 0; i = _dbus_string_get_length (mutated); if (!_dbus_string_lengthen (mutated, delta)) _dbus_assert_not_reached ("couldn't lengthen string"); while (i < _dbus_string_get_length (mutated)) { _dbus_string_set_byte (mutated, i, random_int_in_range (0, 256)); ++i; } } }
static void randomly_change_one_type (const DBusString *orig_data, DBusString *mutated) { int i; int len; 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) == 0) return; len = _dbus_string_get_length (mutated); i = random_int_in_range (0, len); /* Look for a type starting at a random location, * and replace with a different type */ while (i < len) { int b; b = _dbus_string_get_byte (mutated, i); if (dbus_type_is_valid (b)) { _dbus_string_set_byte (mutated, i, random_type ()); return; } ++i; } }
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; }
/** * @ingroup DBusStringInternals * Unit test for DBusString. * * @todo Need to write tests for _dbus_string_copy() and * _dbus_string_move() moving to/from each of start/middle/end of a * string. Also need tests for _dbus_string_move_len () * * @returns #TRUE on success. */ dbus_bool_t _dbus_string_test (void) { DBusString str; DBusString other; int i, end; long v; double d; int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 }; char *s; dbus_unichar_t ch; i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); test_max_len (&str, lens[i]); _dbus_string_free (&str); ++i; } /* Test shortening and setting length */ i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { int j; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); if (!_dbus_string_set_length (&str, lens[i])) _dbus_assert_not_reached ("failed to set string length"); j = lens[i]; while (j > 0) { _dbus_assert (_dbus_string_get_length (&str) == j); if (j > 0) { _dbus_string_shorten (&str, 1); _dbus_assert (_dbus_string_get_length (&str) == (j - 1)); } --j; } _dbus_string_free (&str); ++i; } /* Test equality */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("oom"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("oom"); _dbus_string_init_const (&other, "H"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1)); _dbus_string_init_const (&other, "Hello"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5)); _dbus_string_init_const (&other, "World"); _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11)); _dbus_string_free (&str); /* Test appending data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); i = 0; while (i < 10) { if (!_dbus_string_append (&str, "a")) _dbus_assert_not_reached ("failed to append string to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1); if (!_dbus_string_append_byte (&str, 'b')) _dbus_assert_not_reached ("failed to append byte to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2); ++i; } _dbus_string_free (&str); /* Check steal_data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_steal_data (&str, &s)) _dbus_assert_not_reached ("failed to steal data"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (((int)strlen (s)) == i); dbus_free (s); /* Check move */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_move (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 2); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_string_free (&other); /* Check copy */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_copy (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello World")); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello WorldHello World")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check replace */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 0, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not replace"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World")); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 5, 1)) _dbus_assert_not_reached ("could not replace center space"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorld")); if (!_dbus_string_replace_len (&str, 1, 1, &other, _dbus_string_get_length (&other) - 1, 1)) _dbus_assert_not_reached ("could not replace end character"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorle")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check append/get unichar */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); ch = 0; if (!_dbus_string_append_unichar (&str, 0xfffc)) _dbus_assert_not_reached ("failed to append unichar"); _dbus_string_get_unichar (&str, 0, &ch, &i); _dbus_assert (ch == 0xfffc); _dbus_assert (i == _dbus_string_get_length (&str)); _dbus_string_free (&str); /* Check insert/set/get byte */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("failed to append Hello"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o'); _dbus_string_set_byte (&str, 1, 'q'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q'); if (!_dbus_string_insert_bytes (&str, 0, 1, 255)) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z')) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W')) _dbus_assert_not_reached ("can't insert byte"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 255); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q'); _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o'); _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W'); _dbus_string_free (&str); /* Check append/parse int/double */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_int (&str, 27)) _dbus_assert_not_reached ("failed to append int"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_int (&str, 0, &v, &end)) _dbus_assert_not_reached ("failed to parse int"); _dbus_assert (v == 27); _dbus_assert (end == i); _dbus_string_free (&str); if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_double (&str, 50.3)) _dbus_assert_not_reached ("failed to append float"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_double (&str, 0, &d, &end)) _dbus_assert_not_reached ("failed to parse float"); _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6)); _dbus_assert (end == i); _dbus_string_free (&str); /* Test find */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("couldn't append to string"); if (!_dbus_string_find (&str, 0, "He", &i)) _dbus_assert_not_reached ("didn't find 'He'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "Hello", &i)) _dbus_assert_not_reached ("didn't find 'Hello'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "ello", &i)) _dbus_assert_not_reached ("didn't find 'ello'"); _dbus_assert (i == 1); if (!_dbus_string_find (&str, 0, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (!_dbus_string_find (&str, 2, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (_dbus_string_find (&str, 4, "lo", &i)) _dbus_assert_not_reached ("did find 'lo'"); if (!_dbus_string_find (&str, 0, "l", &i)) _dbus_assert_not_reached ("didn't find 'l'"); _dbus_assert (i == 2); if (!_dbus_string_find (&str, 0, "H", &i)) _dbus_assert_not_reached ("didn't find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "", &i)) _dbus_assert_not_reached ("didn't find ''"); _dbus_assert (i == 0); if (_dbus_string_find (&str, 0, "Hello!", NULL)) _dbus_assert_not_reached ("Did find 'Hello!'"); if (_dbus_string_find (&str, 0, "Oh, Hello", NULL)) _dbus_assert_not_reached ("Did find 'Oh, Hello'"); if (_dbus_string_find (&str, 0, "ill", NULL)) _dbus_assert_not_reached ("Did find 'ill'"); if (_dbus_string_find (&str, 0, "q", NULL)) _dbus_assert_not_reached ("Did find 'q'"); if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) _dbus_assert_not_reached ("Didn't find 'He'"); if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) _dbus_assert_not_reached ("Did find 'Hello'"); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) _dbus_assert_not_reached ("Did not find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) _dbus_assert_not_reached ("Did not find 'o'"); _dbus_assert (i == _dbus_string_get_length (&str) - 1); if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i)) _dbus_assert_not_reached ("Did find 'o'"); _dbus_assert (i == -1); if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) _dbus_assert_not_reached ("Did find 'e'"); _dbus_assert (i == -1); if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) _dbus_assert_not_reached ("Didn't find 'e'"); _dbus_assert (i == 1); _dbus_string_free (&str); /* Hex encoding */ _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0)) _dbus_assert_not_reached ("deccoded bogus hex string with no error"); _dbus_assert (end == 8); _dbus_string_free (&other); test_roundtrips (test_hex_roundtrip); _dbus_string_free (&str); { int found, found_len; _dbus_string_init_const (&str, "012\r\n567\n90"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2) _dbus_assert_not_reached ("Did not find '\\r\\n'"); if (found != 3 || found_len != 2) _dbus_assert_not_reached ("invalid return values"); if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) _dbus_assert_not_reached ("Did not find '\\n'"); if (found != 8 || found_len != 1) _dbus_assert_not_reached ("invalid return values"); if (_dbus_string_find_eol (&str, 9, &found, &found_len)) _dbus_assert_not_reached ("Found not expected '\\n'"); else if (found != 11 || found_len != 0) _dbus_assert_not_reached ("invalid return values '\\n'"); found = -1; found_len = -1; _dbus_string_init_const (&str, ""); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found an eol in an empty string"); _dbus_assert (found == 0); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar"); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found eol in string that lacks one"); _dbus_assert (found == 6); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar\n"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("did not find eol in string that has one at end"); _dbus_assert (found == 6); _dbus_assert (found_len == 1); } { DBusString line; #define FIRST_LINE "this is a line" #define SECOND_LINE "this is a second line" /* third line is empty */ #define THIRD_LINE "" #define FOURTH_LINE "this is a fourth line" if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&line)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop first line"); _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop second line"); _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop third line"); _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop fourth line"); _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE)); _dbus_string_free (&str); _dbus_string_free (&line); } { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); for (i = 0; i < 10000; i++) if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz")) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_set_length (&str, 10)) _dbus_assert_not_reached ("failed to set length"); /* actually compact */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact after set_length"); /* peek inside to make sure it worked */ if (((DBusRealString *)&str)->allocated > 30) _dbus_assert_not_reached ("compacting string didn't do anything"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after compact"); /* compact nothing */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact 2nd time"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after 2nd compact"); /* and make sure it still works...*/ if (!_dbus_string_append (&str, "123456")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content after append"); /* after growing automatically, this should do nothing */ if (!_dbus_string_compact (&str, 20000)) _dbus_assert_not_reached ("failed to compact after grow"); /* but this one will do something */ if (!_dbus_string_compact (&str, 0)) _dbus_assert_not_reached ("failed to compact after grow"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content"); if (!_dbus_string_append (&str, "!@#$%")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%")) _dbus_assert_not_reached ("unexpected content"); _dbus_string_free (&str); } { const char two_strings[] = "one\ttwo"; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, two_strings)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_split_on_byte (&str, '\t', &other)) _dbus_assert_not_reached ("no memory or delimiter not found"); if (strcmp (_dbus_string_get_data (&str), "one") != 0) _dbus_assert_not_reached ("left side after split on tab is wrong"); if (strcmp (_dbus_string_get_data (&other), "two") != 0) _dbus_assert_not_reached ("right side after split on tab is wrong"); _dbus_string_free (&str); _dbus_string_free (&other); } return TRUE; }