diff --git a/bus/Makefile.am b/bus/Makefile.am index fe0f92b1..455437a8 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -82,7 +82,9 @@ DIR_WATCH_SOURCE=dir-watch-default.c endif endif -BUS_SOURCES= \ +noinst_LTLIBRARIES = libdbus-daemon-internal.la + +libdbus_daemon_internal_la_SOURCES = \ activation.c \ activation.h \ activation-exit-codes.h \ @@ -127,17 +129,17 @@ BUS_SOURCES= \ utils.h \ $(NULL) -dbus_daemon_SOURCES= \ - $(BUS_SOURCES) \ - main.c +libdbus_daemon_internal_la_LIBADD = \ + $(top_builddir)/dbus/libdbus-1.la \ + $(top_builddir)/dbus/libdbus-internal.la \ + $(EFENCE) \ + $(DBUS_BUS_LIBS) \ + $(NULL) -dbus_daemon_LDADD= \ - $(top_builddir)/dbus/libdbus-1.la \ - $(top_builddir)/dbus/libdbus-internal.la \ - $(EFENCE) \ - $(DBUS_BUS_LIBS) +dbus_daemon_SOURCES = main.c +dbus_daemon_LDADD = libdbus-daemon-internal.la -LAUNCH_HELPER_SOURCES= \ +liblaunch_helper_internal_la_SOURCES = \ config-loader-expat.c \ config-parser-common.c \ config-parser-common.h \ @@ -149,103 +151,30 @@ LAUNCH_HELPER_SOURCES= \ utils.h \ activation-exit-codes.h \ activation-helper.h \ - activation-helper.c - -## This is the installed launch helper with the setuid checks -dbus_daemon_launch_helper_SOURCES= \ - activation-helper-bin.c \ - $(LAUNCH_HELPER_SOURCES) - -dbus_daemon_launch_helper_LDADD= \ - $(top_builddir)/dbus/libdbus-1.la \ - $(top_builddir)/dbus/libdbus-internal.la \ - $(DBUS_LAUNCHER_LIBS) - -## we build another binary so we can do the launch testing without root privs. -## DO NOT INSTALL THIS FILE -dbus_daemon_launch_helper_test_SOURCES= \ - activation-helper-bin.c \ - $(LAUNCH_HELPER_SOURCES) - -dbus_daemon_launch_helper_test_LDADD= \ - $(top_builddir)/dbus/libdbus-1.la \ - $(top_builddir)/dbus/libdbus-internal.la \ - $(DBUS_LAUNCHER_LIBS) - -dbus_daemon_launch_helper_test_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DACTIVATION_LAUNCHER_TEST - -## we build yet another binary so we can do the OOM tests -## DO NOT INSTALL THIS FILE -test_bus_launch_helper_SOURCES= \ - test-launch-helper.c \ - $(LAUNCH_HELPER_SOURCES) - -test_bus_launch_helper_LDADD= \ - $(top_builddir)/dbus/libdbus-1.la \ - $(top_builddir)/dbus/libdbus-internal.la \ - $(DBUS_LAUNCHER_LIBS) $(NULL) -test_bus_launch_helper_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DACTIVATION_LAUNCHER_TEST \ - -DACTIVATION_LAUNCHER_DO_OOM +## This is the installed launch helper with the setuid checks +## All files that have special cases #ifdef ACTIVATION_LAUNCHER_TEST must +## be listed here and included in test/bus/launch-helper-for-tests.c, +## not in liblaunch-helper-internal.la. +dbus_daemon_launch_helper_SOURCES = \ + activation-helper.c \ + activation-helper-bin.c \ + $(NULL) +dbus_daemon_launch_helper_LDADD = liblaunch-helper-internal.la + +liblaunch_helper_internal_la_LIBADD = \ + $(top_builddir)/dbus/libdbus-1.la \ + $(top_builddir)/dbus/libdbus-internal.la \ + $(DBUS_LAUNCHER_LIBS) noinst_PROGRAMS = dbus_daemon_exec_PROGRAMS = dbus-daemon if DBUS_UNIX +noinst_LTLIBRARIES += liblaunch-helper-internal.la libexec_PROGRAMS = dbus-daemon-launch-helper endif DBUS_UNIX -## Note that TESTS has special meaning (stuff to use in make check). -## We don't actually want to run any of these tests until test/ has been -## compiled, so we don't put them in TESTS here; we run them in test/ -## instead. - -if DBUS_ENABLE_EMBEDDED_TESTS -## we use noinst_PROGRAMS not check_PROGRAMS so that we build -## even when not doing "make check" - -# run as a test by test/Makefile.am -noinst_PROGRAMS += test-bus - -if DBUS_UNIX -# run as a test by test/Makefile.am -noinst_PROGRAMS += test-bus-launch-helper test-bus-system -# this is used by the tests but is not,itself, a test -noinst_PROGRAMS += dbus-daemon-launch-helper-test -endif DBUS_UNIX - -endif DBUS_ENABLE_EMBEDDED_TESTS - -test_bus_system_SOURCES= \ - config-loader-expat.c \ - config-parser-common.c \ - config-parser-common.h \ - config-parser-trivial.c \ - config-parser-trivial.h \ - utils.c \ - utils.h \ - test-system.c - -test_bus_system_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(top_builddir)/dbus/libdbus-internal.la \ - $(DBUS_BUS_LIBS) \ - $(NULL) - -test_bus_SOURCES= \ - $(BUS_SOURCES) \ - test-main.c - -test_bus_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(top_builddir)/dbus/libdbus-internal.la \ - $(DBUS_BUS_LIBS) \ - $(NULL) - install-data-hook: $(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/session.d $(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/services diff --git a/bus/test.c b/bus/test.c index 730cd64a..42651e77 100644 --- a/bus/test.c +++ b/bus/test.c @@ -1,7 +1,9 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* test.c unit test routines * - * Copyright (C) 2003 Red Hat, Inc. + * Copyright 2003-2004 Red Hat, Inc. + * Copyright 2011 Collabora Ltd. + * Copyright 2018 Laurent Bigonville * * Licensed under the Academic Free License version 2.1 * diff --git a/bus/test.h b/bus/test.h index b80a3d76..6f1f6b0d 100644 --- a/bus/test.h +++ b/bus/test.h @@ -1,7 +1,10 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* test.h unit test routines * - * Copyright (C) 2003 Red Hat, Inc. + * Copyright 2003-2007 Red Hat, Inc. + * Copyright 2003-2004 Imendio + * Copyright 2009 Lennart Poettering + * Copyright 2018 Collabora Ltd. * * Licensed under the Academic Free License version 2.1 * diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 429205b3..336fd049 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -495,7 +495,7 @@ if (DBUS_BUILD_TESTS) set(DBUS_TEST_DBUS_LAUNCH ${Z_DRIVE_IF_WINE}${CMAKE_RUNTIME_OUTPUT_DIRECTORY}${IDE_BIN}/dbus-launch${EXEEXT}) set(DBUS_TEST_HOMEDIR ${Z_DRIVE_IF_WINE}${CMAKE_BINARY_DIR}/dbus) set(DBUS_TEST_RUN_SESSION ${Z_DRIVE_IF_WINE}${CMAKE_RUNTIME_OUTPUT_DIRECTORY}${IDE_BIN}/dbus-run-session${EXEEXT}) - set(TEST_LAUNCH_HELPER_BINARY ${Z_DRIVE_IF_WINE}${CMAKE_RUNTIME_OUTPUT_DIRECTORY}${IDE_BIN}/dbus-daemon-launch-helper-test${EXEEXT}) + set(TEST_LAUNCH_HELPER_BINARY ${Z_DRIVE_IF_WINE}${DBUS_TEST_EXEC}/dbus-daemon-launch-helper-for-tests${EXEEXT}) if (UNIX) set(TEST_SOCKET_DIR ${DBUS_SESSION_SOCKET_DIR}) set(TEST_LISTEN "unix:tmpdir=${TEST_SOCKET_DIR}") diff --git a/cmake/bus/CMakeLists.txt b/cmake/bus/CMakeLists.txt index 8c0c8e66..47479dfb 100644 --- a/cmake/bus/CMakeLists.txt +++ b/cmake/bus/CMakeLists.txt @@ -98,8 +98,11 @@ if(WIN32) list(APPEND BUS_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/versioninfo-${DBUS_VER_INTERNAL_NAME}.rc) endif() -add_executable(dbus-daemon ${BUS_SOURCES} ${BUS_DIR}/main.c) -target_link_libraries(dbus-daemon ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES}) +add_library(dbus-daemon-internal STATIC ${BUS_SOURCES}) +target_link_libraries(dbus-daemon-internal ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES}) + +add_executable(dbus-daemon ${BUS_DIR}/main.c) +target_link_libraries(dbus-daemon dbus-daemon-internal) set_target_properties(dbus-daemon PROPERTIES OUTPUT_NAME ${DBUS_DAEMON_NAME}) set_target_properties(dbus-daemon PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) @@ -142,39 +145,16 @@ set(LAUNCH_HELPER_SOURCES ${BUS_DIR}/config-parser-trivial.c ${BUS_DIR}/desktop-file.c ${BUS_DIR}/utils.c - ${BUS_DIR}/activation-helper.c ) if(NOT WIN32) - add_executable(dbus-daemon-launch-helper ${LAUNCH_HELPER_SOURCES} ${BUS_DIR}/activation-helper-bin.c ) - target_link_libraries(dbus-daemon-launch-helper ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES} ) - install(TARGETS dbus-daemon-launch-helper ${INSTALL_TARGETS_DEFAULT_ARGS} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}) + add_library(launch-helper-internal STATIC ${LAUNCH_HELPER_SOURCES}) + target_link_libraries(launch-helper-internal ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES}) + + add_executable(dbus-daemon-launch-helper ${BUS_DIR}/activation-helper.c ${BUS_DIR}/activation-helper-bin.c ) + target_link_libraries(dbus-daemon-launch-helper launch-helper-internal) endif(NOT WIN32) -if (DBUS_ENABLE_EMBEDDED_TESTS) - set(SOURCES ${BUS_SOURCES} ${BUS_DIR}/test-main.c) - add_test_executable(test-bus "${SOURCES}" ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES}) - set_target_properties(test-bus PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) - if (NOT WIN32) - set(test_bus_system_SOURCES - ${BUS_DIR}/config-loader-expat.c - ${BUS_DIR}/config-parser-common.c - ${BUS_DIR}/config-parser-trivial.c - ${BUS_DIR}/utils.c - ${BUS_DIR}/test-system.c - ) - add_test_executable(test-bus-system "${test_bus_system_SOURCES}" ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES} ${DBUS_BUS_LIBS}) - - add_executable(dbus-daemon-launch-helper-test ${LAUNCH_HELPER_SOURCES} ${BUS_DIR}/activation-helper-bin.c) - set_target_properties(dbus-daemon-launch-helper-test PROPERTIES COMPILE_FLAGS "-DACTIVATION_LAUNCHER_TEST") - target_link_libraries(dbus-daemon-launch-helper-test ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES} ) - - set (SOURCES ${LAUNCH_HELPER_SOURCES} ${BUS_DIR}/test-launch-helper.c) - add_test_executable(test-bus-launch-helper "${SOURCES}" ${DBUS_INTERNAL_LIBRARIES} ${EXPAT_LIBRARIES}) - set_target_properties(test-bus-launch-helper PROPERTIES COMPILE_FLAGS "-DACTIVATION_LAUNCHER_TEST -DACTIVATION_LAUNCHER_DO_OOM") - endif() -endif (DBUS_ENABLE_EMBEDDED_TESTS) - if(MSVC) project_source_group(${GROUP_CODE} bus_test_SOURCES dummy) endif(MSVC) diff --git a/cmake/dbus/CMakeLists.txt b/cmake/dbus/CMakeLists.txt index 77b6c10a..2a695d84 100644 --- a/cmake/dbus/CMakeLists.txt +++ b/cmake/dbus/CMakeLists.txt @@ -152,14 +152,7 @@ set (DBUS_SHARED_HEADERS ### to be unless they move to DBUS_SHARED_SOURCES later) set (DBUS_UTIL_SOURCES ${DBUS_DIR}/dbus-asv-util.c - ${DBUS_DIR}/dbus-auth-script.c - ${DBUS_DIR}/dbus-auth-util.c - ${DBUS_DIR}/dbus-credentials-util.c ${DBUS_DIR}/dbus-mainloop.c - ${DBUS_DIR}/dbus-marshal-byteswap-util.c - ${DBUS_DIR}/dbus-marshal-recursive-util.c - ${DBUS_DIR}/dbus-marshal-validate-util.c - ${DBUS_DIR}/dbus-message-factory.c ${DBUS_DIR}/dbus-message-util.c ${DBUS_DIR}/dbus-shell.c ${DBUS_DIR}/dbus-pollable-set.c @@ -168,24 +161,13 @@ set (DBUS_UTIL_SOURCES ${DBUS_DIR}/dbus-sysdeps-util.c ) -if (DBUS_ENABLE_EMBEDDED_TESTS) - set (DBUS_UTIL_SOURCES - ${DBUS_UTIL_SOURCES} - ${DBUS_DIR}/dbus-spawn-test.c - ${DBUS_DIR}/dbus-test-wrappers.c - ) -endif (DBUS_ENABLE_EMBEDDED_TESTS) - set (DBUS_UTIL_HEADERS ${DBUS_DIR}/dbus-asv-util.h - ${DBUS_DIR}/dbus-auth-script.h ${DBUS_DIR}/dbus-mainloop.h - ${DBUS_DIR}/dbus-message-factory.h ${DBUS_DIR}/dbus-shell.h ${DBUS_DIR}/dbus-pollable-set.h ${DBUS_DIR}/dbus-spawn.h ${DBUS_DIR}/dbus-test.h - ${DBUS_DIR}/dbus-test-wrappers.h ) ### platform specific settings @@ -342,11 +324,6 @@ else(WIN32) endif() endif(WIN32) -if (DBUS_ENABLE_EMBEDDED_TESTS) - add_test_executable(test-dbus ${CMAKE_SOURCE_DIR}/../dbus/dbus-test-main.c ${DBUS_INTERNAL_LIBRARIES}) - set_target_properties(test-dbus PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) -ENDIF (DBUS_ENABLE_EMBEDDED_TESTS) - if (UNIX) # set version info ENDIF (UNIX) diff --git a/cmake/test/CMakeLists.txt b/cmake/test/CMakeLists.txt index b505cc61..3a7218a4 100644 --- a/cmake/test/CMakeLists.txt +++ b/cmake/test/CMakeLists.txt @@ -77,6 +77,9 @@ add_test_executable(test-printf ${TEST_DIR}/internals/printf.c dbus-testutils) add_helper_executable(test-privserver ${TEST_DIR}/test-privserver.c dbus-testutils) add_helper_executable(test-shell-service ${test-shell-service_SOURCES} dbus-testutils) add_helper_executable(test-spawn ${test-spawn_SOURCES} ${DBUS_INTERNAL_LIBRARIES}) +if(NOT WINCE) + add_test_executable(test-spawn-oom ${TEST_DIR}/internals/spawn-oom.c dbus-testutils) +endif() add_helper_executable(test-exit ${test-exit_SOURCES} ${DBUS_INTERNAL_LIBRARIES}) # the second argument of add_helper_executable() is a whitespace-separated # list of source files and the third and subsequent arguments are libraries @@ -89,6 +92,60 @@ if(WIN32) add_helper_executable(manual-paths ${manual-paths_SOURCES} ${DBUS_INTERNAL_LIBRARIES}) endif() +if(DBUS_ENABLE_EMBEDDED_TESTS) + add_test_executable(test-hash ${TEST_DIR}/internals/hash.c dbus-testutils) + set_target_properties(test-hash PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) + + set(SOURCES ${TEST_DIR}/internals/dbus-marshal-recursive-util.c + ${TEST_DIR}/internals/dbus-marshal-recursive-util.h + ${TEST_DIR}/internals/marshal-recursive.c) + add_test_executable(test-marshal-recursive "${SOURCES}" dbus-testutils) + set_target_properties(test-marshal-recursive PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) + + set(SOURCES ${TEST_DIR}/internals/dbus-marshal-recursive-util.c + ${TEST_DIR}/internals/dbus-marshal-recursive-util.h + ${TEST_DIR}/internals/dbus-message-factory.c + ${TEST_DIR}/internals/dbus-message-factory.h + ${TEST_DIR}/internals/dbus-message-util.c + ${TEST_DIR}/internals/dbus-message-util.h + ${TEST_DIR}/internals/message-internals.c) + add_test_executable(test-message-internals "${SOURCES}" dbus-testutils) + set_target_properties(test-message-internals PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) + + set(SOURCES ${TEST_DIR}/internals/dbus-auth-script.c + ${TEST_DIR}/internals/dbus-auth-script.h + ${TEST_DIR}/internals/dbus-auth-util.c + ${TEST_DIR}/internals/dbus-credentials-util.c + ${TEST_DIR}/internals/dbus-marshal-byteswap-util.c + ${TEST_DIR}/internals/dbus-marshal-recursive-util.c + ${TEST_DIR}/internals/dbus-marshal-recursive-util.h + ${TEST_DIR}/internals/dbus-marshal-validate-util.c + ${TEST_DIR}/internals/dbus-string-util.c + ${TEST_DIR}/internals/dbus-sysdeps-util.c + ${TEST_DIR}/internals/misc-internals.c + ${TEST_DIR}/internals/misc-internals.h) + add_test_executable(test-misc-internals "${SOURCES}" dbus-testutils) + set_target_properties(test-misc-internals PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) + + set(SOURCES ${TEST_DIR}/bus/main.c) + add_test_executable(test-bus "${SOURCES}" dbus-daemon-internal dbus-testutils ${EXPAT_LIBRARIES}) + set_target_properties(test-bus PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) + + set(SOURCES ${TEST_DIR}/bus/dispatch.c) + add_test_executable(test-bus-dispatch "${SOURCES}" dbus-daemon-internal dbus-testutils ${EXPAT_LIBRARIES}) + set_target_properties(test-bus-dispatch PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) + + set(SOURCES ${TEST_DIR}/bus/dispatch-sha1.c) + add_test_executable(test-bus-dispatch-sha1 "${SOURCES}" dbus-daemon-internal dbus-testutils ${EXPAT_LIBRARIES}) + set_target_properties(test-bus-dispatch-sha1 PROPERTIES COMPILE_FLAGS ${DBUS_INTERNAL_CLIENT_DEFINITIONS}) + + if(NOT WIN32) + add_test_executable(test-bus-system ${TEST_DIR}/bus/system.c launch-helper-internal dbus-testutils) + add_test_executable(test-bus-launch-helper-oom ${TEST_DIR}/bus/launch-helper-oom.c launch-helper-internal dbus-testutils) + add_helper_executable(dbus-daemon-launch-helper-for-tests ${TEST_DIR}/bus/launch-helper-for-tests.c launch-helper-internal) + endif() +endif() + if(DBUS_WITH_GLIB) message(STATUS "with glib test apps") diff --git a/configure.ac b/configure.ac index a5a7fd3e..98afc6d2 100644 --- a/configure.ac +++ b/configure.ac @@ -1565,7 +1565,7 @@ AC_DEFINE_UNQUOTED([DBUS_EXEEXT], ["$EXEEXT"], [Extension for executables, typically empty or .exe]) ## Export the non-setuid external helper -TEST_LAUNCH_HELPER_BINARY="$DBUS_PWD/bus/dbus-daemon-launch-helper-test$EXEEXT" +TEST_LAUNCH_HELPER_BINARY="$DBUS_TEST_EXEC/dbus-daemon-launch-helper-for-tests$EXEEXT" AC_SUBST(TEST_LAUNCH_HELPER_BINARY) AC_DEFINE_UNQUOTED(DBUS_TEST_LAUNCH_HELPER_BINARY, "$TEST_LAUNCH_HELPER_BINARY", [Full path to the launch helper test program in the builddir]) diff --git a/dbus/Makefile.am b/dbus/Makefile.am index 08fb850e..0656b706 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -245,17 +245,8 @@ DBUS_SHARED_SOURCES= \ DBUS_UTIL_SOURCES= \ dbus-asv-util.c \ dbus-asv-util.h \ - dbus-auth-script.c \ - dbus-auth-script.h \ - dbus-auth-util.c \ - dbus-credentials-util.c \ dbus-mainloop.c \ dbus-mainloop.h \ - dbus-marshal-byteswap-util.c \ - dbus-marshal-recursive-util.c \ - dbus-marshal-validate-util.c \ - dbus-message-factory.c \ - dbus-message-factory.h \ dbus-message-util.c \ dbus-shell.c \ dbus-shell.h \ @@ -268,14 +259,6 @@ DBUS_UTIL_SOURCES= \ dbus-sysdeps-util.c \ dbus-test.h -if DBUS_ENABLE_EMBEDDED_TESTS -DBUS_UTIL_SOURCES += \ - dbus-spawn-test.c \ - dbus-test-wrappers.c \ - dbus-test-wrappers.h \ - $(NULL) -endif - libdbus_1_la_SOURCES= \ $(DBUS_LIB_SOURCES) \ $(DBUS_SHARED_SOURCES) @@ -325,16 +308,6 @@ endif noinst_PROGRAMS = -if DBUS_ENABLE_EMBEDDED_TESTS -# We can't actually run this til we've reached test/ -noinst_PROGRAMS += test-dbus -endif - -test_dbus_SOURCES= \ - dbus-test-main.c - -test_dbus_LDADD = libdbus-internal.la - # Add rules for code-coverage testing, as defined by AX_CODE_COVERAGE @CODE_COVERAGE_RULES@ diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h index bcc5570a..06302dd0 100644 --- a/dbus/dbus-connection-internal.h +++ b/dbus/dbus-connection-internal.h @@ -137,6 +137,7 @@ void _dbus_connection_get_stats (DBusConnection *connection, /* if DBUS_ENABLE_EMBEDDED_TESTS */ +DBUS_PRIVATE_EXPORT const char* _dbus_connection_get_address (DBusConnection *connection); /* This _dbus_bus_* stuff doesn't really belong here, but dbus-bus-internal.h seems diff --git a/dbus/dbus-hash.c b/dbus/dbus-hash.c index 12b803f7..f04b0d11 100644 --- a/dbus/dbus-hash.c +++ b/dbus/dbus-hash.c @@ -1,9 +1,14 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-hash.c Generic hash table utility (internal to D-Bus implementation) * - * Copyright (C) 2002 Red Hat, Inc. - * Copyright (c) 1991-1993 The Regents of the University of California. - * Copyright (c) 1994 Sun Microsystems, Inc. + * Copyright 1991-1993 The Regents of the University of California. + * Copyright 1994 Sun Microsystems, Inc. + * Copyright 2002-2005 Red Hat, Inc. + * Copyright 2003 Joe Shaw + * Copyright 2006 Sjoerd Simons + * Copyright 2010 Fridrich Štrba + * Copyright 2016 Ralf Habacker + * Copyright 2017 Endless Mobile, Inc. * * Hash table implementation based on generic/tclHash.c from the Tcl * source code. The original Tcl license applies to portions of the @@ -1587,443 +1592,3 @@ _dbus_hash_table_to_array (DBusHashTable *table, char delimiter) } /** @} */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS -#include "dbus-test.h" -#include - -/* If you're wondering why the hash table test takes - * forever to run, it's because we call this function - * in inner loops thus making things quadratic. - */ -static int -count_entries (DBusHashTable *table) -{ - DBusHashIter iter; - int count; - - count = 0; - _dbus_hash_iter_init (table, &iter); - while (_dbus_hash_iter_next (&iter)) - ++count; - - _dbus_assert (count == _dbus_hash_table_get_n_entries (table)); - - return count; -} - -static inline void * -steal (void *ptr) -{ - /* @ptr is passed in as void* to avoid casting in the call */ - void **_ptr = (void **) ptr; - void *val; - - val = *_ptr; - *_ptr = NULL; - - return val; -} - -/** - * @ingroup DBusHashTableInternals - * Unit test for DBusHashTable - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_hash_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - int i; - DBusHashTable *table1; - DBusHashTable *table2; - DBusHashTable *table3; - DBusHashIter iter; -#define N_HASH_KEYS 5000 - char **keys; - dbus_bool_t ret = FALSE; - char *str_key = NULL; - char *str_value = NULL; - - keys = dbus_new (char *, N_HASH_KEYS); - if (keys == NULL) - _dbus_test_fatal ("no memory"); - - for (i = 0; i < N_HASH_KEYS; i++) - { - keys[i] = dbus_malloc (128); - - if (keys[i] == NULL) - _dbus_test_fatal ("no memory"); - } - - _dbus_test_diag ("Computing test hash keys..."); - i = 0; - while (i < N_HASH_KEYS) - { - int len; - - len = sprintf (keys[i], "Hash key %d", i); - _dbus_assert (*(keys[i] + len) == '\0'); - ++i; - } - _dbus_test_diag ("... done."); - - table1 = _dbus_hash_table_new (DBUS_HASH_STRING, - dbus_free, dbus_free); - if (table1 == NULL) - goto out; - - table2 = _dbus_hash_table_new (DBUS_HASH_INT, - NULL, dbus_free); - if (table2 == NULL) - goto out; - - table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR, - NULL, dbus_free); - if (table3 == NULL) - goto out; - - /* Insert and remove a bunch of stuff, counting the table in between - * to be sure it's not broken and that iteration works - */ - i = 0; - while (i < 3000) - { - const void *out_value; - - str_key = _dbus_strdup (keys[i]); - if (str_key == NULL) - goto out; - str_value = _dbus_strdup ("Value!"); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_table_insert_string (table1, - steal (&str_key), - steal (&str_value))) - goto out; - - str_value = _dbus_strdup (keys[i]); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_table_insert_int (table2, - i, steal (&str_value))) - goto out; - - str_value = _dbus_strdup (keys[i]); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_table_insert_uintptr (table3, - i, steal (&str_value))) - goto out; - - _dbus_assert (count_entries (table1) == i + 1); - _dbus_assert (count_entries (table2) == i + 1); - _dbus_assert (count_entries (table3) == i + 1); - - out_value = _dbus_hash_table_lookup_string (table1, keys[i]); - _dbus_assert (out_value != NULL); - _dbus_assert (strcmp (out_value, "Value!") == 0); - - out_value = _dbus_hash_table_lookup_int (table2, i); - _dbus_assert (out_value != NULL); - _dbus_assert (strcmp (out_value, keys[i]) == 0); - - out_value = _dbus_hash_table_lookup_uintptr (table3, i); - _dbus_assert (out_value != NULL); - _dbus_assert (strcmp (out_value, keys[i]) == 0); - - ++i; - } - - --i; - while (i >= 0) - { - _dbus_hash_table_remove_string (table1, - keys[i]); - - _dbus_hash_table_remove_int (table2, i); - - _dbus_hash_table_remove_uintptr (table3, i); - - _dbus_assert (count_entries (table1) == i); - _dbus_assert (count_entries (table2) == i); - _dbus_assert (count_entries (table3) == i); - - --i; - } - - _dbus_hash_table_ref (table1); - _dbus_hash_table_ref (table2); - _dbus_hash_table_ref (table3); - _dbus_hash_table_unref (table1); - _dbus_hash_table_unref (table2); - _dbus_hash_table_unref (table3); - _dbus_hash_table_unref (table1); - _dbus_hash_table_unref (table2); - _dbus_hash_table_unref (table3); - table3 = NULL; - - /* Insert a bunch of stuff then check - * that iteration works correctly (finds the right - * values, iter_set_value works, etc.) - */ - table1 = _dbus_hash_table_new (DBUS_HASH_STRING, - dbus_free, dbus_free); - if (table1 == NULL) - goto out; - - table2 = _dbus_hash_table_new (DBUS_HASH_INT, - NULL, dbus_free); - if (table2 == NULL) - goto out; - - i = 0; - while (i < 5000) - { - str_key = _dbus_strdup (keys[i]); - if (str_key == NULL) - goto out; - str_value = _dbus_strdup ("Value!"); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_table_insert_string (table1, - steal (&str_key), - steal (&str_value))) - goto out; - - str_value = _dbus_strdup (keys[i]); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_table_insert_int (table2, - i, steal (&str_value))) - goto out; - - _dbus_assert (count_entries (table1) == i + 1); - _dbus_assert (count_entries (table2) == i + 1); - - ++i; - } - - _dbus_hash_iter_init (table1, &iter); - while (_dbus_hash_iter_next (&iter)) - { - const char *key; - const void *value; - - key = _dbus_hash_iter_get_string_key (&iter); - value = _dbus_hash_iter_get_value (&iter); - - _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value); - - str_value = _dbus_strdup ("Different value!"); - if (str_value == NULL) - goto out; - - value = str_value; - _dbus_hash_iter_set_value (&iter, steal (&str_value)); - _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value); - } - - _dbus_hash_iter_init (table1, &iter); - while (_dbus_hash_iter_next (&iter)) - { - _dbus_hash_iter_remove_entry (&iter); - _dbus_assert (count_entries (table1) == i - 1); - --i; - } - - _dbus_hash_iter_init (table2, &iter); - while (_dbus_hash_iter_next (&iter)) - { - int key; - const void *value; - - key = _dbus_hash_iter_get_int_key (&iter); - value = _dbus_hash_iter_get_value (&iter); - - _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value); - - str_value = _dbus_strdup ("Different value!"); - if (str_value == NULL) - goto out; - - value = str_value; - _dbus_hash_iter_set_value (&iter, steal (&str_value)); - _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value); - } - - i = count_entries (table2); - _dbus_hash_iter_init (table2, &iter); - while (_dbus_hash_iter_next (&iter)) - { - _dbus_hash_iter_remove_entry (&iter); - _dbus_assert (count_entries (table2) + 1 == i); - --i; - } - - /* add/remove interleaved, to check that we grow/shrink the table - * appropriately - */ - i = 0; - while (i < 1000) - { - str_key = _dbus_strdup (keys[i]); - if (str_key == NULL) - goto out; - - str_value = _dbus_strdup ("Value!"); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_table_insert_string (table1, - steal (&str_key), - steal (&str_value))) - goto out; - - ++i; - } - - --i; - while (i >= 0) - { - str_key = _dbus_strdup (keys[i]); - if (str_key == NULL) - goto out; - str_value = _dbus_strdup ("Value!"); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_table_remove_string (table1, keys[i])) - goto out; - - if (!_dbus_hash_table_insert_string (table1, - steal (&str_key), - steal (&str_value))) - goto out; - - if (!_dbus_hash_table_remove_string (table1, keys[i])) - goto out; - - _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i); - - --i; - } - - /* nuke these tables */ - _dbus_hash_table_unref (table1); - _dbus_hash_table_unref (table2); - - - /* Now do a bunch of things again using _dbus_hash_iter_lookup() to - * be sure that interface works. - */ - table1 = _dbus_hash_table_new (DBUS_HASH_STRING, - dbus_free, dbus_free); - if (table1 == NULL) - goto out; - - table2 = _dbus_hash_table_new (DBUS_HASH_INT, - NULL, dbus_free); - if (table2 == NULL) - goto out; - - i = 0; - while (i < 3000) - { - const void *out_value; - - str_key = _dbus_strdup (keys[i]); - if (str_key == NULL) - goto out; - str_value = _dbus_strdup ("Value!"); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_iter_lookup (table1, - steal (&str_key), TRUE, &iter)) - goto out; - _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); - _dbus_hash_iter_set_value (&iter, steal (&str_value)); - - str_value = _dbus_strdup (keys[i]); - if (str_value == NULL) - goto out; - - if (!_dbus_hash_iter_lookup (table2, - _DBUS_INT_TO_POINTER (i), TRUE, &iter)) - goto out; - _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); - _dbus_hash_iter_set_value (&iter, steal (&str_value)); - - _dbus_assert (count_entries (table1) == i + 1); - _dbus_assert (count_entries (table2) == i + 1); - - if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter)) - goto out; - - out_value = _dbus_hash_iter_get_value (&iter); - _dbus_assert (out_value != NULL); - _dbus_assert (strcmp (out_value, "Value!") == 0); - - /* Iterate just to be sure it works, though - * it's a stupid thing to do - */ - while (_dbus_hash_iter_next (&iter)) - ; - - if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter)) - goto out; - - out_value = _dbus_hash_iter_get_value (&iter); - _dbus_assert (out_value != NULL); - _dbus_assert (strcmp (out_value, keys[i]) == 0); - - /* Iterate just to be sure it works, though - * it's a stupid thing to do - */ - while (_dbus_hash_iter_next (&iter)) - ; - - ++i; - } - - --i; - while (i >= 0) - { - if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter)) - _dbus_test_fatal ("hash entry should have existed"); - _dbus_hash_iter_remove_entry (&iter); - - if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter)) - _dbus_test_fatal ("hash entry should have existed"); - _dbus_hash_iter_remove_entry (&iter); - - _dbus_assert (count_entries (table1) == i); - _dbus_assert (count_entries (table2) == i); - - --i; - } - - _dbus_hash_table_unref (table1); - _dbus_hash_table_unref (table2); - - ret = TRUE; - - out: - for (i = 0; i < N_HASH_KEYS; i++) - dbus_free (keys[i]); - - dbus_free (keys); - - dbus_free (str_key); - dbus_free (str_value); - - return ret; -} - -#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/dbus/dbus-hash.h b/dbus/dbus-hash.h index 9387f9eb..ea6fef0d 100644 --- a/dbus/dbus-hash.h +++ b/dbus/dbus-hash.h @@ -75,6 +75,7 @@ DBUS_PRIVATE_EXPORT DBusHashTable* _dbus_hash_table_new (DBusHashType type, DBusFreeFunction key_free_function, DBusFreeFunction value_free_function); +DBUS_PRIVATE_EXPORT DBusHashTable* _dbus_hash_table_ref (DBusHashTable *table); DBUS_PRIVATE_EXPORT void _dbus_hash_table_unref (DBusHashTable *table); diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c index 1bf1e7a9..d3ca20f7 100644 --- a/dbus/dbus-list.c +++ b/dbus/dbus-list.c @@ -815,579 +815,3 @@ _dbus_list_length_is_one (DBusList **list) } /** @} */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS -#include "dbus-test.h" -#include - -static void -verify_list (DBusList **list) -{ - DBusList *link; - int length; - - link = *list; - - if (link == NULL) - return; - - if (link->next == link) - { - _dbus_assert (link->prev == link); - _dbus_assert (*list == link); - return; - } - - length = 0; - do - { - length += 1; - _dbus_assert (link->prev->next == link); - _dbus_assert (link->next->prev == link); - link = link->next; - } - while (link != *list); - - _dbus_assert (length == _dbus_list_get_length (list)); - - if (length == 1) - _dbus_assert (_dbus_list_length_is_one (list)); - else - _dbus_assert (!_dbus_list_length_is_one (list)); -} - -static dbus_bool_t -is_ascending_sequence (DBusList **list) -{ - DBusList *link; - int prev; - - prev = _DBUS_INT_MIN; - - link = _dbus_list_get_first_link (list); - while (link != NULL) - { - int v = _DBUS_POINTER_TO_INT (link->data); - - if (v <= prev) - return FALSE; - - prev = v; - - link = _dbus_list_get_next_link (list, link); - } - - return TRUE; -} - -static dbus_bool_t -is_descending_sequence (DBusList **list) -{ - DBusList *link; - int prev; - - prev = _DBUS_INT_MAX; - - link = _dbus_list_get_first_link (list); - while (link != NULL) - { - int v = _DBUS_POINTER_TO_INT (link->data); - - if (v >= prev) - return FALSE; - - prev = v; - - link = _dbus_list_get_next_link (list, link); - } - - return TRUE; -} - -static dbus_bool_t -all_even_values (DBusList **list) -{ - DBusList *link; - - link = _dbus_list_get_first_link (list); - while (link != NULL) - { - int v = _DBUS_POINTER_TO_INT (link->data); - - if ((v % 2) != 0) - return FALSE; - - link = _dbus_list_get_next_link (list, link); - } - - return TRUE; -} - -static dbus_bool_t -all_odd_values (DBusList **list) -{ - DBusList *link; - - link = _dbus_list_get_first_link (list); - while (link != NULL) - { - int v = _DBUS_POINTER_TO_INT (link->data); - - if ((v % 2) == 0) - return FALSE; - - link = _dbus_list_get_next_link (list, link); - } - - return TRUE; -} - -static dbus_bool_t -lists_equal (DBusList **list1, - DBusList **list2) -{ - DBusList *link1; - DBusList *link2; - - link1 = _dbus_list_get_first_link (list1); - link2 = _dbus_list_get_first_link (list2); - while (link1 && link2) - { - if (link1->data != link2->data) - return FALSE; - - link1 = _dbus_list_get_next_link (list1, link1); - link2 = _dbus_list_get_next_link (list2, link2); - } - - if (link1 || link2) - return FALSE; - - return TRUE; -} - -/** - * @ingroup DBusListInternals - * Unit test for DBusList - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_list_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - DBusList *list1; - DBusList *list2; - DBusList *link1; - DBusList *link2; - DBusList *copy1; - DBusList *copy2; - int i; - - list1 = NULL; - list2 = NULL; - - /* Test append and prepend */ - - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("count not allocate for prepend"); - ++i; - - verify_list (&list1); - verify_list (&list2); - - _dbus_assert (_dbus_list_get_length (&list1) == i); - _dbus_assert (_dbus_list_get_length (&list2) == i); - } - - _dbus_assert (is_ascending_sequence (&list1)); - _dbus_assert (is_descending_sequence (&list2)); - - /* Test list clear */ - _dbus_list_clear (&list1); - _dbus_list_clear (&list2); - - verify_list (&list1); - verify_list (&list2); - - /* Test get_first, get_last, pop_first, pop_last */ - - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for prepend"); - ++i; - } - - --i; - while (i >= 0) - { - void *got_data1; - void *got_data2; - - void *data1; - void *data2; - - got_data1 = _dbus_list_get_last (&list1); - got_data2 = _dbus_list_get_first (&list2); - - data1 = _dbus_list_pop_last (&list1); - data2 = _dbus_list_pop_first (&list2); - - _dbus_assert (got_data1 == data1); - _dbus_assert (got_data2 == data2); - - _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); - _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); - - verify_list (&list1); - verify_list (&list2); - - _dbus_assert (is_ascending_sequence (&list1)); - _dbus_assert (is_descending_sequence (&list2)); - - --i; - } - - _dbus_assert (list1 == NULL); - _dbus_assert (list2 == NULL); - - /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */ - - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for prepend"); - ++i; - } - - --i; - while (i >= 0) - { - DBusList *got_link1; - DBusList *got_link2; - - void *data1_indirect; - void *data1; - void *data2; - - got_link1 = _dbus_list_get_last_link (&list1); - got_link2 = _dbus_list_get_first_link (&list2); - - link2 = _dbus_list_pop_first_link (&list2); - - _dbus_assert (got_link2 == link2); - - data1_indirect = got_link1->data; - /* this call makes got_link1 invalid */ - data1 = _dbus_list_pop_last (&list1); - _dbus_assert (data1 == data1_indirect); - data2 = link2->data; - - _dbus_list_free_link (link2); - - _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); - _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); - - verify_list (&list1); - verify_list (&list2); - - _dbus_assert (is_ascending_sequence (&list1)); - _dbus_assert (is_descending_sequence (&list2)); - - --i; - } - - _dbus_assert (list1 == NULL); - _dbus_assert (list2 == NULL); - - /* Test iteration */ - - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for prepend"); - ++i; - - verify_list (&list1); - verify_list (&list2); - - _dbus_assert (_dbus_list_get_length (&list1) == i); - _dbus_assert (_dbus_list_get_length (&list2) == i); - } - - _dbus_assert (is_ascending_sequence (&list1)); - _dbus_assert (is_descending_sequence (&list2)); - - --i; - link2 = _dbus_list_get_first_link (&list2); - while (link2 != NULL) - { - verify_list (&link2); /* pretend this link is the head */ - - _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); - - link2 = _dbus_list_get_next_link (&list2, link2); - --i; - } - - i = 0; - link1 = _dbus_list_get_first_link (&list1); - while (link1 != NULL) - { - verify_list (&link1); /* pretend this link is the head */ - - _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); - - link1 = _dbus_list_get_next_link (&list1, link1); - ++i; - } - - --i; - link1 = _dbus_list_get_last_link (&list1); - while (link1 != NULL) - { - verify_list (&link1); /* pretend this link is the head */ - - _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); - - link1 = _dbus_list_get_prev_link (&list1, link1); - --i; - } - - _dbus_list_clear (&list1); - _dbus_list_clear (&list2); - - /* Test remove */ - - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for prepend"); - ++i; - } - - --i; - while (i >= 0) - { - if ((i % 2) == 0) - { - if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("element should have been in list"); - if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("element should have been in list"); - - verify_list (&list1); - verify_list (&list2); - } - --i; - } - - _dbus_assert (all_odd_values (&list1)); - _dbus_assert (all_odd_values (&list2)); - - _dbus_list_clear (&list1); - _dbus_list_clear (&list2); - - /* test removing the other half of the elements */ - - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for prepend"); - ++i; - } - - --i; - while (i >= 0) - { - if ((i % 2) != 0) - { - if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("element should have been in list"); - if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("element should have been in list"); - - verify_list (&list1); - verify_list (&list2); - } - --i; - } - - _dbus_assert (all_even_values (&list1)); - _dbus_assert (all_even_values (&list2)); - - /* clear list using remove_link */ - while (list1 != NULL) - { - _dbus_list_remove_link (&list1, list1); - verify_list (&list1); - } - while (list2 != NULL) - { - _dbus_list_remove_link (&list2, list2); - verify_list (&list2); - } - - /* Test remove link more generally */ - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for prepend"); - ++i; - } - - --i; - link2 = _dbus_list_get_first_link (&list2); - while (link2 != NULL) - { - DBusList *next = _dbus_list_get_next_link (&list2, link2); - - _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); - - if ((i % 2) == 0) - _dbus_list_remove_link (&list2, link2); - - verify_list (&list2); - - link2 = next; - --i; - } - - _dbus_assert (all_odd_values (&list2)); - _dbus_list_clear (&list2); - - i = 0; - link1 = _dbus_list_get_first_link (&list1); - while (link1 != NULL) - { - DBusList *next = _dbus_list_get_next_link (&list1, link1); - - _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); - - if ((i % 2) != 0) - _dbus_list_remove_link (&list1, link1); - - verify_list (&list1); - - link1 = next; - ++i; - } - - _dbus_assert (all_even_values (&list1)); - _dbus_list_clear (&list1); - - /* Test copying a list */ - i = 0; - while (i < 10) - { - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) - _dbus_test_fatal ("could not allocate for prepend"); - ++i; - } - - /* bad pointers, because they are allowed in the copy dest */ - copy1 = _DBUS_INT_TO_POINTER (0x342234); - copy2 = _DBUS_INT_TO_POINTER (23); - - _dbus_list_copy (&list1, ©1); - verify_list (&list1); - verify_list (©1); - _dbus_assert (lists_equal (&list1, ©1)); - - _dbus_list_copy (&list2, ©2); - verify_list (&list2); - verify_list (©2); - _dbus_assert (lists_equal (&list2, ©2)); - - /* Now test copying empty lists */ - _dbus_list_clear (&list1); - _dbus_list_clear (&list2); - _dbus_list_clear (©1); - _dbus_list_clear (©2); - - /* bad pointers, because they are allowed in the copy dest */ - copy1 = _DBUS_INT_TO_POINTER (0x342234); - copy2 = _DBUS_INT_TO_POINTER (23); - - _dbus_list_copy (&list1, ©1); - verify_list (&list1); - verify_list (©1); - _dbus_assert (lists_equal (&list1, ©1)); - - _dbus_list_copy (&list2, ©2); - verify_list (&list2); - verify_list (©2); - _dbus_assert (lists_equal (&list2, ©2)); - - _dbus_list_clear (&list1); - _dbus_list_clear (&list2); - - /* insert_after on empty list */ - _dbus_list_insert_after (&list1, NULL, - _DBUS_INT_TO_POINTER (0)); - verify_list (&list1); - - /* inserting after first element */ - _dbus_list_insert_after (&list1, list1, - _DBUS_INT_TO_POINTER (1)); - verify_list (&list1); - _dbus_assert (is_ascending_sequence (&list1)); - - /* inserting at the end */ - _dbus_list_insert_after (&list1, list1->next, - _DBUS_INT_TO_POINTER (2)); - verify_list (&list1); - _dbus_assert (is_ascending_sequence (&list1)); - - /* using insert_after to prepend */ - _dbus_list_insert_after (&list1, NULL, - _DBUS_INT_TO_POINTER (-1)); - verify_list (&list1); - _dbus_assert (is_ascending_sequence (&list1)); - - _dbus_list_clear (&list1); - - /* using remove_last */ - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1))) - _dbus_test_fatal ("could not allocate for append"); - if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3))) - _dbus_test_fatal ("could not allocate for append"); - - _dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2)); - - verify_list (&list1); - _dbus_assert (is_ascending_sequence (&list1)); - - _dbus_list_clear (&list1); - - return TRUE; -} - -#endif diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index f62b1f28..3ac9437d 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -1,8 +1,9 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-message-util.c Would be in dbus-message.c, but only used by bus/tests * - * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc. - * Copyright (C) 2002, 2003 CodeFactory AB + * Copyright 2009 Red Hat, Inc. + * Copyright 2011-2017 Collabora Ltd. + * Copyright 2017 Endless Mobile, Inc. * * Licensed under the Academic Free License version 2.1 * @@ -23,6 +24,7 @@ */ #include + #include "dbus-internals.h" #include "dbus-test.h" #include "dbus-message-private.h" @@ -63,104 +65,6 @@ _dbus_message_get_n_unix_fds (DBusMessage *message) } #ifdef DBUS_ENABLE_EMBEDDED_TESTS -/** - * Reads arguments from a message iterator given a variable argument - * list. Only arguments of basic type and arrays of fixed-length - * basic type may be read with this function. See - * dbus_message_get_args() for more details. - * - * @param iter the message iterator - * @param error error to be filled in on failure - * @param first_arg_type the first argument type - * @param ... location for first argument value, then list of type-location pairs - * @returns #FALSE if the error was set - */ -static dbus_bool_t -dbus_message_iter_get_args (DBusMessageIter *iter, - DBusError *error, - int first_arg_type, - ...) -{ - dbus_bool_t retval; - va_list var_args; - - _dbus_return_val_if_fail (iter != NULL, FALSE); - _dbus_return_val_if_error_is_set (error, FALSE); - - va_start (var_args, first_arg_type); - retval = _dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args); - va_end (var_args); - - return retval; -} -#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ - -/** @} */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS -#include "dbus-test.h" -#include "dbus-message-factory.h" -#include -#include - -/* returns FALSE on fatal failure */ -typedef dbus_bool_t (* DBusForeachMessageFileFunc) (const DBusString *filename, - DBusValidity expected_validity, - void *data); - -static dbus_bool_t try_message_data (const DBusString *data, - DBusValidity expected_validity); - -static int validities_seen[DBUS_VALIDITY_LAST + _DBUS_NEGATIVE_VALIDITY_COUNT]; - -static void -reset_validities_seen (void) -{ - int i; - i = 0; - while (i < _DBUS_N_ELEMENTS (validities_seen)) - { - validities_seen[i] = 0; - ++i; - } -} - -static void -record_validity_seen (DBusValidity validity) -{ - validities_seen[validity + _DBUS_NEGATIVE_VALIDITY_COUNT] += 1; -} - -static void -print_validities_seen (dbus_bool_t not_seen) -{ - int i; - i = 0; - while (i < _DBUS_N_ELEMENTS (validities_seen)) - { - if ((i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_VALIDITY_UNKNOWN || - (i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_INVALID_FOR_UNKNOWN_REASON) - ; - else if ((not_seen && validities_seen[i] == 0) || - (!not_seen && validities_seen[i] > 0)) - _dbus_test_diag ("validity %3d seen %d times", - i - _DBUS_NEGATIVE_VALIDITY_COUNT, - validities_seen[i]); - ++i; - } -} - -static void -check_memleaks (void) -{ - dbus_shutdown (); - - if (_dbus_get_malloc_blocks_outstanding () != 0) - { - _dbus_test_fatal ("%d dbus_malloc blocks were not freed in %s", - _dbus_get_malloc_blocks_outstanding (), __FILE__); - } -} #ifdef __linux__ struct DBusInitialFDs { @@ -280,1541 +184,4 @@ _dbus_check_fdleaks_leave (DBusInitialFDs *fds) #endif } -static dbus_bool_t -check_have_valid_message (DBusMessageLoader *loader) -{ - DBusMessage *message; - dbus_bool_t retval; - - message = NULL; - retval = FALSE; - - if (_dbus_message_loader_get_is_corrupted (loader)) - { - _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d", - loader->corruption_reason); - goto failed; - } - - message = _dbus_message_loader_pop_message (loader); - if (message == NULL) - { - _dbus_warn ("didn't load message that was expected to be valid (message not popped)"); - goto failed; - } - - if (_dbus_string_get_length (&loader->data) > 0) - { - _dbus_warn ("had leftover bytes from expected-to-be-valid single message"); - goto failed; - } - -#if 0 - /* FIXME */ - /* Verify that we're able to properly deal with the message. - * For example, this would detect improper handling of messages - * in nonstandard byte order. - */ - if (!check_message_handling (message)) - goto failed; -#endif - - record_validity_seen (DBUS_VALID); - - retval = TRUE; - - failed: - if (message) - dbus_message_unref (message); - - return retval; -} - -static dbus_bool_t -check_invalid_message (DBusMessageLoader *loader, - DBusValidity expected_validity) -{ - dbus_bool_t retval; - - retval = FALSE; - - if (!_dbus_message_loader_get_is_corrupted (loader)) - { - _dbus_warn ("loader not corrupted on message that was expected to be invalid"); - goto failed; - } - - record_validity_seen (loader->corruption_reason); - - if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON && - loader->corruption_reason != expected_validity) - { - _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead", - expected_validity, loader->corruption_reason); - goto failed; - } - - retval = TRUE; - - failed: - return retval; -} - -static dbus_bool_t -check_incomplete_message (DBusMessageLoader *loader) -{ - DBusMessage *message; - dbus_bool_t retval; - - message = NULL; - retval = FALSE; - - if (_dbus_message_loader_get_is_corrupted (loader)) - { - _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d", - loader->corruption_reason); - goto failed; - } - - message = _dbus_message_loader_pop_message (loader); - if (message != NULL) - { - _dbus_warn ("loaded message that was expected to be incomplete"); - goto failed; - } - - record_validity_seen (DBUS_VALID_BUT_INCOMPLETE); - retval = TRUE; - - failed: - if (message) - dbus_message_unref (message); - return retval; -} - -static dbus_bool_t -check_loader_results (DBusMessageLoader *loader, - DBusValidity expected_validity) -{ - if (!_dbus_message_loader_queue_messages (loader)) - _dbus_test_fatal ("no memory to queue messages"); - - if (expected_validity == DBUS_VALID) - return check_have_valid_message (loader); - else if (expected_validity == DBUS_VALID_BUT_INCOMPLETE) - return check_incomplete_message (loader); - else if (expected_validity == DBUS_VALIDITY_UNKNOWN) - { - /* here we just know we didn't segfault and that was the - * only test. Also, we record that we got coverage - * for the validity reason. - */ - if (_dbus_message_loader_get_is_corrupted (loader)) - record_validity_seen (loader->corruption_reason); - - return TRUE; - } - else - return check_invalid_message (loader, expected_validity); -} - -/** - * Loads the message in the given message file. - * - * @param filename filename to load - * @param data string to load message into - * @returns #TRUE if the message was loaded - */ -static dbus_bool_t -load_message_file (const DBusString *filename, - DBusString *data) -{ - dbus_bool_t retval; - DBusError error = DBUS_ERROR_INIT; - - retval = FALSE; - - _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename)); - if (!_dbus_file_get_contents (data, filename, &error)) - { - _dbus_warn ("Could not load message file %s: %s", - _dbus_string_get_const_data (filename), - error.message); - dbus_error_free (&error); - goto failed; - } - - retval = TRUE; - - failed: - - return retval; -} - -/** - * Tries loading the message in the given message file - * and verifies that DBusMessageLoader can handle it. - * - * @param filename filename to load - * @param expected_validity what the message has to be like to return #TRUE - * @param unused ignored - * @returns #TRUE if the message has the expected validity - */ -static dbus_bool_t -try_message_file (const DBusString *filename, - DBusValidity expected_validity, - void *unused) -{ - DBusString data; - dbus_bool_t retval; - - retval = FALSE; - - if (!_dbus_string_init (&data)) - _dbus_test_fatal ("could not allocate string"); - - if (!load_message_file (filename, &data)) - goto failed; - - retval = try_message_data (&data, expected_validity); - - failed: - - if (!retval) - { - if (_dbus_string_get_length (&data) > 0) - _dbus_verbose_bytes_of_string (&data, 0, - _dbus_string_get_length (&data)); - - _dbus_warn ("Failed message loader test on %s", - _dbus_string_get_const_data (filename)); - } - - _dbus_string_free (&data); - - return retval; -} - -/** - * 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 - */ -static dbus_bool_t -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 (); - if (loader == NULL) - goto failed; - - /* check some trivial loader functions */ - _dbus_message_loader_ref (loader); - _dbus_message_loader_unref (loader); - - len = _dbus_string_get_length (data); - for (i = 0; i < len; i++) - { - DBusString *buffer; - - _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); - if (!_dbus_string_append_byte (buffer, - _dbus_string_get_byte (data, i))) - goto failed; - _dbus_message_loader_return_buffer (loader, buffer); - } - - 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 (); - if (loader == NULL) - goto failed; - - { - DBusString *buffer; - - _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); - if (!_dbus_string_copy (data, 0, buffer, - _dbus_string_get_length (buffer))) - goto failed; - _dbus_message_loader_return_buffer (loader, buffer); - } - - 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 (); - if (loader == NULL) - goto failed; - - len = _dbus_string_get_length (data); - for (i = 0; i < len; i += 2) - { - DBusString *buffer; - - _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); - if (!_dbus_string_append_byte (buffer, - _dbus_string_get_byte (data, i))) - goto failed; - - if ((i+1) < len) - { - if (!_dbus_string_append_byte (buffer, - _dbus_string_get_byte (data, i+1))) - goto failed; - } - - _dbus_message_loader_return_buffer (loader, buffer); - } - - 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; -} - -static dbus_bool_t -process_test_subdir (const DBusString *test_base_dir, - const char *subdir, - DBusValidity expected_validity, - DBusForeachMessageFileFunc function, - void *user_data) -{ - DBusString test_directory; - DBusString filename; - DBusDirIter *dir; - dbus_bool_t retval; - DBusError error = DBUS_ERROR_INIT; - - retval = FALSE; - dir = NULL; - - if (!_dbus_string_init (&test_directory)) - _dbus_test_fatal ("didn't allocate test_directory"); - - _dbus_string_init_const (&filename, subdir); - - if (!_dbus_string_copy (test_base_dir, 0, - &test_directory, 0)) - _dbus_test_fatal ("couldn't copy test_base_dir to test_directory"); - - if (!_dbus_concat_dir_and_file (&test_directory, &filename)) - _dbus_test_fatal ("couldn't allocate full path"); - - _dbus_string_free (&filename); - if (!_dbus_string_init (&filename)) - _dbus_test_fatal ("didn't allocate filename string"); - - dir = _dbus_directory_open (&test_directory, &error); - if (dir == NULL) - { - _dbus_warn ("Could not open %s: %s", - _dbus_string_get_const_data (&test_directory), - error.message); - dbus_error_free (&error); - goto failed; - } - - _dbus_test_diag ("Testing %s:", subdir); - - next: - while (_dbus_directory_get_next_file (dir, &filename, &error)) - { - DBusString full_path; - - if (!_dbus_string_init (&full_path)) - _dbus_test_fatal ("couldn't init string"); - - if (!_dbus_string_copy (&test_directory, 0, &full_path, 0)) - _dbus_test_fatal ("couldn't copy dir to full_path"); - - if (!_dbus_concat_dir_and_file (&full_path, &filename)) - _dbus_test_fatal ("couldn't concat file to dir"); - - if (_dbus_string_ends_with_c_str (&filename, ".message-raw")) - ; - else - { - _dbus_verbose ("Skipping non-.message-raw file %s\n", - _dbus_string_get_const_data (&filename)); - _dbus_string_free (&full_path); - goto next; - } - - _dbus_test_diag (" %s", - _dbus_string_get_const_data (&filename)); - - if (! (*function) (&full_path, - expected_validity, user_data)) - { - _dbus_string_free (&full_path); - goto failed; - } - else - _dbus_string_free (&full_path); - } - - if (dbus_error_is_set (&error)) - { - _dbus_warn ("Could not get next file in %s: %s", - _dbus_string_get_const_data (&test_directory), - error.message); - dbus_error_free (&error); - goto failed; - } - - retval = TRUE; - - failed: - - if (dir) - _dbus_directory_close (dir); - _dbus_string_free (&test_directory); - _dbus_string_free (&filename); - - return retval; -} - -/** - * Runs the given function on every message file in the test suite. - * The function should return #FALSE on test failure or fatal error. - * - * @param test_data_dir root dir of the test suite data files (top_srcdir/test/data) - * @param func the function to run - * @param user_data data for function - * @returns #FALSE if there's a failure - */ -static dbus_bool_t -foreach_message_file (const char *test_data_dir, - DBusForeachMessageFileFunc func, - void *user_data) -{ - DBusString test_directory; - dbus_bool_t retval; - - retval = FALSE; - - _dbus_string_init_const (&test_directory, test_data_dir); - - if (!process_test_subdir (&test_directory, "invalid-messages", - DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data)) - goto failed; - - check_memleaks (); - - retval = TRUE; - - failed: - - _dbus_string_free (&test_directory); - - return retval; -} - -#if 0 -#define GET_AND_CHECK(iter, typename, literal) \ - do { \ - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ - _dbus_test_fatal ("got wrong argument type from message iter"); \ - dbus_message_iter_get_basic (&iter, &v_##typename); \ - if (v_##typename != literal) \ - _dbus_test_fatal ("got wrong value from message iter"); \ - } while (0) - -#define GET_AND_CHECK_STRCMP(iter, typename, literal) \ - do { \ - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ - _dbus_test_fatal ("got wrong argument type from message iter"); \ - dbus_message_iter_get_basic (&iter, &v_##typename); \ - if (strcmp (v_##typename, literal) != 0) \ - _dbus_test_fatal ("got wrong value from message iter"); \ - } while (0) - -#define GET_AND_CHECK_AND_NEXT(iter, typename, literal) \ - do { \ - GET_AND_CHECK(iter, typename, literal); \ - if (!dbus_message_iter_next (&iter)) \ - _dbus_test_fatal ("failed to move iter to next"); \ - } while (0) - -#define GET_AND_CHECK_STRCMP_AND_NEXT(iter, typename, literal) \ - do { \ - GET_AND_CHECK_STRCMP(iter, typename, literal); \ - if (!dbus_message_iter_next (&iter)) \ - _dbus_test_fatal ("failed to move iter to next"); \ - } while (0) - -static void -message_iter_test (DBusMessage *message) -{ - DBusMessageIter iter, array, array2; - 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; - dbus_int64_t v_INT64; - dbus_uint64_t v_UINT64; - unsigned char v_BYTE; - dbus_bool_t v_BOOLEAN; - - const dbus_int32_t *our_int_array; - int len; - - dbus_message_iter_init (message, &iter); - - GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string"); - GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678); - GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e); - GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159); - - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) - _dbus_test_fatal ("Argument type not an array"); - - if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DOUBLE) - _dbus_test_fatal ("Array type not double"); - - dbus_message_iter_recurse (&iter, &array); - - GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5); - GET_AND_CHECK (array, DOUBLE, 2.5); - - if (dbus_message_iter_next (&array)) - _dbus_test_fatal ("Didn't reach end of array"); - - if (!dbus_message_iter_next (&iter)) - _dbus_test_fatal ("Reached end of arguments"); - - GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0); - - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) - _dbus_test_fatal ("no array"); - - if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_INT32) - _dbus_test_fatal ("Array type not int32"); - - /* Empty array */ - dbus_message_iter_recurse (&iter, &array); - - if (dbus_message_iter_next (&array)) - _dbus_test_fatal ("Didn't reach end of array"); - - if (!dbus_message_iter_next (&iter)) - _dbus_test_fatal ("Reached end of arguments"); - - GET_AND_CHECK (iter, BYTE, 0xF0); - - if (dbus_message_iter_next (&iter)) - _dbus_test_fatal ("Didn't reach end of arguments"); -} -#endif - -static void -verify_test_message (DBusMessage *message) -{ - DBusMessageIter iter; - DBusError error = DBUS_ERROR_INIT; - dbus_int16_t our_int16; - dbus_uint16_t our_uint16; - dbus_int32_t our_int; - dbus_uint32_t our_uint; - const char *our_str; - double our_double; - double v_DOUBLE; - dbus_bool_t our_bool; - unsigned char our_byte_1, our_byte_2; - const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef; - int our_uint32_array_len; - dbus_int32_t *our_int32_array = (void*)0xdeadbeef; - int our_int32_array_len; - dbus_int64_t our_int64; - dbus_uint64_t our_uint64; - dbus_int64_t *our_uint64_array = (void*)0xdeadbeef; - int our_uint64_array_len; - const dbus_int64_t *our_int64_array = (void*)0xdeadbeef; - int our_int64_array_len; - const double *our_double_array = (void*)0xdeadbeef; - int our_double_array_len; - const unsigned char *our_byte_array = (void*)0xdeadbeef; - int our_byte_array_len; - const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef; - int our_boolean_array_len; - char **our_string_array; - int our_string_array_len; - - dbus_message_iter_init (message, &iter); - - if (!dbus_message_iter_get_args (&iter, &error, - DBUS_TYPE_INT16, &our_int16, - DBUS_TYPE_UINT16, &our_uint16, - DBUS_TYPE_INT32, &our_int, - DBUS_TYPE_UINT32, &our_uint, - DBUS_TYPE_INT64, &our_int64, - DBUS_TYPE_UINT64, &our_uint64, - DBUS_TYPE_STRING, &our_str, - DBUS_TYPE_DOUBLE, &our_double, - DBUS_TYPE_BOOLEAN, &our_bool, - DBUS_TYPE_BYTE, &our_byte_1, - DBUS_TYPE_BYTE, &our_byte_2, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, - &our_uint32_array, &our_uint32_array_len, - DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, - &our_int32_array, &our_int32_array_len, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, - &our_uint64_array, &our_uint64_array_len, - DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, - &our_int64_array, &our_int64_array_len, - DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, - &our_double_array, &our_double_array_len, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, - &our_byte_array, &our_byte_array_len, - DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, - &our_boolean_array, &our_boolean_array_len, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &our_string_array, &our_string_array_len, - 0)) - { - _dbus_test_fatal ("Could not get arguments: %s - %s", error.name, - (error.message != NULL) ? error.message : "no message"); - } - - if (our_int16 != -0x123) - _dbus_test_fatal ("16-bit integers differ!"); - - if (our_uint16 != 0x123) - _dbus_test_fatal ("16-bit uints differ!"); - - if (our_int != -0x12345678) - _dbus_test_fatal ("integers differ!"); - - if (our_uint != 0x12300042) - _dbus_test_fatal ("uints differ!"); - - if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd)) - _dbus_test_fatal ("64-bit integers differ!"); - if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd)) - _dbus_test_fatal ("64-bit unsigned integers differ!"); - - v_DOUBLE = 3.14159; - if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE)) - _dbus_test_fatal ("doubles differ!"); - - if (strcmp (our_str, "Test string") != 0) - _dbus_test_fatal ("strings differ!"); - - if (!our_bool) - _dbus_test_fatal ("booleans differ"); - - if (our_byte_1 != 42) - _dbus_test_fatal ("bytes differ!"); - - if (our_byte_2 != 24) - _dbus_test_fatal ("bytes differ!"); - - if (our_uint32_array_len != 4 || - our_uint32_array[0] != 0x12345678 || - our_uint32_array[1] != 0x23456781 || - our_uint32_array[2] != 0x34567812 || - our_uint32_array[3] != 0x45678123) - _dbus_test_fatal ("uint array differs"); - - if (our_int32_array_len != 4 || - our_int32_array[0] != 0x12345678 || - our_int32_array[1] != -0x23456781 || - our_int32_array[2] != 0x34567812 || - our_int32_array[3] != -0x45678123) - _dbus_test_fatal ("int array differs"); - - if (our_uint64_array_len != 4 || - our_uint64_array[0] != 0x12345678 || - our_uint64_array[1] != 0x23456781 || - our_uint64_array[2] != 0x34567812 || - our_uint64_array[3] != 0x45678123) - _dbus_test_fatal ("uint64 array differs"); - - if (our_int64_array_len != 4 || - our_int64_array[0] != 0x12345678 || - our_int64_array[1] != -0x23456781 || - our_int64_array[2] != 0x34567812 || - our_int64_array[3] != -0x45678123) - _dbus_test_fatal ("int64 array differs"); - - if (our_double_array_len != 3) - _dbus_test_fatal ("double array had wrong length"); - - /* On all IEEE machines (i.e. everything sane) exact equality - * should be preserved over the wire - */ - v_DOUBLE = 0.1234; - if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE)) - _dbus_test_fatal ("double array had wrong values"); - v_DOUBLE = 9876.54321; - if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE)) - _dbus_test_fatal ("double array had wrong values"); - v_DOUBLE = -300.0; - if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE)) - _dbus_test_fatal ("double array had wrong values"); - - if (our_byte_array_len != 4) - _dbus_test_fatal ("byte array had wrong length"); - - if (our_byte_array[0] != 'a' || - our_byte_array[1] != 'b' || - our_byte_array[2] != 'c' || - our_byte_array[3] != 234) - _dbus_test_fatal ("byte array had wrong values"); - - if (our_boolean_array_len != 5) - _dbus_test_fatal ("bool array had wrong length"); - - if (our_boolean_array[0] != TRUE || - our_boolean_array[1] != FALSE || - our_boolean_array[2] != TRUE || - our_boolean_array[3] != TRUE || - our_boolean_array[4] != FALSE) - _dbus_test_fatal ("bool array had wrong values"); - - if (our_string_array_len != 4) - _dbus_test_fatal ("string array was wrong length"); - - if (strcmp (our_string_array[0], "Foo") != 0 || - strcmp (our_string_array[1], "bar") != 0 || - strcmp (our_string_array[2], "") != 0 || - strcmp (our_string_array[3], "woo woo woo woo") != 0) - _dbus_test_fatal ("string array had wrong values"); - - dbus_free_string_array (our_string_array); - - if (dbus_message_iter_next (&iter)) - _dbus_test_fatal ("Didn't reach end of arguments"); -} - -static void -verify_test_message_args_ignored (DBusMessage *message) -{ - DBusMessageIter iter; - DBusError error = DBUS_ERROR_INIT; - dbus_uint32_t our_uint; - DBusInitialFDs *initial_fds; - - initial_fds = _dbus_check_fdleaks_enter (); - - /* parse with empty signature: "" */ - dbus_message_iter_init (message, &iter); - if (!dbus_message_iter_get_args (&iter, &error, - DBUS_TYPE_INVALID)) - { - _dbus_warn ("error: %s - %s", error.name, - (error.message != NULL) ? error.message : "no message"); - } - else - { - _dbus_assert (!dbus_error_is_set (&error)); - _dbus_verbose ("arguments ignored.\n"); - } - - /* parse with shorter signature: "u" */ - dbus_message_iter_init (message, &iter); - if (!dbus_message_iter_get_args (&iter, &error, - DBUS_TYPE_UINT32, &our_uint, - DBUS_TYPE_INVALID)) - { - _dbus_warn ("error: %s - %s", error.name, - (error.message != NULL) ? error.message : "no message"); - } - else - { - _dbus_assert (!dbus_error_is_set (&error)); - _dbus_verbose ("arguments ignored.\n"); - } - - _dbus_check_fdleaks_leave (initial_fds); -} - -static void -verify_test_message_memleak (DBusMessage *message) -{ - DBusMessageIter iter; - DBusError error = DBUS_ERROR_INIT; - dbus_uint32_t our_uint1; - dbus_uint32_t our_uint2; - dbus_uint32_t our_uint3; - char **our_string_array1; - int our_string_array_len1; - char **our_string_array2; - int our_string_array_len2; -#ifdef HAVE_UNIX_FD_PASSING - int our_unix_fd1; - int our_unix_fd2; -#endif - DBusInitialFDs *initial_fds; - - initial_fds = _dbus_check_fdleaks_enter (); - - /* parse with wrong signature: "uashuu" */ - dbus_error_free (&error); - dbus_message_iter_init (message, &iter); - if (!dbus_message_iter_get_args (&iter, &error, - DBUS_TYPE_UINT32, &our_uint1, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &our_string_array1, &our_string_array_len1, -#ifdef HAVE_UNIX_FD_PASSING - DBUS_TYPE_UNIX_FD, &our_unix_fd1, -#endif - DBUS_TYPE_UINT32, &our_uint2, - DBUS_TYPE_UINT32, &our_uint3, - DBUS_TYPE_INVALID)) - { - _dbus_verbose ("expected error: %s - %s\n", error.name, - (error.message != NULL) ? error.message : "no message"); - /* ensure array of string and unix fd not leaked */ - _dbus_assert (our_string_array1 == NULL); -#ifdef HAVE_UNIX_FD_PASSING - _dbus_assert (our_unix_fd1 == -1); -#endif - } - else - { - _dbus_test_fatal ("error: parse with wrong signature: 'uashuu'."); - } - - /* parse with wrong signature: "uashuashu" */ - dbus_message_iter_init (message, &iter); - dbus_error_free (&error); - if (!dbus_message_iter_get_args (&iter, &error, - DBUS_TYPE_UINT32, &our_uint1, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &our_string_array1, &our_string_array_len1, -#ifdef HAVE_UNIX_FD_PASSING - DBUS_TYPE_UNIX_FD, &our_unix_fd1, -#endif - DBUS_TYPE_UINT32, &our_uint2, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &our_string_array2, &our_string_array_len2, -#ifdef HAVE_UNIX_FD_PASSING - DBUS_TYPE_UNIX_FD, &our_unix_fd2, -#endif - DBUS_TYPE_UINT32, &our_uint3, - DBUS_TYPE_INVALID)) - { - _dbus_verbose ("expected error: %s - %s\n", error.name, - (error.message != NULL) ? error.message : "no message"); - /* ensure array of string and unix fd not leaked */ - _dbus_assert (our_string_array1 == NULL); - _dbus_assert (our_string_array2 == NULL); -#ifdef HAVE_UNIX_FD_PASSING - _dbus_assert (our_unix_fd1 == -1); - _dbus_assert (our_unix_fd2 == -1); -#endif - } - else - { - _dbus_test_fatal ("error: parse with wrong signature: 'uashuashu'."); - } - - /* parse with correct signature: "uashuash" */ - dbus_message_iter_init (message, &iter); - dbus_error_free (&error); - if (!dbus_message_iter_get_args (&iter, &error, - DBUS_TYPE_UINT32, &our_uint1, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &our_string_array1, &our_string_array_len1, -#ifdef HAVE_UNIX_FD_PASSING - DBUS_TYPE_UNIX_FD, &our_unix_fd1, -#endif - DBUS_TYPE_UINT32, &our_uint2, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &our_string_array2, &our_string_array_len2, -#ifdef HAVE_UNIX_FD_PASSING - DBUS_TYPE_UNIX_FD, &our_unix_fd2, -#endif - DBUS_TYPE_INVALID)) - { - _dbus_test_fatal ("Could not get arguments: %s - %s", error.name, - (error.message != NULL) ? error.message : "no message"); - } - else - { - dbus_free_string_array (our_string_array1); - dbus_free_string_array (our_string_array2); -#ifdef HAVE_UNIX_FD_PASSING - _dbus_close (our_unix_fd1, &error); - _dbus_close (our_unix_fd2, &error); -#endif - } - _dbus_check_fdleaks_leave (initial_fds); -} - -/** - * @ingroup DBusMessageInternals - * Unit test for DBusMessage. - * - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_message_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - 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; - 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; - const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; - const char *our_string_array1[] = { "foo", "Bar", "", "Woo woo Woo woo" }; - const char **v_ARRAY_STRING = our_string_array; - const char **v1_ARRAY_STRING = our_string_array1; - 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; - dbus_uint32_t v1_UINT32; - dbus_int64_t v_INT64; - dbus_uint64_t v_UINT64; - 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; - int v1_UNIX_FD; -#endif - char **decomposed; - DBusInitialFDs *initial_fds; - dbus_bool_t ok; - char basic_types[] = DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BOOLEAN_AS_STRING \ - DBUS_TYPE_INT16_AS_STRING \ - DBUS_TYPE_INT32_AS_STRING \ - DBUS_TYPE_INT64_AS_STRING \ - DBUS_TYPE_UINT16_AS_STRING \ - DBUS_TYPE_UINT32_AS_STRING \ - DBUS_TYPE_UINT64_AS_STRING \ - DBUS_TYPE_DOUBLE_AS_STRING \ - DBUS_TYPE_STRING_AS_STRING; - - initial_fds = _dbus_check_fdleaks_enter (); - - 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_test_fatal ("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_test_fatal ("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_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_path (message), - "/foo") == 0); - - if (!dbus_message_set_container_instance (message, "/org/freedesktop/DBus/Containers1/c42")) - _dbus_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_container_instance (message), - "/org/freedesktop/DBus/Containers1/c42") == 0); - - if (!dbus_message_set_interface (message, "org.Foo")) - _dbus_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_interface (message), - "org.Foo") == 0); - - if (!dbus_message_set_member (message, "Bar")) - _dbus_test_fatal ("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_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_path (message), - "/foo/bar") == 0); - - if (!dbus_message_set_interface (message, "org.Foo.Bar")) - _dbus_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_interface (message), - "org.Foo.Bar") == 0); - - if (!dbus_message_set_member (message, "BarFoo")) - _dbus_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_member (message), - "BarFoo") == 0); - - /* Realloc shorter again */ - - if (!dbus_message_set_path (message, "/foo")) - _dbus_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_path (message), - "/foo") == 0); - - if (!dbus_message_set_interface (message, "org.Foo")) - _dbus_test_fatal ("out of memory"); - _dbus_assert (strcmp (dbus_message_get_interface (message), - "org.Foo") == 0); - - if (!dbus_message_set_member (message, "Bar")) - _dbus_test_fatal ("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; - v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); - v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); - 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; - v1_UNIX_FD = 2; -#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, - DBUS_TYPE_INT64, &v_INT64, - DBUS_TYPE_UINT64, &v_UINT64, - 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), - 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), - 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; - sig[i++] = DBUS_TYPE_INT64; - sig[i++] = DBUS_TYPE_UINT64; - 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; - sig[i++] = DBUS_TYPE_ARRAY; - sig[i++] = DBUS_TYPE_UINT64; - sig[i++] = DBUS_TYPE_ARRAY; - sig[i++] = DBUS_TYPE_INT64; - 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, NULL, NULL); - _dbus_string_append_byte (buffer, data[i]); - _dbus_message_loader_return_buffer (loader, buffer); - } - - /* 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, NULL, NULL); - _dbus_string_append_byte (buffer, data[i]); - _dbus_message_loader_return_buffer (loader, buffer); - } - -#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_test_fatal ("no memory to queue messages"); - - if (_dbus_message_loader_get_is_corrupted (loader)) - _dbus_test_fatal ("message loader corrupted"); - - message = _dbus_message_loader_pop_message (loader); - if (!message) - _dbus_test_fatal ("received a NULL message"); - - if (dbus_message_get_reply_serial (message) != 5678) - _dbus_test_fatal ("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_test_fatal ("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_leave (initial_fds); - initial_fds = _dbus_check_fdleaks_enter (); - - /* Test enumeration of array elements */ - for (i = strlen (basic_types) - 1; i > 0; i--) - { - DBusBasicValue val; - int some; - char* signature = _dbus_strdup ("?"); - - signature[0] = basic_types[i]; - s = "SomeThingToSay"; - memset (&val, '\0', sizeof (val)); - - message = dbus_message_new_method_call ("de.ende.test", - "/de/ende/test", "de.ende.Test", "ArtistName"); - _dbus_assert (message != NULL); - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, - signature, &array_iter); - for (some = 0; some < 3; some++) - { - if (basic_types[i] == DBUS_TYPE_STRING) - dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &s); - else - dbus_message_iter_append_basic (&array_iter, basic_types[i], &val); - } - dbus_message_iter_close_container (&iter, &array_iter); - dbus_message_iter_init (message, &iter); - _dbus_assert (dbus_message_iter_get_element_count (&iter) == some); - dbus_message_unref (message); - dbus_free (signature); - } - /* Array of structs */ - message = dbus_message_new_method_call ("de.ende.test", - "/de/ende/test", "de.ende.Test", "ArtistName"); - _dbus_assert (message != NULL); - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, - DBUS_STRUCT_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING - DBUS_STRUCT_END_CHAR_AS_STRING, &array_iter); - dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, - NULL, &struct_iter); - s = "SpamAndEggs"; - dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); - dbus_message_iter_close_container (&array_iter, &struct_iter); - dbus_message_iter_close_container (&iter, &array_iter); - dbus_message_iter_init (message, &iter); - _dbus_assert (dbus_message_iter_get_element_count (&iter) == 1); - dbus_message_unref (message); - check_memleaks (); - - /* 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); - - ok = 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 (ok); - ok = dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, - NULL, &struct_iter); - _dbus_assert (ok); - s = "peaches"; - ok = dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); - _dbus_assert (ok); - - /* 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); - - /* Check we should not leak array of string or unix fd, fd.o#21259 */ - message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", - "/org/freedesktop/TestPath", - "Foo.TestInterface", - "Method"); - - /* signature "uashuash" */ - dbus_message_append_args (message, - DBUS_TYPE_UINT32, &v_UINT32, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, - _DBUS_N_ELEMENTS (our_string_array), -#ifdef HAVE_UNIX_FD_PASSING - DBUS_TYPE_UNIX_FD, &v_UNIX_FD, -#endif - DBUS_TYPE_UINT32, &v1_UINT32, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v1_ARRAY_STRING, - _DBUS_N_ELEMENTS (our_string_array1), -#ifdef HAVE_UNIX_FD_PASSING - DBUS_TYPE_UNIX_FD, &v1_UNIX_FD, -#endif - - DBUS_TYPE_INVALID); - - i = 0; - sig[i++] = DBUS_TYPE_UINT32; - sig[i++] = DBUS_TYPE_ARRAY; - sig[i++] = DBUS_TYPE_STRING; -#ifdef HAVE_UNIX_FD_PASSING - sig[i++] = DBUS_TYPE_UNIX_FD; -#endif - sig[i++] = DBUS_TYPE_UINT32; - sig[i++] = DBUS_TYPE_ARRAY; - sig[i++] = DBUS_TYPE_STRING; -#ifdef HAVE_UNIX_FD_PASSING - sig[i++] = DBUS_TYPE_UNIX_FD; -#endif - sig[i++] = DBUS_TYPE_INVALID; - - _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); - - verify_test_message_args_ignored (message); - verify_test_message_memleak (message); - - 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 (!try_message_data (&mdata.data, mdata.expected_validity)) - { - _dbus_test_fatal ("expected validity %d and did not get it", - mdata.expected_validity); - } - - _dbus_message_data_free (&mdata); - - count += 1; - } - - _dbus_test_diag ("%d sample messages tested", count); - - print_validities_seen (FALSE); - print_validities_seen (TRUE); - } - - check_memleaks (); - _dbus_check_fdleaks_leave (initial_fds); - - /* Now load every message in test_data_dir if we have one */ - if (test_data_dir == NULL) - return TRUE; - - initial_fds = _dbus_check_fdleaks_enter (); - - if (!foreach_message_file (test_data_dir, try_message_file, NULL)) - _dbus_test_fatal ("foreach_message_file test failed"); - - _dbus_check_fdleaks_leave (initial_fds); - - return TRUE; -} - #endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/dbus/dbus-misc.c b/dbus/dbus-misc.c index fefe05a4..67a28403 100644 --- a/dbus/dbus-misc.c +++ b/dbus/dbus-misc.c @@ -222,77 +222,3 @@ dbus_get_version (int *major_version_p, /** @} */ /* End of public API */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#include "dbus-test.h" -#include - - -dbus_bool_t -_dbus_misc_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - 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_test_fatal ("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_test_fatal ("no memory"); - - _dbus_assert (_dbus_string_equal_c_str (&str, DBUS_VERSION_STRING)); - - _dbus_string_free (&str); - - return TRUE; -} - -#endif /* !DOXYGEN_SHOULD_SKIP_THIS */ - -#endif diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index b5153cee..cde3c986 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -1193,61 +1193,3 @@ dbus_server_get_data (DBusServer *server, } /** @} */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS -#include "dbus-test.h" -#include - -dbus_bool_t -_dbus_server_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - const char *valid_addresses[] = { - "tcp:port=1234", - "tcp:host=localhost,port=1234", - "tcp:host=localhost,port=1234;tcp:port=5678", -#ifdef DBUS_UNIX - "unix:path=./boogie", - "tcp:port=1234;unix:path=./boogie", -#endif - }; - - DBusServer *server; - int i; - - for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++) - { - DBusError error = DBUS_ERROR_INIT; - char *address; - char *id; - - server = dbus_server_listen (valid_addresses[i], &error); - if (server == NULL) - { - _dbus_warn ("server listen error: %s: %s", error.name, error.message); - dbus_error_free (&error); - _dbus_assert_not_reached ("Failed to listen for valid address."); - } - - id = dbus_server_get_id (server); - _dbus_assert (id != NULL); - address = dbus_server_get_address (server); - _dbus_assert (address != NULL); - - if (strstr (address, id) == NULL) - { - _dbus_warn ("server id '%s' is not in the server address '%s'", - id, address); - _dbus_assert_not_reached ("bad server id or address"); - } - - dbus_free (id); - dbus_free (address); - - dbus_server_disconnect (server); - dbus_server_unref (server); - } - - return TRUE; -} - -#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/dbus/dbus-signature.c b/dbus/dbus-signature.c index 2df893c8..01a456bc 100644 --- a/dbus/dbus-signature.c +++ b/dbus/dbus-signature.c @@ -40,6 +40,8 @@ typedef struct unsigned int in_array : 1; /**< true if we are a subiterator pointing to an array's element type */ } DBusSignatureRealIter; +_DBUS_STATIC_ASSERT (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter)); + /** macro that checks whether a typecode is a container type */ #define TYPE_IS_CONTAINER(typecode) \ ((typecode) == DBUS_TYPE_STRUCT || \ @@ -411,181 +413,3 @@ dbus_type_is_valid (int typecode) } /** @} */ /* end of DBusSignature group */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS - -/** - * @ingroup DBusSignatureInternals - * Unit test for DBusSignature. - * - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_signature_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - DBusSignatureIter iter; - DBusSignatureIter subiter; - DBusSignatureIter subsubiter; - DBusSignatureIter subsubsubiter; - const char *sig; - dbus_bool_t boolres; - - _DBUS_STATIC_ASSERT (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter)); - - sig = ""; - _dbus_assert (dbus_signature_validate (sig, NULL)); - _dbus_assert (!dbus_signature_validate_single (sig, NULL)); - dbus_signature_iter_init (&iter, sig); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID); - - sig = DBUS_TYPE_STRING_AS_STRING; - _dbus_assert (dbus_signature_validate (sig, NULL)); - _dbus_assert (dbus_signature_validate_single (sig, NULL)); - dbus_signature_iter_init (&iter, sig); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); - - sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING; - _dbus_assert (dbus_signature_validate (sig, NULL)); - dbus_signature_iter_init (&iter, sig); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); - boolres = dbus_signature_iter_next (&iter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE); - - sig = DBUS_TYPE_UINT16_AS_STRING - DBUS_STRUCT_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_UINT32_AS_STRING - DBUS_TYPE_VARIANT_AS_STRING - DBUS_TYPE_DOUBLE_AS_STRING - DBUS_STRUCT_END_CHAR_AS_STRING; - _dbus_assert (dbus_signature_validate (sig, NULL)); - dbus_signature_iter_init (&iter, sig); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); - boolres = dbus_signature_iter_next (&iter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); - dbus_signature_iter_recurse (&iter, &subiter); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING); - boolres = dbus_signature_iter_next (&subiter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); - boolres = dbus_signature_iter_next (&subiter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT); - boolres = dbus_signature_iter_next (&subiter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE); - - sig = DBUS_TYPE_UINT16_AS_STRING - DBUS_STRUCT_BEGIN_CHAR_AS_STRING - DBUS_TYPE_UINT32_AS_STRING - DBUS_TYPE_BYTE_AS_STRING - DBUS_TYPE_ARRAY_AS_STRING - DBUS_TYPE_ARRAY_AS_STRING - DBUS_TYPE_DOUBLE_AS_STRING - DBUS_STRUCT_BEGIN_CHAR_AS_STRING - DBUS_TYPE_BYTE_AS_STRING - DBUS_STRUCT_END_CHAR_AS_STRING - DBUS_STRUCT_END_CHAR_AS_STRING; - _dbus_assert (dbus_signature_validate (sig, NULL)); - dbus_signature_iter_init (&iter, sig); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); - boolres = dbus_signature_iter_next (&iter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); - dbus_signature_iter_recurse (&iter, &subiter); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); - boolres = dbus_signature_iter_next (&subiter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE); - boolres = dbus_signature_iter_next (&subiter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY); - _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY); - - dbus_signature_iter_recurse (&subiter, &subsubiter); - _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY); - _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE); - - dbus_signature_iter_recurse (&subsubiter, &subsubsubiter); - _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE); - boolres = dbus_signature_iter_next (&subiter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT); - dbus_signature_iter_recurse (&subiter, &subsubiter); - _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE); - - sig = DBUS_TYPE_ARRAY_AS_STRING - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_INT16_AS_STRING - DBUS_TYPE_STRING_AS_STRING - DBUS_DICT_ENTRY_END_CHAR_AS_STRING - DBUS_TYPE_VARIANT_AS_STRING; - _dbus_assert (dbus_signature_validate (sig, NULL)); - _dbus_assert (!dbus_signature_validate_single (sig, NULL)); - dbus_signature_iter_init (&iter, sig); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY); - _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY); - - dbus_signature_iter_recurse (&iter, &subiter); - dbus_signature_iter_recurse (&subiter, &subsubiter); - _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16); - boolres = dbus_signature_iter_next (&subsubiter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING); - boolres = dbus_signature_iter_next (&subsubiter); - _dbus_assert (!boolres); - - boolres = dbus_signature_iter_next (&iter); - _dbus_assert (boolres); - _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT); - boolres = dbus_signature_iter_next (&iter); - _dbus_assert (!boolres); - - sig = DBUS_TYPE_DICT_ENTRY_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_TYPE_ARRAY_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_TYPE_UINT32_AS_STRING - DBUS_TYPE_ARRAY_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_TYPE_ARRAY_AS_STRING - DBUS_TYPE_DICT_ENTRY_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_INT32_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_INT32_AS_STRING - DBUS_TYPE_STRING_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_STRUCT_END_CHAR_AS_STRING - DBUS_STRUCT_BEGIN_CHAR_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - - sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING - DBUS_TYPE_BOOLEAN_AS_STRING; - _dbus_assert (!dbus_signature_validate (sig, NULL)); - return TRUE; -#if 0 - oom: - _dbus_test_fatal ("out of memory"); - return FALSE; -#endif -} - -#endif - diff --git a/dbus/dbus-string-util.c b/dbus/dbus-string-util.c index 8e304281..5b433102 100644 --- a/dbus/dbus-string-util.c +++ b/dbus/dbus-string-util.c @@ -1,8 +1,14 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-string-util.c Would be in dbus-string.c, but not used in libdbus * - * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - * Copyright (C) 2006 Ralf Habacker + * Copyright 2002-2008 Red Hat, Inc. + * Copyright 2003 CodeFactory AB + * Copyright 2003 Mark McLoughlin + * Copyright 2004 Michael Meeks + * Copyright 2006-2015 Ralf Habacker + * Copyright 2007 Allison Lortie + * Copyright 2011 Roberto Guido + * Copyright 2016-2018 Collabora Ltd. * * Licensed under the Academic Free License version 2.1 * @@ -27,7 +33,6 @@ #include "dbus-string.h" #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1 #include "dbus-string-private.h" -#include /** * @addtogroup DBusString @@ -115,845 +120,3 @@ _dbus_string_find_byte_backward (const DBusString *str, } /** @} */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS -#include "dbus-test.h" -#include - -static void -test_hex_roundtrip (const char *data, - int len) -{ - DBusString orig; - DBusString encoded; - DBusString decoded; - int end; - - if (len < 0) - len = strlen (data); - - if (!_dbus_string_init (&orig)) - _dbus_test_fatal ("could not init string"); - - if (!_dbus_string_init (&encoded)) - _dbus_test_fatal ("could not init string"); - - if (!_dbus_string_init (&decoded)) - _dbus_test_fatal ("could not init string"); - - if (!_dbus_string_append_len (&orig, data, len)) - _dbus_test_fatal ("couldn't append orig data"); - - if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0)) - _dbus_test_fatal ("could not encode"); - - if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0)) - _dbus_test_fatal ("could not decode"); - - _dbus_assert (_dbus_string_get_length (&encoded) == end); - - if (!_dbus_string_equal (&orig, &decoded)) - { - const char *s; - - _dbus_test_diag ("Original string %d bytes encoded %d bytes decoded %d bytes", - _dbus_string_get_length (&orig), - _dbus_string_get_length (&encoded), - _dbus_string_get_length (&decoded)); - _dbus_test_diag ("Original: %s", data); - s = _dbus_string_get_const_data (&decoded); - _dbus_test_diag ("Decoded: %s", s); - _dbus_test_fatal ("original string not the same as string decoded from hex"); - } - - _dbus_string_free (&orig); - _dbus_string_free (&encoded); - _dbus_string_free (&decoded); -} - -typedef void (* TestRoundtripFunc) (const char *data, - int len); -static void -test_roundtrips (TestRoundtripFunc func) -{ - (* func) ("Hello this is a string\n", -1); - (* func) ("Hello this is a string\n1", -1); - (* func) ("Hello this is a string\n12", -1); - (* func) ("Hello this is a string\n123", -1); - (* func) ("Hello this is a string\n1234", -1); - (* func) ("Hello this is a string\n12345", -1); - (* func) ("", 0); - (* func) ("1", 1); - (* func) ("12", 2); - (* func) ("123", 3); - (* func) ("1234", 4); - (* func) ("12345", 5); - (* func) ("", 1); - (* func) ("1", 2); - (* func) ("12", 3); - (* func) ("123", 4); - (* func) ("1234", 5); - (* func) ("12345", 6); - { - unsigned char buf[512]; - int i; - - i = 0; - while (i < _DBUS_N_ELEMENTS (buf)) - { - buf[i] = (i & 0xff); - ++i; - } - i = 0; - while (i < _DBUS_N_ELEMENTS (buf)) - { - (* func) ((const char *) buf, i); - ++i; - } - } -} - -_DBUS_STRING_DEFINE_STATIC (test_static_string, "hello"); - -/** - * @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 (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - DBusString str = _DBUS_STRING_INIT_INVALID; - DBusString other; - int i, a, end; - long v; - 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; - DBusRealString *real_test_static_string = (DBusRealString *) &test_static_string; - - _dbus_assert (real_test_static_string->str != NULL); - _dbus_assert (strcmp ((const char *) real_test_static_string->str, "hello") == 0); - _dbus_assert (real_test_static_string->len == 5); - _dbus_assert (real_test_static_string->allocated > 5); - _dbus_assert (real_test_static_string->constant); - _dbus_assert (real_test_static_string->locked); - _dbus_assert (real_test_static_string->valid); - _dbus_assert (real_test_static_string->align_offset == 0); - - /* Test that _DBUS_STRING_INIT_INVALID has the desired effect */ - _dbus_string_free (&str); - _dbus_string_free (&str); - _dbus_string_free (&str); - - /* Test shortening and setting length */ - i = 0; - while (i < _DBUS_N_ELEMENTS (lens)) - { - int j; - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("failed to init string"); - - if (!_dbus_string_set_length (&str, lens[i])) - _dbus_test_fatal ("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); - /* Test that a cleared string is effectively _DBUS_STRING_INIT_INVALID */ - _dbus_string_free (&str); - _dbus_string_free (&str); - - ++i; - } - - /* Test equality */ - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("oom"); - - if (!_dbus_string_append (&str, "Hello World")) - _dbus_test_fatal ("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_test_fatal ("failed to init string"); - - i = 0; - while (i < 10) - { - if (!_dbus_string_append (&str, "a")) - _dbus_test_fatal ("failed to append string to string"); - - _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1); - - if (!_dbus_string_append_byte (&str, 'b')) - _dbus_test_fatal ("failed to append byte to string"); - - _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2); - - ++i; - } - - _dbus_string_free (&str); - - /* Check steal_data */ - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("failed to init string"); - - if (!_dbus_string_append (&str, "Hello World")) - _dbus_test_fatal ("could not append to string"); - - i = _dbus_string_get_length (&str); - - if (!_dbus_string_steal_data (&str, &s)) - _dbus_test_fatal ("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_test_fatal ("could not append to string"); - - i = _dbus_string_get_length (&str); - - if (!_dbus_string_init (&other)) - _dbus_test_fatal ("could not init string"); - - if (!_dbus_string_move (&str, 0, &other, 0)) - _dbus_test_fatal ("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_test_fatal ("could not append to string"); - - if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other))) - _dbus_test_fatal ("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_test_fatal ("could not append to string"); - - if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2)) - _dbus_test_fatal ("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_test_fatal ("could not append to string"); - - i = _dbus_string_get_length (&str); - - if (!_dbus_string_init (&other)) - _dbus_test_fatal ("could not init string"); - - if (!_dbus_string_copy (&str, 0, &other, 0)) - _dbus_test_fatal ("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_test_fatal ("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_test_fatal ("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_test_fatal ("failed to init string"); - - if (!_dbus_string_append (&str, "Hello World")) - _dbus_test_fatal ("could not append to string"); - - i = _dbus_string_get_length (&str); - - if (!_dbus_string_init (&other)) - _dbus_test_fatal ("could not init string"); - - if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), - &other, 0, _dbus_string_get_length (&other))) - _dbus_test_fatal ("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_test_fatal ("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_test_fatal ("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); - - /* Different tests are provided because different behaviours are - * implemented in _dbus_string_replace_len() in function of replacing and - * replaced lengths - */ - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("failed to init string"); - - if (!_dbus_string_append (&str, "Hello World")) - _dbus_test_fatal ("could not append to string"); - - i = _dbus_string_get_length (&str); - - if (!_dbus_string_init (&other)) - _dbus_test_fatal ("could not init string"); - - if (!_dbus_string_append (&other, "Foo String")) - _dbus_test_fatal ("could not append to string"); - - a = _dbus_string_get_length (&other); - - if (!_dbus_string_replace_len (&str, 0, 6, - &other, 4, 0)) - _dbus_test_fatal ("could not replace 0 length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String")); - - if (!_dbus_string_replace_len (&str, 5, 6, - &other, - _dbus_string_get_length (&other), - 0)) - _dbus_test_fatal ("could not replace at the end"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String World")); - - if (!_dbus_string_replace_len (&str, 0, 5, - &other, - _dbus_string_get_length (&other) - 5, - 5)) - _dbus_test_fatal ("could not replace same length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String Hello")); - - if (!_dbus_string_replace_len (&str, 6, 5, - &other, 4, 12)) - _dbus_test_fatal ("could not replace with shorter string"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 5); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo World Hello")); - - if (!_dbus_string_replace_len (&str, 0, 1, - &other, 0, 3)) - _dbus_test_fatal ("could not replace at the beginning"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 3); - _dbus_assert (_dbus_string_equal_c_str (&other, - "H World Hello")); - - if (!_dbus_string_replace_len (&str, 6, 5, - &other, - _dbus_string_get_length (&other) - 5, - 5)) - _dbus_test_fatal ("could not replace same length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 3); - _dbus_assert (_dbus_string_equal_c_str (&other, - "H World World")); - - _dbus_string_free (&str); - _dbus_string_free (&other); - - /* Check insert/set/get byte */ - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("failed to init string"); - - if (!_dbus_string_append (&str, "Hello")) - _dbus_test_fatal ("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_test_fatal ("can't insert byte"); - - if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z')) - _dbus_test_fatal ("can't insert byte"); - - if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W')) - _dbus_test_fatal ("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_test_fatal ("failed to init string"); - - if (!_dbus_string_append_int (&str, 27)) - _dbus_test_fatal ("failed to append int"); - - i = _dbus_string_get_length (&str); - - if (!_dbus_string_parse_int (&str, 0, &v, &end)) - _dbus_test_fatal ("failed to parse int"); - - _dbus_assert (v == 27); - _dbus_assert (end == i); - - _dbus_string_free (&str); - - /* Test find */ - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("failed to init string"); - - if (!_dbus_string_append (&str, "Hello")) - _dbus_test_fatal ("couldn't append to string"); - - if (!_dbus_string_find (&str, 0, "He", &i)) - _dbus_test_fatal ("didn't find 'He'"); - _dbus_assert (i == 0); - - if (!_dbus_string_find (&str, 0, "Hello", &i)) - _dbus_test_fatal ("didn't find 'Hello'"); - _dbus_assert (i == 0); - - if (!_dbus_string_find (&str, 0, "ello", &i)) - _dbus_test_fatal ("didn't find 'ello'"); - _dbus_assert (i == 1); - - if (!_dbus_string_find (&str, 0, "lo", &i)) - _dbus_test_fatal ("didn't find 'lo'"); - _dbus_assert (i == 3); - - if (!_dbus_string_find (&str, 2, "lo", &i)) - _dbus_test_fatal ("didn't find 'lo'"); - _dbus_assert (i == 3); - - if (_dbus_string_find (&str, 4, "lo", &i)) - _dbus_test_fatal ("did find 'lo'"); - - if (!_dbus_string_find (&str, 0, "l", &i)) - _dbus_test_fatal ("didn't find 'l'"); - _dbus_assert (i == 2); - - if (!_dbus_string_find (&str, 0, "H", &i)) - _dbus_test_fatal ("didn't find 'H'"); - _dbus_assert (i == 0); - - if (!_dbus_string_find (&str, 0, "", &i)) - _dbus_test_fatal ("didn't find ''"); - _dbus_assert (i == 0); - - if (_dbus_string_find (&str, 0, "Hello!", NULL)) - _dbus_test_fatal ("Did find 'Hello!'"); - - if (_dbus_string_find (&str, 0, "Oh, Hello", NULL)) - _dbus_test_fatal ("Did find 'Oh, Hello'"); - - if (_dbus_string_find (&str, 0, "ill", NULL)) - _dbus_test_fatal ("Did find 'ill'"); - - if (_dbus_string_find (&str, 0, "q", NULL)) - _dbus_test_fatal ("Did find 'q'"); - - if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) - _dbus_test_fatal ("Didn't find 'He'"); - - if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) - _dbus_test_fatal ("Did find 'Hello'"); - - if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) - _dbus_test_fatal ("Did not find 'H'"); - _dbus_assert (i == 0); - - if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) - _dbus_test_fatal ("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_test_fatal ("Did find 'o'"); - _dbus_assert (i == -1); - - if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) - _dbus_test_fatal ("Did find 'e'"); - _dbus_assert (i == -1); - - if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) - _dbus_test_fatal ("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_test_fatal ("could not init string"); - - if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0)) - _dbus_test_fatal ("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_test_fatal ("Did not find '\\r\\n'"); - if (found != 3 || found_len != 2) - _dbus_test_fatal ("invalid return values"); - - if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) - _dbus_test_fatal ("Did not find '\\n'"); - if (found != 8 || found_len != 1) - _dbus_test_fatal ("invalid return values"); - - if (_dbus_string_find_eol (&str, 9, &found, &found_len)) - _dbus_test_fatal ("Found not expected '\\n'"); - else if (found != 11 || found_len != 0) - _dbus_test_fatal ("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_test_fatal ("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_test_fatal ("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_test_fatal ("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_test_fatal ("no memory"); - - if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_init (&line)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_pop_line (&str, &line)) - _dbus_test_fatal ("failed to pop first line"); - - _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); - - if (!_dbus_string_pop_line (&str, &line)) - _dbus_test_fatal ("failed to pop second line"); - - _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); - - if (!_dbus_string_pop_line (&str, &line)) - _dbus_test_fatal ("failed to pop third line"); - - _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); - - if (!_dbus_string_pop_line (&str, &line)) - _dbus_test_fatal ("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_test_fatal ("no memory"); - - for (i = 0; i < 10000; i++) - if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz")) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_set_length (&str, 10)) - _dbus_test_fatal ("failed to set length"); - - /* actually compact */ - if (!_dbus_string_compact (&str, 2048)) - _dbus_test_fatal ("failed to compact after set_length"); - - /* peek inside to make sure it worked */ - if (((DBusRealString *)&str)->allocated > 30) - _dbus_test_fatal ("compacting string didn't do anything"); - - if (!_dbus_string_equal_c_str (&str, "abcdefghij")) - _dbus_test_fatal ("unexpected content after compact"); - - /* compact nothing */ - if (!_dbus_string_compact (&str, 2048)) - _dbus_test_fatal ("failed to compact 2nd time"); - - if (!_dbus_string_equal_c_str (&str, "abcdefghij")) - _dbus_test_fatal ("unexpected content after 2nd compact"); - - /* and make sure it still works...*/ - if (!_dbus_string_append (&str, "123456")) - _dbus_test_fatal ("failed to append after compact"); - - if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) - _dbus_test_fatal ("unexpected content after append"); - - /* after growing automatically, this should do nothing */ - if (!_dbus_string_compact (&str, 20000)) - _dbus_test_fatal ("failed to compact after grow"); - - /* but this one will do something */ - if (!_dbus_string_compact (&str, 0)) - _dbus_test_fatal ("failed to compact after grow"); - - if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) - _dbus_test_fatal ("unexpected content"); - - if (!_dbus_string_append (&str, "!@#$%")) - _dbus_test_fatal ("failed to append after compact"); - - if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%")) - _dbus_test_fatal ("unexpected content"); - - _dbus_string_free (&str); - } - - { - const char two_strings[] = "one\ttwo"; - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_init (&other)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_append (&str, two_strings)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_split_on_byte (&str, '\t', &other)) - _dbus_test_fatal ("no memory or delimiter not found"); - - if (strcmp (_dbus_string_get_data (&str), "one") != 0) - _dbus_test_fatal ("left side after split on tab is wrong"); - - if (strcmp (_dbus_string_get_data (&other), "two") != 0) - _dbus_test_fatal ("right side after split on tab is wrong"); - - _dbus_string_free (&str); - _dbus_string_free (&other); - } - - { - const char upper_string[] = "TOUPPERSTRING"; - const char lower_string[] = "toupperstring"; - const char lower2_string[] = "toupperSTRING"; - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_append (&str, upper_string)) - _dbus_test_fatal ("no memory"); - - _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str)); - - if (!_dbus_string_equal_c_str (&str, lower_string)) - _dbus_test_fatal ("_dbus_string_tolower_ascii failed"); - - _dbus_string_free (&str); - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_append (&str, upper_string)) - _dbus_test_fatal ("no memory"); - - _dbus_string_tolower_ascii (&str, 0, 7); - - if (!_dbus_string_equal_c_str (&str, lower2_string)) - _dbus_test_fatal ("_dbus_string_tolower_ascii failed in partial conversion"); - - _dbus_string_free (&str); - } - - { - const char lower_string[] = "toupperstring"; - const char upper_string[] = "TOUPPERSTRING"; - const char upper2_string[] = "TOUPPERstring"; - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_append (&str, lower_string)) - _dbus_test_fatal ("no memory"); - - _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str)); - - if (!_dbus_string_equal_c_str (&str, upper_string)) - _dbus_test_fatal ("_dbus_string_toupper_ascii failed"); - - _dbus_string_free (&str); - - if (!_dbus_string_init (&str)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_append (&str, lower_string)) - _dbus_test_fatal ("no memory"); - - _dbus_string_toupper_ascii (&str, 0, 7); - - if (!_dbus_string_equal_c_str (&str, upper2_string)) - _dbus_test_fatal ("_dbus_string_toupper_ascii failed in partial conversion"); - - _dbus_string_free (&str); - } - - return TRUE; -} - -#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index fc17e026..52c71c5b 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -1,8 +1,15 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-string.c String utility class (internal to D-Bus implementation) * - * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - * Copyright (C) 2006 Ralf Habacker + * Copyright 2002-2007 Red Hat, Inc. + * Copyright 2003 CodeFactory AB + * Copyright 2003 Mark McLoughlin + * Copyright 2004 Michael Meeks + * Copyright 2006-2014 Ralf Habacker + * Copyright 2006-2018 Collabora Ltd. + * Copyright 2007 Allison Lortie + * Copyright 2011 Roberto Guido + * Copyright 2013 Chengwei Yang / Intel * * Licensed under the Academic Free License version 2.1 * diff --git a/dbus/dbus-sysdeps-util.c b/dbus/dbus-sysdeps-util.c index 4a7d08cc..66af910e 100644 --- a/dbus/dbus-sysdeps-util.c +++ b/dbus/dbus-sysdeps-util.c @@ -1,8 +1,11 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-sysdeps-util.c Tests for dbus-sysdeps.h API * - * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - * Copyright (C) 2003 CodeFactory AB + * Copyright 2002-2008 Red Hat, Inc. + * Copyright 2003 CodeFactory AB + * Copyright 2006 Ralf Habacker + * Copyright 2006 Sjoerd Simons + * Copyright 2016-2018 Collabora Ltd. * * Licensed under the Academic Free License version 2.1 * @@ -26,8 +29,6 @@ #include "dbus-sysdeps.h" #include "dbus-internals.h" #include "dbus-string.h" -#include "dbus-test.h" -#include #include @@ -82,121 +83,3 @@ _dbus_get_environment (void) return environment; } - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS -static void -check_dirname (const char *filename, - const char *dirname) -{ - DBusString f, d; - - _dbus_string_init_const (&f, filename); - - if (!_dbus_string_init (&d)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_get_dirname (&f, &d)) - _dbus_test_fatal ("no memory"); - - if (!_dbus_string_equal_c_str (&d, dirname)) - { - _dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"", - filename, - _dbus_string_get_const_data (&d), - dirname); - exit (1); - } - - _dbus_string_free (&d); -} - -static void -check_path_absolute (const char *path, - dbus_bool_t expected) -{ - DBusString p; - - _dbus_string_init_const (&p, path); - - if (_dbus_path_is_absolute (&p) != expected) - { - _dbus_warn ("For path \"%s\" expected absolute = %d got %d", - path, expected, _dbus_path_is_absolute (&p)); - exit (1); - } -} - -/** - * Unit test for dbus-sysdeps.c. - * - * @returns #TRUE on success. - */ -dbus_bool_t -_dbus_sysdeps_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ -#ifdef DBUS_WIN - check_dirname ("foo\\bar", "foo"); - check_dirname ("foo\\\\bar", "foo"); - check_dirname ("foo/\\/bar", "foo"); - check_dirname ("foo\\bar/", "foo"); - check_dirname ("foo//bar\\", "foo"); - check_dirname ("foo\\bar/", "foo"); - check_dirname ("foo/bar\\\\", "foo"); - check_dirname ("\\foo", "\\"); - check_dirname ("\\\\foo", "\\"); - check_dirname ("\\", "\\"); - check_dirname ("\\\\", "\\"); - check_dirname ("\\/", "\\"); - check_dirname ("/\\/", "/"); - check_dirname ("c:\\foo\\bar", "c:\\foo"); - check_dirname ("c:\\foo", "c:\\"); - check_dirname ("c:/foo", "c:/"); - check_dirname ("c:\\", "c:\\"); - check_dirname ("c:/", "c:/"); - check_dirname ("", "."); -#else - check_dirname ("foo", "."); - check_dirname ("foo/bar", "foo"); - check_dirname ("foo//bar", "foo"); - check_dirname ("foo///bar", "foo"); - check_dirname ("foo/bar/", "foo"); - check_dirname ("foo//bar/", "foo"); - check_dirname ("foo///bar/", "foo"); - check_dirname ("foo/bar//", "foo"); - check_dirname ("foo//bar////", "foo"); - check_dirname ("foo///bar///////", "foo"); - check_dirname ("/foo", "/"); - check_dirname ("////foo", "/"); - check_dirname ("/foo/bar", "/foo"); - check_dirname ("/foo//bar", "/foo"); - check_dirname ("/foo///bar", "/foo"); - check_dirname ("/", "/"); - check_dirname ("///", "/"); - check_dirname ("", "."); -#endif - -#ifdef DBUS_WIN - check_path_absolute ("c:/", TRUE); - check_path_absolute ("c:/foo", TRUE); - check_path_absolute ("", FALSE); - check_path_absolute ("foo", FALSE); - check_path_absolute ("foo/bar", FALSE); - check_path_absolute ("", FALSE); - check_path_absolute ("foo\\bar", FALSE); - check_path_absolute ("c:\\", TRUE); - check_path_absolute ("c:\\foo", TRUE); - check_path_absolute ("c:", TRUE); - check_path_absolute ("c:\\foo\\bar", TRUE); - check_path_absolute ("\\", TRUE); - check_path_absolute ("/", TRUE); -#else - check_path_absolute ("/", TRUE); - check_path_absolute ("/foo", TRUE); - check_path_absolute ("", FALSE); - check_path_absolute ("foo", FALSE); - check_path_absolute ("foo/bar", FALSE); -#endif - - return TRUE; -} -#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/dbus/dbus-test-main.c b/dbus/dbus-test-main.c deleted file mode 100644 index 7a4eda7e..00000000 --- a/dbus/dbus-test-main.c +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* dbus-test.c Program to run all tests - * - * Copyright (C) 2002 Red Hat Inc. - * - * Licensed under the Academic Free License version 2.1 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include - -#include "dbus-internals.h" -#include "dbus-test.h" -#include "dbus-test-wrappers.h" - -static DBusTestCase tests[] = -{ - { "string", _dbus_string_test }, - { "sysdeps", _dbus_sysdeps_test }, - { "data-slot", _dbus_data_slot_test }, - { "misc", _dbus_misc_test }, - { "address", _dbus_address_test }, - { "server", _dbus_server_test }, - { "object-tree", _dbus_object_tree_test }, - { "signature", _dbus_signature_test }, - { "marshalling", _dbus_marshal_test }, - { "marshal-recursive" , _dbus_marshal_recursive_test }, - { "byteswap", _dbus_marshal_byteswap_test }, - { "memory", _dbus_memory_test }, - { "mem-pool", _dbus_mem_pool_test }, - { "list", _dbus_list_test }, - { "marshal-validate", _dbus_marshal_validate_test }, - { "message", _dbus_message_test }, - { "hash", _dbus_hash_test }, - { "credentials", _dbus_credentials_test }, - { "keyring", _dbus_keyring_test }, - { "sha", _dbus_sha_test }, - { "auth", _dbus_auth_test }, - -#if defined(DBUS_UNIX) - { "userdb", _dbus_userdb_test }, - { "transport-unix", _dbus_transport_unix_test }, -#endif - -#if !defined(DBUS_WINCE) - { "spawn", _dbus_spawn_test }, -#endif - - { NULL } -}; - -int -main (int argc, - char **argv) -{ - return _dbus_test_main (argc, argv, _DBUS_N_ELEMENTS (tests), tests, - DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS, - NULL, NULL); -} diff --git a/dbus/dbus-test-wrappers.c b/dbus/dbus-test-wrappers.c deleted file mode 100644 index 5121687f..00000000 --- a/dbus/dbus-test-wrappers.c +++ /dev/null @@ -1,183 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright 2002-2009 Red Hat Inc. - * Copyright 2011-2018 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include "dbus/dbus-test-wrappers.h" - -#ifndef DBUS_ENABLE_EMBEDDED_TESTS -#error This file is only relevant for the embedded tests -#endif - -#include -#include - -#include "dbus/dbus-message-internal.h" -#include "dbus/dbus-test-tap.h" - -#if HAVE_LOCALE_H -#include -#endif - -#ifdef DBUS_UNIX -# include -#endif - -/* - * Like strdup(), but crash on out-of-memory, and pass through NULL - * unchanged (the "0" in the name is meant to be a mnemonic for this, - * similar to g_strcmp0()). - */ -static char * -strdup0_or_die (const char *str) -{ - char *ret; - - if (str == NULL) - return NULL; /* not an error */ - - ret = strdup (str); - - if (ret == NULL) - _dbus_test_fatal ("Out of memory"); - - return ret; -} - -/* - * _dbus_test_main: - * @argc: number of command-line arguments - * @argv: array of @argc arguments - * @n_tests: length of @tests - * @tests: array of @n_tests tests - * @flags: flags affecting all tests - * @test_pre_hook: if not %NULL, called before each test - * @test_post_hook: if not %NULL, called after each test - * - * Wrapper for dbus tests that do not use GLib. Processing of @tests - * can be terminated early by an entry with @name = NULL, which is a - * convenient way to put a trailing comma on every "real" test entry - * without breaking compilation on pedantic C compilers. - */ -int -_dbus_test_main (int argc, - char **argv, - size_t n_tests, - const DBusTestCase *tests, - DBusTestFlags flags, - void (*test_pre_hook) (void), - void (*test_post_hook) (void)) -{ - char *test_data_dir; - char *specific_test; - size_t i; - -#ifdef DBUS_UNIX - /* close any inherited fds so dbus-spawn's check for close-on-exec works */ - _dbus_close_all (); -#endif - -#if HAVE_SETLOCALE - setlocale(LC_ALL, ""); -#endif - - /* We can't assume that strings from _dbus_getenv() will remain valid - * forever, because some tests call setenv(), which is allowed to - * reallocate the entire environment block, and in Wine it seems that it - * genuinely does; so we copy them. - * - * We can't use _dbus_strdup() here because the test might be checking - * for memory leaks, so we don't want any libdbus allocations still - * alive at the end; so we use strdup(), which is not in Standard C but - * is available in both POSIX and Windows. */ - if (argc > 1 && strcmp (argv[1], "--tap") != 0) - test_data_dir = strdup0_or_die (argv[1]); - else - test_data_dir = strdup0_or_die (_dbus_getenv ("DBUS_TEST_DATA")); - - if (test_data_dir != NULL) - _dbus_test_diag ("Test data in %s", test_data_dir); - else if (flags & DBUS_TEST_FLAGS_REQUIRE_DATA) - _dbus_test_fatal ("Must specify test data directory as argv[1] or " - "in DBUS_TEST_DATA environment variable"); - else - _dbus_test_diag ("No test data!"); - - if (argc > 2) - specific_test = strdup0_or_die (argv[2]); - else - specific_test = strdup0_or_die (_dbus_getenv ("DBUS_TEST_ONLY")); - - for (i = 0; i < n_tests; i++) - { - long before, after; - DBusInitialFDs *initial_fds = NULL; - - if (tests[i].name == NULL) - break; - - if (n_tests > 1 && - specific_test != NULL && - strcmp (specific_test, tests[i].name) != 0) - { - _dbus_test_skip ("%s - Only intending to run %s", - tests[i].name, specific_test); - continue; - } - - _dbus_test_diag ("Running test: %s", tests[i].name); - _dbus_get_monotonic_time (&before, NULL); - - if (test_pre_hook) - test_pre_hook (); - - if (flags & DBUS_TEST_FLAGS_CHECK_FD_LEAKS) - initial_fds = _dbus_check_fdleaks_enter (); - - if (tests[i].func (test_data_dir)) - _dbus_test_ok ("%s", tests[i].name); - else - _dbus_test_not_ok ("%s", tests[i].name); - - _dbus_get_monotonic_time (&after, NULL); - - _dbus_test_diag ("%s test took %ld seconds", - tests[i].name, after - before); - - if (test_post_hook) - test_post_hook (); - - if (flags & DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS) - _dbus_test_check_memleaks (tests[i].name); - - if (flags & DBUS_TEST_FLAGS_CHECK_FD_LEAKS) - _dbus_check_fdleaks_leave (initial_fds); - } - - free (test_data_dir); - free (specific_test); - - return _dbus_test_done_testing (); -} diff --git a/dbus/dbus-test-wrappers.h b/dbus/dbus-test-wrappers.h deleted file mode 100644 index 42aa2ead..00000000 --- a/dbus/dbus-test-wrappers.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright © 2017 Collabora Ltd. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef DBUS_TEST_WRAPPERS_H -#define DBUS_TEST_WRAPPERS_H - -#include - -typedef struct -{ - const char *name; - dbus_bool_t (*func) (const char *test_data_dir); -} DBusTestCase; - -typedef enum -{ - DBUS_TEST_FLAGS_REQUIRE_DATA = (1 << 0), - DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS = (1 << 1), - DBUS_TEST_FLAGS_CHECK_FD_LEAKS = (1 << 2), - DBUS_TEST_FLAGS_NONE = 0 -} DBusTestFlags; - -int _dbus_test_main (int argc, - char **argv, - size_t n_tests, - const DBusTestCase *tests, - DBusTestFlags flags, - void (*test_pre_hook) (void), - void (*test_post_hook) (void)); - -#endif diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index 4476a5e5..197e0dc7 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -37,39 +37,15 @@ * then you have added too many. */ -DBUS_PRIVATE_EXPORT -dbus_bool_t _dbus_hash_test (const char *test_data_dir); - -DBUS_PRIVATE_EXPORT -dbus_bool_t _dbus_list_test (const char *test_data_dir); - DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_marshal_test (const char *test_data_dir); -dbus_bool_t _dbus_marshal_recursive_test (const char *test_data_dir); -dbus_bool_t _dbus_marshal_byteswap_test (const char *test_data_dir); -dbus_bool_t _dbus_marshal_validate_test (const char *test_data_dir); - -DBUS_PRIVATE_EXPORT -dbus_bool_t _dbus_misc_test (const char *test_data_dir); - -DBUS_PRIVATE_EXPORT -dbus_bool_t _dbus_signature_test (const char *test_data_dir); - DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_mem_pool_test (const char *test_data_dir); -dbus_bool_t _dbus_string_test (const char *test_data_dir); - DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_address_test (const char *test_data_dir); -DBUS_PRIVATE_EXPORT -dbus_bool_t _dbus_server_test (const char *test_data_dir); - -dbus_bool_t _dbus_message_test (const char *test_data_dir); -dbus_bool_t _dbus_auth_test (const char *test_data_dir); - DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_sha_test (const char *test_data_dir); @@ -79,26 +55,13 @@ dbus_bool_t _dbus_keyring_test (const char *test_data_dir); DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_data_slot_test (const char *test_data_dir); -dbus_bool_t _dbus_sysdeps_test (const char *test_data_dir); -dbus_bool_t _dbus_spawn_test (const char *test_data_dir); - DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_userdb_test (const char *test_data_dir); -DBUS_PRIVATE_EXPORT -dbus_bool_t _dbus_transport_unix_test (const char *test_data_dir); - DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_memory_test (const char *test_data_dir); DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_object_tree_test (const char *test_data_dir); -dbus_bool_t _dbus_credentials_test (const char *test_data_dir); - -dbus_bool_t _dbus_test_generate_bodies (int sequence, - int byte_order, - DBusString *signature, - DBusString *body); - #endif /* DBUS_TEST_H */ diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c index 1989c9bb..30c3ba44 100644 --- a/dbus/dbus-transport-unix.c +++ b/dbus/dbus-transport-unix.c @@ -407,32 +407,3 @@ _dbus_transport_open_platform_specific (DBusAddressEntry *entry, } /** @} */ - -#ifdef DBUS_ENABLE_EMBEDDED_TESTS - -dbus_bool_t -_dbus_transport_unix_test (const char *test_data_dir _DBUS_GNUC_UNUSED) -{ - DBusConnection *c; - DBusError error; - dbus_bool_t ret; - const char *address; - - dbus_error_init (&error); - - c = dbus_connection_open ("unixexec:argv0=false,argv1=foobar,path=/bin/false", &error); - _dbus_assert (c != NULL); - _dbus_assert (!dbus_error_is_set (&error)); - - address = _dbus_connection_get_address (c); - _dbus_assert (address != NULL); - - /* Let's see if the address got parsed, reordered and formatted correctly */ - ret = strcmp (address, "unixexec:path=/bin/false,argv0=false,argv1=foobar") == 0; - - dbus_connection_unref (c); - - return ret; -} - -#endif diff --git a/test/Makefile.am b/test/Makefile.am index 1e7c2db4..6e81d1b6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -58,8 +58,12 @@ EXTRA_DIST += glib-tap-test.sh EXTRA_DIST += tap-test.sh.in TESTS = +noinst_PROGRAMS = if DBUS_ENABLE_EMBEDDED_TESTS + +uninstallable_test_programs = + ## break-loader removed for now ## these binaries are used in tests but are not themselves tests TEST_BINARIES = \ @@ -71,19 +75,29 @@ TEST_BINARIES = \ test-shell-service \ $(NULL) -## These are conceptually part of directories that come earlier in SUBDIRS -## order, but we don't want to run them til we arrive in this directory, -## since they depend on stuff from this directory. We wrap some of them in a -## simple shell script to get TAP output. - -TESTS += ../bus/test-bus$(EXEEXT) - -if DBUS_UNIX -TESTS += ../bus/test-bus-launch-helper$(EXEEXT) -TESTS += ../bus/test-bus-system$(EXEEXT) +if !DBUS_WINCE +uninstallable_test_programs += test-spawn-oom endif -TESTS += ../dbus/test-dbus$(EXEEXT) +uninstallable_test_programs += \ + test-bus \ + test-bus-dispatch \ + test-bus-dispatch-sha1 \ + test-hash \ + test-marshal-recursive \ + test-message-internals \ + test-misc-internals \ + $(NULL) + +if DBUS_UNIX +uninstallable_test_programs += test-bus-launch-helper-oom +uninstallable_test_programs += test-bus-system +# this is used by the tests but is not, itself, a test +TEST_BINARIES += dbus-daemon-launch-helper-for-tests +endif + +noinst_PROGRAMS += $(uninstallable_test_programs) +TESTS += $(uninstallable_test_programs) else !DBUS_ENABLE_EMBEDDED_TESTS @@ -91,7 +105,7 @@ TEST_BINARIES= endif !DBUS_ENABLE_EMBEDDED_TESTS -noinst_PROGRAMS= $(TEST_BINARIES) +noinst_PROGRAMS += $(TEST_BINARIES) # This helper is meant to crash, so if we're compiling the rest with # AddressSanitizer, we need to stop it from catching the SIGSEGV and @@ -108,6 +122,8 @@ test_shell_SOURCES = shell-test.c test_shell_LDADD = libdbus-testutils.la test_spawn_SOURCES = spawn-test.c test_spawn_LDADD = $(top_builddir)/dbus/libdbus-internal.la +test_spawn_oom_SOURCES = internals/spawn-oom.c +test_spawn_oom_LDADD = libdbus-testutils.la test_assertions_SOURCES = internals/assertions.c test_assertions_LDADD = libdbus-testutils.la $(GLIB_LIBS) @@ -151,6 +167,76 @@ manual_paths_LDADD = $(top_builddir)/dbus/libdbus-internal.la manual_tcp_SOURCES = manual-tcp.c manual_tcp_LDADD = $(top_builddir)/dbus/libdbus-internal.la +test_bus_launch_helper_oom_SOURCES = bus/launch-helper-oom.c +test_bus_launch_helper_oom_LDADD = \ + $(top_builddir)/bus/liblaunch-helper-internal.la \ + libdbus-testutils.la \ + $(NULL) + +dbus_daemon_launch_helper_for_tests_SOURCES = bus/launch-helper-for-tests.c +dbus_daemon_launch_helper_for_tests_LDADD = $(top_builddir)/bus/liblaunch-helper-internal.la + +test_bus_system_SOURCES = bus/system.c +test_bus_system_LDADD = \ + $(top_builddir)/bus/liblaunch-helper-internal.la \ + libdbus-testutils.la \ + $(NULL) + +test_bus_SOURCES = bus/main.c +test_bus_LDADD = \ + $(top_builddir)/bus/libdbus-daemon-internal.la \ + libdbus-testutils.la \ + $(NULL) + +test_bus_dispatch_SOURCES = bus/dispatch.c +test_bus_dispatch_LDADD = \ + $(top_builddir)/bus/libdbus-daemon-internal.la \ + libdbus-testutils.la \ + $(NULL) + +test_bus_dispatch_sha1_SOURCES = bus/dispatch-sha1.c +test_bus_dispatch_sha1_LDADD = \ + $(top_builddir)/bus/libdbus-daemon-internal.la \ + libdbus-testutils.la \ + $(NULL) + +test_hash_SOURCES = internals/hash.c +test_hash_LDADD = libdbus-testutils.la + +test_marshal_recursive_SOURCES = \ + internals/dbus-marshal-recursive-util.c \ + internals/dbus-marshal-recursive-util.h \ + internals/marshal-recursive.c \ + $(NULL) +test_marshal_recursive_LDADD = libdbus-testutils.la + +test_message_internals_SOURCES = \ + internals/dbus-marshal-recursive-util.c \ + internals/dbus-marshal-recursive-util.h \ + internals/dbus-message-factory.c \ + internals/dbus-message-factory.h \ + internals/dbus-message-util.c \ + internals/dbus-message-util.h \ + internals/message-internals.c \ + $(NULL) +test_message_internals_LDADD = libdbus-testutils.la + +test_misc_internals_SOURCES = \ + internals/dbus-auth-script.c \ + internals/dbus-auth-script.h \ + internals/dbus-auth-util.c \ + internals/dbus-credentials-util.c \ + internals/dbus-marshal-byteswap-util.c \ + internals/dbus-marshal-recursive-util.c \ + internals/dbus-marshal-recursive-util.h \ + internals/dbus-marshal-validate-util.c \ + internals/dbus-string-util.c \ + internals/dbus-sysdeps-util.c \ + internals/misc-internals.c \ + internals/misc-internals.h \ + $(NULL) +test_misc_internals_LDADD = libdbus-testutils.la + EXTRA_DIST += dbus-test-runner testexecdir = $(libexecdir)/installed-tests/dbus @@ -632,7 +718,7 @@ uninstalled-config-local: -e 's,[@]DBUS_TEST_EXEC[@],@abs_builddir@,' \ -e 's,[@]DBUS_USER[@],$(DBUS_USER),' \ -e 's,[@]EXEEXT[@],$(EXEEXT),' \ - -e 's,[@]TEST_LAUNCH_HELPER_BINARY[@],@abs_top_builddir@/bus/dbus-daemon-launch-helper-test$(EXEEXT),' \ + -e 's,[@]TEST_LAUNCH_HELPER_BINARY[@],@abs_top_builddir@/test/dbus-daemon-launch-helper-for-tests$(EXEEXT),' \ -e 's,[@]TEST_LISTEN[@],$(TEST_LISTEN),' \ < $(srcdir)/"$$F" > "$${F%.in}"; \ done diff --git a/test/bus/dispatch-sha1.c b/test/bus/dispatch-sha1.c new file mode 100644 index 00000000..36430012 --- /dev/null +++ b/test/bus/dispatch-sha1.c @@ -0,0 +1,59 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2003-2009 Red Hat, Inc. + * Copyright 2011-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "bus/test.h" + +#include + +#include "bus/selinux.h" +#include "test/test-utils.h" + +#ifndef DBUS_ENABLE_EMBEDDED_TESTS +#error This file is only relevant for the embedded tests +#endif + +static void +test_pre_hook (void) +{ +} + +static void +test_post_hook (void) +{ + if (_dbus_getenv ("DBUS_TEST_SELINUX")) + bus_selinux_shutdown (); +} + +static DBusTestCase test = { "dispatch-sha1", bus_dispatch_sha1_test }; + +int +main (int argc, char **argv) +{ + return _dbus_test_main (argc, argv, 1, &test, + (DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS | + DBUS_TEST_FLAGS_CHECK_FD_LEAKS | + DBUS_TEST_FLAGS_REQUIRE_DATA), + test_pre_hook, test_post_hook); +} diff --git a/test/bus/dispatch.c b/test/bus/dispatch.c new file mode 100644 index 00000000..52bf363d --- /dev/null +++ b/test/bus/dispatch.c @@ -0,0 +1,59 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2003-2009 Red Hat, Inc. + * Copyright 2011-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "bus/test.h" + +#include + +#include "bus/selinux.h" +#include "test/test-utils.h" + +#ifndef DBUS_ENABLE_EMBEDDED_TESTS +#error This file is only relevant for the embedded tests +#endif + +static void +test_pre_hook (void) +{ +} + +static void +test_post_hook (void) +{ + if (_dbus_getenv ("DBUS_TEST_SELINUX")) + bus_selinux_shutdown (); +} + +static DBusTestCase test = { "dispatch", bus_dispatch_test }; + +int +main (int argc, char **argv) +{ + return _dbus_test_main (argc, argv, 1, &test, + (DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS | + DBUS_TEST_FLAGS_CHECK_FD_LEAKS | + DBUS_TEST_FLAGS_REQUIRE_DATA), + test_pre_hook, test_post_hook); +} diff --git a/test/bus/launch-helper-for-tests.c b/test/bus/launch-helper-for-tests.c new file mode 100644 index 00000000..6ad003d0 --- /dev/null +++ b/test/bus/launch-helper-for-tests.c @@ -0,0 +1,8 @@ +/* Embed a version of the real activation helper that has been altered + * to be testable. We monkey-patch it like this because we don't want to + * compile test-only code into the real setuid executable, and Automake + * versions older than 1.16 can't cope with expanding directory variables + * in SOURCES when using subdir-objects. */ +#define ACTIVATION_LAUNCHER_TEST +#include "bus/activation-helper.c" +#include "bus/activation-helper-bin.c" diff --git a/bus/test-launch-helper.c b/test/bus/launch-helper-oom.c similarity index 84% rename from bus/test-launch-helper.c rename to test/bus/launch-helper-oom.c index 42126e19..8a9879e1 100644 --- a/bus/test-launch-helper.c +++ b/test/bus/launch-helper-oom.c @@ -1,7 +1,8 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* test-main.c main() for the OOM check of the launch helper * - * Copyright (C) 2007 Red Hat, Inc. + * Copyright 2007 Red Hat, Inc. + * Copyright 2013-2018 Collabora Ltd. * * Licensed under the Academic Free License version 2.1 * @@ -22,18 +23,27 @@ */ #include -#include "test.h" -#include "activation-helper.h" + +#include "bus/test.h" #include #include -#include + +#include "bus/activation-helper.h" +#include "test/test-utils.h" #if !defined(DBUS_ENABLE_EMBEDDED_TESTS) || !defined(DBUS_UNIX) #error This file is only relevant for the embedded tests on Unix #endif -#ifdef ACTIVATION_LAUNCHER_DO_OOM +/* Embed a version of the real activation helper that has been altered + * to be testable. We monkey-patch it like this because we don't want to + * compile test-only code into the real setuid executable, and Automake + * versions older than 1.16 can't cope with expanding directory variables + * in SOURCES when using subdir-objects. */ +#define ACTIVATION_LAUNCHER_TEST +#define ACTIVATION_LAUNCHER_DO_OOM +#include "bus/activation-helper.c" /* returns true if good things happen, or if we get OOM */ static dbus_bool_t @@ -68,8 +78,6 @@ bus_activation_helper_oom_test (void *data, return retval; } -#endif - static dbus_bool_t bus_activation_helper_test (const char *test_data_dir) { diff --git a/bus/test-main.c b/test/bus/main.c similarity index 90% rename from bus/test-main.c rename to test/bus/main.c index d1a61de7..77065430 100644 --- a/bus/test-main.c +++ b/test/bus/main.c @@ -1,7 +1,8 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* test-main.c main() for make check * - * Copyright (C) 2003 Red Hat, Inc. + * Copyright 2003-2009 Red Hat, Inc. + * Copyright 2011-2018 Collabora Ltd. * * Licensed under the Academic Free License version 2.1 * @@ -23,12 +24,12 @@ #include -#include "test.h" +#include "bus/test.h" #include -#include -#include "selinux.h" +#include "bus/selinux.h" +#include "test/test-utils.h" #ifndef DBUS_ENABLE_EMBEDDED_TESTS #error This file is only relevant for the embedded tests @@ -51,8 +52,6 @@ static DBusTestCase tests[] = { "expire-list", bus_expire_list_test }, { "config-parser", bus_config_parser_test }, { "signals", bus_signals_test }, - { "dispatch-sha1", bus_dispatch_sha1_test }, - { "dispatch", bus_dispatch_test }, { "activation-service-reload", bus_activation_service_reload_test }, { "unix-fds-passing", bus_unix_fds_passing_test }, { NULL } diff --git a/bus/test-system.c b/test/bus/system.c similarity index 91% rename from bus/test-system.c rename to test/bus/system.c index 875c035d..38307e1f 100644 --- a/bus/test-system.c +++ b/test/bus/system.c @@ -1,7 +1,8 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ /* test-main.c main() for make check * - * Copyright (C) 2003 Red Hat, Inc. + * Copyright 2003-2007 Red Hat, Inc. + * Copyright 2013-2018 Collabora Ltd. * * Licensed under the Academic Free License version 2.1 * @@ -23,10 +24,11 @@ #include -#include "test.h" +#include "bus/test.h" #include -#include + +#include "test/test-utils.h" #if !defined(DBUS_ENABLE_EMBEDDED_TESTS) || !defined(DBUS_UNIX) #error This file is only relevant for the embedded tests on Unix diff --git a/dbus/dbus-auth-script.c b/test/internals/dbus-auth-script.c similarity index 98% rename from dbus/dbus-auth-script.c rename to test/internals/dbus-auth-script.c index 5fecad09..85103010 100644 --- a/dbus/dbus-auth-script.c +++ b/test/internals/dbus-auth-script.c @@ -24,16 +24,18 @@ #ifdef DBUS_ENABLE_EMBEDDED_TESTS +#include "misc-internals.h" + #include "dbus-auth-script.h" #include -#include "dbus-auth.h" -#include "dbus-string.h" -#include "dbus-hash.h" -#include "dbus-credentials.h" -#include "dbus-internals.h" -#include +#include "dbus/dbus-auth.h" +#include "dbus/dbus-credentials.h" +#include "dbus/dbus-hash.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-string.h" +#include "dbus/dbus-test-tap.h" #ifdef DBUS_UNIX # include "dbus/dbus-userdb.h" @@ -71,7 +73,7 @@ append_quoted_string (DBusString *dest, if (in_backslash) { unsigned char a; - + if (b == 'r') a = '\r'; else if (b == 'n') @@ -86,7 +88,7 @@ append_quoted_string (DBusString *dest, if (!_dbus_string_append_byte (dest, a)) return FALSE; - + in_backslash = FALSE; } else if (b == '\\') @@ -115,7 +117,7 @@ append_quoted_string (DBusString *dest, return FALSE; } } - + ++i; } @@ -139,7 +141,7 @@ same_first_word (const DBusString *a, static DBusAuthState auth_state_from_string (const DBusString *str) -{ +{ if (_dbus_string_starts_with_c_str (str, "WAITING_FOR_INPUT")) return DBUS_AUTH_STATE_WAITING_FOR_INPUT; else if (_dbus_string_starts_with_c_str (str, "WAITING_FOR_MEMORY")) @@ -270,13 +272,13 @@ _dbus_auth_script_run (const DBusString *filename) DBusAuthState state; DBusString context; DBusString guid; - + retval = FALSE; auth = NULL; _dbus_string_init_const (&guid, "5fa01f4202cd837709a3274ca0df9d00"); _dbus_string_init_const (&context, "org_freedesktop_test"); - + if (!_dbus_string_init (&file)) return FALSE; @@ -305,11 +307,11 @@ _dbus_auth_script_run (const DBusString *filename) next_iteration: while (_dbus_string_pop_line (&file, &line)) - { + { line_no += 1; /* _dbus_warn ("%s", _dbus_string_get_const_data (&line)); */ - + _dbus_string_delete_leading_blanks (&line); if (auth != NULL) @@ -328,7 +330,7 @@ _dbus_auth_script_run (const DBusString *filename) } } } - + if (_dbus_string_get_length (&line) == 0) { /* empty line */ @@ -376,7 +378,7 @@ _dbus_auth_script_run (const DBusString *filename) "CLIENT")) { DBusCredentials *creds; - + if (auth != NULL) { _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)"); @@ -402,7 +404,7 @@ _dbus_auth_script_run (const DBusString *filename) auth = NULL; goto out; } - + if (!_dbus_auth_set_credentials (auth, creds)) { _dbus_warn ("no memory for setting credentials"); @@ -411,14 +413,14 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_credentials_unref (creds); goto out; } - + _dbus_credentials_unref (creds); } else if (_dbus_string_starts_with_c_str (&line, "SERVER")) { DBusCredentials *creds; - + if (auth != NULL) { _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)"); @@ -444,7 +446,7 @@ _dbus_auth_script_run (const DBusString *filename) auth = NULL; goto out; } - + if (!_dbus_auth_set_credentials (auth, creds)) { _dbus_warn ("no memory for setting credentials"); @@ -453,7 +455,7 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_credentials_unref (creds); goto out; } - + _dbus_credentials_unref (creds); _dbus_auth_set_context (auth, &context); @@ -493,7 +495,7 @@ _dbus_auth_script_run (const DBusString *filename) "SEND")) { DBusString to_send; - + _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&to_send)) @@ -511,7 +513,7 @@ _dbus_auth_script_run (const DBusString *filename) } _dbus_verbose ("Sending '%s'\n", _dbus_string_get_const_data (&to_send)); - + if (!_dbus_string_append (&to_send, "\r\n")) { _dbus_warn ("failed to append \\r\\n from line %d", @@ -523,7 +525,7 @@ _dbus_auth_script_run (const DBusString *filename) /* Replace USERID_HEX with our username in hex */ { int where; - + if (_dbus_string_find (&to_send, 0, "USERID_HEX", &where)) { @@ -545,7 +547,7 @@ _dbus_auth_script_run (const DBusString *filename) } _dbus_string_delete (&to_send, where, (int) strlen ("USERID_HEX")); - + if (!_dbus_string_hex_encode (&username, 0, &to_send, where)) { @@ -571,7 +573,7 @@ _dbus_auth_script_run (const DBusString *filename) } _dbus_string_delete (&to_send, where, (int) strlen ("USERNAME_HEX")); - + if (!_dbus_string_hex_encode (username, 0, &to_send, where)) { @@ -605,14 +607,14 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_auth_return_buffer (auth, buffer); } - + _dbus_string_free (&to_send); } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_STATE")) { DBusAuthState expected; - + _dbus_string_delete_first_word (&line); expected = auth_state_from_string (&line); @@ -635,7 +637,7 @@ _dbus_auth_script_run (const DBusString *filename) "EXPECT_COMMAND")) { DBusString received; - + _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&received)) @@ -661,7 +663,7 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_string_free (&received); goto out; } - + _dbus_string_free (&received); } else if (_dbus_string_starts_with_c_str (&line, @@ -669,7 +671,7 @@ _dbus_auth_script_run (const DBusString *filename) { DBusString expected; const DBusString *unused; - + _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&expected)) @@ -687,7 +689,7 @@ _dbus_auth_script_run (const DBusString *filename) } _dbus_auth_get_unused_bytes (auth, &unused); - + if (_dbus_string_equal (&expected, unused)) { _dbus_auth_delete_unused_bytes (auth); @@ -706,7 +708,7 @@ _dbus_auth_script_run (const DBusString *filename) "EXPECT_HAVE_NO_CREDENTIALS")) { DBusCredentials *authorized_identity; - + authorized_identity = _dbus_auth_get_identity (auth); if (!_dbus_credentials_are_anonymous (authorized_identity)) { @@ -718,7 +720,7 @@ _dbus_auth_script_run (const DBusString *filename) "EXPECT_HAVE_SOME_CREDENTIALS")) { DBusCredentials *authorized_identity; - + authorized_identity = _dbus_auth_get_identity (auth); if (_dbus_credentials_are_anonymous (authorized_identity)) { @@ -730,7 +732,7 @@ _dbus_auth_script_run (const DBusString *filename) "EXPECT")) { DBusString expected; - + _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&expected)) @@ -767,7 +769,7 @@ _dbus_auth_script_run (const DBusString *filename) goto parse_failed; goto next_iteration; /* skip parse_failed */ - + parse_failed: { _dbus_warn ("couldn't process line %d \"%s\"", @@ -800,9 +802,9 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_warn ("Leftover data: %s", _dbus_string_get_const_data (&from_auth)); goto out; } - + retval = TRUE; - + out: if (auth) _dbus_auth_unref (auth); @@ -810,7 +812,7 @@ _dbus_auth_script_run (const DBusString *filename) _dbus_string_free (&file); _dbus_string_free (&line); _dbus_string_free (&from_auth); - + return retval; } diff --git a/dbus/dbus-auth-script.h b/test/internals/dbus-auth-script.h similarity index 100% rename from dbus/dbus-auth-script.h rename to test/internals/dbus-auth-script.h diff --git a/dbus/dbus-auth-util.c b/test/internals/dbus-auth-util.c similarity index 94% rename from dbus/dbus-auth-util.c rename to test/internals/dbus-auth-util.c index c8ba6042..bd862b0e 100644 --- a/dbus/dbus-auth-util.c +++ b/test/internals/dbus-auth-util.c @@ -22,10 +22,13 @@ */ #include -#include "dbus-internals.h" -#include "dbus-test.h" -#include "dbus-auth.h" -#include + +#include "misc-internals.h" + +#include "dbus/dbus-auth.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-test-tap.h" +#include "dbus/dbus-test.h" /** * @addtogroup DBusAuth @@ -50,17 +53,17 @@ process_test_subdir (const DBusString *test_base_dir, retval = FALSE; dir = NULL; - + if (!_dbus_string_init (&test_directory)) _dbus_test_fatal ("didn't allocate test_directory"); _dbus_string_init_const (&filename, subdir); - + if (!_dbus_string_copy (test_base_dir, 0, &test_directory, 0)) _dbus_test_fatal ("couldn't copy test_base_dir to test_directory"); - if (!_dbus_concat_dir_and_file (&test_directory, &filename)) + if (!_dbus_concat_dir_and_file (&test_directory, &filename)) _dbus_test_fatal ("couldn't allocate full path"); _dbus_string_free (&filename); @@ -83,7 +86,7 @@ process_test_subdir (const DBusString *test_base_dir, while (_dbus_directory_get_next_file (dir, &filename, &error)) { DBusString full_path; - + if (!_dbus_string_init (&full_path)) _dbus_test_fatal ("couldn't init string"); @@ -119,9 +122,9 @@ process_test_subdir (const DBusString *test_base_dir, dbus_error_free (&error); goto failed; } - + retval = TRUE; - + failed: if (dir) @@ -139,28 +142,28 @@ process_test_dirs (const char *test_data_dir) dbus_bool_t retval; retval = FALSE; - + _dbus_string_init_const (&test_directory, test_data_dir); if (!process_test_subdir (&test_directory, "auth")) goto failed; retval = TRUE; - + failed: _dbus_string_free (&test_directory); - + return retval; } dbus_bool_t _dbus_auth_test (const char *test_data_dir) { - + if (test_data_dir == NULL) return TRUE; - + if (!process_test_dirs (test_data_dir)) return FALSE; diff --git a/dbus/dbus-credentials-util.c b/test/internals/dbus-credentials-util.c similarity index 98% rename from dbus/dbus-credentials-util.c rename to test/internals/dbus-credentials-util.c index 69a822bb..8c497b22 100644 --- a/dbus/dbus-credentials-util.c +++ b/test/internals/dbus-credentials-util.c @@ -22,10 +22,13 @@ */ #include -#include "dbus-internals.h" -#include "dbus-test.h" -#include "dbus-credentials.h" -#include + +#include "misc-internals.h" + +#include "dbus/dbus-credentials.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-test-tap.h" +#include "dbus/dbus-test.h" /** * @addtogroup DBusCredentials @@ -126,7 +129,7 @@ _dbus_credentials_test (const char *test_data_dir) DBusString str; const dbus_gid_t *gids; size_t n; - + if (test_data_dir == NULL) return TRUE; @@ -137,7 +140,7 @@ _dbus_credentials_test (const char *test_data_dir) /* test refcounting */ _dbus_credentials_ref (creds); _dbus_credentials_unref (creds); - + _dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_UNIX_USER_ID)); _dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_UNIX_PROCESS_ID)); _dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_UNIX_GROUP_IDS)); @@ -168,7 +171,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (_dbus_credentials_get_unix_uid (creds2) == 12); _dbus_assert (_dbus_credentials_get_pid (creds2) == 511); - _dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds2), SAMPLE_SID) == 0); + _dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds2), SAMPLE_SID) == 0); _dbus_assert (_dbus_credentials_get_unix_gids (creds2, &gids, &n)); _dbus_assert (n == 4); _dbus_assert (gids[0] == 42); @@ -177,9 +180,9 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (gids[3] == 5678); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); - + _dbus_credentials_unref (creds2); - + /* Same user if both unix and windows are the same */ creds2 = make_credentials (12, DBUS_PID_UNSET, 0, SAMPLE_SID); if (creds2 == NULL) @@ -196,7 +199,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); - + _dbus_credentials_unref (creds2); /* Not the same user if Windows is different */ @@ -206,7 +209,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (!_dbus_credentials_are_superset (creds, creds2)); - + _dbus_credentials_unref (creds2); /* Not the same user if Unix is missing */ @@ -216,7 +219,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); - + _dbus_credentials_unref (creds2); /* Not the same user if Unix is different */ @@ -226,7 +229,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (!_dbus_credentials_are_superset (creds, creds2)); - + _dbus_credentials_unref (creds2); /* Not the same user if both are missing */ @@ -236,7 +239,7 @@ _dbus_credentials_test (const char *test_data_dir) _dbus_assert (!_dbus_credentials_same_user (creds, creds2)); _dbus_assert (_dbus_credentials_are_superset (creds, creds2)); - + _dbus_credentials_unref (creds2); /* Same user, but not a superset, if groups are different */ diff --git a/dbus/dbus-marshal-byteswap-util.c b/test/internals/dbus-marshal-byteswap-util.c similarity index 95% rename from dbus/dbus-marshal-byteswap-util.c rename to test/internals/dbus-marshal-byteswap-util.c index 66f65c24..40b1780a 100644 --- a/dbus/dbus-marshal-byteswap-util.c +++ b/test/internals/dbus-marshal-byteswap-util.c @@ -23,12 +23,16 @@ #include +#include "misc-internals.h" + #ifdef DBUS_ENABLE_EMBEDDED_TESTS -#include "dbus-marshal-byteswap.h" -#include "dbus-test.h" +#include "dbus/dbus-marshal-byteswap.h" +#include "dbus/dbus-test.h" #include #include +#include "dbus-marshal-recursive-util.h" + static void do_byteswap_test (int byte_order) { @@ -41,7 +45,7 @@ do_byteswap_test (int byte_order) _dbus_test_fatal ("oom"); opposite_order = byte_order == DBUS_LITTLE_ENDIAN ? DBUS_BIG_ENDIAN : DBUS_LITTLE_ENDIAN; - + sequence = 0; while (_dbus_test_generate_bodies (sequence, byte_order, &signature, &body)) { @@ -64,7 +68,7 @@ do_byteswap_test (int byte_order) &body, 0); _dbus_type_reader_init (©_reader, opposite_order, &signature, 0, ©, 0); - + if (!_dbus_type_reader_equal_values (&body_reader, ©_reader)) { _dbus_verbose_bytes_of_string (&signature, 0, @@ -76,9 +80,9 @@ do_byteswap_test (int byte_order) _dbus_test_fatal ("Byte-swapped data did not have same values as original data"); } - + _dbus_string_free (©); - + _dbus_string_set_length (&signature, 0); _dbus_string_set_length (&body, 0); ++sequence; diff --git a/dbus/dbus-marshal-recursive-util.c b/test/internals/dbus-marshal-recursive-util.c similarity index 99% rename from dbus/dbus-marshal-recursive-util.c rename to test/internals/dbus-marshal-recursive-util.c index edeebc43..f81efffa 100644 --- a/dbus/dbus-marshal-recursive-util.c +++ b/test/internals/dbus-marshal-recursive-util.c @@ -23,12 +23,14 @@ #include +#include "dbus-marshal-recursive-util.h" + #ifdef DBUS_ENABLE_EMBEDDED_TESTS -#include "dbus-marshal-recursive.h" -#include "dbus-marshal-basic.h" -#include "dbus-signature.h" -#include "dbus-internals.h" +#include "dbus/dbus-marshal-recursive.h" +#include "dbus/dbus-marshal-basic.h" +#include "dbus/dbus-signature.h" +#include "dbus/dbus-internals.h" #include #include @@ -85,7 +87,7 @@ equal_values_helper (DBusTypeReader *lhs, basic_value_zero (&lhs_value); basic_value_zero (&rhs_value); - + _dbus_type_reader_read_basic (lhs, &lhs_value); _dbus_type_reader_read_basic (rhs, &rhs_value); @@ -124,8 +126,8 @@ _dbus_type_reader_equal_values (const DBusTypeReader *lhs, #ifndef DOXYGEN_SHOULD_SKIP_THIS -#include "dbus-test.h" -#include "dbus-list.h" +#include "dbus/dbus-test.h" +#include "dbus/dbus-list.h" #include #include @@ -1611,7 +1613,7 @@ build_body (TestTypeNode **nodes, data_block_init_reader_writer (&block, &reader, &writer); - + /* DBusTypeWriter assumes it's writing into an existing signature, * so doesn't add nul on its own. We have to do that. */ @@ -1633,7 +1635,7 @@ build_body (TestTypeNode **nodes, body, 0)) _dbus_test_fatal ("oom"); - data_block_free (&block); + data_block_free (&block); } dbus_bool_t @@ -1652,7 +1654,7 @@ _dbus_test_generate_bodies (int sequence, return FALSE; n_nodes = 1; - + build_body (nodes, n_nodes, byte_order, signature, body); @@ -1662,7 +1664,7 @@ _dbus_test_generate_bodies (int sequence, node_destroy (nodes[i]); ++i; } - + return TRUE; } @@ -2681,7 +2683,7 @@ object_path_from_seed (char *buf, ++i; buf[i] = v; ++i; - + v += 1; } } @@ -3304,7 +3306,7 @@ dict_write_value (TestTypeNode *node, _dbus_string_free (&entry_value_signature); return FALSE; } - + child = _dbus_list_get_first (&container->children); if (!node_build_signature (child, @@ -3347,19 +3349,19 @@ dict_write_value (TestTypeNode *node, DBUS_TYPE_INT32, &key)) goto oom; - + if (!node_write_value (child, block, &entry_sub, seed + i)) goto oom; if (!_dbus_type_writer_unrecurse (&sub, &entry_sub)) goto oom; - + ++i; } if (!_dbus_type_writer_unrecurse (writer, &sub)) goto oom; - + _dbus_string_free (&entry_value_signature); _dbus_string_free (&dict_entry_signature); return TRUE; @@ -3394,20 +3396,20 @@ dict_read_or_set_value (TestTypeNode *node, _dbus_type_reader_recurse (reader, &sub); check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY); - + i = 0; while (i < n_entries) { DBusTypeReader entry_sub; check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY); - + _dbus_type_reader_recurse (&sub, &entry_sub); - + if (realign_root == NULL) { dbus_int32_t v; - + check_expected_type (&entry_sub, DBUS_TYPE_INT32); _dbus_type_reader_read_basic (&entry_sub, &v); @@ -3415,7 +3417,7 @@ dict_read_or_set_value (TestTypeNode *node, _dbus_assert (v == (dbus_int32_t) uint32_from_seed (seed + i)); NEXT_EXPECTING_TRUE (&entry_sub); - + if (!node_read_value (child, &entry_sub, seed + i)) return FALSE; @@ -3424,22 +3426,22 @@ dict_read_or_set_value (TestTypeNode *node, else { dbus_int32_t v; - + v = (dbus_int32_t) uint32_from_seed (seed + i); - + if (!_dbus_type_reader_set_basic (&entry_sub, &v, realign_root)) return FALSE; NEXT_EXPECTING_TRUE (&entry_sub); - + if (!node_set_value (child, &entry_sub, realign_root, seed + i)) return FALSE; NEXT_EXPECTING_FALSE (&entry_sub); } - + if (i == (n_entries - 1)) NEXT_EXPECTING_FALSE (&sub); else @@ -3483,7 +3485,7 @@ dict_build_signature (TestTypeNode *node, if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING)) goto oom; - + if (!node_build_signature (_dbus_list_get_first (&container->children), str)) goto oom; diff --git a/test/internals/dbus-marshal-recursive-util.h b/test/internals/dbus-marshal-recursive-util.h new file mode 100644 index 00000000..ab069e4c --- /dev/null +++ b/test/internals/dbus-marshal-recursive-util.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-marshal-recursive-util.c Would be in dbus-marshal-recursive.c, but only used in bus/tests + * + * Copyright (C) 2004, 2005 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef TEST_INTERNALS_DBUS_MARSHAL_RECURSIVE_UTIL_H +#define TEST_INTERNALS_DBUS_MARSHAL_RECURSIVE_UTIL_H + +#include +#include + +dbus_bool_t _dbus_marshal_recursive_test (const char *test_data_dir); +dbus_bool_t _dbus_test_generate_bodies (int sequence, + int byte_order, + DBusString *signature, + DBusString *body); + +#endif diff --git a/dbus/dbus-marshal-validate-util.c b/test/internals/dbus-marshal-validate-util.c similarity index 98% rename from dbus/dbus-marshal-validate-util.c rename to test/internals/dbus-marshal-validate-util.c index e62c1120..4179928b 100644 --- a/dbus/dbus-marshal-validate-util.c +++ b/test/internals/dbus-marshal-validate-util.c @@ -22,16 +22,22 @@ */ #include + +#include "misc-internals.h" + #ifdef DBUS_ENABLE_EMBEDDED_TESTS #ifndef DOXYGEN_SHOULD_SKIP_THIS -#include "dbus-internals.h" -#include "dbus-marshal-validate.h" -#include "dbus-marshal-recursive.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-marshal-validate.h" +#include "dbus/dbus-marshal-recursive.h" #include -#include "dbus-test.h" +#include "dbus/dbus-test.h" + +#include "dbus-marshal-recursive-util.h" + #include typedef struct @@ -433,7 +439,7 @@ _dbus_marshal_validate_test (const char *test_data_dir _DBUS_GNUC_UNUSED) _dbus_string_free (&str); /* Body validation; test basic validation of valid bodies for both endian */ - + { int sequence; DBusString signature; @@ -465,7 +471,7 @@ _dbus_marshal_validate_test (const char *test_data_dir _DBUS_GNUC_UNUSED) _dbus_string_set_length (&body, 0); ++sequence; } - + sequence = 0; while (_dbus_test_generate_bodies (sequence, DBUS_BIG_ENDIAN, &signature, &body)) @@ -493,7 +499,7 @@ _dbus_marshal_validate_test (const char *test_data_dir _DBUS_GNUC_UNUSED) _dbus_string_free (&signature); _dbus_string_free (&body); } - + return TRUE; } diff --git a/dbus/dbus-message-factory.c b/test/internals/dbus-message-factory.c similarity index 98% rename from dbus/dbus-message-factory.c rename to test/internals/dbus-message-factory.c index 05e6aa67..db02737a 100644 --- a/dbus/dbus-message-factory.c +++ b/test/internals/dbus-message-factory.c @@ -26,10 +26,14 @@ #ifdef DBUS_ENABLE_EMBEDDED_TESTS #include "dbus-message-factory.h" -#include "dbus-message-private.h" -#include "dbus-signature.h" -#include "dbus-test.h" -#include + +#include "dbus/dbus-message-private.h" +#include "dbus/dbus-signature.h" +#include "dbus/dbus-test.h" +#include "dbus/dbus-test-tap.h" + +#include "dbus-marshal-recursive-util.h" + #include typedef enum @@ -142,25 +146,25 @@ generate_trivial_inner (DBusMessageDataIter *iter, { DBusMessageIter iter2; const char *v_STRING = "This is an error"; - + dbus_message_iter_init_append (message, &iter2); if (!dbus_message_iter_append_basic (&iter2, DBUS_TYPE_STRING, &v_STRING)) _dbus_test_fatal ("oom"); } - + set_reply_serial (message); break; default: return FALSE; } - + if (message == NULL) _dbus_test_fatal ("oom"); *message_p = message; - + return TRUE; } @@ -206,7 +210,7 @@ generate_many_bodies_inner (DBusMessageDataIter *iter, _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET, _dbus_string_get_length (&message->body), byte_order); - + *message_p = message; } else @@ -214,7 +218,7 @@ generate_many_bodies_inner (DBusMessageDataIter *iter, dbus_message_unref (message); *message_p = NULL; } - + _dbus_string_free (&signature); _dbus_string_free (&body); @@ -230,7 +234,7 @@ generate_from_message (DBusString *data, dbus_message_lock (message); *expected_validity = DBUS_VALID; - + /* move for efficiency, since we'll nuke the message anyway */ if (!_dbus_string_move (&message->header.data, 0, data, 0)) @@ -254,7 +258,7 @@ generate_outer (DBusMessageDataIter *iter, return FALSE; iter_next (iter); - + _dbus_assert (message != NULL); generate_from_message (data, expected_validity, message); @@ -317,7 +321,7 @@ simple_method_return (void) _dbus_test_fatal ("oom"); set_reply_serial (message); - + return message; } @@ -333,7 +337,7 @@ simple_error (void) _dbus_test_fatal ("oom"); set_reply_serial (message); - + return message; } @@ -400,7 +404,7 @@ generate_special (DBusMessageDataIter *iter, dbus_int32_t v_INT32; _dbus_assert (_dbus_string_get_length (data) == 0); - + message = NULL; pos = -1; v_INT32 = 42; @@ -420,7 +424,7 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + /* set an invalid typecode */ _dbus_string_set_byte (data, pos + 1, '$'); @@ -431,7 +435,7 @@ generate_special (DBusMessageDataIter *iter, char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2]; const char *v_STRING; int i; - + message = simple_method_call (); if (!dbus_message_append_args (message, DBUS_TYPE_INT32, &v_INT32, @@ -459,7 +463,7 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION; } else if (item_seq == 2) @@ -467,7 +471,7 @@ generate_special (DBusMessageDataIter *iter, char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4]; const char *v_STRING; int i; - + message = simple_method_call (); if (!dbus_message_append_args (message, DBUS_TYPE_INT32, &v_INT32, @@ -492,7 +496,7 @@ generate_special (DBusMessageDataIter *iter, ++i; } long_sig[i] = DBUS_TYPE_INVALID; - + v_STRING = long_sig; if (!_dbus_header_set_field_basic (&message->header, DBUS_HEADER_FIELD_SIGNATURE, @@ -504,7 +508,7 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION; } else if (item_seq == 3) @@ -521,9 +525,9 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR); - + *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED; } else if (item_seq == 4) @@ -540,9 +544,9 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR); - + *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED; } else if (item_seq == 5) @@ -559,19 +563,19 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR); _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR); - + *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS; } else if (item_seq == 6) { message = simple_method_call (); generate_from_message (data, expected_validity, message); - + _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID); - + *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE; } else if (item_seq == 7) @@ -579,9 +583,9 @@ generate_special (DBusMessageDataIter *iter, /* Messages of unknown type are considered valid */ message = simple_method_call (); generate_from_message (data, expected_validity, message); - + _dbus_string_set_byte (data, TYPE_OFFSET, 100); - + *expected_validity = DBUS_VALID; } else if (item_seq == 8) @@ -591,7 +595,7 @@ generate_special (DBusMessageDataIter *iter, message = simple_method_call (); byte_order = _dbus_header_get_byte_order (&message->header); generate_from_message (data, expected_validity, message); - + _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET, DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4, byte_order); @@ -645,7 +649,7 @@ generate_special (DBusMessageDataIter *iter, _dbus_test_fatal ("oom"); generate_from_message (data, expected_validity, message); - + *expected_validity = DBUS_VALID; } else if (item_seq == 13) @@ -657,7 +661,7 @@ generate_special (DBusMessageDataIter *iter, _dbus_test_fatal ("oom"); generate_from_message (data, expected_validity, message); - + *expected_validity = DBUS_INVALID_MISSING_INTERFACE; } else if (item_seq == 14) @@ -668,7 +672,7 @@ generate_special (DBusMessageDataIter *iter, _dbus_test_fatal ("oom"); generate_from_message (data, expected_validity, message); - + *expected_validity = DBUS_INVALID_MISSING_REPLY_SERIAL; } else if (item_seq == 15) @@ -679,7 +683,7 @@ generate_special (DBusMessageDataIter *iter, _dbus_test_fatal ("oom"); generate_from_message (data, expected_validity, message); - + *expected_validity = DBUS_INVALID_MISSING_ERROR_NAME; } else if (item_seq == 16) @@ -688,7 +692,7 @@ generate_special (DBusMessageDataIter *iter, const char *v_STRING; int i; int n_begins; - + message = simple_method_call (); if (!dbus_message_append_args (message, DBUS_TYPE_INT32, &v_INT32, @@ -711,7 +715,7 @@ generate_special (DBusMessageDataIter *iter, long_sig[i] = DBUS_TYPE_INT32; ++i; - + while (n_begins > 0) { long_sig[i] = DBUS_DICT_ENTRY_END_CHAR; @@ -719,7 +723,7 @@ generate_special (DBusMessageDataIter *iter, n_begins -= 1; } long_sig[i] = DBUS_TYPE_INVALID; - + v_STRING = long_sig; if (!_dbus_header_set_field_basic (&message->header, DBUS_HEADER_FIELD_SIGNATURE, @@ -731,7 +735,7 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION; } else if (item_seq == 17) @@ -751,7 +755,7 @@ generate_special (DBusMessageDataIter *iter, _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY); _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR); - + *expected_validity = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED; } else if (item_seq == 18) @@ -768,9 +772,9 @@ generate_special (DBusMessageDataIter *iter, DBUS_HEADER_FIELD_SIGNATURE, NULL, &pos); generate_from_message (data, expected_validity, message); - + _dbus_string_set_byte (data, pos + 1, DBUS_DICT_ENTRY_END_CHAR); - + *expected_validity = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED; } else if (item_seq == 19) @@ -791,7 +795,7 @@ generate_special (DBusMessageDataIter *iter, _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY); _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR); _dbus_string_set_byte (data, pos + 3, DBUS_DICT_ENTRY_END_CHAR); - + *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS; } else if (item_seq == 20) @@ -840,7 +844,7 @@ generate_wrong_length (DBusMessageDataIter *iter, return FALSE; _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths)); - + iter_recurse (iter); if (!generate_many_bodies (iter, data, expected_validity)) { @@ -862,7 +866,7 @@ generate_wrong_length (DBusMessageDataIter *iter, *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON; } else - { + { if (!_dbus_string_lengthen (data, adjust)) _dbus_test_fatal ("oom"); *expected_validity = DBUS_INVALID_TOO_MUCH_DATA; @@ -873,9 +877,9 @@ generate_wrong_length (DBusMessageDataIter *iter, int old_body_len; int new_body_len; int byte_order; - + _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE); - + byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET); old_body_len = _dbus_marshal_read_uint32 (data, BODY_LENGTH_OFFSET, @@ -892,7 +896,7 @@ generate_wrong_length (DBusMessageDataIter *iter, _dbus_verbose ("changing body len from %u to %u by adjust %d\n", old_body_len, new_body_len, adjust); - + _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET, new_body_len, byte_order); @@ -922,7 +926,7 @@ generate_byte_changed (DBusMessageDataIter *iter, byte_seq = iter_get_sequence (iter); iter_next (iter); iter_unrecurse (iter); - + if (byte_seq == _dbus_string_get_length (data)) { _dbus_string_set_length (data, 0); @@ -966,21 +970,21 @@ find_next_typecode (DBusMessageDataIter *iter, _dbus_string_set_length (data, 0); body_seq = iter_get_sequence (iter); - + if (!generate_many_bodies (iter, data, expected_validity)) return FALSE; /* Undo the "next" in generate_many_bodies */ iter_set_sequence (iter, body_seq); - + iter_recurse (iter); while (TRUE) { _dbus_assert (iter->depth == (base_depth + 1)); - + byte_seq = iter_get_sequence (iter); _dbus_assert (byte_seq <= _dbus_string_get_length (data)); - + if (byte_seq == _dbus_string_get_length (data)) { /* reset byte count */ @@ -1005,7 +1009,7 @@ find_next_typecode (DBusMessageDataIter *iter, iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); - + return TRUE; } @@ -1047,7 +1051,7 @@ generate_typecode_changed (DBusMessageDataIter *iter, restart: _dbus_assert (iter->depth == (base_depth + 0)); _dbus_string_set_length (data, 0); - + if (!find_next_typecode (iter, data, expected_validity)) return FALSE; @@ -1055,13 +1059,13 @@ generate_typecode_changed (DBusMessageDataIter *iter, byte_seq = iter_get_sequence (iter); _dbus_assert (byte_seq < _dbus_string_get_length (data)); - + iter_recurse (iter); typecode_seq = iter_get_sequence (iter); iter_next (iter); _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes)); - + if (typecode_seq == _DBUS_N_ELEMENTS (typecodes)) { _dbus_assert (iter->depth == (base_depth + 2)); @@ -1084,7 +1088,7 @@ generate_typecode_changed (DBusMessageDataIter *iter, _dbus_test_diag ("Changing byte %d in message %d to %c", byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]); #endif - + _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]); *expected_validity = DBUS_VALIDITY_UNKNOWN; return TRUE; @@ -1129,12 +1133,12 @@ generate_uint32_changed (DBusMessageDataIter *iter, */ base_depth = iter->depth; - + next_body: _dbus_assert (iter->depth == (base_depth + 0)); _dbus_string_set_length (data, 0); body_seq = iter_get_sequence (iter); - + if (!generate_many_bodies (iter, data, expected_validity)) return FALSE; @@ -1145,7 +1149,7 @@ generate_uint32_changed (DBusMessageDataIter *iter, next_change: _dbus_assert (iter->depth == (base_depth + 1)); change_seq = iter_get_sequence (iter); - + if (change_seq == _DBUS_N_ELEMENTS (uint32_changes)) { /* Reset change count */ @@ -1156,7 +1160,7 @@ generate_uint32_changed (DBusMessageDataIter *iter, } _dbus_assert (iter->depth == (base_depth + 1)); - + iter_recurse (iter); _dbus_assert (iter->depth == (base_depth + 2)); byte_seq = iter_get_sequence (iter); @@ -1180,11 +1184,11 @@ generate_uint32_changed (DBusMessageDataIter *iter, iter_next (iter); goto next_change; } - + _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4)); byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET); - + v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL); change = &uint32_changes[change_seq]; @@ -1206,26 +1210,26 @@ generate_uint32_changed (DBusMessageDataIter *iter, _dbus_test_diag ("adjust by %d", (int) change->value); else _dbus_test_diag ("set to %u", change->value); - + _dbus_test_diag (" \t%u -> %u", _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL), v_UINT32); #endif - + _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order); *expected_validity = DBUS_VALIDITY_UNKNOWN; _dbus_assert (iter->depth == (base_depth + 1)); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); - + return TRUE; } typedef struct { const char *name; - DBusMessageGeneratorFunc func; + DBusMessageGeneratorFunc func; } DBusMessageGenerator; static const DBusMessageGenerator generators[] = { @@ -1251,7 +1255,7 @@ void _dbus_message_data_iter_init (DBusMessageDataIter *iter) { int i; - + iter->depth = 0; i = 0; while (i < _DBUS_MESSAGE_DATA_MAX_NESTING) @@ -1271,17 +1275,17 @@ _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter, restart: generator = iter_get_sequence (iter); - + if (generator == _DBUS_N_ELEMENTS (generators)) return FALSE; iter_recurse (iter); - + if (iter_first_in_series (iter)) { _dbus_test_diag (" testing message loading: %s ", generators[generator].name); } - + func = generators[generator].func; if (!_dbus_string_init (&data->data)) diff --git a/dbus/dbus-message-factory.h b/test/internals/dbus-message-factory.h similarity index 99% rename from dbus/dbus-message-factory.h rename to test/internals/dbus-message-factory.h index 5903916b..636e4709 100644 --- a/dbus/dbus-message-factory.h +++ b/test/internals/dbus-message-factory.h @@ -35,7 +35,7 @@ DBUS_BEGIN_DECLS typedef struct { DBusValidity expected_validity; - + DBusString data; } DBusMessageData; diff --git a/test/internals/dbus-message-util.c b/test/internals/dbus-message-util.c new file mode 100644 index 00000000..2fe1ffd2 --- /dev/null +++ b/test/internals/dbus-message-util.c @@ -0,0 +1,1677 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-message-util.c Would be in dbus-message.c, but only used by bus/tests + * + * Copyright 2002-2009 Red Hat, Inc. + * Copyright 2002-2003 CodeFactory AB + * Copyright 2007-2018 Collabora Ltd. + * Copyright 2009 Scott James Remnant / Canonical Ltd. + * Copyright 2009 William Lachance + * Copyright 2010 Christian Dywan / Lanedo + * Copyright 2013 Chengwei Yang / Intel + * Copyright 2013 Vasiliy Balyasnyy / Samsung + * Copyright 2014 Ralf Habacker + * Copyright 2017 Endless Mobile, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "dbus-message-util.h" + +#include "dbus/dbus-internals.h" +#include "dbus/dbus-test.h" +#include "dbus/dbus-message-private.h" +#include "dbus/dbus-marshal-recursive.h" +#include "dbus/dbus-string.h" +#ifdef HAVE_UNIX_FD_PASSING +#include "dbus/dbus-sysdeps-unix.h" +#endif +#include "dbus/dbus-test-tap.h" + +#include "dbus-message-factory.h" + +#ifdef DBUS_ENABLE_EMBEDDED_TESTS +/** + * Reads arguments from a message iterator given a variable argument + * list. Only arguments of basic type and arrays of fixed-length + * basic type may be read with this function. See + * dbus_message_get_args() for more details. + * + * @param iter the message iterator + * @param error error to be filled in on failure + * @param first_arg_type the first argument type + * @param ... location for first argument value, then list of type-location pairs + * @returns #FALSE if the error was set + */ +static dbus_bool_t +dbus_message_iter_get_args (DBusMessageIter *iter, + DBusError *error, + int first_arg_type, + ...) +{ + dbus_bool_t retval; + va_list var_args; + + _dbus_return_val_if_fail (iter != NULL, FALSE); + _dbus_return_val_if_error_is_set (error, FALSE); + + va_start (var_args, first_arg_type); + retval = _dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args); + va_end (var_args); + + return retval; +} + +/* returns FALSE on fatal failure */ +typedef dbus_bool_t (* DBusForeachMessageFileFunc) (const DBusString *filename, + DBusValidity expected_validity, + void *data); + +static dbus_bool_t try_message_data (const DBusString *data, + DBusValidity expected_validity); + +static int validities_seen[DBUS_VALIDITY_LAST + _DBUS_NEGATIVE_VALIDITY_COUNT]; + +static void +reset_validities_seen (void) +{ + int i; + i = 0; + while (i < _DBUS_N_ELEMENTS (validities_seen)) + { + validities_seen[i] = 0; + ++i; + } +} + +static void +record_validity_seen (DBusValidity validity) +{ + validities_seen[validity + _DBUS_NEGATIVE_VALIDITY_COUNT] += 1; +} + +static void +print_validities_seen (dbus_bool_t not_seen) +{ + int i; + i = 0; + while (i < _DBUS_N_ELEMENTS (validities_seen)) + { + if ((i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_VALIDITY_UNKNOWN || + (i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_INVALID_FOR_UNKNOWN_REASON) + ; + else if ((not_seen && validities_seen[i] == 0) || + (!not_seen && validities_seen[i] > 0)) + _dbus_test_diag ("validity %3d seen %d times", + i - _DBUS_NEGATIVE_VALIDITY_COUNT, + validities_seen[i]); + ++i; + } +} + +static void +check_memleaks (void) +{ + dbus_shutdown (); + + if (_dbus_get_malloc_blocks_outstanding () != 0) + { + _dbus_test_fatal ("%d dbus_malloc blocks were not freed in %s", + _dbus_get_malloc_blocks_outstanding (), __FILE__); + } +} + +static dbus_bool_t +check_have_valid_message (DBusMessageLoader *loader) +{ + DBusMessage *message; + dbus_bool_t retval; + + message = NULL; + retval = FALSE; + + if (_dbus_message_loader_get_is_corrupted (loader)) + { + _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d", + loader->corruption_reason); + goto failed; + } + + message = _dbus_message_loader_pop_message (loader); + if (message == NULL) + { + _dbus_warn ("didn't load message that was expected to be valid (message not popped)"); + goto failed; + } + + if (_dbus_string_get_length (&loader->data) > 0) + { + _dbus_warn ("had leftover bytes from expected-to-be-valid single message"); + goto failed; + } + +#if 0 + /* FIXME */ + /* Verify that we're able to properly deal with the message. + * For example, this would detect improper handling of messages + * in nonstandard byte order. + */ + if (!check_message_handling (message)) + goto failed; +#endif + + record_validity_seen (DBUS_VALID); + + retval = TRUE; + + failed: + if (message) + dbus_message_unref (message); + + return retval; +} + +static dbus_bool_t +check_invalid_message (DBusMessageLoader *loader, + DBusValidity expected_validity) +{ + dbus_bool_t retval; + + retval = FALSE; + + if (!_dbus_message_loader_get_is_corrupted (loader)) + { + _dbus_warn ("loader not corrupted on message that was expected to be invalid"); + goto failed; + } + + record_validity_seen (loader->corruption_reason); + + if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON && + loader->corruption_reason != expected_validity) + { + _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead", + expected_validity, loader->corruption_reason); + goto failed; + } + + retval = TRUE; + + failed: + return retval; +} + +static dbus_bool_t +check_incomplete_message (DBusMessageLoader *loader) +{ + DBusMessage *message; + dbus_bool_t retval; + + message = NULL; + retval = FALSE; + + if (_dbus_message_loader_get_is_corrupted (loader)) + { + _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d", + loader->corruption_reason); + goto failed; + } + + message = _dbus_message_loader_pop_message (loader); + if (message != NULL) + { + _dbus_warn ("loaded message that was expected to be incomplete"); + goto failed; + } + + record_validity_seen (DBUS_VALID_BUT_INCOMPLETE); + retval = TRUE; + + failed: + if (message) + dbus_message_unref (message); + return retval; +} + +static dbus_bool_t +check_loader_results (DBusMessageLoader *loader, + DBusValidity expected_validity) +{ + if (!_dbus_message_loader_queue_messages (loader)) + _dbus_test_fatal ("no memory to queue messages"); + + if (expected_validity == DBUS_VALID) + return check_have_valid_message (loader); + else if (expected_validity == DBUS_VALID_BUT_INCOMPLETE) + return check_incomplete_message (loader); + else if (expected_validity == DBUS_VALIDITY_UNKNOWN) + { + /* here we just know we didn't segfault and that was the + * only test. Also, we record that we got coverage + * for the validity reason. + */ + if (_dbus_message_loader_get_is_corrupted (loader)) + record_validity_seen (loader->corruption_reason); + + return TRUE; + } + else + return check_invalid_message (loader, expected_validity); +} + +/** + * Loads the message in the given message file. + * + * @param filename filename to load + * @param data string to load message into + * @returns #TRUE if the message was loaded + */ +static dbus_bool_t +load_message_file (const DBusString *filename, + DBusString *data) +{ + dbus_bool_t retval; + DBusError error = DBUS_ERROR_INIT; + + retval = FALSE; + + _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename)); + if (!_dbus_file_get_contents (data, filename, &error)) + { + _dbus_warn ("Could not load message file %s: %s", + _dbus_string_get_const_data (filename), + error.message); + dbus_error_free (&error); + goto failed; + } + + retval = TRUE; + + failed: + + return retval; +} + +/** + * Tries loading the message in the given message file + * and verifies that DBusMessageLoader can handle it. + * + * @param filename filename to load + * @param expected_validity what the message has to be like to return #TRUE + * @param unused ignored + * @returns #TRUE if the message has the expected validity + */ +static dbus_bool_t +try_message_file (const DBusString *filename, + DBusValidity expected_validity, + void *unused) +{ + DBusString data; + dbus_bool_t retval; + + retval = FALSE; + + if (!_dbus_string_init (&data)) + _dbus_test_fatal ("could not allocate string"); + + if (!load_message_file (filename, &data)) + goto failed; + + retval = try_message_data (&data, expected_validity); + + failed: + + if (!retval) + { + if (_dbus_string_get_length (&data) > 0) + _dbus_verbose_bytes_of_string (&data, 0, + _dbus_string_get_length (&data)); + + _dbus_warn ("Failed message loader test on %s", + _dbus_string_get_const_data (filename)); + } + + _dbus_string_free (&data); + + return retval; +} + +/** + * 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 + */ +static dbus_bool_t +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 (); + if (loader == NULL) + goto failed; + + /* check some trivial loader functions */ + _dbus_message_loader_ref (loader); + _dbus_message_loader_unref (loader); + + len = _dbus_string_get_length (data); + for (i = 0; i < len; i++) + { + DBusString *buffer; + + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); + if (!_dbus_string_append_byte (buffer, + _dbus_string_get_byte (data, i))) + goto failed; + _dbus_message_loader_return_buffer (loader, buffer); + } + + 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 (); + if (loader == NULL) + goto failed; + + { + DBusString *buffer; + + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); + if (!_dbus_string_copy (data, 0, buffer, + _dbus_string_get_length (buffer))) + goto failed; + _dbus_message_loader_return_buffer (loader, buffer); + } + + 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 (); + if (loader == NULL) + goto failed; + + len = _dbus_string_get_length (data); + for (i = 0; i < len; i += 2) + { + DBusString *buffer; + + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); + if (!_dbus_string_append_byte (buffer, + _dbus_string_get_byte (data, i))) + goto failed; + + if ((i+1) < len) + { + if (!_dbus_string_append_byte (buffer, + _dbus_string_get_byte (data, i+1))) + goto failed; + } + + _dbus_message_loader_return_buffer (loader, buffer); + } + + 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; +} + +static dbus_bool_t +process_test_subdir (const DBusString *test_base_dir, + const char *subdir, + DBusValidity expected_validity, + DBusForeachMessageFileFunc function, + void *user_data) +{ + DBusString test_directory; + DBusString filename; + DBusDirIter *dir; + dbus_bool_t retval; + DBusError error = DBUS_ERROR_INIT; + + retval = FALSE; + dir = NULL; + + if (!_dbus_string_init (&test_directory)) + _dbus_test_fatal ("didn't allocate test_directory"); + + _dbus_string_init_const (&filename, subdir); + + if (!_dbus_string_copy (test_base_dir, 0, + &test_directory, 0)) + _dbus_test_fatal ("couldn't copy test_base_dir to test_directory"); + + if (!_dbus_concat_dir_and_file (&test_directory, &filename)) + _dbus_test_fatal ("couldn't allocate full path"); + + _dbus_string_free (&filename); + if (!_dbus_string_init (&filename)) + _dbus_test_fatal ("didn't allocate filename string"); + + dir = _dbus_directory_open (&test_directory, &error); + if (dir == NULL) + { + _dbus_warn ("Could not open %s: %s", + _dbus_string_get_const_data (&test_directory), + error.message); + dbus_error_free (&error); + goto failed; + } + + _dbus_test_diag ("Testing %s:", subdir); + + next: + while (_dbus_directory_get_next_file (dir, &filename, &error)) + { + DBusString full_path; + + if (!_dbus_string_init (&full_path)) + _dbus_test_fatal ("couldn't init string"); + + if (!_dbus_string_copy (&test_directory, 0, &full_path, 0)) + _dbus_test_fatal ("couldn't copy dir to full_path"); + + if (!_dbus_concat_dir_and_file (&full_path, &filename)) + _dbus_test_fatal ("couldn't concat file to dir"); + + if (_dbus_string_ends_with_c_str (&filename, ".message-raw")) + ; + else + { + _dbus_verbose ("Skipping non-.message-raw file %s\n", + _dbus_string_get_const_data (&filename)); + _dbus_string_free (&full_path); + goto next; + } + + _dbus_test_diag (" %s", + _dbus_string_get_const_data (&filename)); + + if (! (*function) (&full_path, + expected_validity, user_data)) + { + _dbus_string_free (&full_path); + goto failed; + } + else + _dbus_string_free (&full_path); + } + + if (dbus_error_is_set (&error)) + { + _dbus_warn ("Could not get next file in %s: %s", + _dbus_string_get_const_data (&test_directory), + error.message); + dbus_error_free (&error); + goto failed; + } + + retval = TRUE; + + failed: + + if (dir) + _dbus_directory_close (dir); + _dbus_string_free (&test_directory); + _dbus_string_free (&filename); + + return retval; +} + +/** + * Runs the given function on every message file in the test suite. + * The function should return #FALSE on test failure or fatal error. + * + * @param test_data_dir root dir of the test suite data files (top_srcdir/test/data) + * @param func the function to run + * @param user_data data for function + * @returns #FALSE if there's a failure + */ +static dbus_bool_t +foreach_message_file (const char *test_data_dir, + DBusForeachMessageFileFunc func, + void *user_data) +{ + DBusString test_directory; + dbus_bool_t retval; + + retval = FALSE; + + _dbus_string_init_const (&test_directory, test_data_dir); + + if (!process_test_subdir (&test_directory, "invalid-messages", + DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data)) + goto failed; + + check_memleaks (); + + retval = TRUE; + + failed: + + _dbus_string_free (&test_directory); + + return retval; +} + +#if 0 +#define GET_AND_CHECK(iter, typename, literal) \ + do { \ + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ + _dbus_test_fatal ("got wrong argument type from message iter"); \ + dbus_message_iter_get_basic (&iter, &v_##typename); \ + if (v_##typename != literal) \ + _dbus_test_fatal ("got wrong value from message iter"); \ + } while (0) + +#define GET_AND_CHECK_STRCMP(iter, typename, literal) \ + do { \ + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ + _dbus_test_fatal ("got wrong argument type from message iter"); \ + dbus_message_iter_get_basic (&iter, &v_##typename); \ + if (strcmp (v_##typename, literal) != 0) \ + _dbus_test_fatal ("got wrong value from message iter"); \ + } while (0) + +#define GET_AND_CHECK_AND_NEXT(iter, typename, literal) \ + do { \ + GET_AND_CHECK(iter, typename, literal); \ + if (!dbus_message_iter_next (&iter)) \ + _dbus_test_fatal ("failed to move iter to next"); \ + } while (0) + +#define GET_AND_CHECK_STRCMP_AND_NEXT(iter, typename, literal) \ + do { \ + GET_AND_CHECK_STRCMP(iter, typename, literal); \ + if (!dbus_message_iter_next (&iter)) \ + _dbus_test_fatal ("failed to move iter to next"); \ + } while (0) + +static void +message_iter_test (DBusMessage *message) +{ + DBusMessageIter iter, array, array2; + 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; + dbus_int64_t v_INT64; + dbus_uint64_t v_UINT64; + unsigned char v_BYTE; + dbus_bool_t v_BOOLEAN; + + const dbus_int32_t *our_int_array; + int len; + + dbus_message_iter_init (message, &iter); + + GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string"); + GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678); + GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e); + GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159); + + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) + _dbus_test_fatal ("Argument type not an array"); + + if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DOUBLE) + _dbus_test_fatal ("Array type not double"); + + dbus_message_iter_recurse (&iter, &array); + + GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5); + GET_AND_CHECK (array, DOUBLE, 2.5); + + if (dbus_message_iter_next (&array)) + _dbus_test_fatal ("Didn't reach end of array"); + + if (!dbus_message_iter_next (&iter)) + _dbus_test_fatal ("Reached end of arguments"); + + GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0); + + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) + _dbus_test_fatal ("no array"); + + if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_INT32) + _dbus_test_fatal ("Array type not int32"); + + /* Empty array */ + dbus_message_iter_recurse (&iter, &array); + + if (dbus_message_iter_next (&array)) + _dbus_test_fatal ("Didn't reach end of array"); + + if (!dbus_message_iter_next (&iter)) + _dbus_test_fatal ("Reached end of arguments"); + + GET_AND_CHECK (iter, BYTE, 0xF0); + + if (dbus_message_iter_next (&iter)) + _dbus_test_fatal ("Didn't reach end of arguments"); +} +#endif + +static void +verify_test_message (DBusMessage *message) +{ + DBusMessageIter iter; + DBusError error = DBUS_ERROR_INIT; + dbus_int16_t our_int16; + dbus_uint16_t our_uint16; + dbus_int32_t our_int; + dbus_uint32_t our_uint; + const char *our_str; + double our_double; + double v_DOUBLE; + dbus_bool_t our_bool; + unsigned char our_byte_1, our_byte_2; + const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef; + int our_uint32_array_len; + dbus_int32_t *our_int32_array = (void*)0xdeadbeef; + int our_int32_array_len; + dbus_int64_t our_int64; + dbus_uint64_t our_uint64; + dbus_int64_t *our_uint64_array = (void*)0xdeadbeef; + int our_uint64_array_len; + const dbus_int64_t *our_int64_array = (void*)0xdeadbeef; + int our_int64_array_len; + const double *our_double_array = (void*)0xdeadbeef; + int our_double_array_len; + const unsigned char *our_byte_array = (void*)0xdeadbeef; + int our_byte_array_len; + const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef; + int our_boolean_array_len; + char **our_string_array; + int our_string_array_len; + + dbus_message_iter_init (message, &iter); + + if (!dbus_message_iter_get_args (&iter, &error, + DBUS_TYPE_INT16, &our_int16, + DBUS_TYPE_UINT16, &our_uint16, + DBUS_TYPE_INT32, &our_int, + DBUS_TYPE_UINT32, &our_uint, + DBUS_TYPE_INT64, &our_int64, + DBUS_TYPE_UINT64, &our_uint64, + DBUS_TYPE_STRING, &our_str, + DBUS_TYPE_DOUBLE, &our_double, + DBUS_TYPE_BOOLEAN, &our_bool, + DBUS_TYPE_BYTE, &our_byte_1, + DBUS_TYPE_BYTE, &our_byte_2, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, + &our_uint32_array, &our_uint32_array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, + &our_int32_array, &our_int32_array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, + &our_uint64_array, &our_uint64_array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, + &our_int64_array, &our_int64_array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, + &our_double_array, &our_double_array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &our_byte_array, &our_byte_array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, + &our_boolean_array, &our_boolean_array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &our_string_array, &our_string_array_len, + 0)) + { + _dbus_test_fatal ("Could not get arguments: %s - %s", error.name, + (error.message != NULL) ? error.message : "no message"); + } + + if (our_int16 != -0x123) + _dbus_test_fatal ("16-bit integers differ!"); + + if (our_uint16 != 0x123) + _dbus_test_fatal ("16-bit uints differ!"); + + if (our_int != -0x12345678) + _dbus_test_fatal ("integers differ!"); + + if (our_uint != 0x12300042) + _dbus_test_fatal ("uints differ!"); + + if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd)) + _dbus_test_fatal ("64-bit integers differ!"); + if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd)) + _dbus_test_fatal ("64-bit unsigned integers differ!"); + + v_DOUBLE = 3.14159; + if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE)) + _dbus_test_fatal ("doubles differ!"); + + if (strcmp (our_str, "Test string") != 0) + _dbus_test_fatal ("strings differ!"); + + if (!our_bool) + _dbus_test_fatal ("booleans differ"); + + if (our_byte_1 != 42) + _dbus_test_fatal ("bytes differ!"); + + if (our_byte_2 != 24) + _dbus_test_fatal ("bytes differ!"); + + if (our_uint32_array_len != 4 || + our_uint32_array[0] != 0x12345678 || + our_uint32_array[1] != 0x23456781 || + our_uint32_array[2] != 0x34567812 || + our_uint32_array[3] != 0x45678123) + _dbus_test_fatal ("uint array differs"); + + if (our_int32_array_len != 4 || + our_int32_array[0] != 0x12345678 || + our_int32_array[1] != -0x23456781 || + our_int32_array[2] != 0x34567812 || + our_int32_array[3] != -0x45678123) + _dbus_test_fatal ("int array differs"); + + if (our_uint64_array_len != 4 || + our_uint64_array[0] != 0x12345678 || + our_uint64_array[1] != 0x23456781 || + our_uint64_array[2] != 0x34567812 || + our_uint64_array[3] != 0x45678123) + _dbus_test_fatal ("uint64 array differs"); + + if (our_int64_array_len != 4 || + our_int64_array[0] != 0x12345678 || + our_int64_array[1] != -0x23456781 || + our_int64_array[2] != 0x34567812 || + our_int64_array[3] != -0x45678123) + _dbus_test_fatal ("int64 array differs"); + + if (our_double_array_len != 3) + _dbus_test_fatal ("double array had wrong length"); + + /* On all IEEE machines (i.e. everything sane) exact equality + * should be preserved over the wire + */ + v_DOUBLE = 0.1234; + if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE)) + _dbus_test_fatal ("double array had wrong values"); + v_DOUBLE = 9876.54321; + if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE)) + _dbus_test_fatal ("double array had wrong values"); + v_DOUBLE = -300.0; + if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE)) + _dbus_test_fatal ("double array had wrong values"); + + if (our_byte_array_len != 4) + _dbus_test_fatal ("byte array had wrong length"); + + if (our_byte_array[0] != 'a' || + our_byte_array[1] != 'b' || + our_byte_array[2] != 'c' || + our_byte_array[3] != 234) + _dbus_test_fatal ("byte array had wrong values"); + + if (our_boolean_array_len != 5) + _dbus_test_fatal ("bool array had wrong length"); + + if (our_boolean_array[0] != TRUE || + our_boolean_array[1] != FALSE || + our_boolean_array[2] != TRUE || + our_boolean_array[3] != TRUE || + our_boolean_array[4] != FALSE) + _dbus_test_fatal ("bool array had wrong values"); + + if (our_string_array_len != 4) + _dbus_test_fatal ("string array was wrong length"); + + if (strcmp (our_string_array[0], "Foo") != 0 || + strcmp (our_string_array[1], "bar") != 0 || + strcmp (our_string_array[2], "") != 0 || + strcmp (our_string_array[3], "woo woo woo woo") != 0) + _dbus_test_fatal ("string array had wrong values"); + + dbus_free_string_array (our_string_array); + + if (dbus_message_iter_next (&iter)) + _dbus_test_fatal ("Didn't reach end of arguments"); +} + +static void +verify_test_message_args_ignored (DBusMessage *message) +{ + DBusMessageIter iter; + DBusError error = DBUS_ERROR_INIT; + dbus_uint32_t our_uint; + DBusInitialFDs *initial_fds; + + initial_fds = _dbus_check_fdleaks_enter (); + + /* parse with empty signature: "" */ + dbus_message_iter_init (message, &iter); + if (!dbus_message_iter_get_args (&iter, &error, + DBUS_TYPE_INVALID)) + { + _dbus_warn ("error: %s - %s", error.name, + (error.message != NULL) ? error.message : "no message"); + } + else + { + _dbus_assert (!dbus_error_is_set (&error)); + _dbus_verbose ("arguments ignored.\n"); + } + + /* parse with shorter signature: "u" */ + dbus_message_iter_init (message, &iter); + if (!dbus_message_iter_get_args (&iter, &error, + DBUS_TYPE_UINT32, &our_uint, + DBUS_TYPE_INVALID)) + { + _dbus_warn ("error: %s - %s", error.name, + (error.message != NULL) ? error.message : "no message"); + } + else + { + _dbus_assert (!dbus_error_is_set (&error)); + _dbus_verbose ("arguments ignored.\n"); + } + + _dbus_check_fdleaks_leave (initial_fds); +} + +static void +verify_test_message_memleak (DBusMessage *message) +{ + DBusMessageIter iter; + DBusError error = DBUS_ERROR_INIT; + dbus_uint32_t our_uint1; + dbus_uint32_t our_uint2; + dbus_uint32_t our_uint3; + char **our_string_array1; + int our_string_array_len1; + char **our_string_array2; + int our_string_array_len2; +#ifdef HAVE_UNIX_FD_PASSING + int our_unix_fd1; + int our_unix_fd2; +#endif + DBusInitialFDs *initial_fds; + + initial_fds = _dbus_check_fdleaks_enter (); + + /* parse with wrong signature: "uashuu" */ + dbus_error_free (&error); + dbus_message_iter_init (message, &iter); + if (!dbus_message_iter_get_args (&iter, &error, + DBUS_TYPE_UINT32, &our_uint1, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &our_string_array1, &our_string_array_len1, +#ifdef HAVE_UNIX_FD_PASSING + DBUS_TYPE_UNIX_FD, &our_unix_fd1, +#endif + DBUS_TYPE_UINT32, &our_uint2, + DBUS_TYPE_UINT32, &our_uint3, + DBUS_TYPE_INVALID)) + { + _dbus_verbose ("expected error: %s - %s\n", error.name, + (error.message != NULL) ? error.message : "no message"); + /* ensure array of string and unix fd not leaked */ + _dbus_assert (our_string_array1 == NULL); +#ifdef HAVE_UNIX_FD_PASSING + _dbus_assert (our_unix_fd1 == -1); +#endif + } + else + { + _dbus_test_fatal ("error: parse with wrong signature: 'uashuu'."); + } + + /* parse with wrong signature: "uashuashu" */ + dbus_message_iter_init (message, &iter); + dbus_error_free (&error); + if (!dbus_message_iter_get_args (&iter, &error, + DBUS_TYPE_UINT32, &our_uint1, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &our_string_array1, &our_string_array_len1, +#ifdef HAVE_UNIX_FD_PASSING + DBUS_TYPE_UNIX_FD, &our_unix_fd1, +#endif + DBUS_TYPE_UINT32, &our_uint2, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &our_string_array2, &our_string_array_len2, +#ifdef HAVE_UNIX_FD_PASSING + DBUS_TYPE_UNIX_FD, &our_unix_fd2, +#endif + DBUS_TYPE_UINT32, &our_uint3, + DBUS_TYPE_INVALID)) + { + _dbus_verbose ("expected error: %s - %s\n", error.name, + (error.message != NULL) ? error.message : "no message"); + /* ensure array of string and unix fd not leaked */ + _dbus_assert (our_string_array1 == NULL); + _dbus_assert (our_string_array2 == NULL); +#ifdef HAVE_UNIX_FD_PASSING + _dbus_assert (our_unix_fd1 == -1); + _dbus_assert (our_unix_fd2 == -1); +#endif + } + else + { + _dbus_test_fatal ("error: parse with wrong signature: 'uashuashu'."); + } + + /* parse with correct signature: "uashuash" */ + dbus_message_iter_init (message, &iter); + dbus_error_free (&error); + if (!dbus_message_iter_get_args (&iter, &error, + DBUS_TYPE_UINT32, &our_uint1, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &our_string_array1, &our_string_array_len1, +#ifdef HAVE_UNIX_FD_PASSING + DBUS_TYPE_UNIX_FD, &our_unix_fd1, +#endif + DBUS_TYPE_UINT32, &our_uint2, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &our_string_array2, &our_string_array_len2, +#ifdef HAVE_UNIX_FD_PASSING + DBUS_TYPE_UNIX_FD, &our_unix_fd2, +#endif + DBUS_TYPE_INVALID)) + { + _dbus_test_fatal ("Could not get arguments: %s - %s", error.name, + (error.message != NULL) ? error.message : "no message"); + } + else + { + dbus_free_string_array (our_string_array1); + dbus_free_string_array (our_string_array2); +#ifdef HAVE_UNIX_FD_PASSING + _dbus_close (our_unix_fd1, &error); + _dbus_close (our_unix_fd2, &error); +#endif + } + _dbus_check_fdleaks_leave (initial_fds); +} + +/** + * @ingroup DBusMessageInternals + * Unit test for DBusMessage. + * + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_message_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + 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; + 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; + const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; + const char *our_string_array1[] = { "foo", "Bar", "", "Woo woo Woo woo" }; + const char **v_ARRAY_STRING = our_string_array; + const char **v1_ARRAY_STRING = our_string_array1; + 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; + dbus_uint32_t v1_UINT32; + dbus_int64_t v_INT64; + dbus_uint64_t v_UINT64; + 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; + int v1_UNIX_FD; +#endif + char **decomposed; + DBusInitialFDs *initial_fds; + dbus_bool_t ok; + char basic_types[] = DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BOOLEAN_AS_STRING \ + DBUS_TYPE_INT16_AS_STRING \ + DBUS_TYPE_INT32_AS_STRING \ + DBUS_TYPE_INT64_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_TYPE_UINT64_AS_STRING \ + DBUS_TYPE_DOUBLE_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING; + + initial_fds = _dbus_check_fdleaks_enter (); + + 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_test_fatal ("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_test_fatal ("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_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_path (message), + "/foo") == 0); + + if (!dbus_message_set_container_instance (message, "/org/freedesktop/DBus/Containers1/c42")) + _dbus_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_container_instance (message), + "/org/freedesktop/DBus/Containers1/c42") == 0); + + if (!dbus_message_set_interface (message, "org.Foo")) + _dbus_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_interface (message), + "org.Foo") == 0); + + if (!dbus_message_set_member (message, "Bar")) + _dbus_test_fatal ("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_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_path (message), + "/foo/bar") == 0); + + if (!dbus_message_set_interface (message, "org.Foo.Bar")) + _dbus_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_interface (message), + "org.Foo.Bar") == 0); + + if (!dbus_message_set_member (message, "BarFoo")) + _dbus_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_member (message), + "BarFoo") == 0); + + /* Realloc shorter again */ + + if (!dbus_message_set_path (message, "/foo")) + _dbus_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_path (message), + "/foo") == 0); + + if (!dbus_message_set_interface (message, "org.Foo")) + _dbus_test_fatal ("out of memory"); + _dbus_assert (strcmp (dbus_message_get_interface (message), + "org.Foo") == 0); + + if (!dbus_message_set_member (message, "Bar")) + _dbus_test_fatal ("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; + v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); + v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); + 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; + v1_UNIX_FD = 2; +#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, + DBUS_TYPE_INT64, &v_INT64, + DBUS_TYPE_UINT64, &v_UINT64, + 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), + 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), + 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; + sig[i++] = DBUS_TYPE_INT64; + sig[i++] = DBUS_TYPE_UINT64; + 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; + sig[i++] = DBUS_TYPE_ARRAY; + sig[i++] = DBUS_TYPE_UINT64; + sig[i++] = DBUS_TYPE_ARRAY; + sig[i++] = DBUS_TYPE_INT64; + 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, NULL, NULL); + _dbus_string_append_byte (buffer, data[i]); + _dbus_message_loader_return_buffer (loader, buffer); + } + + /* 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, NULL, NULL); + _dbus_string_append_byte (buffer, data[i]); + _dbus_message_loader_return_buffer (loader, buffer); + } + +#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_test_fatal ("no memory to queue messages"); + + if (_dbus_message_loader_get_is_corrupted (loader)) + _dbus_test_fatal ("message loader corrupted"); + + message = _dbus_message_loader_pop_message (loader); + if (!message) + _dbus_test_fatal ("received a NULL message"); + + if (dbus_message_get_reply_serial (message) != 5678) + _dbus_test_fatal ("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_test_fatal ("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_leave (initial_fds); + initial_fds = _dbus_check_fdleaks_enter (); + + /* Test enumeration of array elements */ + for (i = strlen (basic_types) - 1; i > 0; i--) + { + DBusBasicValue val; + int some; + char* signature = _dbus_strdup ("?"); + + signature[0] = basic_types[i]; + s = "SomeThingToSay"; + memset (&val, '\0', sizeof (val)); + + message = dbus_message_new_method_call ("de.ende.test", + "/de/ende/test", "de.ende.Test", "ArtistName"); + _dbus_assert (message != NULL); + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, + signature, &array_iter); + for (some = 0; some < 3; some++) + { + if (basic_types[i] == DBUS_TYPE_STRING) + dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &s); + else + dbus_message_iter_append_basic (&array_iter, basic_types[i], &val); + } + dbus_message_iter_close_container (&iter, &array_iter); + dbus_message_iter_init (message, &iter); + _dbus_assert (dbus_message_iter_get_element_count (&iter) == some); + dbus_message_unref (message); + dbus_free (signature); + } + /* Array of structs */ + message = dbus_message_new_method_call ("de.ende.test", + "/de/ende/test", "de.ende.Test", "ArtistName"); + _dbus_assert (message != NULL); + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING, &array_iter); + dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, + NULL, &struct_iter); + s = "SpamAndEggs"; + dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); + dbus_message_iter_close_container (&array_iter, &struct_iter); + dbus_message_iter_close_container (&iter, &array_iter); + dbus_message_iter_init (message, &iter); + _dbus_assert (dbus_message_iter_get_element_count (&iter) == 1); + dbus_message_unref (message); + check_memleaks (); + + /* 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); + + ok = 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 (ok); + ok = dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, + NULL, &struct_iter); + _dbus_assert (ok); + s = "peaches"; + ok = dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); + _dbus_assert (ok); + + /* 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); + + /* Check we should not leak array of string or unix fd, fd.o#21259 */ + message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", + "/org/freedesktop/TestPath", + "Foo.TestInterface", + "Method"); + + /* signature "uashuash" */ + dbus_message_append_args (message, + DBUS_TYPE_UINT32, &v_UINT32, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, + _DBUS_N_ELEMENTS (our_string_array), +#ifdef HAVE_UNIX_FD_PASSING + DBUS_TYPE_UNIX_FD, &v_UNIX_FD, +#endif + DBUS_TYPE_UINT32, &v1_UINT32, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v1_ARRAY_STRING, + _DBUS_N_ELEMENTS (our_string_array1), +#ifdef HAVE_UNIX_FD_PASSING + DBUS_TYPE_UNIX_FD, &v1_UNIX_FD, +#endif + + DBUS_TYPE_INVALID); + + i = 0; + sig[i++] = DBUS_TYPE_UINT32; + sig[i++] = DBUS_TYPE_ARRAY; + sig[i++] = DBUS_TYPE_STRING; +#ifdef HAVE_UNIX_FD_PASSING + sig[i++] = DBUS_TYPE_UNIX_FD; +#endif + sig[i++] = DBUS_TYPE_UINT32; + sig[i++] = DBUS_TYPE_ARRAY; + sig[i++] = DBUS_TYPE_STRING; +#ifdef HAVE_UNIX_FD_PASSING + sig[i++] = DBUS_TYPE_UNIX_FD; +#endif + sig[i++] = DBUS_TYPE_INVALID; + + _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); + + verify_test_message_args_ignored (message); + verify_test_message_memleak (message); + + 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 (!try_message_data (&mdata.data, mdata.expected_validity)) + { + _dbus_test_fatal ("expected validity %d and did not get it", + mdata.expected_validity); + } + + _dbus_message_data_free (&mdata); + + count += 1; + } + + _dbus_test_diag ("%d sample messages tested", count); + + print_validities_seen (FALSE); + print_validities_seen (TRUE); + } + + check_memleaks (); + _dbus_check_fdleaks_leave (initial_fds); + + /* Now load every message in test_data_dir if we have one */ + if (test_data_dir == NULL) + return TRUE; + + initial_fds = _dbus_check_fdleaks_enter (); + + if (!foreach_message_file (test_data_dir, try_message_file, NULL)) + _dbus_test_fatal ("foreach_message_file test failed"); + + _dbus_check_fdleaks_leave (initial_fds); + + return TRUE; +} + +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/test/internals/dbus-message-util.h b/test/internals/dbus-message-util.h new file mode 100644 index 00000000..d65be2d9 --- /dev/null +++ b/test/internals/dbus-message-util.h @@ -0,0 +1,39 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2002-2009 Red Hat, Inc. + * Copyright 2002-2003 CodeFactory AB + * Copyright 2007-2018 Collabora Ltd. + * Copyright 2009 Scott James Remnant / Canonical Ltd. + * Copyright 2009 William Lachance + * Copyright 2010 Christian Dywan / Lanedo + * Copyright 2013 Chengwei Yang / Intel + * Copyright 2013 Vasiliy Balyasnyy / Samsung + * Copyright 2014 Ralf Habacker + * Copyright 2017 Endless Mobile, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef TEST_INTERNALS_DBUS_MESSAGE_UTIL_H +#define TEST_INTERNALS_DBUS_MESSAGE_UTIL_H + +#include + +dbus_bool_t _dbus_message_test (const char *test_data_dir); + +#endif diff --git a/test/internals/dbus-string-util.c b/test/internals/dbus-string-util.c new file mode 100644 index 00000000..b2af6ca3 --- /dev/null +++ b/test/internals/dbus-string-util.c @@ -0,0 +1,881 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-string-util.c Would be in dbus-string.c, but not used in libdbus + * + * Copyright 2002-2008 Red Hat, Inc. + * Copyright 2003 CodeFactory AB + * Copyright 2003 Mark McLoughlin + * Copyright 2004 Michael Meeks + * Copyright 2006-2015 Ralf Habacker + * Copyright 2007 Allison Lortie + * Copyright 2011 Roberto Guido + * Copyright 2016-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "misc-internals.h" + +#include "dbus/dbus-internals.h" +#include "dbus/dbus-string.h" +#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1 +#include "dbus/dbus-string-private.h" +#include + +#ifdef DBUS_ENABLE_EMBEDDED_TESTS +#include "dbus/dbus-test.h" +#include + +static void +test_hex_roundtrip (const char *data, + int len) +{ + DBusString orig; + DBusString encoded; + DBusString decoded; + int end; + + if (len < 0) + len = strlen (data); + + if (!_dbus_string_init (&orig)) + _dbus_test_fatal ("could not init string"); + + if (!_dbus_string_init (&encoded)) + _dbus_test_fatal ("could not init string"); + + if (!_dbus_string_init (&decoded)) + _dbus_test_fatal ("could not init string"); + + if (!_dbus_string_append_len (&orig, data, len)) + _dbus_test_fatal ("couldn't append orig data"); + + if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0)) + _dbus_test_fatal ("could not encode"); + + if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0)) + _dbus_test_fatal ("could not decode"); + + _dbus_assert (_dbus_string_get_length (&encoded) == end); + + if (!_dbus_string_equal (&orig, &decoded)) + { + const char *s; + + _dbus_test_diag ("Original string %d bytes encoded %d bytes decoded %d bytes", + _dbus_string_get_length (&orig), + _dbus_string_get_length (&encoded), + _dbus_string_get_length (&decoded)); + _dbus_test_diag ("Original: %s", data); + s = _dbus_string_get_const_data (&decoded); + _dbus_test_diag ("Decoded: %s", s); + _dbus_test_fatal ("original string not the same as string decoded from hex"); + } + + _dbus_string_free (&orig); + _dbus_string_free (&encoded); + _dbus_string_free (&decoded); +} + +typedef void (* TestRoundtripFunc) (const char *data, + int len); +static void +test_roundtrips (TestRoundtripFunc func) +{ + (* func) ("Hello this is a string\n", -1); + (* func) ("Hello this is a string\n1", -1); + (* func) ("Hello this is a string\n12", -1); + (* func) ("Hello this is a string\n123", -1); + (* func) ("Hello this is a string\n1234", -1); + (* func) ("Hello this is a string\n12345", -1); + (* func) ("", 0); + (* func) ("1", 1); + (* func) ("12", 2); + (* func) ("123", 3); + (* func) ("1234", 4); + (* func) ("12345", 5); + (* func) ("", 1); + (* func) ("1", 2); + (* func) ("12", 3); + (* func) ("123", 4); + (* func) ("1234", 5); + (* func) ("12345", 6); + { + unsigned char buf[512]; + int i; + + i = 0; + while (i < _DBUS_N_ELEMENTS (buf)) + { + buf[i] = (i & 0xff); + ++i; + } + i = 0; + while (i < _DBUS_N_ELEMENTS (buf)) + { + (* func) ((const char *) buf, i); + ++i; + } + } +} + +_DBUS_STRING_DEFINE_STATIC (test_static_string, "hello"); + +/** + * @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 (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + DBusString str = _DBUS_STRING_INIT_INVALID; + DBusString other; + int i, a, end; + long v; + 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; + DBusRealString *real_test_static_string = (DBusRealString *) &test_static_string; + + _dbus_assert (real_test_static_string->str != NULL); + _dbus_assert (strcmp ((const char *) real_test_static_string->str, "hello") == 0); + _dbus_assert (real_test_static_string->len == 5); + _dbus_assert (real_test_static_string->allocated > 5); + _dbus_assert (real_test_static_string->constant); + _dbus_assert (real_test_static_string->locked); + _dbus_assert (real_test_static_string->valid); + _dbus_assert (real_test_static_string->align_offset == 0); + + /* Test that _DBUS_STRING_INIT_INVALID has the desired effect */ + _dbus_string_free (&str); + _dbus_string_free (&str); + _dbus_string_free (&str); + + /* Test shortening and setting length */ + i = 0; + while (i < _DBUS_N_ELEMENTS (lens)) + { + int j; + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("failed to init string"); + + if (!_dbus_string_set_length (&str, lens[i])) + _dbus_test_fatal ("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); + /* Test that a cleared string is effectively _DBUS_STRING_INIT_INVALID */ + _dbus_string_free (&str); + _dbus_string_free (&str); + + ++i; + } + + /* Test equality */ + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("oom"); + + if (!_dbus_string_append (&str, "Hello World")) + _dbus_test_fatal ("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_test_fatal ("failed to init string"); + + i = 0; + while (i < 10) + { + if (!_dbus_string_append (&str, "a")) + _dbus_test_fatal ("failed to append string to string"); + + _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1); + + if (!_dbus_string_append_byte (&str, 'b')) + _dbus_test_fatal ("failed to append byte to string"); + + _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2); + + ++i; + } + + _dbus_string_free (&str); + + /* Check steal_data */ + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("failed to init string"); + + if (!_dbus_string_append (&str, "Hello World")) + _dbus_test_fatal ("could not append to string"); + + i = _dbus_string_get_length (&str); + + if (!_dbus_string_steal_data (&str, &s)) + _dbus_test_fatal ("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_test_fatal ("could not append to string"); + + i = _dbus_string_get_length (&str); + + if (!_dbus_string_init (&other)) + _dbus_test_fatal ("could not init string"); + + if (!_dbus_string_move (&str, 0, &other, 0)) + _dbus_test_fatal ("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_test_fatal ("could not append to string"); + + if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other))) + _dbus_test_fatal ("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_test_fatal ("could not append to string"); + + if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2)) + _dbus_test_fatal ("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_test_fatal ("could not append to string"); + + i = _dbus_string_get_length (&str); + + if (!_dbus_string_init (&other)) + _dbus_test_fatal ("could not init string"); + + if (!_dbus_string_copy (&str, 0, &other, 0)) + _dbus_test_fatal ("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_test_fatal ("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_test_fatal ("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_test_fatal ("failed to init string"); + + if (!_dbus_string_append (&str, "Hello World")) + _dbus_test_fatal ("could not append to string"); + + i = _dbus_string_get_length (&str); + + if (!_dbus_string_init (&other)) + _dbus_test_fatal ("could not init string"); + + if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), + &other, 0, _dbus_string_get_length (&other))) + _dbus_test_fatal ("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_test_fatal ("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_test_fatal ("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); + + /* Different tests are provided because different behaviours are + * implemented in _dbus_string_replace_len() in function of replacing and + * replaced lengths + */ + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("failed to init string"); + + if (!_dbus_string_append (&str, "Hello World")) + _dbus_test_fatal ("could not append to string"); + + i = _dbus_string_get_length (&str); + + if (!_dbus_string_init (&other)) + _dbus_test_fatal ("could not init string"); + + if (!_dbus_string_append (&other, "Foo String")) + _dbus_test_fatal ("could not append to string"); + + a = _dbus_string_get_length (&other); + + if (!_dbus_string_replace_len (&str, 0, 6, + &other, 4, 0)) + _dbus_test_fatal ("could not replace 0 length"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == a + 6); + _dbus_assert (_dbus_string_equal_c_str (&other, + "Foo Hello String")); + + if (!_dbus_string_replace_len (&str, 5, 6, + &other, + _dbus_string_get_length (&other), + 0)) + _dbus_test_fatal ("could not replace at the end"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); + _dbus_assert (_dbus_string_equal_c_str (&other, + "Foo Hello String World")); + + if (!_dbus_string_replace_len (&str, 0, 5, + &other, + _dbus_string_get_length (&other) - 5, + 5)) + _dbus_test_fatal ("could not replace same length"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); + _dbus_assert (_dbus_string_equal_c_str (&other, + "Foo Hello String Hello")); + + if (!_dbus_string_replace_len (&str, 6, 5, + &other, 4, 12)) + _dbus_test_fatal ("could not replace with shorter string"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == a + 5); + _dbus_assert (_dbus_string_equal_c_str (&other, + "Foo World Hello")); + + if (!_dbus_string_replace_len (&str, 0, 1, + &other, 0, 3)) + _dbus_test_fatal ("could not replace at the beginning"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == a + 3); + _dbus_assert (_dbus_string_equal_c_str (&other, + "H World Hello")); + + if (!_dbus_string_replace_len (&str, 6, 5, + &other, + _dbus_string_get_length (&other) - 5, + 5)) + _dbus_test_fatal ("could not replace same length"); + + _dbus_assert (_dbus_string_get_length (&str) == i); + _dbus_assert (_dbus_string_get_length (&other) == a + 3); + _dbus_assert (_dbus_string_equal_c_str (&other, + "H World World")); + + _dbus_string_free (&str); + _dbus_string_free (&other); + + /* Check insert/set/get byte */ + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("failed to init string"); + + if (!_dbus_string_append (&str, "Hello")) + _dbus_test_fatal ("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_test_fatal ("can't insert byte"); + + if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z')) + _dbus_test_fatal ("can't insert byte"); + + if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W')) + _dbus_test_fatal ("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_test_fatal ("failed to init string"); + + if (!_dbus_string_append_int (&str, 27)) + _dbus_test_fatal ("failed to append int"); + + i = _dbus_string_get_length (&str); + + if (!_dbus_string_parse_int (&str, 0, &v, &end)) + _dbus_test_fatal ("failed to parse int"); + + _dbus_assert (v == 27); + _dbus_assert (end == i); + + _dbus_string_free (&str); + + /* Test find */ + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("failed to init string"); + + if (!_dbus_string_append (&str, "Hello")) + _dbus_test_fatal ("couldn't append to string"); + + if (!_dbus_string_find (&str, 0, "He", &i)) + _dbus_test_fatal ("didn't find 'He'"); + _dbus_assert (i == 0); + + if (!_dbus_string_find (&str, 0, "Hello", &i)) + _dbus_test_fatal ("didn't find 'Hello'"); + _dbus_assert (i == 0); + + if (!_dbus_string_find (&str, 0, "ello", &i)) + _dbus_test_fatal ("didn't find 'ello'"); + _dbus_assert (i == 1); + + if (!_dbus_string_find (&str, 0, "lo", &i)) + _dbus_test_fatal ("didn't find 'lo'"); + _dbus_assert (i == 3); + + if (!_dbus_string_find (&str, 2, "lo", &i)) + _dbus_test_fatal ("didn't find 'lo'"); + _dbus_assert (i == 3); + + if (_dbus_string_find (&str, 4, "lo", &i)) + _dbus_test_fatal ("did find 'lo'"); + + if (!_dbus_string_find (&str, 0, "l", &i)) + _dbus_test_fatal ("didn't find 'l'"); + _dbus_assert (i == 2); + + if (!_dbus_string_find (&str, 0, "H", &i)) + _dbus_test_fatal ("didn't find 'H'"); + _dbus_assert (i == 0); + + if (!_dbus_string_find (&str, 0, "", &i)) + _dbus_test_fatal ("didn't find ''"); + _dbus_assert (i == 0); + + if (_dbus_string_find (&str, 0, "Hello!", NULL)) + _dbus_test_fatal ("Did find 'Hello!'"); + + if (_dbus_string_find (&str, 0, "Oh, Hello", NULL)) + _dbus_test_fatal ("Did find 'Oh, Hello'"); + + if (_dbus_string_find (&str, 0, "ill", NULL)) + _dbus_test_fatal ("Did find 'ill'"); + + if (_dbus_string_find (&str, 0, "q", NULL)) + _dbus_test_fatal ("Did find 'q'"); + + if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) + _dbus_test_fatal ("Didn't find 'He'"); + + if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) + _dbus_test_fatal ("Did find 'Hello'"); + + if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) + _dbus_test_fatal ("Did not find 'H'"); + _dbus_assert (i == 0); + + if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) + _dbus_test_fatal ("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_test_fatal ("Did find 'o'"); + _dbus_assert (i == -1); + + if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) + _dbus_test_fatal ("Did find 'e'"); + _dbus_assert (i == -1); + + if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) + _dbus_test_fatal ("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_test_fatal ("could not init string"); + + if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0)) + _dbus_test_fatal ("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_test_fatal ("Did not find '\\r\\n'"); + if (found != 3 || found_len != 2) + _dbus_test_fatal ("invalid return values"); + + if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) + _dbus_test_fatal ("Did not find '\\n'"); + if (found != 8 || found_len != 1) + _dbus_test_fatal ("invalid return values"); + + if (_dbus_string_find_eol (&str, 9, &found, &found_len)) + _dbus_test_fatal ("Found not expected '\\n'"); + else if (found != 11 || found_len != 0) + _dbus_test_fatal ("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_test_fatal ("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_test_fatal ("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_test_fatal ("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_test_fatal ("no memory"); + + if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_init (&line)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_test_fatal ("failed to pop first line"); + + _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_test_fatal ("failed to pop second line"); + + _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_test_fatal ("failed to pop third line"); + + _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); + + if (!_dbus_string_pop_line (&str, &line)) + _dbus_test_fatal ("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_test_fatal ("no memory"); + + for (i = 0; i < 10000; i++) + if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz")) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_set_length (&str, 10)) + _dbus_test_fatal ("failed to set length"); + + /* actually compact */ + if (!_dbus_string_compact (&str, 2048)) + _dbus_test_fatal ("failed to compact after set_length"); + + /* peek inside to make sure it worked */ + if (((DBusRealString *)&str)->allocated > 30) + _dbus_test_fatal ("compacting string didn't do anything"); + + if (!_dbus_string_equal_c_str (&str, "abcdefghij")) + _dbus_test_fatal ("unexpected content after compact"); + + /* compact nothing */ + if (!_dbus_string_compact (&str, 2048)) + _dbus_test_fatal ("failed to compact 2nd time"); + + if (!_dbus_string_equal_c_str (&str, "abcdefghij")) + _dbus_test_fatal ("unexpected content after 2nd compact"); + + /* and make sure it still works...*/ + if (!_dbus_string_append (&str, "123456")) + _dbus_test_fatal ("failed to append after compact"); + + if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) + _dbus_test_fatal ("unexpected content after append"); + + /* after growing automatically, this should do nothing */ + if (!_dbus_string_compact (&str, 20000)) + _dbus_test_fatal ("failed to compact after grow"); + + /* but this one will do something */ + if (!_dbus_string_compact (&str, 0)) + _dbus_test_fatal ("failed to compact after grow"); + + if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) + _dbus_test_fatal ("unexpected content"); + + if (!_dbus_string_append (&str, "!@#$%")) + _dbus_test_fatal ("failed to append after compact"); + + if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%")) + _dbus_test_fatal ("unexpected content"); + + _dbus_string_free (&str); + } + + { + const char two_strings[] = "one\ttwo"; + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_init (&other)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_append (&str, two_strings)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_split_on_byte (&str, '\t', &other)) + _dbus_test_fatal ("no memory or delimiter not found"); + + if (strcmp (_dbus_string_get_data (&str), "one") != 0) + _dbus_test_fatal ("left side after split on tab is wrong"); + + if (strcmp (_dbus_string_get_data (&other), "two") != 0) + _dbus_test_fatal ("right side after split on tab is wrong"); + + _dbus_string_free (&str); + _dbus_string_free (&other); + } + + { + const char upper_string[] = "TOUPPERSTRING"; + const char lower_string[] = "toupperstring"; + const char lower2_string[] = "toupperSTRING"; + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_append (&str, upper_string)) + _dbus_test_fatal ("no memory"); + + _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str)); + + if (!_dbus_string_equal_c_str (&str, lower_string)) + _dbus_test_fatal ("_dbus_string_tolower_ascii failed"); + + _dbus_string_free (&str); + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_append (&str, upper_string)) + _dbus_test_fatal ("no memory"); + + _dbus_string_tolower_ascii (&str, 0, 7); + + if (!_dbus_string_equal_c_str (&str, lower2_string)) + _dbus_test_fatal ("_dbus_string_tolower_ascii failed in partial conversion"); + + _dbus_string_free (&str); + } + + { + const char lower_string[] = "toupperstring"; + const char upper_string[] = "TOUPPERSTRING"; + const char upper2_string[] = "TOUPPERstring"; + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_append (&str, lower_string)) + _dbus_test_fatal ("no memory"); + + _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str)); + + if (!_dbus_string_equal_c_str (&str, upper_string)) + _dbus_test_fatal ("_dbus_string_toupper_ascii failed"); + + _dbus_string_free (&str); + + if (!_dbus_string_init (&str)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_append (&str, lower_string)) + _dbus_test_fatal ("no memory"); + + _dbus_string_toupper_ascii (&str, 0, 7); + + if (!_dbus_string_equal_c_str (&str, upper2_string)) + _dbus_test_fatal ("_dbus_string_toupper_ascii failed in partial conversion"); + + _dbus_string_free (&str); + } + + return TRUE; +} + +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/test/internals/dbus-sysdeps-util.c b/test/internals/dbus-sysdeps-util.c new file mode 100644 index 00000000..7e2dc064 --- /dev/null +++ b/test/internals/dbus-sysdeps-util.c @@ -0,0 +1,156 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-sysdeps-util.c Tests for dbus-sysdeps.h API + * + * Copyright 2002-2008 Red Hat, Inc. + * Copyright 2003 CodeFactory AB + * Copyright 2006 Ralf Habacker + * Copyright 2006 Sjoerd Simons + * Copyright 2016-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "misc-internals.h" + +#include "dbus/dbus-sysdeps.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-string.h" +#include "dbus/dbus-test.h" +#include + +#include + +#ifdef DBUS_ENABLE_EMBEDDED_TESTS +static void +check_dirname (const char *filename, + const char *dirname) +{ + DBusString f, d; + + _dbus_string_init_const (&f, filename); + + if (!_dbus_string_init (&d)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_get_dirname (&f, &d)) + _dbus_test_fatal ("no memory"); + + if (!_dbus_string_equal_c_str (&d, dirname)) + { + _dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"", + filename, + _dbus_string_get_const_data (&d), + dirname); + exit (1); + } + + _dbus_string_free (&d); +} + +static void +check_path_absolute (const char *path, + dbus_bool_t expected) +{ + DBusString p; + + _dbus_string_init_const (&p, path); + + if (_dbus_path_is_absolute (&p) != expected) + { + _dbus_warn ("For path \"%s\" expected absolute = %d got %d", + path, expected, _dbus_path_is_absolute (&p)); + exit (1); + } +} + +/** + * Unit test for dbus-sysdeps.c. + * + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_sysdeps_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ +#ifdef DBUS_WIN + check_dirname ("foo\\bar", "foo"); + check_dirname ("foo\\\\bar", "foo"); + check_dirname ("foo/\\/bar", "foo"); + check_dirname ("foo\\bar/", "foo"); + check_dirname ("foo//bar\\", "foo"); + check_dirname ("foo\\bar/", "foo"); + check_dirname ("foo/bar\\\\", "foo"); + check_dirname ("\\foo", "\\"); + check_dirname ("\\\\foo", "\\"); + check_dirname ("\\", "\\"); + check_dirname ("\\\\", "\\"); + check_dirname ("\\/", "\\"); + check_dirname ("/\\/", "/"); + check_dirname ("c:\\foo\\bar", "c:\\foo"); + check_dirname ("c:\\foo", "c:\\"); + check_dirname ("c:/foo", "c:/"); + check_dirname ("c:\\", "c:\\"); + check_dirname ("c:/", "c:/"); + check_dirname ("", "."); +#else + check_dirname ("foo", "."); + check_dirname ("foo/bar", "foo"); + check_dirname ("foo//bar", "foo"); + check_dirname ("foo///bar", "foo"); + check_dirname ("foo/bar/", "foo"); + check_dirname ("foo//bar/", "foo"); + check_dirname ("foo///bar/", "foo"); + check_dirname ("foo/bar//", "foo"); + check_dirname ("foo//bar////", "foo"); + check_dirname ("foo///bar///////", "foo"); + check_dirname ("/foo", "/"); + check_dirname ("////foo", "/"); + check_dirname ("/foo/bar", "/foo"); + check_dirname ("/foo//bar", "/foo"); + check_dirname ("/foo///bar", "/foo"); + check_dirname ("/", "/"); + check_dirname ("///", "/"); + check_dirname ("", "."); +#endif + +#ifdef DBUS_WIN + check_path_absolute ("c:/", TRUE); + check_path_absolute ("c:/foo", TRUE); + check_path_absolute ("", FALSE); + check_path_absolute ("foo", FALSE); + check_path_absolute ("foo/bar", FALSE); + check_path_absolute ("", FALSE); + check_path_absolute ("foo\\bar", FALSE); + check_path_absolute ("c:\\", TRUE); + check_path_absolute ("c:\\foo", TRUE); + check_path_absolute ("c:", TRUE); + check_path_absolute ("c:\\foo\\bar", TRUE); + check_path_absolute ("\\", TRUE); + check_path_absolute ("/", TRUE); +#else + check_path_absolute ("/", TRUE); + check_path_absolute ("/foo", TRUE); + check_path_absolute ("", FALSE); + check_path_absolute ("foo", FALSE); + check_path_absolute ("foo/bar", FALSE); +#endif + + return TRUE; +} +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ diff --git a/test/internals/hash.c b/test/internals/hash.c new file mode 100644 index 00000000..314c65f0 --- /dev/null +++ b/test/internals/hash.c @@ -0,0 +1,525 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 1991-1993 The Regents of the University of California + * Copyright 1994 Sun Microsystems, Inc. + * Copyright 2002-2009 Red Hat, Inc. + * Copyright 2003 Joe Shaw + * Copyright 2011-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The following license applies to code from the Tcl distribution, + * if there is any in this file: + * + * Copyright (c) 1991-1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * This software is copyrighted by the Regents of the University of + * California, Sun Microsystems, Inc., Scriptics Corporation, and + * other parties. The following terms apply to all files associated + * with the software unless explicitly disclaimed in individual files. + * + * The authors hereby grant permission to use, copy, modify, + * distribute, and license this software and its documentation for any + * purpose, provided that existing copyright notices are retained in + * all copies and that this notice is included verbatim in any + * distributions. No written agreement, license, or royalty fee is + * required for any of the authorized uses. Modifications to this + * software may be copyrighted by their authors and need not follow + * the licensing terms described here, provided that the new terms are + * clearly indicated on the first page of each file where they apply. + * + * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL + * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, + * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND + * NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, + * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE + * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf of the + * U.S. government, the Government shall have only "Restricted Rights" + * in the software and related documentation as defined in the Federal + * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you + * are acquiring the software on behalf of the Department of Defense, + * the software shall be classified as "Commercial Computer Software" + * and the Government shall have only "Restricted Rights" as defined + * in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the + * foregoing, the authors grant the U.S. Government and others acting + * in its behalf permission to use and distribute the software in + * accordance with the terms specified in this license. + */ + +#include + +#include + +#include "dbus/dbus-hash.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-test.h" +#include "dbus/dbus-test-tap.h" +#include "test/test-utils.h" + +/* If you're wondering why the hash table test takes + * forever to run, it's because we call this function + * in inner loops thus making things quadratic. + */ +static int +count_entries (DBusHashTable *table) +{ + DBusHashIter iter; + int count; + + count = 0; + _dbus_hash_iter_init (table, &iter); + while (_dbus_hash_iter_next (&iter)) + ++count; + + _dbus_assert (count == _dbus_hash_table_get_n_entries (table)); + + return count; +} + +static inline void * +steal (void *ptr) +{ + /* @ptr is passed in as void* to avoid casting in the call */ + void **_ptr = (void **) ptr; + void *val; + + val = *_ptr; + *_ptr = NULL; + + return val; +} + +/** + * @ingroup DBusHashTableInternals + * Unit test for DBusHashTable + * @returns #TRUE on success. + */ +static dbus_bool_t +_dbus_hash_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + int i; + DBusHashTable *table1; + DBusHashTable *table2; + DBusHashTable *table3; + DBusHashIter iter; +#define N_HASH_KEYS 5000 + char **keys; + dbus_bool_t ret = FALSE; + char *str_key = NULL; + char *str_value = NULL; + + keys = dbus_new (char *, N_HASH_KEYS); + if (keys == NULL) + _dbus_test_fatal ("no memory"); + + for (i = 0; i < N_HASH_KEYS; i++) + { + keys[i] = dbus_malloc (128); + + if (keys[i] == NULL) + _dbus_test_fatal ("no memory"); + } + + _dbus_test_diag ("Computing test hash keys..."); + i = 0; + while (i < N_HASH_KEYS) + { + int len; + + len = sprintf (keys[i], "Hash key %d", i); + _dbus_assert (*(keys[i] + len) == '\0'); + ++i; + } + _dbus_test_diag ("... done."); + + table1 = _dbus_hash_table_new (DBUS_HASH_STRING, + dbus_free, dbus_free); + if (table1 == NULL) + goto out; + + table2 = _dbus_hash_table_new (DBUS_HASH_INT, + NULL, dbus_free); + if (table2 == NULL) + goto out; + + table3 = _dbus_hash_table_new (DBUS_HASH_UINTPTR, + NULL, dbus_free); + if (table3 == NULL) + goto out; + + /* Insert and remove a bunch of stuff, counting the table in between + * to be sure it's not broken and that iteration works + */ + i = 0; + while (i < 3000) + { + const void *out_value; + + str_key = _dbus_strdup (keys[i]); + if (str_key == NULL) + goto out; + str_value = _dbus_strdup ("Value!"); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_table_insert_string (table1, + steal (&str_key), + steal (&str_value))) + goto out; + + str_value = _dbus_strdup (keys[i]); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_table_insert_int (table2, + i, steal (&str_value))) + goto out; + + str_value = _dbus_strdup (keys[i]); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_table_insert_uintptr (table3, + i, steal (&str_value))) + goto out; + + _dbus_assert (count_entries (table1) == i + 1); + _dbus_assert (count_entries (table2) == i + 1); + _dbus_assert (count_entries (table3) == i + 1); + + out_value = _dbus_hash_table_lookup_string (table1, keys[i]); + _dbus_assert (out_value != NULL); + _dbus_assert (strcmp (out_value, "Value!") == 0); + + out_value = _dbus_hash_table_lookup_int (table2, i); + _dbus_assert (out_value != NULL); + _dbus_assert (strcmp (out_value, keys[i]) == 0); + + out_value = _dbus_hash_table_lookup_uintptr (table3, i); + _dbus_assert (out_value != NULL); + _dbus_assert (strcmp (out_value, keys[i]) == 0); + + ++i; + } + + --i; + while (i >= 0) + { + _dbus_hash_table_remove_string (table1, + keys[i]); + + _dbus_hash_table_remove_int (table2, i); + + _dbus_hash_table_remove_uintptr (table3, i); + + _dbus_assert (count_entries (table1) == i); + _dbus_assert (count_entries (table2) == i); + _dbus_assert (count_entries (table3) == i); + + --i; + } + + _dbus_hash_table_ref (table1); + _dbus_hash_table_ref (table2); + _dbus_hash_table_ref (table3); + _dbus_hash_table_unref (table1); + _dbus_hash_table_unref (table2); + _dbus_hash_table_unref (table3); + _dbus_hash_table_unref (table1); + _dbus_hash_table_unref (table2); + _dbus_hash_table_unref (table3); + table3 = NULL; + + /* Insert a bunch of stuff then check + * that iteration works correctly (finds the right + * values, iter_set_value works, etc.) + */ + table1 = _dbus_hash_table_new (DBUS_HASH_STRING, + dbus_free, dbus_free); + if (table1 == NULL) + goto out; + + table2 = _dbus_hash_table_new (DBUS_HASH_INT, + NULL, dbus_free); + if (table2 == NULL) + goto out; + + i = 0; + while (i < 5000) + { + str_key = _dbus_strdup (keys[i]); + if (str_key == NULL) + goto out; + str_value = _dbus_strdup ("Value!"); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_table_insert_string (table1, + steal (&str_key), + steal (&str_value))) + goto out; + + str_value = _dbus_strdup (keys[i]); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_table_insert_int (table2, + i, steal (&str_value))) + goto out; + + _dbus_assert (count_entries (table1) == i + 1); + _dbus_assert (count_entries (table2) == i + 1); + + ++i; + } + + _dbus_hash_iter_init (table1, &iter); + while (_dbus_hash_iter_next (&iter)) + { + const char *key; + const void *value; + + key = _dbus_hash_iter_get_string_key (&iter); + value = _dbus_hash_iter_get_value (&iter); + + _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value); + + str_value = _dbus_strdup ("Different value!"); + if (str_value == NULL) + goto out; + + value = str_value; + _dbus_hash_iter_set_value (&iter, steal (&str_value)); + _dbus_assert (_dbus_hash_table_lookup_string (table1, key) == value); + } + + _dbus_hash_iter_init (table1, &iter); + while (_dbus_hash_iter_next (&iter)) + { + _dbus_hash_iter_remove_entry (&iter); + _dbus_assert (count_entries (table1) == i - 1); + --i; + } + + _dbus_hash_iter_init (table2, &iter); + while (_dbus_hash_iter_next (&iter)) + { + int key; + const void *value; + + key = _dbus_hash_iter_get_int_key (&iter); + value = _dbus_hash_iter_get_value (&iter); + + _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value); + + str_value = _dbus_strdup ("Different value!"); + if (str_value == NULL) + goto out; + + value = str_value; + _dbus_hash_iter_set_value (&iter, steal (&str_value)); + _dbus_assert (_dbus_hash_table_lookup_int (table2, key) == value); + } + + i = count_entries (table2); + _dbus_hash_iter_init (table2, &iter); + while (_dbus_hash_iter_next (&iter)) + { + _dbus_hash_iter_remove_entry (&iter); + _dbus_assert (count_entries (table2) + 1 == i); + --i; + } + + /* add/remove interleaved, to check that we grow/shrink the table + * appropriately + */ + i = 0; + while (i < 1000) + { + str_key = _dbus_strdup (keys[i]); + if (str_key == NULL) + goto out; + + str_value = _dbus_strdup ("Value!"); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_table_insert_string (table1, + steal (&str_key), + steal (&str_value))) + goto out; + + ++i; + } + + --i; + while (i >= 0) + { + str_key = _dbus_strdup (keys[i]); + if (str_key == NULL) + goto out; + str_value = _dbus_strdup ("Value!"); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_table_remove_string (table1, keys[i])) + goto out; + + if (!_dbus_hash_table_insert_string (table1, + steal (&str_key), + steal (&str_value))) + goto out; + + if (!_dbus_hash_table_remove_string (table1, keys[i])) + goto out; + + _dbus_assert (_dbus_hash_table_get_n_entries (table1) == i); + + --i; + } + + /* nuke these tables */ + _dbus_hash_table_unref (table1); + _dbus_hash_table_unref (table2); + + + /* Now do a bunch of things again using _dbus_hash_iter_lookup() to + * be sure that interface works. + */ + table1 = _dbus_hash_table_new (DBUS_HASH_STRING, + dbus_free, dbus_free); + if (table1 == NULL) + goto out; + + table2 = _dbus_hash_table_new (DBUS_HASH_INT, + NULL, dbus_free); + if (table2 == NULL) + goto out; + + i = 0; + while (i < 3000) + { + const void *out_value; + + str_key = _dbus_strdup (keys[i]); + if (str_key == NULL) + goto out; + str_value = _dbus_strdup ("Value!"); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_iter_lookup (table1, + steal (&str_key), TRUE, &iter)) + goto out; + _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); + _dbus_hash_iter_set_value (&iter, steal (&str_value)); + + str_value = _dbus_strdup (keys[i]); + if (str_value == NULL) + goto out; + + if (!_dbus_hash_iter_lookup (table2, + _DBUS_INT_TO_POINTER (i), TRUE, &iter)) + goto out; + _dbus_assert (_dbus_hash_iter_get_value (&iter) == NULL); + _dbus_hash_iter_set_value (&iter, steal (&str_value)); + + _dbus_assert (count_entries (table1) == i + 1); + _dbus_assert (count_entries (table2) == i + 1); + + if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter)) + goto out; + + out_value = _dbus_hash_iter_get_value (&iter); + _dbus_assert (out_value != NULL); + _dbus_assert (strcmp (out_value, "Value!") == 0); + + /* Iterate just to be sure it works, though + * it's a stupid thing to do + */ + while (_dbus_hash_iter_next (&iter)) + ; + + if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter)) + goto out; + + out_value = _dbus_hash_iter_get_value (&iter); + _dbus_assert (out_value != NULL); + _dbus_assert (strcmp (out_value, keys[i]) == 0); + + /* Iterate just to be sure it works, though + * it's a stupid thing to do + */ + while (_dbus_hash_iter_next (&iter)) + ; + + ++i; + } + + --i; + while (i >= 0) + { + if (!_dbus_hash_iter_lookup (table1, keys[i], FALSE, &iter)) + _dbus_test_fatal ("hash entry should have existed"); + _dbus_hash_iter_remove_entry (&iter); + + if (!_dbus_hash_iter_lookup (table2, _DBUS_INT_TO_POINTER (i), FALSE, &iter)) + _dbus_test_fatal ("hash entry should have existed"); + _dbus_hash_iter_remove_entry (&iter); + + _dbus_assert (count_entries (table1) == i); + _dbus_assert (count_entries (table2) == i); + + --i; + } + + _dbus_hash_table_unref (table1); + _dbus_hash_table_unref (table2); + + ret = TRUE; + + out: + for (i = 0; i < N_HASH_KEYS; i++) + dbus_free (keys[i]); + + dbus_free (keys); + + dbus_free (str_key); + dbus_free (str_value); + + return ret; +} + +static DBusTestCase test = { "hash", _dbus_hash_test }; + +int +main (int argc, + char **argv) +{ + return _dbus_test_main (argc, argv, 1, &test, + DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS, + NULL, NULL); +} diff --git a/test/internals/marshal-recursive.c b/test/internals/marshal-recursive.c new file mode 100644 index 00000000..5866657a --- /dev/null +++ b/test/internals/marshal-recursive.c @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2002-2009 Red Hat, Inc. + * Copyright 2011-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "dbus/dbus-internals.h" +#include "dbus/dbus-test.h" +#include "test/test-utils.h" + +#include "dbus-marshal-recursive-util.h" + +static DBusTestCase test = { "marshal-recursive", _dbus_marshal_recursive_test }; + +int +main (int argc, + char **argv) +{ + return _dbus_test_main (argc, argv, 1, &test, + DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS, + NULL, NULL); +} diff --git a/test/internals/message-internals.c b/test/internals/message-internals.c new file mode 100644 index 00000000..547947ae --- /dev/null +++ b/test/internals/message-internals.c @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2002-2009 Red Hat, Inc. + * Copyright 2011-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "dbus/dbus-internals.h" +#include "dbus/dbus-test.h" +#include "test/test-utils.h" + +#include "dbus-message-util.h" + +static DBusTestCase test = { "message", _dbus_message_test }; + +int +main (int argc, + char **argv) +{ + return _dbus_test_main (argc, argv, 1, &test, + DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS, + NULL, NULL); +} diff --git a/test/internals/misc-internals.c b/test/internals/misc-internals.c new file mode 100644 index 00000000..7661853f --- /dev/null +++ b/test/internals/misc-internals.c @@ -0,0 +1,955 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2002-2011 Red Hat, Inc. + * Copyright 2006 Julio M. Merino Vidal + * Copyright 2006 Ralf Habacker + * Copyright 2011-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include +#include "dbus/dbus-connection-internal.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-test.h" +#include "dbus/dbus-test-tap.h" +#include "test/test-utils.h" + +#include "misc-internals.h" + +static void +verify_list (DBusList **list) +{ + DBusList *link; + int length; + + link = *list; + + if (link == NULL) + return; + + if (link->next == link) + { + _dbus_assert (link->prev == link); + _dbus_assert (*list == link); + return; + } + + length = 0; + do + { + length += 1; + _dbus_assert (link->prev->next == link); + _dbus_assert (link->next->prev == link); + link = link->next; + } + while (link != *list); + + _dbus_assert (length == _dbus_list_get_length (list)); + + if (length == 1) + _dbus_assert (_dbus_list_length_is_one (list)); + else + _dbus_assert (!_dbus_list_length_is_one (list)); +} + +static dbus_bool_t +is_ascending_sequence (DBusList **list) +{ + DBusList *link; + int prev; + + prev = _DBUS_INT_MIN; + + link = _dbus_list_get_first_link (list); + while (link != NULL) + { + int v = _DBUS_POINTER_TO_INT (link->data); + + if (v <= prev) + return FALSE; + + prev = v; + + link = _dbus_list_get_next_link (list, link); + } + + return TRUE; +} + +static dbus_bool_t +is_descending_sequence (DBusList **list) +{ + DBusList *link; + int prev; + + prev = _DBUS_INT_MAX; + + link = _dbus_list_get_first_link (list); + while (link != NULL) + { + int v = _DBUS_POINTER_TO_INT (link->data); + + if (v >= prev) + return FALSE; + + prev = v; + + link = _dbus_list_get_next_link (list, link); + } + + return TRUE; +} + +static dbus_bool_t +all_even_values (DBusList **list) +{ + DBusList *link; + + link = _dbus_list_get_first_link (list); + while (link != NULL) + { + int v = _DBUS_POINTER_TO_INT (link->data); + + if ((v % 2) != 0) + return FALSE; + + link = _dbus_list_get_next_link (list, link); + } + + return TRUE; +} + +static dbus_bool_t +all_odd_values (DBusList **list) +{ + DBusList *link; + + link = _dbus_list_get_first_link (list); + while (link != NULL) + { + int v = _DBUS_POINTER_TO_INT (link->data); + + if ((v % 2) == 0) + return FALSE; + + link = _dbus_list_get_next_link (list, link); + } + + return TRUE; +} + +static dbus_bool_t +lists_equal (DBusList **list1, + DBusList **list2) +{ + DBusList *link1; + DBusList *link2; + + link1 = _dbus_list_get_first_link (list1); + link2 = _dbus_list_get_first_link (list2); + while (link1 && link2) + { + if (link1->data != link2->data) + return FALSE; + + link1 = _dbus_list_get_next_link (list1, link1); + link2 = _dbus_list_get_next_link (list2, link2); + } + + if (link1 || link2) + return FALSE; + + return TRUE; +} + +/** + * @ingroup DBusListInternals + * Unit test for DBusList + * @returns #TRUE on success. + */ +static dbus_bool_t +_dbus_list_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + DBusList *list1; + DBusList *list2; + DBusList *link1; + DBusList *link2; + DBusList *copy1; + DBusList *copy2; + int i; + + list1 = NULL; + list2 = NULL; + + /* Test append and prepend */ + + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("count not allocate for prepend"); + ++i; + + verify_list (&list1); + verify_list (&list2); + + _dbus_assert (_dbus_list_get_length (&list1) == i); + _dbus_assert (_dbus_list_get_length (&list2) == i); + } + + _dbus_assert (is_ascending_sequence (&list1)); + _dbus_assert (is_descending_sequence (&list2)); + + /* Test list clear */ + _dbus_list_clear (&list1); + _dbus_list_clear (&list2); + + verify_list (&list1); + verify_list (&list2); + + /* Test get_first, get_last, pop_first, pop_last */ + + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for prepend"); + ++i; + } + + --i; + while (i >= 0) + { + void *got_data1; + void *got_data2; + + void *data1; + void *data2; + + got_data1 = _dbus_list_get_last (&list1); + got_data2 = _dbus_list_get_first (&list2); + + data1 = _dbus_list_pop_last (&list1); + data2 = _dbus_list_pop_first (&list2); + + _dbus_assert (got_data1 == data1); + _dbus_assert (got_data2 == data2); + + _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); + _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); + + verify_list (&list1); + verify_list (&list2); + + _dbus_assert (is_ascending_sequence (&list1)); + _dbus_assert (is_descending_sequence (&list2)); + + --i; + } + + _dbus_assert (list1 == NULL); + _dbus_assert (list2 == NULL); + + /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */ + + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for prepend"); + ++i; + } + + --i; + while (i >= 0) + { + DBusList *got_link1; + DBusList *got_link2; + + void *data1_indirect; + void *data1; + void *data2; + + got_link1 = _dbus_list_get_last_link (&list1); + got_link2 = _dbus_list_get_first_link (&list2); + + link2 = _dbus_list_pop_first_link (&list2); + + _dbus_assert (got_link2 == link2); + + data1_indirect = got_link1->data; + /* this call makes got_link1 invalid */ + data1 = _dbus_list_pop_last (&list1); + _dbus_assert (data1 == data1_indirect); + data2 = link2->data; + + _dbus_list_free_link (link2); + + _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); + _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); + + verify_list (&list1); + verify_list (&list2); + + _dbus_assert (is_ascending_sequence (&list1)); + _dbus_assert (is_descending_sequence (&list2)); + + --i; + } + + _dbus_assert (list1 == NULL); + _dbus_assert (list2 == NULL); + + /* Test iteration */ + + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for prepend"); + ++i; + + verify_list (&list1); + verify_list (&list2); + + _dbus_assert (_dbus_list_get_length (&list1) == i); + _dbus_assert (_dbus_list_get_length (&list2) == i); + } + + _dbus_assert (is_ascending_sequence (&list1)); + _dbus_assert (is_descending_sequence (&list2)); + + --i; + link2 = _dbus_list_get_first_link (&list2); + while (link2 != NULL) + { + verify_list (&link2); /* pretend this link is the head */ + + _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); + + link2 = _dbus_list_get_next_link (&list2, link2); + --i; + } + + i = 0; + link1 = _dbus_list_get_first_link (&list1); + while (link1 != NULL) + { + verify_list (&link1); /* pretend this link is the head */ + + _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); + + link1 = _dbus_list_get_next_link (&list1, link1); + ++i; + } + + --i; + link1 = _dbus_list_get_last_link (&list1); + while (link1 != NULL) + { + verify_list (&link1); /* pretend this link is the head */ + + _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); + + link1 = _dbus_list_get_prev_link (&list1, link1); + --i; + } + + _dbus_list_clear (&list1); + _dbus_list_clear (&list2); + + /* Test remove */ + + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for prepend"); + ++i; + } + + --i; + while (i >= 0) + { + if ((i % 2) == 0) + { + if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("element should have been in list"); + if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("element should have been in list"); + + verify_list (&list1); + verify_list (&list2); + } + --i; + } + + _dbus_assert (all_odd_values (&list1)); + _dbus_assert (all_odd_values (&list2)); + + _dbus_list_clear (&list1); + _dbus_list_clear (&list2); + + /* test removing the other half of the elements */ + + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for prepend"); + ++i; + } + + --i; + while (i >= 0) + { + if ((i % 2) != 0) + { + if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("element should have been in list"); + if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("element should have been in list"); + + verify_list (&list1); + verify_list (&list2); + } + --i; + } + + _dbus_assert (all_even_values (&list1)); + _dbus_assert (all_even_values (&list2)); + + /* clear list using remove_link */ + while (list1 != NULL) + { + _dbus_list_remove_link (&list1, list1); + verify_list (&list1); + } + while (list2 != NULL) + { + _dbus_list_remove_link (&list2, list2); + verify_list (&list2); + } + + /* Test remove link more generally */ + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for prepend"); + ++i; + } + + --i; + link2 = _dbus_list_get_first_link (&list2); + while (link2 != NULL) + { + DBusList *next = _dbus_list_get_next_link (&list2, link2); + + _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); + + if ((i % 2) == 0) + _dbus_list_remove_link (&list2, link2); + + verify_list (&list2); + + link2 = next; + --i; + } + + _dbus_assert (all_odd_values (&list2)); + _dbus_list_clear (&list2); + + i = 0; + link1 = _dbus_list_get_first_link (&list1); + while (link1 != NULL) + { + DBusList *next = _dbus_list_get_next_link (&list1, link1); + + _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); + + if ((i % 2) != 0) + _dbus_list_remove_link (&list1, link1); + + verify_list (&list1); + + link1 = next; + ++i; + } + + _dbus_assert (all_even_values (&list1)); + _dbus_list_clear (&list1); + + /* Test copying a list */ + i = 0; + while (i < 10) + { + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) + _dbus_test_fatal ("could not allocate for prepend"); + ++i; + } + + /* bad pointers, because they are allowed in the copy dest */ + copy1 = _DBUS_INT_TO_POINTER (0x342234); + copy2 = _DBUS_INT_TO_POINTER (23); + + _dbus_list_copy (&list1, ©1); + verify_list (&list1); + verify_list (©1); + _dbus_assert (lists_equal (&list1, ©1)); + + _dbus_list_copy (&list2, ©2); + verify_list (&list2); + verify_list (©2); + _dbus_assert (lists_equal (&list2, ©2)); + + /* Now test copying empty lists */ + _dbus_list_clear (&list1); + _dbus_list_clear (&list2); + _dbus_list_clear (©1); + _dbus_list_clear (©2); + + /* bad pointers, because they are allowed in the copy dest */ + copy1 = _DBUS_INT_TO_POINTER (0x342234); + copy2 = _DBUS_INT_TO_POINTER (23); + + _dbus_list_copy (&list1, ©1); + verify_list (&list1); + verify_list (©1); + _dbus_assert (lists_equal (&list1, ©1)); + + _dbus_list_copy (&list2, ©2); + verify_list (&list2); + verify_list (©2); + _dbus_assert (lists_equal (&list2, ©2)); + + _dbus_list_clear (&list1); + _dbus_list_clear (&list2); + + /* insert_after on empty list */ + _dbus_list_insert_after (&list1, NULL, + _DBUS_INT_TO_POINTER (0)); + verify_list (&list1); + + /* inserting after first element */ + _dbus_list_insert_after (&list1, list1, + _DBUS_INT_TO_POINTER (1)); + verify_list (&list1); + _dbus_assert (is_ascending_sequence (&list1)); + + /* inserting at the end */ + _dbus_list_insert_after (&list1, list1->next, + _DBUS_INT_TO_POINTER (2)); + verify_list (&list1); + _dbus_assert (is_ascending_sequence (&list1)); + + /* using insert_after to prepend */ + _dbus_list_insert_after (&list1, NULL, + _DBUS_INT_TO_POINTER (-1)); + verify_list (&list1); + _dbus_assert (is_ascending_sequence (&list1)); + + _dbus_list_clear (&list1); + + /* using remove_last */ + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1))) + _dbus_test_fatal ("could not allocate for append"); + if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3))) + _dbus_test_fatal ("could not allocate for append"); + + _dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2)); + + verify_list (&list1); + _dbus_assert (is_ascending_sequence (&list1)); + + _dbus_list_clear (&list1); + + return TRUE; +} + +static dbus_bool_t +_dbus_misc_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + 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_test_fatal ("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_test_fatal ("no memory"); + + _dbus_assert (_dbus_string_equal_c_str (&str, DBUS_VERSION_STRING)); + + _dbus_string_free (&str); + + return TRUE; +} + +static dbus_bool_t +_dbus_server_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + const char *valid_addresses[] = { + "tcp:port=1234", + "tcp:host=localhost,port=1234", + "tcp:host=localhost,port=1234;tcp:port=5678", +#ifdef DBUS_UNIX + "unix:path=./boogie", + "tcp:port=1234;unix:path=./boogie", +#endif + }; + + DBusServer *server; + int i; + + for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++) + { + DBusError error = DBUS_ERROR_INIT; + char *address; + char *id; + + server = dbus_server_listen (valid_addresses[i], &error); + if (server == NULL) + { + _dbus_warn ("server listen error: %s: %s", error.name, error.message); + dbus_error_free (&error); + _dbus_assert_not_reached ("Failed to listen for valid address."); + } + + id = dbus_server_get_id (server); + _dbus_assert (id != NULL); + address = dbus_server_get_address (server); + _dbus_assert (address != NULL); + + if (strstr (address, id) == NULL) + { + _dbus_warn ("server id '%s' is not in the server address '%s'", + id, address); + _dbus_assert_not_reached ("bad server id or address"); + } + + dbus_free (id); + dbus_free (address); + + dbus_server_disconnect (server); + dbus_server_unref (server); + } + + return TRUE; +} + +/** + * @ingroup DBusSignatureInternals + * Unit test for DBusSignature. + * + * @returns #TRUE on success. + */ +static dbus_bool_t +_dbus_signature_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + DBusSignatureIter iter; + DBusSignatureIter subiter; + DBusSignatureIter subsubiter; + DBusSignatureIter subsubsubiter; + const char *sig; + dbus_bool_t boolres; + + sig = ""; + _dbus_assert (dbus_signature_validate (sig, NULL)); + _dbus_assert (!dbus_signature_validate_single (sig, NULL)); + dbus_signature_iter_init (&iter, sig); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID); + + sig = DBUS_TYPE_STRING_AS_STRING; + _dbus_assert (dbus_signature_validate (sig, NULL)); + _dbus_assert (dbus_signature_validate_single (sig, NULL)); + dbus_signature_iter_init (&iter, sig); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); + + sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING; + _dbus_assert (dbus_signature_validate (sig, NULL)); + dbus_signature_iter_init (&iter, sig); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); + boolres = dbus_signature_iter_next (&iter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE); + + sig = DBUS_TYPE_UINT16_AS_STRING + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_UINT32_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_TYPE_DOUBLE_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING; + _dbus_assert (dbus_signature_validate (sig, NULL)); + dbus_signature_iter_init (&iter, sig); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); + boolres = dbus_signature_iter_next (&iter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); + dbus_signature_iter_recurse (&iter, &subiter); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING); + boolres = dbus_signature_iter_next (&subiter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); + boolres = dbus_signature_iter_next (&subiter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT); + boolres = dbus_signature_iter_next (&subiter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE); + + sig = DBUS_TYPE_UINT16_AS_STRING + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_UINT32_AS_STRING + DBUS_TYPE_BYTE_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_DOUBLE_AS_STRING + DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_BYTE_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING; + _dbus_assert (dbus_signature_validate (sig, NULL)); + dbus_signature_iter_init (&iter, sig); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); + boolres = dbus_signature_iter_next (&iter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); + dbus_signature_iter_recurse (&iter, &subiter); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); + boolres = dbus_signature_iter_next (&subiter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE); + boolres = dbus_signature_iter_next (&subiter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY); + _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY); + + dbus_signature_iter_recurse (&subiter, &subsubiter); + _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY); + _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE); + + dbus_signature_iter_recurse (&subsubiter, &subsubsubiter); + _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE); + boolres = dbus_signature_iter_next (&subiter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT); + dbus_signature_iter_recurse (&subiter, &subsubiter); + _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE); + + sig = DBUS_TYPE_ARRAY_AS_STRING + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_INT16_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING; + _dbus_assert (dbus_signature_validate (sig, NULL)); + _dbus_assert (!dbus_signature_validate_single (sig, NULL)); + dbus_signature_iter_init (&iter, sig); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY); + _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY); + + dbus_signature_iter_recurse (&iter, &subiter); + dbus_signature_iter_recurse (&subiter, &subsubiter); + _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16); + boolres = dbus_signature_iter_next (&subsubiter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING); + boolres = dbus_signature_iter_next (&subsubiter); + _dbus_assert (!boolres); + + boolres = dbus_signature_iter_next (&iter); + _dbus_assert (boolres); + _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT); + boolres = dbus_signature_iter_next (&iter); + _dbus_assert (!boolres); + + sig = DBUS_TYPE_DICT_ENTRY_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_TYPE_ARRAY_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_TYPE_UINT32_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_DICT_ENTRY_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_INT32_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_INT32_AS_STRING + DBUS_TYPE_STRING_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_STRUCT_END_CHAR_AS_STRING + DBUS_STRUCT_BEGIN_CHAR_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + + sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING + DBUS_TYPE_BOOLEAN_AS_STRING; + _dbus_assert (!dbus_signature_validate (sig, NULL)); + return TRUE; +#if 0 + oom: + _dbus_test_fatal ("out of memory"); + return FALSE; +#endif +} + +#ifdef DBUS_UNIX +static dbus_bool_t +_dbus_transport_unix_test (const char *test_data_dir _DBUS_GNUC_UNUSED) +{ + DBusConnection *c; + DBusError error; + dbus_bool_t ret; + const char *address; + + dbus_error_init (&error); + + c = dbus_connection_open ("unixexec:argv0=false,argv1=foobar,path=/bin/false", &error); + _dbus_assert (c != NULL); + _dbus_assert (!dbus_error_is_set (&error)); + + address = _dbus_connection_get_address (c); + _dbus_assert (address != NULL); + + /* Let's see if the address got parsed, reordered and formatted correctly */ + ret = strcmp (address, "unixexec:path=/bin/false,argv0=false,argv1=foobar") == 0; + + dbus_connection_unref (c); + + return ret; +} +#endif + +static DBusTestCase tests[] = +{ + { "string", _dbus_string_test }, + { "sysdeps", _dbus_sysdeps_test }, + { "data-slot", _dbus_data_slot_test }, + { "misc", _dbus_misc_test }, + { "address", _dbus_address_test }, + { "server", _dbus_server_test }, + { "object-tree", _dbus_object_tree_test }, + { "signature", _dbus_signature_test }, + { "marshalling", _dbus_marshal_test }, + { "byteswap", _dbus_marshal_byteswap_test }, + { "memory", _dbus_memory_test }, + { "mem-pool", _dbus_mem_pool_test }, + { "list", _dbus_list_test }, + { "marshal-validate", _dbus_marshal_validate_test }, + { "credentials", _dbus_credentials_test }, + { "keyring", _dbus_keyring_test }, + { "sha", _dbus_sha_test }, + { "auth", _dbus_auth_test }, + +#if defined(DBUS_UNIX) + { "userdb", _dbus_userdb_test }, + { "transport-unix", _dbus_transport_unix_test }, +#endif + + { NULL } +}; + +int +main (int argc, + char **argv) +{ + return _dbus_test_main (argc, argv, _DBUS_N_ELEMENTS (tests), tests, + DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS, + NULL, NULL); +} diff --git a/test/internals/misc-internals.h b/test/internals/misc-internals.h new file mode 100644 index 00000000..700af46e --- /dev/null +++ b/test/internals/misc-internals.h @@ -0,0 +1,36 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright 2002-2009 Red Hat, Inc. + * Copyright 2011-2018 Collabora Ltd. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef TEST_INTERNALS_MISC_INTERNALS_H +#define TEST_INTERNALS_MISC_INTERNALS_H + +#include + +dbus_bool_t _dbus_auth_test (const char *test_data_dir); +dbus_bool_t _dbus_credentials_test (const char *test_data_dir); +dbus_bool_t _dbus_marshal_byteswap_test (const char *test_data_dir); +dbus_bool_t _dbus_marshal_validate_test (const char *test_data_dir); +dbus_bool_t _dbus_string_test (const char *test_data_dir); +dbus_bool_t _dbus_sysdeps_test (const char *test_data_dir); + +#endif diff --git a/dbus/dbus-spawn-test.c b/test/internals/spawn-oom.c similarity index 95% rename from dbus/dbus-spawn-test.c rename to test/internals/spawn-oom.c index 6bc6f025..a9a19fc5 100644 --- a/dbus/dbus-spawn-test.c +++ b/test/internals/spawn-oom.c @@ -24,10 +24,11 @@ */ #include - -#include "dbus-spawn.h" -#include "dbus-sysdeps.h" -#include "dbus-test.h" +#include "dbus/dbus-internals.h" +#include "dbus/dbus-spawn.h" +#include "dbus/dbus-sysdeps.h" +#include "dbus/dbus-test.h" +#include "test/test-utils.h" static char * get_test_exec (const char *exe, @@ -265,7 +266,7 @@ check_spawn_and_kill (void *data, return TRUE; } -dbus_bool_t +static dbus_bool_t _dbus_spawn_test (const char *test_data_dir) { if (!_dbus_test_oom_handling ("spawn_nonexistent", @@ -290,3 +291,14 @@ _dbus_spawn_test (const char *test_data_dir) return TRUE; } + +static DBusTestCase test = { "spawn", _dbus_spawn_test }; + +int +main (int argc, + char **argv) +{ + return _dbus_test_main (argc, argv, 1, &test, + DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS, + NULL, NULL); +} diff --git a/test/test-utils.c b/test/test-utils.c index 99560523..d3616504 100644 --- a/test/test-utils.c +++ b/test/test-utils.c @@ -1,6 +1,70 @@ +/* + * Copyright 2002-2008 Red Hat Inc. + * Copyright 2011-2017 Collabora Ltd. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #include #include "test-utils.h" +#include +#include + +#if HAVE_LOCALE_H +#include +#endif + +#ifdef DBUS_UNIX +# include +#endif + +#include "dbus/dbus-message-internal.h" +#include "dbus/dbus-test-tap.h" + +#ifdef DBUS_ENABLE_EMBEDDED_TESTS +/* + * Like strdup(), but crash on out-of-memory, and pass through NULL + * unchanged (the "0" in the name is meant to be a mnemonic for this, + * similar to g_strcmp0()). + */ +static char * +strdup0_or_die (const char *str) +{ + char *ret; + + if (str == NULL) + return NULL; /* not an error */ + + ret = strdup (str); + + if (ret == NULL) + _dbus_test_fatal ("Out of memory"); + + return ret; +} +#endif + typedef struct { DBusLoop *loop; @@ -389,3 +453,122 @@ test_pending_call_store_reply (DBusPendingCall *pc, *message_p = dbus_pending_call_steal_reply (pc); _dbus_assert (*message_p != NULL); } + +#ifdef DBUS_ENABLE_EMBEDDED_TESTS +/* + * _dbus_test_main: + * @argc: number of command-line arguments + * @argv: array of @argc arguments + * @n_tests: length of @tests + * @tests: array of @n_tests tests + * @flags: flags affecting all tests + * @test_pre_hook: if not %NULL, called before each test + * @test_post_hook: if not %NULL, called after each test + * + * Wrapper for dbus tests that do not use GLib. Processing of @tests + * can be terminated early by an entry with @name = NULL, which is a + * convenient way to put a trailing comma on every "real" test entry + * without breaking compilation on pedantic C compilers. + */ +int +_dbus_test_main (int argc, + char **argv, + size_t n_tests, + const DBusTestCase *tests, + DBusTestFlags flags, + void (*test_pre_hook) (void), + void (*test_post_hook) (void)) +{ + char *test_data_dir; + char *specific_test; + size_t i; + +#ifdef DBUS_UNIX + /* close any inherited fds so dbus-spawn's check for close-on-exec works */ + _dbus_close_all (); +#endif + +#if HAVE_SETLOCALE + setlocale(LC_ALL, ""); +#endif + + /* We can't assume that strings from _dbus_getenv() will remain valid + * forever, because some tests call setenv(), which is allowed to + * reallocate the entire environment block, and in Wine it seems that it + * genuinely does; so we copy them. + * + * We can't use _dbus_strdup() here because the test might be checking + * for memory leaks, so we don't want any libdbus allocations still + * alive at the end; so we use strdup(), which is not in Standard C but + * is available in both POSIX and Windows. */ + if (argc > 1 && strcmp (argv[1], "--tap") != 0) + test_data_dir = strdup0_or_die (argv[1]); + else + test_data_dir = strdup0_or_die (_dbus_getenv ("DBUS_TEST_DATA")); + + if (test_data_dir != NULL) + _dbus_test_diag ("Test data in %s", test_data_dir); + else if (flags & DBUS_TEST_FLAGS_REQUIRE_DATA) + _dbus_test_fatal ("Must specify test data directory as argv[1] or " + "in DBUS_TEST_DATA environment variable"); + else + _dbus_test_diag ("No test data!"); + + if (argc > 2) + specific_test = strdup0_or_die (argv[2]); + else + specific_test = strdup0_or_die (_dbus_getenv ("DBUS_TEST_ONLY")); + + for (i = 0; i < n_tests; i++) + { + long before, after; + DBusInitialFDs *initial_fds = NULL; + + if (tests[i].name == NULL) + break; + + if (n_tests > 1 && + specific_test != NULL && + strcmp (specific_test, tests[i].name) != 0) + { + _dbus_test_skip ("%s - Only intending to run %s", + tests[i].name, specific_test); + continue; + } + + _dbus_test_diag ("Running test: %s", tests[i].name); + _dbus_get_monotonic_time (&before, NULL); + + if (test_pre_hook) + test_pre_hook (); + + if (flags & DBUS_TEST_FLAGS_CHECK_FD_LEAKS) + initial_fds = _dbus_check_fdleaks_enter (); + + if (tests[i].func (test_data_dir)) + _dbus_test_ok ("%s", tests[i].name); + else + _dbus_test_not_ok ("%s", tests[i].name); + + _dbus_get_monotonic_time (&after, NULL); + + _dbus_test_diag ("%s test took %ld seconds", + tests[i].name, after - before); + + if (test_post_hook) + test_post_hook (); + + if (flags & DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS) + _dbus_test_check_memleaks (tests[i].name); + + if (flags & DBUS_TEST_FLAGS_CHECK_FD_LEAKS) + _dbus_check_fdleaks_leave (initial_fds); + } + + free (test_data_dir); + free (specific_test); + + return _dbus_test_done_testing (); +} + +#endif diff --git a/test/test-utils.h b/test/test-utils.h index 14ea365d..a2afe788 100644 --- a/test/test-utils.h +++ b/test/test-utils.h @@ -1,3 +1,30 @@ +/* + * Copyright 2002-2008 Red Hat Inc. + * Copyright 2011-2017 Collabora Ltd. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + #ifndef TEST_UTILS_H #define TEST_UTILS_H @@ -8,6 +35,8 @@ #include #include +#include + typedef DBusLoop TestMainContext; _DBUS_WARN_UNUSED_RESULT @@ -37,4 +66,26 @@ void test_server_shutdown (TestMainContext *ctx, void test_pending_call_store_reply (DBusPendingCall *pc, void *data); +typedef struct +{ + const char *name; + dbus_bool_t (*func) (const char *test_data_dir); +} DBusTestCase; + +typedef enum +{ + DBUS_TEST_FLAGS_REQUIRE_DATA = (1 << 0), + DBUS_TEST_FLAGS_CHECK_MEMORY_LEAKS = (1 << 1), + DBUS_TEST_FLAGS_CHECK_FD_LEAKS = (1 << 2), + DBUS_TEST_FLAGS_NONE = 0 +} DBusTestFlags; + +int _dbus_test_main (int argc, + char **argv, + size_t n_tests, + const DBusTestCase *tests, + DBusTestFlags flags, + void (*test_pre_hook) (void), + void (*test_post_hook) (void)); + #endif