From 3791dcca16cb46b0ff7305beff75d1aa2645940c Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Thu, 13 Feb 2003 00:08:18 +0000 Subject: 2003-02-10 Havoc Pennington * dbus/dbus-auth-script.c, dbus/dbus-auth-script.h: sync initial cut at test framework for DBusAuth from laptop. Doesn't quite work yet but it compiles and I need to get it off the 266mhz laptop. ;-) * dbus/dbus-server-debug.c (_dbus_server_debug_accept_transport): fix a memleak in error case --- ChangeLog | 10 ++ dbus/Makefile.am | 2 + dbus/dbus-auth-script.c | 396 ++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-auth-script.h | 39 +++++ dbus/dbus-auth.c | 17 +- dbus/dbus-message-builder.c | 96 ++--------- dbus/dbus-server-debug.c | 20 +-- dbus/dbus-string.c | 141 +++++++++++++++- dbus/dbus-string.h | 10 ++ dbus/dbus-test.c | 4 + dbus/dbus-test.h | 1 + 11 files changed, 636 insertions(+), 100 deletions(-) create mode 100644 dbus/dbus-auth-script.c create mode 100644 dbus/dbus-auth-script.h diff --git a/ChangeLog b/ChangeLog index 093ac15c..2ecd37d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-02-10 Havoc Pennington + + * dbus/dbus-auth-script.c, dbus/dbus-auth-script.h: sync + initial cut at test framework for DBusAuth from laptop. + Doesn't quite work yet but it compiles and I need to get + it off the 266mhz laptop. ;-) + + * dbus/dbus-server-debug.c (_dbus_server_debug_accept_transport): + fix a memleak in error case + 2003-02-12 Anders Carlsson * bus/Makefile.am: diff --git a/dbus/Makefile.am b/dbus/Makefile.am index f6f84a61..52d77c9e 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -24,6 +24,8 @@ libdbus_1_la_SOURCES= \ dbus-address.c \ dbus-auth.c \ dbus-auth.h \ + dbus-auth-script.c \ + dbus-auth-script.h \ dbus-bus.c \ dbus-connection.c \ dbus-connection-internal.h \ diff --git a/dbus/dbus-auth-script.c b/dbus/dbus-auth-script.c new file mode 100644 index 00000000..a9df6d90 --- /dev/null +++ b/dbus/dbus-auth-script.c @@ -0,0 +1,396 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-auth-script.c Test DBusAuth using a special script file (internal to D-BUS implementation) + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include + +#ifdef DBUS_BUILD_TESTS + +#include "dbus-auth-script.h" +#include "dbus-auth.h" +#include "dbus-string.h" +#include "dbus-hash.h" +#include "dbus-internals.h" +#include "dbus-marshal.h" + +/** + * @defgroup DBusAuthScript code for running unit test scripts for DBusAuth + * @ingroup DBusInternals + * @brief DBusAuth unit test scripting + * + * The code in here is used for unit testing, it loads + * up a script that tests DBusAuth. + * + * @{ + */ + +static dbus_bool_t +append_quoted_string (DBusString *dest, + const DBusString *quoted) +{ + dbus_bool_t in_quotes = FALSE; + int i; + + i = 0; + while (i < _dbus_string_get_length (quoted)) + { + unsigned char b; + + b = _dbus_string_get_byte (quoted, i); + + if (in_quotes) + { + if (b == '\'') + in_quotes = FALSE; + else + { + if (!_dbus_string_append_byte (dest, b)) + return FALSE; + } + } + else + { + if (b == '\'') + in_quotes = TRUE; + else if (b == ' ' || b == '\n' || b == '\t') + break; /* end on whitespace if not quoted */ + else + { + if (!_dbus_string_append_byte (dest, b)) + return FALSE; + } + } + + ++i; + } + + if (!_dbus_string_append_byte (dest, '\0')) + return FALSE; + return TRUE; +} + +static dbus_bool_t +same_first_word (const DBusString *a, + const DBusString *b) +{ + int first_a_blank, first_b_blank; + + _dbus_string_find_blank (a, 0, &first_a_blank); + _dbus_string_find_blank (b, 0, &first_b_blank); + + if (first_a_blank != first_b_blank) + return FALSE; + + return _dbus_string_equal_len (a, b, first_a_blank); +} + +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")) + return DBUS_AUTH_STATE_WAITING_FOR_MEMORY; + else if (_dbus_string_starts_with_c_str (str, "HAVE_BYTES_TO_SEND")) + return DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND; + else if (_dbus_string_starts_with_c_str (str, "NEED_DISCONNECT")) + return DBUS_AUTH_STATE_NEED_DISCONNECT; + else if (_dbus_string_starts_with_c_str (str, "AUTHENTICATED_WITH_UNUSED_BYTES")) + return DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES; + else if (_dbus_string_starts_with_c_str (str, "AUTHENTICATED")) + return DBUS_AUTH_STATE_AUTHENTICATED; + else + return -1; +} + +static const char* +auth_state_to_string (DBusAuthState state) +{ + switch (state) + { + case DBUS_AUTH_STATE_WAITING_FOR_INPUT: + return "WAITING_FOR_INPUT"; + case DBUS_AUTH_STATE_WAITING_FOR_MEMORY: + return "WAITING_FOR_MEMORY"; + case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND: + return "HAVE_BYTES_TO_SEND"; + case DBUS_AUTH_STATE_NEED_DISCONNECT: + return "NEED_DISCONNECT"; + case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES: + return "AUTHENTICATED_WITH_UNUSED_BYTES"; + case DBUS_AUTH_STATE_AUTHENTICATED: + return "AUTHENTICATED"; + } + + return "unknown"; +} + +dbus_bool_t +_dbus_auth_script_run (const DBusString *filename) +{ + DBusString file; + DBusResultCode result; + DBusString line; + dbus_bool_t retval; + int line_no; + DBusAuth *auth; + DBusString from_auth; + DBusAuthState state; + + retval = FALSE; + auth = NULL; + + if (!_dbus_string_init (&file, _DBUS_INT_MAX)) + return FALSE; + + if (!_dbus_string_init (&line, _DBUS_INT_MAX)) + { + _dbus_string_free (&file); + return FALSE; + } + + if (!_dbus_string_init (&from_auth, _DBUS_INT_MAX)) + { + _dbus_string_free (&file); + _dbus_string_free (&line); + return FALSE; + } + + if ((result = _dbus_file_get_contents (&file, filename)) != DBUS_RESULT_SUCCESS) + { + const char *s; + _dbus_string_get_const_data (filename, &s); + _dbus_warn ("Getting contents of %s failed: %s\n", + s, dbus_result_to_string (result)); + + goto out; + } + + state = DBUS_AUTH_STATE_NEED_DISCONNECT; + line_no = 0; + next_iteration: + while (_dbus_string_pop_line (&file, &line)) + { + line_no += 1; + + _dbus_string_delete_leading_blanks (&line); + + if (auth != NULL) + { + while ((state = _dbus_auth_do_work (auth)) == + DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND) + { + const DBusString *tmp; + if (_dbus_auth_get_bytes_to_send (auth, &tmp)) + { + int count = _dbus_string_get_length (tmp); + + if (_dbus_string_copy (tmp, 0, &from_auth, + _dbus_string_get_length (&from_auth))) + _dbus_auth_bytes_sent (auth, count); + } + } + } + + if (_dbus_string_get_length (&line) == 0) + { + /* empty line */ + goto next_iteration; + } + else if (_dbus_string_starts_with_c_str (&line, + "#")) + { + /* Ignore this comment */ + goto next_iteration; + } + else if (_dbus_string_starts_with_c_str (&line, + "CLIENT")) + { + if (auth != NULL) + { + _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n"); + goto out; + } + + auth = _dbus_auth_client_new (); + if (auth == NULL) + { + _dbus_warn ("no memory to create DBusAuth\n"); + goto out; + } + } + else if (_dbus_string_starts_with_c_str (&line, + "SERVER")) + { + if (auth != NULL) + { + _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n"); + goto out; + } + + auth = _dbus_auth_server_new (); + if (auth == NULL) + { + _dbus_warn ("no memory to create DBusAuth\n"); + goto out; + } + } + else if (auth == NULL) + { + _dbus_warn ("must specify CLIENT or SERVER\n"); + goto out; + + } + else if (_dbus_string_starts_with_c_str (&line, + "SEND")) + { + DBusString to_send; + + _dbus_string_delete_first_word (&line); + + if (!_dbus_string_init (&to_send, _DBUS_INT_MAX)) + { + _dbus_warn ("no memory to allocate string\n"); + goto out; + } + + if (!append_quoted_string (&to_send, &line)) + { + _dbus_warn ("failed to append quoted string line %d\n", + line_no); + _dbus_string_free (&to_send); + goto out; + } + + if (!_dbus_auth_bytes_received (auth, &to_send)) + { + _dbus_warn ("not enough memory to call bytes_received\n"); + _dbus_string_free (&to_send); + goto out; + } + + _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); + if (expected < 0) + { + _dbus_warn ("bad auth state given to EXPECT_STATE\n"); + goto parse_failed; + } + + if (expected != state) + { + _dbus_warn ("expected auth state %s but got %s on line %d\n", + auth_state_to_string (expected), + auth_state_to_string (state), + line_no); + goto out; + } + } + else if (_dbus_string_starts_with_c_str (&line, + "EXPECT_COMMAND")) + { + DBusString received; + + _dbus_string_delete_first_word (&line); + + if (!_dbus_string_init (&received, _DBUS_INT_MAX)) + { + _dbus_warn ("no mem to allocate string received\n"); + goto out; + } + + if (!_dbus_string_pop_line (&from_auth, &received)) + { + const char *command; + _dbus_string_get_const_data (&line, &command); + _dbus_warn ("no line popped from the DBusAuth being tested, expected command %s on line %d\n", + command, line_no); + _dbus_string_free (&received); + goto out; + } + + if (!same_first_word (&received, &line)) + { + const char *s1, *s2; + _dbus_string_get_const_data (&line, &s1); + _dbus_string_get_const_data (&received, &s2); + _dbus_warn ("expected command '%s' and got '%s' line %d\n", + s1, s2, line_no); + _dbus_string_free (&received); + goto out; + } + + _dbus_string_free (&received); + } + else + goto parse_failed; + + goto next_iteration; /* skip parse_failed */ + + parse_failed: + { + const char *s; + _dbus_string_get_const_data (&line, &s); + _dbus_warn ("couldn't process line %d \"%s\"\n", + line_no, s); + goto out; + } + } + + if (auth != NULL && + state == DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES) + { + _dbus_warn ("did not expect unused bytes (scripts must specify explicitly if they are expected)\n"); + goto out; + } + + if (_dbus_string_get_length (&from_auth) > 0) + { + const char *s; + _dbus_warn ("script did not have EXPECT_ statements for all the data received from the DBusAuth\n"); + _dbus_string_get_const_data (&from_auth, &s); + _dbus_warn ("Leftover data: %s\n", s); + goto out; + } + + retval = TRUE; + + out: + if (auth) + _dbus_auth_unref (auth); + + _dbus_string_free (&file); + _dbus_string_free (&file); + _dbus_string_free (&from_auth); + + return retval; +} + +/** @} */ +#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-auth-script.h b/dbus/dbus-auth-script.h new file mode 100644 index 00000000..8f561e68 --- /dev/null +++ b/dbus/dbus-auth-script.h @@ -0,0 +1,39 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-auth-script.h Test DBusAuth using a special script file (internal to D-BUS implementation) + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef DBUS_AUTH_SCRIPT_H +#define DBUS_AUTH_SCRIPT_H + +#include + +#include +#include +#include + +DBUS_BEGIN_DECLS; + +dbus_bool_t _dbus_auth_script_run (const DBusString *filename); + +DBUS_END_DECLS; + +#endif /* DBUS_AUTH_SCRIPT_H */ diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index 55b2c9b5..697723b1 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -1301,7 +1301,7 @@ _dbus_auth_do_work (DBusAuth *auth) auth->needed_memory = FALSE; /* Max amount we'll buffer up before deciding someone's on crack */ -#define MAX_BUFFER (16 * 1024) +#define MAX_BUFFER (16 * _DBUS_ONE_KILOBYTE) do { @@ -1592,5 +1592,18 @@ _dbus_auth_get_identity (DBusAuth *auth, } } - /** @} */ + +#ifdef DBUS_BUILD_TESTS +#include "dbus-test.h" +#include + +dbus_bool_t +_dbus_auth_test (const char *test_data_dir) +{ + + + return TRUE; +} + +#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c index 47313337..58c4430c 100644 --- a/dbus/dbus-message-builder.c +++ b/dbus/dbus-message-builder.c @@ -40,72 +40,6 @@ * @{ */ -static dbus_bool_t -pop_line (DBusString *source, - DBusString *dest) -{ - int eol; - dbus_bool_t have_newline; - - _dbus_string_set_length (dest, 0); - - eol = 0; - if (_dbus_string_find (source, 0, "\n", &eol)) - { - have_newline = TRUE; - eol += 1; /* include newline */ - } - else - { - eol = _dbus_string_get_length (source); - have_newline = FALSE; - } - - if (eol == 0) - return FALSE; /* eof */ - - if (!_dbus_string_move_len (source, 0, eol, - dest, 0)) - { - _dbus_warn ("failed to pop line\n"); - return FALSE; - } - - /* dump the newline */ - if (have_newline) - { - _dbus_assert (_dbus_string_get_length (dest) > 0); - _dbus_string_set_length (dest, - _dbus_string_get_length (dest) - 1); - } - - return TRUE; -} - -static void -strip_command_name (DBusString *str) -{ - int i; - - i = 0; - if (_dbus_string_find_blank (str, 0, &i)) - _dbus_string_skip_blank (str, i, &i); - - _dbus_string_delete (str, 0, i); -} - -static void -strip_leading_space (DBusString *str) -{ - int i; - - i = 0; - _dbus_string_skip_blank (str, 0, &i); - - if (i > 0) - _dbus_string_delete (str, 0, i); -} - typedef struct { DBusString name; @@ -394,7 +328,7 @@ _dbus_message_data_load (DBusString *dest, const char *s; _dbus_string_get_const_data (filename, &s); _dbus_warn ("Getting contents of %s failed: %s\n", - s, dbus_result_to_string (result)); + s, dbus_result_to_string (result)); goto out; } @@ -409,14 +343,14 @@ _dbus_message_data_load (DBusString *dest, unalign = FALSE; line_no = 0; next_iteration: - while (pop_line (&file, &line)) + while (_dbus_string_pop_line (&file, &line)) { dbus_bool_t just_set_unalign; just_set_unalign = FALSE; line_no += 1; - strip_leading_space (&line); + _dbus_string_delete_leading_blanks (&line); if (_dbus_string_get_length (&line) == 0) { @@ -494,7 +428,7 @@ _dbus_message_data_load (DBusString *dest, { long val; - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (!_dbus_string_parse_int (&line, 0, &val, NULL)) { @@ -525,7 +459,7 @@ _dbus_message_data_load (DBusString *dest, * command, we segfault. */ - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (!_dbus_string_parse_int (&line, 0, &val, NULL)) { @@ -547,7 +481,7 @@ _dbus_message_data_load (DBusString *dest, { unsigned char the_byte; - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (_dbus_string_equal_c_str (&line, "'\\''")) the_byte = '\''; @@ -578,7 +512,7 @@ _dbus_message_data_load (DBusString *dest, else if (_dbus_string_starts_with_c_str (&line, "START_LENGTH")) { - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (!save_start (length_hash, &line, _dbus_string_get_length (dest))) @@ -590,7 +524,7 @@ _dbus_message_data_load (DBusString *dest, else if (_dbus_string_starts_with_c_str (&line, "END_LENGTH")) { - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (!save_length (length_hash, &line, _dbus_string_get_length (dest))) @@ -604,7 +538,7 @@ _dbus_message_data_load (DBusString *dest, { SAVE_FOR_UNALIGN (dest, 4); - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (!append_saved_length (dest, length_hash, &line, @@ -620,7 +554,7 @@ _dbus_message_data_load (DBusString *dest, else if (_dbus_string_starts_with_c_str (&line, "FIELD_NAME")) { - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (_dbus_string_get_length (&line) != 4) { @@ -645,7 +579,7 @@ _dbus_message_data_load (DBusString *dest, { int code; - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (_dbus_string_starts_with_c_str (&line, "INVALID")) code = DBUS_TYPE_INVALID; @@ -689,7 +623,7 @@ _dbus_message_data_load (DBusString *dest, SAVE_FOR_UNALIGN (dest, 4); long val; - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (!_dbus_string_parse_int (&line, 0, &val, NULL)) { @@ -712,7 +646,7 @@ _dbus_message_data_load (DBusString *dest, SAVE_FOR_UNALIGN (dest, 4); long val; - strip_command_name (&line); + _dbus_string_delete_first_word (&line); /* FIXME should have _dbus_string_parse_uint32 */ if (!_dbus_string_parse_int (&line, 0, &val, NULL)) @@ -733,7 +667,7 @@ _dbus_message_data_load (DBusString *dest, SAVE_FOR_UNALIGN (dest, 8); double val; - strip_command_name (&line); + _dbus_string_delete_first_word (&line); if (!_dbus_string_parse_double (&line, 0, &val, NULL)) goto parse_failed; @@ -754,7 +688,7 @@ _dbus_message_data_load (DBusString *dest, int size_offset; int old_len; - strip_command_name (&line); + _dbus_string_delete_first_word (&line); size_offset = _dbus_string_get_length (dest); size_offset = _DBUS_ALIGN_VALUE (size_offset, 4); diff --git a/dbus/dbus-server-debug.c b/dbus/dbus-server-debug.c index 57d68066..f558e82e 100644 --- a/dbus/dbus-server-debug.c +++ b/dbus/dbus-server-debug.c @@ -231,8 +231,8 @@ dbus_bool_t _dbus_server_debug_accept_transport (DBusServer *server, DBusTransport *transport) { - DBusTimeout *timeout; - ServerAndTransport *st; + DBusTimeout *timeout = NULL; + ServerAndTransport *st = NULL; st = dbus_new (ServerAndTransport, 1); if (st == NULL) @@ -244,18 +244,18 @@ _dbus_server_debug_accept_transport (DBusServer *server, timeout = _dbus_timeout_new (DEFAULT_INTERVAL, handle_new_client, st, dbus_free); if (timeout == NULL) - { - dbus_free (st); - return FALSE; - } + goto failed; if (!_dbus_server_add_timeout (server, timeout)) - { - _dbus_timeout_unref (timeout); - return FALSE; - } + goto failed; return TRUE; + + failed: + dbus_free (st); + if (timeout) + _dbus_timeout_unref (timeout); + return FALSE; } /** @} */ diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index a5bf3ebc..ded726fa 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -139,11 +139,12 @@ typedef struct * no maximum. The string starts life with zero length. * The string must eventually be freed with _dbus_string_free(). * - * @todo the max length feature is useless, because it looks - * to the app like out of memory, and the app might try - * to "recover" - but recovery in this case is impossible, - * as we can't ever "get more memory" - so should delete the - * max length feature I think. + * @todo the max length feature is useless, because it looks to the + * app like out of memory, and the app might try to "recover" - but + * recovery in this case is impossible, as we can't ever "get more + * memory" - so should delete the max length feature I think. Well, at + * least there's a strong caveat that it can only be used when + * out-of-memory is a permanent fatal error. * * @todo we could make this init routine not alloc any memory and * return void, would simplify a lot of code, however it might @@ -152,8 +153,7 @@ typedef struct * * @param str memory to hold the string * @param max_length the maximum size of the string - * @returns #TRUE on success - */ + * @returns #TRUE on success */ dbus_bool_t _dbus_string_init (DBusString *str, int max_length) @@ -1415,6 +1415,92 @@ _dbus_string_skip_blank (const DBusString *str, *end = i; } +/** + * Assigns a newline-terminated line from the front of the string + * to the given dest string. The dest string's previous contents are + * deleted. If the source string contains no newline, moves the + * entire source string to the dest string. + * + * @param source the source string + * @param dest the destination string (contents are replaced) + * @returns #FALSE if no memory, or source has length 0 + */ +dbus_bool_t +_dbus_string_pop_line (DBusString *source, + DBusString *dest) +{ + int eol; + dbus_bool_t have_newline; + + _dbus_string_set_length (dest, 0); + + eol = 0; + if (_dbus_string_find (source, 0, "\n", &eol)) + { + have_newline = TRUE; + eol += 1; /* include newline */ + } + else + { + eol = _dbus_string_get_length (source); + have_newline = FALSE; + } + + if (eol == 0) + return FALSE; /* eof */ + + if (!_dbus_string_move_len (source, 0, eol, + dest, 0)) + { + return FALSE; + } + + /* dump the newline */ + if (have_newline) + { + _dbus_assert (_dbus_string_get_length (dest) > 0); + _dbus_string_set_length (dest, + _dbus_string_get_length (dest) - 1); + } + + return TRUE; +} + +/** + * Deletes up to and including the first blank space + * in the string. + * + * @param str the string + */ +void +_dbus_string_delete_first_word (DBusString *str) +{ + int i; + + i = 0; + if (_dbus_string_find_blank (str, 0, &i)) + _dbus_string_skip_blank (str, i, &i); + + _dbus_string_delete (str, 0, i); +} + +/** + * Deletes any leading blanks in the string + * + * @param str the string + */ +void +_dbus_string_delete_leading_blanks (DBusString *str) +{ + int i; + + i = 0; + _dbus_string_skip_blank (str, 0, &i); + + if (i > 0) + _dbus_string_delete (str, 0, i); +} + /** * Tests two DBusString for equality. * @@ -1452,6 +1538,47 @@ _dbus_string_equal (const DBusString *a, return TRUE; } +/** + * Tests two DBusString for equality up to the given length. + * + * @todo write a unit test + * + * @param a first string + * @param b second string + * @returns #TRUE if equal for the given number of bytes + */ +dbus_bool_t +_dbus_string_equal_len (const DBusString *a, + const DBusString *b, + int len) +{ + const unsigned char *ap; + const unsigned char *bp; + const unsigned char *a_end; + const DBusRealString *real_a = (const DBusRealString*) a; + const DBusRealString *real_b = (const DBusRealString*) b; + DBUS_GENERIC_STRING_PREAMBLE (real_a); + DBUS_GENERIC_STRING_PREAMBLE (real_b); + + if (real_a->len != real_b->len && + (real_a->len < len || real_b->len < len)) + return FALSE; + + ap = real_a->str; + bp = real_b->str; + a_end = real_a->str + MIN (real_a->len, len); + while (ap != a_end) + { + if (*ap != *bp) + return FALSE; + + ++ap; + ++bp; + } + + return TRUE; +} + /** * Checks whether a string is equal to a C string. * diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index 54297ee7..f22aa307 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -176,11 +176,21 @@ dbus_bool_t _dbus_string_equal (const DBusString *a, 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, diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index 4b3d9f27..31453497 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -59,6 +59,10 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir) if (!_dbus_string_test ()) die ("strings"); + printf ("%s: running auth tests\n", "dbus-test"); + if (!_dbus_auth_test (test_data_dir)) + die ("auth"); + printf ("%s: running address parse tests\n", "dbus-test"); if (!_dbus_address_test ()) die ("address parsing"); diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index 31753ac0..4374ac62 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -42,6 +42,7 @@ dbus_bool_t _dbus_mem_pool_test (void); dbus_bool_t _dbus_string_test (void); dbus_bool_t _dbus_address_test (void); dbus_bool_t _dbus_message_test (const char *test_data_dir); +dbus_bool_t _dbus_auth_test (const char *test_data_dir); 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