2003-02-10 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Thu, 13 Feb 2003 00:08:18 +0000 (00:08 +0000)
committerHavoc Pennington <hp@redhat.com>
Thu, 13 Feb 2003 00:08:18 +0000 (00:08 +0000)
        * 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
dbus/Makefile.am
dbus/dbus-auth-script.c [new file with mode: 0644]
dbus/dbus-auth-script.h [new file with mode: 0644]
dbus/dbus-auth.c
dbus/dbus-message-builder.c
dbus/dbus-server-debug.c
dbus/dbus-string.c
dbus/dbus-string.h
dbus/dbus-test.c
dbus/dbus-test.h

index 093ac15..2ecd37d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2003-02-10  Havoc Pennington  <hp@pobox.com>
+
+        * 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  <andersca@codefactory.se>
 
        * bus/Makefile.am:
index f6f84a6..52d77c9 100644 (file)
@@ -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 (file)
index 0000000..a9df6d9
--- /dev/null
@@ -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 <config.h>
+
+#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 (file)
index 0000000..8f561e6
--- /dev/null
@@ -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 <config.h>
+
+#include <dbus/dbus-memory.h>
+#include <dbus/dbus-types.h>
+#include <dbus/dbus-string.h>
+
+DBUS_BEGIN_DECLS;
+
+dbus_bool_t _dbus_auth_script_run (const DBusString *filename);
+
+DBUS_END_DECLS;
+
+#endif /* DBUS_AUTH_SCRIPT_H */
index 55b2c9b..697723b 100644 (file)
@@ -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 <stdio.h>
+
+dbus_bool_t
+_dbus_auth_test (const char *test_data_dir)
+{
+  
+
+  return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */
index 4731333..58c4430 100644 (file)
  * @{
  */
 
-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);
index 57d6806..f558e82 100644 (file)
@@ -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;
 }
 
 /** @} */
index a5bf3eb..ded726f 100644 (file)
@@ -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)
@@ -1416,6 +1416,92 @@ _dbus_string_skip_blank (const DBusString *str,
 }
 
 /**
+ * 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.
  *
  * @param a first string
@@ -1453,6 +1539,47 @@ _dbus_string_equal (const DBusString *a,
 }
 
 /**
+ * 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.
  *
  * @param a the string
index 54297ee..f22aa30 100644 (file)
@@ -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,
index 4b3d9f2..3145349 100644 (file)
@@ -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");
index 31753ac..4374ac6 100644 (file)
@@ -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,