static dbus_bool_t build_common_query (DBusString *query, const char *con, const char *bustype) { /** * libapparmor's aa_query_label() function scribbles over the first * AA_QUERY_CMD_LABEL_SIZE bytes of the query string with a private value. */ return _dbus_string_insert_bytes (query, 0, AA_QUERY_CMD_LABEL_SIZE, 0) && _dbus_string_append (query, con) && _dbus_string_append_byte (query, '\0') && _dbus_string_append_byte (query, AA_CLASS_DBUS) && _dbus_string_append (query, bustype ? bustype : ""); }
static dbus_bool_t _dbus_create_uuid_file_exclusively (const DBusString *filename, DBusGUID *uuid, DBusError *error) { DBusString encoded; if (!_dbus_string_init (&encoded)) { _DBUS_SET_OOM (error); return FALSE; } _dbus_generate_uuid (uuid); if (!_dbus_uuid_encode (uuid, &encoded)) { _DBUS_SET_OOM (error); goto error; } /* FIXME this is racy; we need a save_file_exclusively * function. But in practice this should be fine for now. * * - first be sure we can create the file and it * doesn't exist by creating it empty with O_EXCL * - then create it by creating a temporary file and * overwriting atomically with rename() */ if (!_dbus_create_file_exclusively (filename, error)) goto error; if (!_dbus_string_append_byte (&encoded, '\n')) { _DBUS_SET_OOM (error); goto error; } if (!_dbus_string_save_to_file (&encoded, filename, error)) goto error; if (!_dbus_make_file_world_readable (filename, error)) goto error; _dbus_string_free (&encoded); _DBUS_ASSERT_ERROR_IS_CLEAR (error); return TRUE; error: _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_string_free (&encoded); return FALSE; }
static dbus_bool_t query_append (DBusString *query, const char *buffer) { if (!_dbus_string_append_byte (query, '\0')) return FALSE; if (buffer && !_dbus_string_append (query, buffer)) return FALSE; return TRUE; }
/** * Write the give UUID to a file. * * @param filename the file to write * @param uuid the UUID to save * @param error used to raise an error * @returns #FALSE on error */ dbus_bool_t _dbus_write_uuid_file (const DBusString *filename, const DBusGUID *uuid, DBusError *error) { DBusString encoded; if (!_dbus_string_init (&encoded)) { _DBUS_SET_OOM (error); return FALSE; } if (!_dbus_uuid_encode (uuid, &encoded)) { _DBUS_SET_OOM (error); goto error; } if (!_dbus_string_append_byte (&encoded, '\n')) { _DBUS_SET_OOM (error); goto error; } if (!_dbus_string_save_to_file (&encoded, filename, TRUE, error)) goto error; _dbus_string_free (&encoded); _DBUS_ASSERT_ERROR_IS_CLEAR (error); return TRUE; error: _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_string_free (&encoded); return FALSE; }
/** * @ingroup DBusMessageInternals * Unit test for DBusMessage. * * @returns #TRUE on success. */ dbus_bool_t _dbus_message_test (const char *test_data_dir) { DBusMessage *message, *message_without_unix_fds; DBusMessageLoader *loader; int i; const char *data; DBusMessage *copy; const char *name1; const char *name2; const dbus_uint32_t our_uint32_array[] = { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; const dbus_int32_t our_int32_array[] = { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array; const dbus_int32_t *v_ARRAY_INT32 = our_int32_array; #ifdef DBUS_HAVE_INT64 const dbus_uint64_t our_uint64_array[] = { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; const dbus_int64_t our_int64_array[] = { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array; const dbus_int64_t *v_ARRAY_INT64 = our_int64_array; #endif const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; const char **v_ARRAY_STRING = our_string_array; const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; const double *v_ARRAY_DOUBLE = our_double_array; const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; const unsigned char *v_ARRAY_BYTE = our_byte_array; const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array; char sig[64]; const char *s; const char *v_STRING; double v_DOUBLE; dbus_int16_t v_INT16; dbus_uint16_t v_UINT16; dbus_int32_t v_INT32; dbus_uint32_t v_UINT32; #ifdef DBUS_HAVE_INT64 dbus_int64_t v_INT64; dbus_uint64_t v_UINT64; #endif unsigned char v_BYTE; unsigned char v2_BYTE; dbus_bool_t v_BOOLEAN; DBusMessageIter iter, array_iter, struct_iter; #ifdef HAVE_UNIX_FD_PASSING int v_UNIX_FD; #endif char **decomposed; message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", "Foo.TestInterface", "TestMethod"); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", "TestMethod")); _dbus_assert (strcmp (dbus_message_get_path (message), "/org/freedesktop/TestPath") == 0); dbus_message_set_serial (message, 1234); /* string length including nul byte not a multiple of 4 */ if (!dbus_message_set_sender (message, "org.foo.bar1")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); dbus_message_set_reply_serial (message, 5678); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); if (!dbus_message_set_sender (message, NULL)) _dbus_assert_not_reached ("out of memory"); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); _dbus_assert (dbus_message_get_serial (message) == 1234); _dbus_assert (dbus_message_get_reply_serial (message) == 5678); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); _dbus_assert (dbus_message_get_no_reply (message) == FALSE); dbus_message_set_no_reply (message, TRUE); _dbus_assert (dbus_message_get_no_reply (message) == TRUE); dbus_message_set_no_reply (message, FALSE); _dbus_assert (dbus_message_get_no_reply (message) == FALSE); /* Set/get some header fields */ if (!dbus_message_set_path (message, "/foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo") == 0); if (!dbus_message_set_interface (message, "org.Foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo") == 0); if (!dbus_message_set_member (message, "Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "Bar") == 0); /* Set/get them with longer values */ if (!dbus_message_set_path (message, "/foo/bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo/bar") == 0); if (!dbus_message_set_interface (message, "org.Foo.Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo.Bar") == 0); if (!dbus_message_set_member (message, "BarFoo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "BarFoo") == 0); /* Realloc shorter again */ if (!dbus_message_set_path (message, "/foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo") == 0); if (!dbus_message_set_interface (message, "org.Foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo") == 0); if (!dbus_message_set_member (message, "Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "Bar") == 0); /* Path decomposing */ dbus_message_set_path (message, NULL); dbus_message_get_path_decomposed (message, &decomposed); _dbus_assert (decomposed == NULL); dbus_free_string_array (decomposed); dbus_message_set_path (message, "/"); dbus_message_get_path_decomposed (message, &decomposed); _dbus_assert (decomposed != NULL); _dbus_assert (decomposed[0] == NULL); dbus_free_string_array (decomposed); dbus_message_set_path (message, "/a/b"); dbus_message_get_path_decomposed (message, &decomposed); _dbus_assert (decomposed != NULL); _dbus_assert (strcmp (decomposed[0], "a") == 0); _dbus_assert (strcmp (decomposed[1], "b") == 0); _dbus_assert (decomposed[2] == NULL); dbus_free_string_array (decomposed); dbus_message_set_path (message, "/spam/eggs"); dbus_message_get_path_decomposed (message, &decomposed); _dbus_assert (decomposed != NULL); _dbus_assert (strcmp (decomposed[0], "spam") == 0); _dbus_assert (strcmp (decomposed[1], "eggs") == 0); _dbus_assert (decomposed[2] == NULL); dbus_free_string_array (decomposed); dbus_message_unref (message); /* Test the vararg functions */ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", "Foo.TestInterface", "TestMethod"); dbus_message_set_serial (message, 1); dbus_message_set_reply_serial (message, 5678); v_INT16 = -0x123; v_UINT16 = 0x123; v_INT32 = -0x12345678; v_UINT32 = 0x12300042; #ifdef DBUS_HAVE_INT64 v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); #endif v_STRING = "Test string"; v_DOUBLE = 3.14159; v_BOOLEAN = TRUE; v_BYTE = 42; v2_BYTE = 24; #ifdef HAVE_UNIX_FD_PASSING v_UNIX_FD = 1; #endif dbus_message_append_args (message, DBUS_TYPE_INT16, &v_INT16, DBUS_TYPE_UINT16, &v_UINT16, DBUS_TYPE_INT32, &v_INT32, DBUS_TYPE_UINT32, &v_UINT32, #ifdef DBUS_HAVE_INT64 DBUS_TYPE_INT64, &v_INT64, DBUS_TYPE_UINT64, &v_UINT64, #endif DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_DOUBLE, &v_DOUBLE, DBUS_TYPE_BOOLEAN, &v_BOOLEAN, DBUS_TYPE_BYTE, &v_BYTE, DBUS_TYPE_BYTE, &v2_BYTE, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32, _DBUS_N_ELEMENTS (our_uint32_array), DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32, _DBUS_N_ELEMENTS (our_int32_array), #ifdef DBUS_HAVE_INT64 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64, _DBUS_N_ELEMENTS (our_uint64_array), DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64, _DBUS_N_ELEMENTS (our_int64_array), #endif DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE, _DBUS_N_ELEMENTS (our_double_array), DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE, _DBUS_N_ELEMENTS (our_byte_array), DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN, _DBUS_N_ELEMENTS (our_boolean_array), DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, _DBUS_N_ELEMENTS (our_string_array), DBUS_TYPE_INVALID); i = 0; sig[i++] = DBUS_TYPE_INT16; sig[i++] = DBUS_TYPE_UINT16; sig[i++] = DBUS_TYPE_INT32; sig[i++] = DBUS_TYPE_UINT32; #ifdef DBUS_HAVE_INT64 sig[i++] = DBUS_TYPE_INT64; sig[i++] = DBUS_TYPE_UINT64; #endif sig[i++] = DBUS_TYPE_STRING; sig[i++] = DBUS_TYPE_DOUBLE; sig[i++] = DBUS_TYPE_BOOLEAN; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_UINT32; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_INT32; #ifdef DBUS_HAVE_INT64 sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_UINT64; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_INT64; #endif sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_DOUBLE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_BOOLEAN; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_STRING; message_without_unix_fds = dbus_message_copy(message); _dbus_assert(message_without_unix_fds); #ifdef HAVE_UNIX_FD_PASSING dbus_message_append_args (message, DBUS_TYPE_UNIX_FD, &v_UNIX_FD, DBUS_TYPE_INVALID); sig[i++] = DBUS_TYPE_UNIX_FD; #endif sig[i++] = DBUS_TYPE_INVALID; _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); _dbus_verbose ("HEADER\n"); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose ("BODY\n"); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", sig, dbus_message_get_signature (message)); s = dbus_message_get_signature (message); _dbus_assert (dbus_message_has_signature (message, sig)); _dbus_assert (strcmp (s, sig) == 0); verify_test_message (message); copy = dbus_message_copy (message); _dbus_assert (dbus_message_get_reply_serial (message) == dbus_message_get_reply_serial (copy)); _dbus_assert (message->header.padding == copy->header.padding); _dbus_assert (_dbus_string_get_length (&message->header.data) == _dbus_string_get_length (©->header.data)); _dbus_assert (_dbus_string_get_length (&message->body) == _dbus_string_get_length (©->body)); verify_test_message (copy); name1 = dbus_message_get_interface (message); name2 = dbus_message_get_interface (copy); _dbus_assert (strcmp (name1, name2) == 0); name1 = dbus_message_get_member (message); name2 = dbus_message_get_member (copy); _dbus_assert (strcmp (name1, name2) == 0); dbus_message_unref (copy); /* Message loader test */ dbus_message_lock (message); loader = _dbus_message_loader_new (); /* check ref/unref */ _dbus_message_loader_ref (loader); _dbus_message_loader_unref (loader); /* Write the header data one byte at a time */ data = _dbus_string_get_const_data (&message->header.data); for (i = 0; i < _dbus_string_get_length (&message->header.data); i++) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer, 1); } /* Write the body data one byte at a time */ data = _dbus_string_get_const_data (&message->body); for (i = 0; i < _dbus_string_get_length (&message->body); i++) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer, 1); } #ifdef HAVE_UNIX_FD_PASSING { int *unix_fds; unsigned n_unix_fds; /* Write unix fd */ _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds); _dbus_assert(n_unix_fds > 0); _dbus_assert(message->n_unix_fds == 1); unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL); _dbus_assert(unix_fds[0] >= 0); _dbus_message_loader_return_unix_fds(loader, unix_fds, 1); } #endif dbus_message_unref (message); /* Now pop back the message */ if (!_dbus_message_loader_queue_messages (loader)) _dbus_assert_not_reached ("no memory to queue messages"); if (_dbus_message_loader_get_is_corrupted (loader)) _dbus_assert_not_reached ("message loader corrupted"); message = _dbus_message_loader_pop_message (loader); if (!message) _dbus_assert_not_reached ("received a NULL message"); if (dbus_message_get_reply_serial (message) != 5678) _dbus_assert_not_reached ("reply serial fields differ"); dbus_message_unref (message); /* ovveride the serial, since it was reset by dbus_message_copy() */ dbus_message_set_serial(message_without_unix_fds, 8901); dbus_message_lock (message_without_unix_fds); verify_test_message (message_without_unix_fds); { /* Marshal and demarshal the message. */ DBusMessage *message2; DBusError error = DBUS_ERROR_INIT; char *marshalled = NULL; int len = 0; char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx"; if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len)) _dbus_assert_not_reached ("failed to marshal message"); _dbus_assert (len != 0); _dbus_assert (marshalled != NULL); _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len); message2 = dbus_message_demarshal (marshalled, len, &error); _dbus_assert (message2 != NULL); _dbus_assert (!dbus_error_is_set (&error)); verify_test_message (message2); dbus_message_unref (message2); dbus_free (marshalled); /* Demarshal invalid message. */ message2 = dbus_message_demarshal ("invalid", 7, &error); _dbus_assert (message2 == NULL); _dbus_assert (dbus_error_is_set (&error)); dbus_error_free (&error); /* Demarshal invalid (empty) message. */ message2 = dbus_message_demarshal ("", 0, &error); _dbus_assert (message2 == NULL); _dbus_assert (dbus_error_is_set (&error)); dbus_error_free (&error); /* Bytes needed to demarshal empty message: 0 (more) */ _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0); /* Bytes needed to demarshal invalid message: -1 (error). */ _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1); } dbus_message_unref (message_without_unix_fds); _dbus_message_loader_unref (loader); check_memleaks (); _dbus_check_fdleaks(); /* Check that we can abandon a container */ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", "Foo.TestInterface", "Method"); dbus_message_iter_init_append (message, &iter); _dbus_assert (dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, (DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING), &array_iter)); _dbus_assert (dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter)); s = "peaches"; _dbus_assert (dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s)); /* uh-oh, error, try and unwind */ dbus_message_iter_abandon_container (&array_iter, &struct_iter); dbus_message_iter_abandon_container (&array_iter, &iter); dbus_message_unref (message); /* Load all the sample messages from the message factory */ { DBusMessageDataIter diter; DBusMessageData mdata; int count; reset_validities_seen (); count = 0; _dbus_message_data_iter_init (&diter); while (_dbus_message_data_iter_get_and_next (&diter, &mdata)) { if (!dbus_internal_do_not_use_try_message_data (&mdata.data, mdata.expected_validity)) { _dbus_warn ("expected validity %d and did not get it\n", mdata.expected_validity); _dbus_assert_not_reached ("message data failed"); } _dbus_message_data_free (&mdata); count += 1; } printf ("%d sample messages tested\n", count); print_validities_seen (FALSE); print_validities_seen (TRUE); } check_memleaks (); _dbus_check_fdleaks(); /* Now load every message in test_data_dir if we have one */ if (test_data_dir == NULL) return TRUE; return dbus_internal_do_not_use_foreach_message_file (test_data_dir, (DBusForeachMessageFileFunc) dbus_internal_do_not_use_try_message_file, NULL); }
/** * Tries loading the given message data. * * * @param data the message data * @param expected_validity what the message has to be like to return #TRUE * @returns #TRUE if the message has the expected validity */ dbus_bool_t dbus_internal_do_not_use_try_message_data (const DBusString *data, DBusValidity expected_validity) { DBusMessageLoader *loader; dbus_bool_t retval; int len; int i; loader = NULL; retval = FALSE; /* Write the data one byte at a time */ loader = _dbus_message_loader_new (); /* check some trivial loader functions */ _dbus_message_loader_ref (loader); _dbus_message_loader_unref (loader); _dbus_message_loader_get_max_message_size (loader); len = _dbus_string_get_length (data); for (i = 0; i < len; i++) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, _dbus_string_get_byte (data, i)); _dbus_message_loader_return_buffer (loader, buffer, 1); } if (!check_loader_results (loader, expected_validity)) goto failed; _dbus_message_loader_unref (loader); loader = NULL; /* Write the data all at once */ loader = _dbus_message_loader_new (); { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_copy (data, 0, buffer, _dbus_string_get_length (buffer)); _dbus_message_loader_return_buffer (loader, buffer, 1); } if (!check_loader_results (loader, expected_validity)) goto failed; _dbus_message_loader_unref (loader); loader = NULL; /* Write the data 2 bytes at a time */ loader = _dbus_message_loader_new (); len = _dbus_string_get_length (data); for (i = 0; i < len; i += 2) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, _dbus_string_get_byte (data, i)); if ((i+1) < len) _dbus_string_append_byte (buffer, _dbus_string_get_byte (data, i+1)); _dbus_message_loader_return_buffer (loader, buffer, 1); } if (!check_loader_results (loader, expected_validity)) goto failed; _dbus_message_loader_unref (loader); loader = NULL; retval = TRUE; failed: if (loader) _dbus_message_loader_unref (loader); return retval; }
dbus_bool_t _dbus_misc_test (void) { int major, minor, micro; DBusString str; /* make sure we don't crash on NULL */ dbus_get_version (NULL, NULL, NULL); /* Now verify that all the compile-time version stuff * is right and matches the runtime. These tests * are mostly intended to catch various kinds of * typo (mixing up major and minor, that sort of thing). */ dbus_get_version (&major, &minor, µ); _dbus_assert (major == DBUS_MAJOR_VERSION); _dbus_assert (minor == DBUS_MINOR_VERSION); _dbus_assert (micro == DBUS_MICRO_VERSION); #define MAKE_VERSION(x, y, z) (((x) << 16) | ((y) << 8) | (z)) /* check that MAKE_VERSION works and produces the intended ordering */ _dbus_assert (MAKE_VERSION (1, 0, 0) > MAKE_VERSION (0, 0, 0)); _dbus_assert (MAKE_VERSION (1, 1, 0) > MAKE_VERSION (1, 0, 0)); _dbus_assert (MAKE_VERSION (1, 1, 1) > MAKE_VERSION (1, 1, 0)); _dbus_assert (MAKE_VERSION (2, 0, 0) > MAKE_VERSION (1, 1, 1)); _dbus_assert (MAKE_VERSION (2, 1, 0) > MAKE_VERSION (1, 1, 1)); _dbus_assert (MAKE_VERSION (2, 1, 1) > MAKE_VERSION (1, 1, 1)); /* check DBUS_VERSION */ _dbus_assert (MAKE_VERSION (major, minor, micro) == DBUS_VERSION); /* check that ordering works with DBUS_VERSION */ _dbus_assert (MAKE_VERSION (major - 1, minor, micro) < DBUS_VERSION); _dbus_assert (MAKE_VERSION (major, minor - 1, micro) < DBUS_VERSION); _dbus_assert (MAKE_VERSION (major, minor, micro - 1) < DBUS_VERSION); _dbus_assert (MAKE_VERSION (major + 1, minor, micro) > DBUS_VERSION); _dbus_assert (MAKE_VERSION (major, minor + 1, micro) > DBUS_VERSION); _dbus_assert (MAKE_VERSION (major, minor, micro + 1) > DBUS_VERSION); /* Check DBUS_VERSION_STRING */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!(_dbus_string_append_int (&str, major) && _dbus_string_append_byte (&str, '.') && _dbus_string_append_int (&str, minor) && _dbus_string_append_byte (&str, '.') && _dbus_string_append_int (&str, micro))) _dbus_assert_not_reached ("no memory"); _dbus_assert (_dbus_string_equal_c_str (&str, DBUS_VERSION_STRING)); _dbus_string_free (&str); return TRUE; }
/** * @ingroup DBusMessageInternals * Unit test for DBusMessage. * * @returns #TRUE on success. */ dbus_bool_t _dbus_message_test (const char *test_data_dir) { DBusMessage *message; DBusMessageLoader *loader; int i; const char *data; DBusMessage *copy; const char *name1; const char *name2; const dbus_uint32_t our_uint32_array[] = { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; const dbus_int32_t our_int32_array[] = { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array; const dbus_int32_t *v_ARRAY_INT32 = our_int32_array; #ifdef DBUS_HAVE_INT64 const dbus_uint64_t our_uint64_array[] = { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; const dbus_int64_t our_int64_array[] = { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array; const dbus_int64_t *v_ARRAY_INT64 = our_int64_array; #endif const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; const char **v_ARRAY_STRING = our_string_array; const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; const double *v_ARRAY_DOUBLE = our_double_array; const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; const unsigned char *v_ARRAY_BYTE = our_byte_array; const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array; char sig[64]; const char *s; const char *v_STRING; double v_DOUBLE; dbus_int16_t v_INT16; dbus_uint16_t v_UINT16; dbus_int32_t v_INT32; dbus_uint32_t v_UINT32; #ifdef DBUS_HAVE_INT64 dbus_int64_t v_INT64; dbus_uint64_t v_UINT64; #endif unsigned char v_BYTE; unsigned char v2_BYTE; dbus_bool_t v_BOOLEAN; message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", "Foo.TestInterface", "TestMethod"); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", "TestMethod")); _dbus_assert (strcmp (dbus_message_get_path (message), "/org/freedesktop/TestPath") == 0); _dbus_message_set_serial (message, 1234); /* string length including nul byte not a multiple of 4 */ if (!dbus_message_set_sender (message, "org.foo.bar1")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); dbus_message_set_reply_serial (message, 5678); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); if (!dbus_message_set_sender (message, NULL)) _dbus_assert_not_reached ("out of memory"); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); _dbus_assert (dbus_message_get_serial (message) == 1234); _dbus_assert (dbus_message_get_reply_serial (message) == 5678); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); _dbus_assert (dbus_message_get_no_reply (message) == FALSE); dbus_message_set_no_reply (message, TRUE); _dbus_assert (dbus_message_get_no_reply (message) == TRUE); dbus_message_set_no_reply (message, FALSE); _dbus_assert (dbus_message_get_no_reply (message) == FALSE); /* Set/get some header fields */ if (!dbus_message_set_path (message, "/foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo") == 0); if (!dbus_message_set_interface (message, "org.Foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo") == 0); if (!dbus_message_set_member (message, "Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "Bar") == 0); /* Set/get them with longer values */ if (!dbus_message_set_path (message, "/foo/bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo/bar") == 0); if (!dbus_message_set_interface (message, "org.Foo.Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo.Bar") == 0); if (!dbus_message_set_member (message, "BarFoo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "BarFoo") == 0); /* Realloc shorter again */ if (!dbus_message_set_path (message, "/foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo") == 0); if (!dbus_message_set_interface (message, "org.Foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo") == 0); if (!dbus_message_set_member (message, "Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "Bar") == 0); dbus_message_unref (message); /* Test the vararg functions */ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", "Foo.TestInterface", "TestMethod"); _dbus_message_set_serial (message, 1); dbus_message_set_reply_serial (message, 5678); v_INT16 = -0x123; v_UINT16 = 0x123; v_INT32 = -0x12345678; v_UINT32 = 0x12300042; #ifdef DBUS_HAVE_INT64 v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); #endif v_STRING = "Test string"; v_DOUBLE = 3.14159; v_BOOLEAN = TRUE; v_BYTE = 42; v2_BYTE = 24; dbus_message_append_args (message, DBUS_TYPE_INT16, &v_INT16, DBUS_TYPE_UINT16, &v_UINT16, DBUS_TYPE_INT32, &v_INT32, DBUS_TYPE_UINT32, &v_UINT32, #ifdef DBUS_HAVE_INT64 DBUS_TYPE_INT64, &v_INT64, DBUS_TYPE_UINT64, &v_UINT64, #endif DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_DOUBLE, &v_DOUBLE, DBUS_TYPE_BOOLEAN, &v_BOOLEAN, DBUS_TYPE_BYTE, &v_BYTE, DBUS_TYPE_BYTE, &v2_BYTE, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32, _DBUS_N_ELEMENTS (our_uint32_array), DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32, _DBUS_N_ELEMENTS (our_int32_array), #ifdef DBUS_HAVE_INT64 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64, _DBUS_N_ELEMENTS (our_uint64_array), DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64, _DBUS_N_ELEMENTS (our_int64_array), #endif DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE, _DBUS_N_ELEMENTS (our_double_array), DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE, _DBUS_N_ELEMENTS (our_byte_array), DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN, _DBUS_N_ELEMENTS (our_boolean_array), DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, _DBUS_N_ELEMENTS (our_string_array), DBUS_TYPE_INVALID); i = 0; sig[i++] = DBUS_TYPE_INT16; sig[i++] = DBUS_TYPE_UINT16; sig[i++] = DBUS_TYPE_INT32; sig[i++] = DBUS_TYPE_UINT32; #ifdef DBUS_HAVE_INT64 sig[i++] = DBUS_TYPE_INT64; sig[i++] = DBUS_TYPE_UINT64; #endif sig[i++] = DBUS_TYPE_STRING; sig[i++] = DBUS_TYPE_DOUBLE; sig[i++] = DBUS_TYPE_BOOLEAN; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_UINT32; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_INT32; #ifdef DBUS_HAVE_INT64 sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_UINT64; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_INT64; #endif sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_DOUBLE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_BOOLEAN; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_STRING; sig[i++] = DBUS_TYPE_INVALID; _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); _dbus_verbose ("HEADER\n"); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose ("BODY\n"); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", sig, dbus_message_get_signature (message)); s = dbus_message_get_signature (message); _dbus_assert (dbus_message_has_signature (message, sig)); _dbus_assert (strcmp (s, sig) == 0); verify_test_message (message); copy = dbus_message_copy (message); _dbus_assert (dbus_message_get_reply_serial (message) == dbus_message_get_reply_serial (copy)); _dbus_assert (message->header.padding == copy->header.padding); _dbus_assert (_dbus_string_get_length (&message->header.data) == _dbus_string_get_length (©->header.data)); _dbus_assert (_dbus_string_get_length (&message->body) == _dbus_string_get_length (©->body)); verify_test_message (copy); name1 = dbus_message_get_interface (message); name2 = dbus_message_get_interface (copy); _dbus_assert (strcmp (name1, name2) == 0); name1 = dbus_message_get_member (message); name2 = dbus_message_get_member (copy); _dbus_assert (strcmp (name1, name2) == 0); dbus_message_unref (copy); /* Message loader test */ _dbus_message_lock (message); loader = _dbus_message_loader_new (); /* check ref/unref */ _dbus_message_loader_ref (loader); _dbus_message_loader_unref (loader); /* Write the header data one byte at a time */ data = _dbus_string_get_const_data (&message->header.data); for (i = 0; i < _dbus_string_get_length (&message->header.data); i++) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer, 1); } /* Write the body data one byte at a time */ data = _dbus_string_get_const_data (&message->body); for (i = 0; i < _dbus_string_get_length (&message->body); i++) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer, 1); } dbus_message_unref (message); /* Now pop back the message */ if (!_dbus_message_loader_queue_messages (loader)) _dbus_assert_not_reached ("no memory to queue messages"); if (_dbus_message_loader_get_is_corrupted (loader)) _dbus_assert_not_reached ("message loader corrupted"); message = _dbus_message_loader_pop_message (loader); if (!message) _dbus_assert_not_reached ("received a NULL message"); if (dbus_message_get_reply_serial (message) != 5678) _dbus_assert_not_reached ("reply serial fields differ"); verify_test_message (message); dbus_message_unref (message); _dbus_message_loader_unref (loader); check_memleaks (); /* Load all the sample messages from the message factory */ { DBusMessageDataIter diter; DBusMessageData mdata; int count; reset_validities_seen (); count = 0; _dbus_message_data_iter_init (&diter); while (_dbus_message_data_iter_get_and_next (&diter, &mdata)) { if (!dbus_internal_do_not_use_try_message_data (&mdata.data, mdata.expected_validity)) { _dbus_warn ("expected validity %d and did not get it\n", mdata.expected_validity); _dbus_assert_not_reached ("message data failed"); } _dbus_message_data_free (&mdata); count += 1; } printf ("%d sample messages tested\n", count); print_validities_seen (FALSE); print_validities_seen (TRUE); } check_memleaks (); /* Now load every message in test_data_dir if we have one */ if (test_data_dir == NULL) return TRUE; return dbus_internal_do_not_use_foreach_message_file (test_data_dir, (DBusForeachMessageFileFunc) dbus_internal_do_not_use_try_message_file, NULL); }
static dbus_bool_t test_command_line (const char *arg1, ...) { int i, original_argc, shell_argc; char **shell_argv; char **original_argv; char *command_line, *tmp; DBusString str; DBusList *list = NULL, *node; va_list var_args; DBusError error; va_start (var_args, arg1); _dbus_list_append (&list, (char *)arg1); do { tmp = va_arg (var_args, char *); if (!tmp) break; _dbus_list_append (&list, tmp); } while (tmp); va_end (var_args); original_argc = _dbus_list_get_length (&list); original_argv = dbus_new (char *, original_argc); _dbus_string_init (&str); for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node; i++, node = _dbus_list_get_next_link (&list, node)) { original_argv[i] = node->data; if (i > 0) _dbus_string_append_byte (&str, ' '); _dbus_string_append (&str, original_argv[i]); } _dbus_list_clear (&list); command_line = _dbus_string_get_data (&str); printf ("\n\nTesting command line '%s'\n", command_line); dbus_error_init (&error); if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error)) { fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : ""); return FALSE; } else { if (shell_argc != original_argc) { printf ("Number of arguments returned (%d) don't match original (%d)\n", shell_argc, original_argc); return FALSE; } printf ("Number of arguments: %d\n", shell_argc); for (i = 0; i < shell_argc; i++) { char *unquoted; unquoted = _dbus_shell_unquote (original_argv[i]); if (strcmp (unquoted ? unquoted : "", shell_argv[i] ? shell_argv[i] : "")) { printf ("Position %d, returned argument (%s) does not match original (%s)\n", i, shell_argv[i], unquoted); dbus_free (unquoted); return FALSE; } dbus_free (unquoted); if (shell_argv[i]) printf ("Argument %d = %s\n", i, shell_argv[i]); } dbus_free_string_array (shell_argv); } _dbus_string_free (&str); return TRUE; }
static DBusList* tokenize_command_line (const char *command_line, DBusError *error) { char current_quote; const char *p; DBusString current_token; DBusList *retval = NULL; dbus_bool_t quoted;; current_quote = '\0'; quoted = FALSE; p = command_line; if (!_dbus_string_init (¤t_token)) { _DBUS_SET_OOM (error); return NULL; } while (*p) { if (current_quote == '\\') { if (*p == '\n') { /* we append nothing; backslash-newline become nothing */ } else { if (!_dbus_string_append_byte (¤t_token, '\\') || !_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } } current_quote = '\0'; } else if (current_quote == '#') { /* Discard up to and including next newline */ while (*p && *p != '\n') ++p; current_quote = '\0'; if (*p == '\0') break; } else if (current_quote) { if (*p == current_quote && /* check that it isn't an escaped double quote */ !(current_quote == '"' && quoted)) { /* close the quote */ current_quote = '\0'; } /* Everything inside quotes, and the close quote, * gets appended literally. */ if (!_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } } else { switch (*p) { case '\n': if (!delimit_token (¤t_token, &retval, error)) goto error; _dbus_string_free (¤t_token); if (!_dbus_string_init (¤t_token)) { _DBUS_SET_OOM (error); goto init_error; } break; case ' ': case '\t': /* If the current token contains the previous char, delimit * the current token. A nonzero length * token should always contain the previous char. */ if (_dbus_string_get_length (¤t_token) > 0) { if (!delimit_token (¤t_token, &retval, error)) goto error; _dbus_string_free (¤t_token); if (!_dbus_string_init (¤t_token)) { _DBUS_SET_OOM (error); goto init_error; } } /* discard all unquoted blanks (don't add them to a token) */ break; /* single/double quotes are appended to the token, * escapes are maybe appended next time through the loop, * comment chars are never appended. */ case '\'': case '"': if (!_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } /* FALL THRU */ case '#': case '\\': current_quote = *p; break; default: /* Combines rules 4) and 6) - if we have a token, append to it, * otherwise create a new token. */ if (!_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } break; } } /* We need to count consecutive backslashes mod 2, * to detect escaped doublequotes. */ if (*p != '\\') quoted = FALSE; else quoted = !quoted; ++p; } if (!delimit_token (¤t_token, &retval, error)) goto error; if (current_quote) { dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "Unclosed quotes in command line"); goto error; } if (retval == NULL) { dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "No tokens found in command line"); goto error; } _dbus_string_free (¤t_token); return retval; error: _dbus_string_free (¤t_token); init_error: if (retval) { _dbus_list_foreach (&retval, (DBusForeachFunction) dbus_free, NULL); _dbus_list_clear (&retval); } return NULL; }
/** * Unquotes a string as the shell (/bin/sh) would. Only handles * quotes; if a string contains file globs, arithmetic operators, * variables, backticks, redirections, or other special-to-the-shell * features, the result will be different from the result a real shell * would produce (the variables, backticks, etc. will be passed * through literally instead of being expanded). This function is * guaranteed to succeed if applied to the result of * _dbus_shell_quote(). If it fails, it returns %NULL. * The @quoted_string need not actually contain quoted or * escaped text; _dbus_shell_unquote() simply goes through the string and * unquotes/unescapes anything that the shell would. Both single and * double quotes are handled, as are escapes including escaped * newlines. The return value must be freed with dbus_free(). * * Shell quoting rules are a bit strange. Single quotes preserve the * literal string exactly. escape sequences are not allowed; not even * \' - if you want a ' in the quoted text, you have to do something * like 'foo'\''bar'. Double quotes allow $, `, ", \, and newline to * be escaped with backslash. Otherwise double quotes preserve things * literally. * * @quoted_string: shell-quoted string **/ char* _dbus_shell_unquote (const char *quoted_string) { char *unquoted; char *end; char *start; char *ret; DBusString retval; unquoted = _dbus_strdup (quoted_string); if (unquoted == NULL) return NULL; start = unquoted; end = unquoted; if (!_dbus_string_init (&retval)) { dbus_free (unquoted); return NULL; } /* The loop allows cases such as * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo' */ while (*start) { /* Append all non-quoted chars, honoring backslash escape */ while (*start && !(*start == '"' || *start == '\'')) { if (*start == '\\') { /* all characters can get escaped by backslash, * except newline, which is removed if it follows * a backslash outside of quotes */ ++start; if (*start) { if (*start != '\n') { if (!_dbus_string_append_byte (&retval, *start)) goto error; } ++start; } } else { if (!_dbus_string_append_byte (&retval, *start)) goto error; ++start; } } if (*start) { if (!unquote_string_inplace (start, &end)) goto error; else { if (!_dbus_string_append (&retval, start)) goto error; start = end; } } } ret = _dbus_strdup (_dbus_string_get_data (&retval)); if (!ret) goto error; dbus_free (unquoted); _dbus_string_free (&retval); return ret; error: dbus_free (unquoted); _dbus_string_free (&retval); return NULL; }
static dbus_bool_t try_mutated_data (const DBusString *data) { int pid; total_attempts += 1; /* printf (" attempt %d\n", total_attempts); */ pid = fork (); if (pid < 0) { fprintf (stderr, "fork() failed: %s\n", strerror (errno)); exit (1); return FALSE; } if (pid == 0) { /* Child, try loading the data */ if (!dbus_internal_do_not_use_try_message_data (data, _DBUS_MESSAGE_UNKNOWN)) exit (1); else exit (0); } else { /* Parent, wait for child */ int status; DBusString filename; dbus_bool_t failed; if (waitpid (pid, &status, 0) < 0) { fprintf (stderr, "waitpid() failed: %s\n", strerror (errno)); exit (1); return FALSE; } failed = FALSE; if (!_dbus_string_init (&filename) || !_dbus_string_copy (&failure_dir, 0, &filename, 0) || !_dbus_string_append_byte (&filename, '/')) { fprintf (stderr, "out of memory\n"); exit (1); } _dbus_string_append_int (&filename, total_attempts); if (WIFEXITED (status)) { if (WEXITSTATUS (status) != 0) { _dbus_string_append (&filename, "-exited-"); _dbus_string_append_int (&filename, WEXITSTATUS (status)); failed = TRUE; } } else if (WIFSIGNALED (status)) { _dbus_string_append (&filename, "signaled-"); _dbus_string_append_int (&filename, WTERMSIG (status)); failed = TRUE; } if (failed) { DBusError error; _dbus_string_append (&filename, ".message-raw"); printf ("Child failed, writing %s\n", _dbus_string_get_const_data (&filename)); dbus_error_init (&error); if (!_dbus_string_save_to_file (data, &filename, FALSE, &error)) { fprintf (stderr, "Failed to save failed message data: %s\n", error.message); dbus_error_free (&error); exit (1); /* so we can see the seed that was printed out */ } failures_this_iteration += 1; _dbus_string_free (&filename); return FALSE; } else { _dbus_string_free (&filename); return TRUE; } } _dbus_assert_not_reached ("should not be reached"); 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; }
/* this is slightly different from the other append_quoted_string * in dbus-message-builder.c */ static dbus_bool_t append_quoted_string (DBusString *dest, const DBusString *quoted) { dbus_bool_t in_quotes = FALSE; dbus_bool_t in_backslash = FALSE; int i; i = 0; while (i < _dbus_string_get_length (quoted)) { unsigned char b; b = _dbus_string_get_byte (quoted, i); if (in_backslash) { unsigned char a; if (b == 'r') a = '\r'; else if (b == 'n') a = '\n'; else if (b == '\\') a = '\\'; else { _dbus_warn ("bad backslashed byte %c\n", b); return FALSE; } if (!_dbus_string_append_byte (dest, a)) return FALSE; in_backslash = FALSE; } else if (b == '\\') { in_backslash = TRUE; } else if (in_quotes) { if (b == '\'') in_quotes = FALSE; else { if (!_dbus_string_append_byte (dest, b)) return FALSE; } } else { if (b == '\'') in_quotes = TRUE; else if (b == ' ' || b == '\n' || b == '\t') break; /* end on whitespace if not quoted */ else { if (!_dbus_string_append_byte (dest, b)) return FALSE; } } ++i; } return TRUE; }