/** * Tests how well the given function responds to out-of-memory * situations. Calls the function repeatedly, failing a different * call to malloc() each time. If the function ever returns #FALSE, * the test fails. The function should return #TRUE whenever something * valid (such as returning an error, or succeeding) occurs, and #FALSE * if it gets confused in some way. * * @param description description of the test used in verbose output * @param func function to call * @param data data to pass to function * @returns #TRUE if the function never returns FALSE */ dbus_bool_t _dbus_test_oom_handling (const char *description, DBusTestMemoryFunction func, void *data) { int approx_mallocs; const char *setting; int max_failures_to_try; int i; /* Run once to see about how many mallocs are involved */ _dbus_set_fail_alloc_counter (_DBUS_INT_MAX); _dbus_verbose ("Running once to count mallocs\n"); if (!(* func) (data)) return FALSE; approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter (); _dbus_verbose ("\n=================\n%s: about %d mallocs total\n=================\n", description, approx_mallocs); setting = _dbus_getenv ("DBUS_TEST_MALLOC_FAILURES"); if (setting != NULL) { DBusString str; long v; _dbus_string_init_const (&str, setting); v = 4; if (!_dbus_string_parse_int (&str, 0, &v, NULL)) _dbus_warn ("couldn't parse '%s' as integer\n", setting); max_failures_to_try = v; } else { max_failures_to_try = 4; } i = setting ? max_failures_to_try - 1 : 1; while (i < max_failures_to_try) { _dbus_set_fail_alloc_failures (i); if (!run_failing_each_malloc (approx_mallocs, description, func, data)) return FALSE; ++i; } _dbus_verbose ("\n=================\n%s: all iterations passed\n=================\n", description); return TRUE; }
dbus_bool_t _dbus_is_a_number (const DBusString *str, unsigned long *num) { int end; if (_dbus_string_parse_int (str, 0, num, &end) && end == _dbus_string_get_length (str)) return TRUE; else return FALSE; }
int main (int argc, char **argv) { DBusError error; DBusString config_file; DBusString address; DBusString addr_fd; DBusString pid_fd; const char *prev_arg; DBusPipe print_addr_pipe; DBusPipe print_pid_pipe; int i; dbus_bool_t print_address; dbus_bool_t print_pid; BusContextFlags flags; if (!_dbus_string_init (&config_file)) return 1; if (!_dbus_string_init (&address)) return 1; if (!_dbus_string_init (&addr_fd)) return 1; if (!_dbus_string_init (&pid_fd)) return 1; print_address = FALSE; print_pid = FALSE; flags = BUS_CONTEXT_FLAG_WRITE_PID_FILE; prev_arg = NULL; i = 1; while (i < argc) { const char *arg = argv[i]; if (strcmp (arg, "--help") == 0 || strcmp (arg, "-h") == 0 || strcmp (arg, "-?") == 0) { usage (); } else if (strcmp (arg, "--version") == 0) { version (); } else if (strcmp (arg, "--introspect") == 0) { introspect (); } else if (strcmp (arg, "--nofork") == 0) { flags &= ~BUS_CONTEXT_FLAG_FORK_ALWAYS; flags |= BUS_CONTEXT_FLAG_FORK_NEVER; } #ifdef DBUS_UNIX else if (strcmp (arg, "--fork") == 0) { flags &= ~BUS_CONTEXT_FLAG_FORK_NEVER; flags |= BUS_CONTEXT_FLAG_FORK_ALWAYS; } else if (strcmp (arg, "--systemd-activation") == 0) { flags |= BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION; } #endif else if (strcmp (arg, "--nopidfile") == 0) { flags &= ~BUS_CONTEXT_FLAG_WRITE_PID_FILE; } else if (strcmp (arg, "--system") == 0) { check_two_config_files (&config_file, "system"); if (!_dbus_append_system_config_file (&config_file)) exit (1); } else if (strcmp (arg, "--session") == 0) { check_two_config_files (&config_file, "session"); if (!_dbus_append_session_config_file (&config_file)) exit (1); } else if (strstr (arg, "--config-file=") == arg) { const char *file; check_two_config_files (&config_file, "config-file"); file = strchr (arg, '='); ++file; if (!_dbus_string_append (&config_file, file)) exit (1); } else if (prev_arg && strcmp (prev_arg, "--config-file") == 0) { check_two_config_files (&config_file, "config-file"); if (!_dbus_string_append (&config_file, arg)) exit (1); } else if (strcmp (arg, "--config-file") == 0) { /* wait for next arg */ } else if (strstr (arg, "--address=") == arg) { const char *file; check_two_addresses (&address, "address"); file = strchr (arg, '='); ++file; if (!_dbus_string_append (&address, file)) exit (1); } else if (prev_arg && strcmp (prev_arg, "--address") == 0) { check_two_addresses (&address, "address"); if (!_dbus_string_append (&address, arg)) exit (1); } else if (strcmp (arg, "--address") == 0) { /* wait for next arg */ } else if (strstr (arg, "--print-address=") == arg) { const char *desc; check_two_addr_descriptors (&addr_fd, "print-address"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&addr_fd, desc)) exit (1); print_address = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-address") == 0) { check_two_addr_descriptors (&addr_fd, "print-address"); if (!_dbus_string_append (&addr_fd, arg)) exit (1); print_address = TRUE; } else if (strcmp (arg, "--print-address") == 0) { print_address = TRUE; /* and we'll get the next arg if appropriate */ } else if (strstr (arg, "--print-pid=") == arg) { const char *desc; check_two_pid_descriptors (&pid_fd, "print-pid"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&pid_fd, desc)) exit (1); print_pid = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-pid") == 0) { check_two_pid_descriptors (&pid_fd, "print-pid"); if (!_dbus_string_append (&pid_fd, arg)) exit (1); print_pid = TRUE; } else if (strcmp (arg, "--print-pid") == 0) { print_pid = TRUE; /* and we'll get the next arg if appropriate */ } else { usage (); } prev_arg = arg; ++i; } if (_dbus_string_get_length (&config_file) == 0) { fprintf (stderr, "No configuration file specified.\n"); usage (); } _dbus_pipe_invalidate (&print_addr_pipe); if (print_address) { _dbus_pipe_init_stdout (&print_addr_pipe); if (_dbus_string_get_length (&addr_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) || end != _dbus_string_get_length (&addr_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&addr_fd)); exit (1); } _dbus_pipe_init (&print_addr_pipe, val); } } _dbus_string_free (&addr_fd); _dbus_pipe_invalidate (&print_pid_pipe); if (print_pid) { _dbus_pipe_init_stdout (&print_pid_pipe); if (_dbus_string_get_length (&pid_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) || end != _dbus_string_get_length (&pid_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&pid_fd)); exit (1); } _dbus_pipe_init (&print_pid_pipe, val); } } _dbus_string_free (&pid_fd); if (!bus_selinux_pre_init ()) { _dbus_warn ("SELinux pre-initialization failed\n"); exit (1); } dbus_error_init (&error); context = bus_context_new (&config_file, flags, &print_addr_pipe, &print_pid_pipe, _dbus_string_get_length(&address) > 0 ? &address : NULL, &error); _dbus_string_free (&config_file); if (context == NULL) { _dbus_warn ("Failed to start message bus: %s\n", error.message); dbus_error_free (&error); exit (1); } /* bus_context_new() closes the print_addr_pipe and * print_pid_pipe */ #ifdef DBUS_UNIX setup_reload_pipe (bus_context_get_loop (context)); /* POSIX signals are Unix-specific, and _dbus_set_signal_handler is * unimplemented (and probably unimplementable) on Windows, so there's * no point in trying to make the handler portable to non-Unix. */ _dbus_set_signal_handler (SIGTERM, signal_handler); _dbus_set_signal_handler (SIGHUP, signal_handler); #endif /* DBUS_UNIX */ _dbus_verbose ("We are on D-Bus...\n"); _dbus_loop_run (bus_context_get_loop (context)); bus_context_shutdown (context); bus_context_unref (context); bus_selinux_shutdown (); return 0; }
/* This code only gets executed the first time the * config files are parsed. It is not executed * when config files are reloaded. */ static dbus_bool_t process_config_first_time_only (BusContext *context, BusConfigParser *parser, const DBusString *address, BusContextFlags flags, DBusError *error) { DBusString log_prefix; DBusList *link; DBusList **addresses; const char *user, *pidfile; char **auth_mechanisms; DBusList **auth_mechanisms_list; int len; dbus_bool_t retval; _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = FALSE; auth_mechanisms = NULL; pidfile = NULL; _dbus_init_system_log (TRUE); if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION) context->systemd_activation = TRUE; else context->systemd_activation = FALSE; /* Check for an existing pid file. Of course this is a race; * we'd have to use fcntl() locks on the pid file to * avoid that. But we want to check for the pid file * before overwriting any existing sockets, etc. */ if (flags & BUS_CONTEXT_FLAG_WRITE_PID_FILE) pidfile = bus_config_parser_get_pidfile (parser); if (pidfile != NULL) { DBusString u; DBusStat stbuf; _dbus_string_init_const (&u, pidfile); if (_dbus_stat (&u, &stbuf, NULL)) { #ifdef DBUS_CYGWIN DBusString p; long /* int */ pid; _dbus_string_init (&p); _dbus_file_get_contents(&p, &u, NULL); _dbus_string_parse_int(&p, 0, &pid, NULL); _dbus_string_free(&p); if ((kill((int)pid, 0))) { dbus_set_error(NULL, DBUS_ERROR_FILE_EXISTS, "pid %ld not running, removing stale pid file\n", pid); _dbus_delete_file(&u, NULL); } else { #endif dbus_set_error (error, DBUS_ERROR_FAILED, "The pid file \"%s\" exists, if the message bus is not running, remove this file", pidfile); goto failed; #ifdef DBUS_CYGWIN } #endif } } /* keep around the pid filename so we can delete it later */ context->pidfile = _dbus_strdup (pidfile); /* note that type may be NULL */ context->type = _dbus_strdup (bus_config_parser_get_type (parser)); if (bus_config_parser_get_type (parser) != NULL && context->type == NULL) goto oom; user = bus_config_parser_get_user (parser); if (user != NULL) { context->user = _dbus_strdup (user); if (context->user == NULL) goto oom; } /* Set up the prefix for syslog messages */ if (!_dbus_string_init (&log_prefix)) goto oom; if (context->type && !strcmp (context->type, "system")) { if (!_dbus_string_append (&log_prefix, "[system] ")) goto oom; } else if (context->type && !strcmp (context->type, "session")) { DBusCredentials *credentials; credentials = _dbus_credentials_new_from_current_process (); if (!credentials) goto oom; if (!_dbus_string_append (&log_prefix, "[session ")) { _dbus_credentials_unref (credentials); goto oom; } if (!_dbus_credentials_to_string_append (credentials, &log_prefix)) { _dbus_credentials_unref (credentials); goto oom; } if (!_dbus_string_append (&log_prefix, "] ")) { _dbus_credentials_unref (credentials); goto oom; } _dbus_credentials_unref (credentials); } if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix)) goto oom; _dbus_string_free (&log_prefix); /* Build an array of auth mechanisms */ auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); len = _dbus_list_get_length (auth_mechanisms_list); if (len > 0) { int i; auth_mechanisms = dbus_new0 (char*, len + 1); if (auth_mechanisms == NULL) goto oom; i = 0; link = _dbus_list_get_first_link (auth_mechanisms_list); while (link != NULL) { auth_mechanisms[i] = _dbus_strdup (link->data); if (auth_mechanisms[i] == NULL) goto oom; link = _dbus_list_get_next_link (auth_mechanisms_list, link); i += 1; } }
/** * Try to open a new transport for the given address entry. (This * opens a client-side-of-the-connection transport.) * * @param entry the address entry * @param error location to store reason for failure. * @returns new transport of #NULL on failure. */ DBusTransport* _dbus_transport_open (DBusAddressEntry *entry, DBusError *error) { DBusTransport *transport; const char *address_problem_type; const char *address_problem_field; const char *address_problem_other; const char *method; const char *expected_guid_orig; char *expected_guid; _DBUS_ASSERT_ERROR_IS_CLEAR (error); transport = NULL; address_problem_type = NULL; address_problem_field = NULL; address_problem_other = NULL; expected_guid_orig = dbus_address_entry_get_value (entry, "guid"); expected_guid = _dbus_strdup (expected_guid_orig); if (expected_guid_orig != NULL && expected_guid == NULL) { _DBUS_SET_OOM (error); return NULL; } method = dbus_address_entry_get_method (entry); _dbus_assert (method != NULL); if (strcmp (method, "unix") == 0) { const char *path = dbus_address_entry_get_value (entry, "path"); const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir"); const char *abstract = dbus_address_entry_get_value (entry, "abstract"); if (tmpdir != NULL) { address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on"; goto bad_address; } if (path == NULL && abstract == NULL) { address_problem_type = "unix"; address_problem_field = "path or abstract"; goto bad_address; } if (path != NULL && abstract != NULL) { address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address"; goto bad_address; } if (path) transport = _dbus_transport_new_for_domain_socket (path, FALSE, error); else transport = _dbus_transport_new_for_domain_socket (abstract, TRUE, error); } else if (strcmp (method, "tcp") == 0) { const char *host = dbus_address_entry_get_value (entry, "host"); const char *port = dbus_address_entry_get_value (entry, "port"); DBusString str; long lport; dbus_bool_t sresult; if (port == NULL) { address_problem_type = "tcp"; address_problem_field = "port"; goto bad_address; } _dbus_string_init_const (&str, port); sresult = _dbus_string_parse_int (&str, 0, &lport, NULL); _dbus_string_free (&str); if (sresult == FALSE || lport <= 0 || lport > 65535) { address_problem_other = "Port is not an integer between 0 and 65535"; goto bad_address; } transport = _dbus_transport_new_for_tcp_socket (host, lport, error); } #ifdef DBUS_BUILD_TESTS else if (strcmp (method, "debug-pipe") == 0) { const char *name = dbus_address_entry_get_value (entry, "name"); if (name == NULL) { address_problem_type = "debug-pipe"; address_problem_field = "name"; goto bad_address; } transport = _dbus_transport_debug_pipe_new (name, error); } #endif else { address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")"; goto bad_address; } if (transport == NULL) { _DBUS_ASSERT_ERROR_IS_SET (error); dbus_free (expected_guid); } else { transport->expected_guid = expected_guid; } return transport; bad_address: dbus_free (expected_guid); if (address_problem_type != NULL) dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Address of type %s was missing argument %s", address_problem_type, address_problem_field); else dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Could not parse address: %s", address_problem_other); return NULL; }
int main (int argc, char **argv) { DBusError error; DBusString config_file; DBusString addr_fd; DBusString pid_fd; const char *prev_arg; int print_addr_fd; int print_pid_fd; int i; dbus_bool_t print_address; dbus_bool_t print_pid; int force_fork; if (!_dbus_string_init (&config_file)) return 1; if (!_dbus_string_init (&addr_fd)) return 1; if (!_dbus_string_init (&pid_fd)) return 1; print_address = FALSE; print_pid = FALSE; force_fork = FORK_FOLLOW_CONFIG_FILE; prev_arg = NULL; i = 1; while (i < argc) { const char *arg = argv[i]; if (strcmp (arg, "--help") == 0 || strcmp (arg, "-h") == 0 || strcmp (arg, "-?") == 0) usage (); else if (strcmp (arg, "--version") == 0) version (); else if (strcmp (arg, "--introspect") == 0) introspect (); else if (strcmp (arg, "--nofork") == 0) force_fork = FORK_NEVER; else if (strcmp (arg, "--fork") == 0) force_fork = FORK_ALWAYS; else if (strcmp (arg, "--system") == 0) { check_two_config_files (&config_file, "system"); if (!_dbus_string_append (&config_file, DBUS_SYSTEM_CONFIG_FILE)) exit (1); } else if (strcmp (arg, "--session") == 0) { check_two_config_files (&config_file, "session"); if (!_dbus_string_append (&config_file, DBUS_SESSION_CONFIG_FILE)) exit (1); } else if (strstr (arg, "--config-file=") == arg) { const char *file; check_two_config_files (&config_file, "config-file"); file = strchr (arg, '='); ++file; if (!_dbus_string_append (&config_file, file)) exit (1); } else if (prev_arg && strcmp (prev_arg, "--config-file") == 0) { check_two_config_files (&config_file, "config-file"); if (!_dbus_string_append (&config_file, arg)) exit (1); } else if (strcmp (arg, "--config-file") == 0) ; /* wait for next arg */ else if (strstr (arg, "--print-address=") == arg) { const char *desc; check_two_addr_descriptors (&addr_fd, "print-address"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&addr_fd, desc)) exit (1); print_address = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-address") == 0) { check_two_addr_descriptors (&addr_fd, "print-address"); if (!_dbus_string_append (&addr_fd, arg)) exit (1); print_address = TRUE; } else if (strcmp (arg, "--print-address") == 0) print_address = TRUE; /* and we'll get the next arg if appropriate */ else if (strstr (arg, "--print-pid=") == arg) { const char *desc; check_two_pid_descriptors (&pid_fd, "print-pid"); desc = strchr (arg, '='); ++desc; if (!_dbus_string_append (&pid_fd, desc)) exit (1); print_pid = TRUE; } else if (prev_arg && strcmp (prev_arg, "--print-pid") == 0) { check_two_pid_descriptors (&pid_fd, "print-pid"); if (!_dbus_string_append (&pid_fd, arg)) exit (1); print_pid = TRUE; } else if (strcmp (arg, "--print-pid") == 0) print_pid = TRUE; /* and we'll get the next arg if appropriate */ else usage (); prev_arg = arg; ++i; } if (_dbus_string_get_length (&config_file) == 0) { fprintf (stderr, "No configuration file specified.\n"); usage (); } print_addr_fd = -1; if (print_address) { print_addr_fd = 1; /* stdout */ if (_dbus_string_get_length (&addr_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) || end != _dbus_string_get_length (&addr_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&addr_fd)); exit (1); } print_addr_fd = val; } } _dbus_string_free (&addr_fd); print_pid_fd = -1; if (print_pid) { print_pid_fd = 1; /* stdout */ if (_dbus_string_get_length (&pid_fd) > 0) { long val; int end; if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) || end != _dbus_string_get_length (&pid_fd) || val < 0 || val > _DBUS_INT_MAX) { fprintf (stderr, "Invalid file descriptor: \"%s\"\n", _dbus_string_get_const_data (&pid_fd)); exit (1); } print_pid_fd = val; } } _dbus_string_free (&pid_fd); if (!bus_selinux_pre_init ()) { _dbus_warn ("SELinux pre-initialization failed\n"); exit (1); } dbus_error_init (&error); context = bus_context_new (&config_file, force_fork, print_addr_fd, print_pid_fd, &error); _dbus_string_free (&config_file); if (context == NULL) { _dbus_warn ("Failed to start message bus: %s\n", error.message); dbus_error_free (&error); exit (1); } setup_reload_pipe (bus_context_get_loop (context)); _dbus_set_signal_handler (SIGHUP, signal_handler); _dbus_set_signal_handler (SIGTERM, signal_handler); #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX _dbus_set_signal_handler (SIGIO, signal_handler); #endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */ _dbus_verbose ("We are on D-Bus...\n"); _dbus_loop_run (bus_context_get_loop (context)); bus_context_shutdown (context); bus_context_unref (context); bus_selinux_shutdown (); return 0; }
/** * @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; }