From 94790fef4a846ef2bed9bf1825c4c2b0ca7b8566 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 2 Apr 2003 21:43:29 +0000 Subject: 2003-04-02 Havoc Pennington * dbus/dbus-sysdeps.c (_dbus_file_get_contents): include filenames in error messages (_dbus_string_get_dirname): new (_dbus_sysdeps_test): new (_dbus_directory_open): include dirnames in error messages * bus/config-parser.c: interpret and and relative to config file location if the given filename is not absolute. * dbus/dbus-string.c (_dbus_string_find_byte_backward): new --- dbus/dbus-string.c | 56 +++++++++ dbus/dbus-string.h | 351 +++++++++++++++++++++++++--------------------------- dbus/dbus-sysdeps.c | 172 +++++++++++++++++++++++-- dbus/dbus-sysdeps.h | 3 + dbus/dbus-test.c | 6 + dbus/dbus-test.h | 1 + 6 files changed, 397 insertions(+), 192 deletions(-) (limited to 'dbus') diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 305b488f..dd5781fa 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -1448,6 +1448,42 @@ _dbus_string_find_to (const DBusString *str, return FALSE; } +/** + * Find the given byte scanning backward from the given start. + * Sets *found to -1 if the byte is not found. + * + * @param str the string + * @param byte the byte to find + * @param found return location for where it was found + * @returns #TRUE if found + */ +dbus_bool_t +_dbus_string_find_byte_backward (const DBusString *str, + int start, + unsigned char byte, + int *found) +{ + int i; + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (start <= real->len); + _dbus_assert (start >= 0); + _dbus_assert (found != NULL); + + i = start - 1; + while (i >= 0) + { + if (real->str[i] == byte) + break; + + --i; + } + + if (found) + *found = i; + + return i >= 0; +} + /** * Finds a blank (space or tab) in the string. Returns #TRUE * if found, #FALSE otherwise. If a blank is not found sets @@ -3145,6 +3181,26 @@ _dbus_string_test (void) if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) _dbus_assert_not_reached ("Did find 'Hello'"); + + if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) + _dbus_assert_not_reached ("Did not find 'H'"); + _dbus_assert (i == 0); + + if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) + _dbus_assert_not_reached ("Did not find 'o'"); + _dbus_assert (i == _dbus_string_get_length (&str) - 1); + + if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i)) + _dbus_assert_not_reached ("Did find 'o'"); + _dbus_assert (i == -1); + + if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) + _dbus_assert_not_reached ("Did find 'e'"); + _dbus_assert (i == -1); + + if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) + _dbus_assert_not_reached ("Didn't find 'e'"); + _dbus_assert (i == 1); _dbus_string_free (&str); diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index ba0fcf85..065c9caa 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -45,192 +45,173 @@ struct DBusString unsigned int dummy8 : 3; /**< placeholder */ }; -dbus_bool_t _dbus_string_init (DBusString *str); -void _dbus_string_init_const (DBusString *str, - const char *value); -void _dbus_string_init_const_len (DBusString *str, - const char *value, - int len); -void _dbus_string_free (DBusString *str); -void _dbus_string_lock (DBusString *str); +dbus_bool_t _dbus_string_init (DBusString *str); +void _dbus_string_init_const (DBusString *str, + const char *value); +void _dbus_string_init_const_len (DBusString *str, + const char *value, + int len); +void _dbus_string_free (DBusString *str); +void _dbus_string_lock (DBusString *str); +char* _dbus_string_get_data (DBusString *str); +const char* _dbus_string_get_const_data (const DBusString *str); +char* _dbus_string_get_data_len (DBusString *str, + int start, + int len); +const char* _dbus_string_get_const_data_len (const DBusString *str, + int start, + int len); +void _dbus_string_set_byte (DBusString *str, + int i, + unsigned char byte); +unsigned char _dbus_string_get_byte (const DBusString *str, + int start); +dbus_bool_t _dbus_string_insert_byte (DBusString *str, + int i, + unsigned char byte); +dbus_bool_t _dbus_string_steal_data (DBusString *str, + char **data_return); +dbus_bool_t _dbus_string_steal_data_len (DBusString *str, + char **data_return, + int start, + int len); +dbus_bool_t _dbus_string_copy_data (const DBusString *str, + char **data_return); +dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, + char **data_return, + int start, + int len); +int _dbus_string_get_length (const DBusString *str); +dbus_bool_t _dbus_string_lengthen (DBusString *str, + int additional_length); +void _dbus_string_shorten (DBusString *str, + int length_to_remove); +dbus_bool_t _dbus_string_set_length (DBusString *str, + int length); +dbus_bool_t _dbus_string_align_length (DBusString *str, + int alignment); +dbus_bool_t _dbus_string_append (DBusString *str, + const char *buffer); +dbus_bool_t _dbus_string_append_len (DBusString *str, + const char *buffer, + int len); +dbus_bool_t _dbus_string_append_int (DBusString *str, + long value); +dbus_bool_t _dbus_string_append_uint (DBusString *str, + unsigned long value); +dbus_bool_t _dbus_string_append_double (DBusString *str, + double value); +dbus_bool_t _dbus_string_append_byte (DBusString *str, + unsigned char byte); +dbus_bool_t _dbus_string_append_unichar (DBusString *str, + dbus_unichar_t ch); +void _dbus_string_delete (DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_move (DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_copy (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_move_len (DBusString *source, + int start, + int len, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_copy_len (const DBusString *source, + int start, + int len, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_replace_len (const DBusString *source, + int start, + int len, + DBusString *dest, + int replace_at, + int replace_len); +void _dbus_string_get_unichar (const DBusString *str, + int start, + dbus_unichar_t *ch_return, + int *end_return); +dbus_bool_t _dbus_string_parse_int (const DBusString *str, + int start, + long *value_return, + int *end_return); +dbus_bool_t _dbus_string_parse_uint (const DBusString *str, + int start, + unsigned long *value_return, + int *end_return); +dbus_bool_t _dbus_string_parse_double (const DBusString *str, + int start, + double *value, + int *end_return); +dbus_bool_t _dbus_string_find (const DBusString *str, + int start, + const char *substr, + int *found); +dbus_bool_t _dbus_string_find_to (const DBusString *str, + int start, + int end, + const char *substr, + int *found); +dbus_bool_t _dbus_string_find_byte_backward (const DBusString *str, + int start, + unsigned char byte, + int *found); +dbus_bool_t _dbus_string_find_blank (const DBusString *str, + int start, + int *found); +void _dbus_string_skip_blank (const DBusString *str, + int start, + int *end); +void _dbus_string_skip_white (const DBusString *str, + int start, + int *end); +dbus_bool_t _dbus_string_equal (const DBusString *a, + const DBusString *b); +dbus_bool_t _dbus_string_equal_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_equal_len (const DBusString *a, + const DBusString *b, + int len); +dbus_bool_t _dbus_string_starts_with_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_ends_with_c_str (const DBusString *a, + const char *c_str); +dbus_bool_t _dbus_string_pop_line (DBusString *source, + DBusString *dest); +void _dbus_string_delete_first_word (DBusString *str); +void _dbus_string_delete_leading_blanks (DBusString *str); +dbus_bool_t _dbus_string_base64_encode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_base64_decode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_hex_encode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_hex_decode (const DBusString *source, + int start, + DBusString *dest, + int insert_at); +dbus_bool_t _dbus_string_validate_ascii (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_validate_utf8 (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_string_validate_nul (const DBusString *str, + int start, + int len); +void _dbus_string_zero (DBusString *str); -char* _dbus_string_get_data (DBusString *str); -const char* _dbus_string_get_const_data (const DBusString *str); -char* _dbus_string_get_data_len (DBusString *str, - int start, - int len); -const char* _dbus_string_get_const_data_len (const DBusString *str, - int start, - int len); -void _dbus_string_set_byte (DBusString *str, - int i, - unsigned char byte); -unsigned char _dbus_string_get_byte (const DBusString *str, - int start); -dbus_bool_t _dbus_string_insert_byte (DBusString *str, - int i, - unsigned char byte); -dbus_bool_t _dbus_string_steal_data (DBusString *str, - char **data_return); -dbus_bool_t _dbus_string_steal_data_len (DBusString *str, - char **data_return, - int start, - int len); -dbus_bool_t _dbus_string_copy_data (const DBusString *str, - char **data_return); -dbus_bool_t _dbus_string_copy_data_len (const DBusString *str, - char **data_return, - int start, - int len); - -int _dbus_string_get_length (const DBusString *str); - -dbus_bool_t _dbus_string_lengthen (DBusString *str, - int additional_length); -void _dbus_string_shorten (DBusString *str, - int length_to_remove); -dbus_bool_t _dbus_string_set_length (DBusString *str, - int length); -dbus_bool_t _dbus_string_align_length (DBusString *str, - int alignment); - -dbus_bool_t _dbus_string_append (DBusString *str, - const char *buffer); -dbus_bool_t _dbus_string_append_len (DBusString *str, - const char *buffer, - int len); -dbus_bool_t _dbus_string_append_int (DBusString *str, - long value); -dbus_bool_t _dbus_string_append_uint (DBusString *str, - unsigned long value); -dbus_bool_t _dbus_string_append_double (DBusString *str, - double value); -dbus_bool_t _dbus_string_append_byte (DBusString *str, - unsigned char byte); -dbus_bool_t _dbus_string_append_unichar (DBusString *str, - dbus_unichar_t ch); - - -void _dbus_string_delete (DBusString *str, - int start, - int len); -dbus_bool_t _dbus_string_move (DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_copy (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_move_len (DBusString *source, - int start, - int len, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_copy_len (const DBusString *source, - int start, - int len, - DBusString *dest, - int insert_at); - -dbus_bool_t _dbus_string_replace_len (const DBusString *source, - int start, - int len, - DBusString *dest, - int replace_at, - int replace_len); - -void _dbus_string_get_unichar (const DBusString *str, - int start, - dbus_unichar_t *ch_return, - int *end_return); - -dbus_bool_t _dbus_string_parse_int (const DBusString *str, - int start, - long *value_return, - int *end_return); -dbus_bool_t _dbus_string_parse_uint (const DBusString *str, - int start, - unsigned long *value_return, - int *end_return); -dbus_bool_t _dbus_string_parse_double (const DBusString *str, - int start, - double *value, - int *end_return); - -dbus_bool_t _dbus_string_find (const DBusString *str, - int start, - const char *substr, - int *found); - -dbus_bool_t _dbus_string_find_to (const DBusString *str, - int start, - int end, - const char *substr, - int *found); -dbus_bool_t _dbus_string_find_blank (const DBusString *str, - int start, - int *found); - -void _dbus_string_skip_blank (const DBusString *str, - int start, - int *end); - -void _dbus_string_skip_white (const DBusString *str, - int start, - int *end); - -dbus_bool_t _dbus_string_equal (const DBusString *a, - const DBusString *b); - -dbus_bool_t _dbus_string_equal_c_str (const DBusString *a, - const char *c_str); - -dbus_bool_t _dbus_string_equal_len (const DBusString *a, - const DBusString *b, - int len); - -dbus_bool_t _dbus_string_starts_with_c_str (const DBusString *a, - const char *c_str); -dbus_bool_t _dbus_string_ends_with_c_str (const DBusString *a, - const char *c_str); - -dbus_bool_t _dbus_string_pop_line (DBusString *source, - DBusString *dest); -void _dbus_string_delete_first_word (DBusString *str); -void _dbus_string_delete_leading_blanks (DBusString *str); - - -dbus_bool_t _dbus_string_base64_encode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_base64_decode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_hex_encode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); -dbus_bool_t _dbus_string_hex_decode (const DBusString *source, - int start, - DBusString *dest, - int insert_at); - -dbus_bool_t _dbus_string_validate_ascii (const DBusString *str, - int start, - int len); - -dbus_bool_t _dbus_string_validate_utf8 (const DBusString *str, - int start, - int len); - -dbus_bool_t _dbus_string_validate_nul (const DBusString *str, - int start, - int len); - -void _dbus_string_zero (DBusString *str); DBUS_END_DECLS; diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 8aa91811..4798aa73 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -24,6 +24,7 @@ #include "dbus-internals.h" #include "dbus-sysdeps.h" #include "dbus-threads.h" +#include "dbus-test.h" #include #include #include @@ -1890,14 +1891,18 @@ _dbus_file_get_contents (DBusString *str, if (fd < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Failed to open \"%s\": %s", + filename_c, + _dbus_strerror (errno)); return FALSE; } if (fstat (fd, &sb) < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Failed to stat \"%s\": %s", + filename_c, + _dbus_strerror (errno)); _dbus_verbose ("fstat() failed: %s", _dbus_strerror (errno)); @@ -1910,8 +1915,8 @@ _dbus_file_get_contents (DBusString *str, if (sb.st_size > _DBUS_ONE_MEGABYTE) { dbus_set_error (error, DBUS_ERROR_FAILED, - "File size %lu is too large.\n", - (unsigned long) sb.st_size); + "File size %lu of \"%s\" is too large.", + filename_c, (unsigned long) sb.st_size); close (fd); return FALSE; } @@ -1929,7 +1934,9 @@ _dbus_file_get_contents (DBusString *str, if (bytes_read <= 0) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Error reading \"%s\": %s", + filename_c, + _dbus_strerror (errno)); _dbus_verbose ("read() failed: %s", _dbus_strerror (errno)); @@ -1949,7 +1956,8 @@ _dbus_file_get_contents (DBusString *str, { _dbus_verbose ("Can only open regular files at the moment.\n"); dbus_set_error (error, DBUS_ERROR_FAILED, - "Not a regular file"); + "\"%s\" is not a regular file", + filename_c); close (fd); return FALSE; } @@ -2231,6 +2239,9 @@ _dbus_create_directory (const DBusString *filename, /** * Appends the given filename to the given directory. * + * @todo it might be cute to collapse multiple '/' such as "foo//" + * concat "//bar" + * * @param dir the directory name * @param next_component the filename * @returns #TRUE on success @@ -2265,6 +2276,69 @@ _dbus_concat_dir_and_file (DBusString *dir, _dbus_string_get_length (dir)); } +/** + * Get the directory name from a complete filename + * @param filename the filename + * @param dirname string to append directory name to + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_string_get_dirname (const DBusString *filename, + DBusString *dirname) +{ + int sep; + + _dbus_assert (filename != dirname); + _dbus_assert (filename != NULL); + _dbus_assert (dirname != NULL); + + /* Ignore any separators on the end */ + sep = _dbus_string_get_length (filename); + if (sep == 0) + return _dbus_string_append (dirname, "."); /* empty string passed in */ + + while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/') + --sep; + + _dbus_assert (sep >= 0); + + if (sep == 0) + return _dbus_string_append (dirname, "/"); + + /* Now find the previous separator */ + _dbus_string_find_byte_backward (filename, sep, '/', &sep); + if (sep < 0) + return _dbus_string_append (dirname, "."); + + /* skip multiple separators */ + while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/') + --sep; + + _dbus_assert (sep >= 0); + + if (sep == 0 && + _dbus_string_get_byte (filename, 0) == '/') + return _dbus_string_append (dirname, "/"); + else + return _dbus_string_copy_len (filename, 0, sep - 0, + dirname, _dbus_string_get_length (dirname)); +} + +/** + * Checks whether the filename is an absolute path + * + * @param filename the filename + * @returns #TRUE if an absolute path + */ +dbus_bool_t +_dbus_path_is_absolute (const DBusString *filename) +{ + if (_dbus_string_get_length (filename) > 0) + return _dbus_string_get_byte (filename, 0) == '/'; + else + return FALSE; +} + struct DBusDirIter { DIR *d; @@ -2294,7 +2368,9 @@ _dbus_directory_open (const DBusString *filename, if (d == NULL) { dbus_set_error (error, _dbus_error_from_errno (errno), - "%s", _dbus_strerror (errno)); + "Failed to read directory \"%s\": %s", + filename_c, + _dbus_strerror (errno)); return NULL; } iter = dbus_new0 (DBusDirIter, 1); @@ -3207,4 +3283,86 @@ _dbus_change_identity (unsigned long uid, return TRUE; } +#ifdef DBUS_BUILD_TESTS +#include +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_assert_not_reached ("no memory"); + + if (!_dbus_string_get_dirname (&f, &d)) + _dbus_assert_not_reached ("no memory"); + + if (!_dbus_string_equal_c_str (&d, dirname)) + { + _dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"\n", + 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\n", + 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 (void) +{ + 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 ("", "."); + + check_path_absolute ("/", TRUE); + check_path_absolute ("/foo", TRUE); + check_path_absolute ("", FALSE); + check_path_absolute ("foo", FALSE); + check_path_absolute ("foo/bar", FALSE); + + return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ + /** @} end of sysdeps */ + diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 6a6a965b..113db5eb 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -163,6 +163,9 @@ dbus_bool_t _dbus_create_directory (const DBusString *filename, dbus_bool_t _dbus_concat_dir_and_file (DBusString *dir, const DBusString *next_component); +dbus_bool_t _dbus_string_get_dirname (const DBusString *filename, + DBusString *dirname); +dbus_bool_t _dbus_path_is_absolute (const DBusString *filename); typedef struct DBusDirIter DBusDirIter; diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index b9cf64c8..0b0893ab 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -78,6 +78,12 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir) die ("strings"); check_memleaks (); + + printf ("%s: running sysdeps tests\n", "dbus-test"); + if (!_dbus_sysdeps_test ()) + die ("sysdeps"); + + check_memleaks (); printf ("%s: running data slot tests\n", "dbus-test"); if (!_dbus_data_slot_test ()) diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index e4cb52d7..06154487 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -48,6 +48,7 @@ dbus_bool_t _dbus_md5_test (void); dbus_bool_t _dbus_sha_test (const char *test_data_dir); dbus_bool_t _dbus_keyring_test (void); dbus_bool_t _dbus_data_slot_test (void); +dbus_bool_t _dbus_sysdeps_test (void); void dbus_internal_do_not_use_run_tests (const char *test_data_dir); dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename, -- cgit