[daemon-fix] fixed getting uid and pid when transport is not kdbus
[platform/upstream/dbus.git] / test / break-loader.c
index db9a14a..e62b8c2 100644 (file)
@@ -1,9 +1,9 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 /* dbus-break-loader.c  Program to find byte streams that break the message loader
  *
  * Copyright (C) 2003  Red Hat Inc.
  *
- * Licensed under the Academic Free License version 1.2
+ * 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
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
+#include <config.h>
 #include <dbus/dbus.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -36,7 +37,7 @@
 #include <dbus/dbus-string.h>
 #include <dbus/dbus-internals.h>
 #include <dbus/dbus-test.h>
-#include <dbus/dbus-marshal.h>
+#include <dbus/dbus-marshal-basic.h>
 #undef DBUS_COMPILATION
 
 static DBusString failure_dir;
@@ -124,7 +125,7 @@ try_mutated_data (const DBusString *data)
 
       failed = FALSE;
 
-      if (!_dbus_string_init (&filename, _DBUS_INT_MAX) ||
+      if (!_dbus_string_init (&filename) ||
           !_dbus_string_copy (&failure_dir, 0,
                               &filename, 0) ||
           !_dbus_string_append_byte (&filename, '/'))
@@ -153,21 +154,18 @@ try_mutated_data (const DBusString *data)
 
       if (failed)
         {
-          const char *filename_c;
-          DBusResultCode result;
+          DBusError error;
 
           _dbus_string_append (&filename, ".message-raw");
           
-          _dbus_string_get_const_data (&filename, &filename_c);
-          printf ("Child failed, writing %s\n",
-                  filename_c);
+          printf ("Child failed, writing %s\n", _dbus_string_get_const_data (&filename));
 
-          result = _dbus_string_save_to_file (data, &filename);
-
-          if (result != DBUS_RESULT_SUCCESS)
+          dbus_error_init (&error);
+          if (!_dbus_string_save_to_file (data, &filename, FALSE, &error))
             {
               fprintf (stderr, "Failed to save failed message data: %s\n",
-                       dbus_result_to_string (result));
+                       error.message);
+              dbus_error_free (&error);
               exit (1); /* so we can see the seed that was printed out */
             }
 
@@ -290,8 +288,8 @@ randomly_add_one_byte (const DBusString *orig_data,
 
   i = random_int_in_range (0, _dbus_string_get_length (mutated));
 
-  _dbus_string_insert_byte (mutated, i,
-                            random_int_in_range (0, 256));
+  _dbus_string_insert_bytes (mutated, i, 1,
+                            random_int_in_range (0, 256));
 }
 
 static void
@@ -315,7 +313,7 @@ randomly_modify_length (const DBusString *orig_data,
   if (_dbus_string_get_length (mutated) < 12)
     return;
   
-  _dbus_string_get_const_data (mutated, &d);
+  d = _dbus_string_get_const_data (mutated);
 
   if (!(*d == DBUS_LITTLE_ENDIAN ||
         *d == DBUS_BIG_ENDIAN))
@@ -335,6 +333,131 @@ randomly_modify_length (const DBusString *orig_data,
 }
 
 static void
+randomly_set_extreme_ints (const DBusString *orig_data,
+                           DBusString       *mutated)
+{
+  int i;
+  int byte_order;
+  const char *d;
+  dbus_uint32_t orig;
+  static int which = 0;
+  unsigned int extreme_ints[] = {
+    _DBUS_INT_MAX,
+    _DBUS_UINT_MAX,
+    _DBUS_INT_MAX - 1,
+    _DBUS_UINT_MAX - 1,
+    _DBUS_INT_MAX - 2,
+    _DBUS_UINT_MAX - 2,
+    _DBUS_INT_MAX - 17,
+    _DBUS_UINT_MAX - 17,
+    _DBUS_INT_MAX / 2,
+    _DBUS_INT_MAX / 3,
+    _DBUS_UINT_MAX / 2,
+    _DBUS_UINT_MAX / 3,
+    0, 1, 2, 3,
+    (unsigned int) -1,
+    (unsigned int) -2,
+    (unsigned int) -3
+  };
+    
+  if (orig_data != mutated)
+    {
+      _dbus_string_set_length (mutated, 0);
+      
+      if (!_dbus_string_copy (orig_data, 0, mutated, 0))
+        _dbus_assert_not_reached ("out of mem");
+    }
+
+  if (_dbus_string_get_length (mutated) < 12)
+    return;
+  
+  d = _dbus_string_get_const_data (mutated);
+
+  if (!(*d == DBUS_LITTLE_ENDIAN ||
+        *d == DBUS_BIG_ENDIAN))
+    return;
+
+  byte_order = *d;
+  
+  i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8);
+  i = _DBUS_ALIGN_VALUE (i, 4);
+
+  orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL);
+
+  which = random_int_in_range (0, _DBUS_N_ELEMENTS (extreme_ints));
+
+  _dbus_assert (which >= 0);
+  _dbus_assert (which < _DBUS_N_ELEMENTS (extreme_ints));
+  
+  _dbus_marshal_set_uint32 (mutated, byte_order, i,
+                            extreme_ints[which]);
+}
+
+static int
+random_type (void)
+{
+  const char types[] = {
+    DBUS_TYPE_INVALID,
+    DBUS_TYPE_NIL,
+    DBUS_TYPE_BYTE,
+    DBUS_TYPE_BOOLEAN,
+    DBUS_TYPE_INT32,
+    DBUS_TYPE_UINT32,
+    DBUS_TYPE_INT64,
+    DBUS_TYPE_UINT64,
+    DBUS_TYPE_DOUBLE,
+    DBUS_TYPE_STRING,
+    DBUS_TYPE_CUSTOM,
+    DBUS_TYPE_ARRAY,
+    DBUS_TYPE_DICT,
+    DBUS_TYPE_OBJECT_PATH
+  };
+
+  _dbus_assert (_DBUS_N_ELEMENTS (types) == DBUS_NUMBER_OF_TYPES + 1);
+
+  return types[ random_int_in_range (0, _DBUS_N_ELEMENTS (types)) ];
+}
+
+static void
+randomly_change_one_type (const DBusString *orig_data,
+                          DBusString       *mutated)
+{
+  int i;
+  int len;
+  
+  if (orig_data != mutated)
+    {
+      _dbus_string_set_length (mutated, 0);
+      
+      if (!_dbus_string_copy (orig_data, 0, mutated, 0))
+        _dbus_assert_not_reached ("out of mem");
+    }
+
+  if (_dbus_string_get_length (mutated) == 0)
+    return;
+
+  len = _dbus_string_get_length (mutated);
+  i = random_int_in_range (0, len);
+
+  /* Look for a type starting at a random location,
+   * and replace with a different type
+   */
+  while (i < len)
+    {
+      int b;
+      b = _dbus_string_get_byte (mutated, i);
+      if (dbus_type_is_valid (b))
+        {
+          _dbus_string_set_byte (mutated, i, random_type ());
+          return;
+        }
+      ++i;
+    }
+}
+
+static int times_we_did_each_thing[7] = { 0, };
+
+static void
 randomly_do_n_things (const DBusString *orig_data,
                       DBusString       *mutated,
                       int               n)
@@ -347,7 +470,9 @@ randomly_do_n_things (const DBusString *orig_data,
       randomly_change_one_byte,
       randomly_add_one_byte,
       randomly_remove_one_byte,
-      randomly_modify_length
+      randomly_modify_length,
+      randomly_set_extreme_ints,
+      randomly_change_one_type
     };
 
   _dbus_string_set_length (mutated, 0);
@@ -363,6 +488,7 @@ randomly_do_n_things (const DBusString *orig_data,
       which = random_int_in_range (0, _DBUS_N_ELEMENTS (functions));
 
       (* functions[which]) (mutated, mutated);
+      times_we_did_each_thing[which] += 1;
       
       ++i;
     }
@@ -380,14 +506,14 @@ find_breaks_based_on (const DBusString   *filename,
   dbus_bool_t retval;
   int i;
 
-  _dbus_string_get_const_data (filename, &filename_c);
+  filename_c = _dbus_string_get_const_data (filename);
 
   retval = FALSE;
 
-  if (!_dbus_string_init (&orig_data, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&orig_data))
     _dbus_assert_not_reached ("could not allocate string\n");
 
-  if (!_dbus_string_init (&mutated, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&mutated))
     _dbus_assert_not_reached ("could not allocate string\n");
 
   if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
@@ -397,6 +523,7 @@ find_breaks_based_on (const DBusString   *filename,
       goto failed;
     }
 
+  printf ("        changing one random byte 100 times\n");
   i = 0;
   while (i < 100)
     {
@@ -406,6 +533,7 @@ find_breaks_based_on (const DBusString   *filename,
       ++i;
     }
 
+  printf ("        changing length 50 times\n");
   i = 0;
   while (i < 50)
     {
@@ -414,7 +542,8 @@ find_breaks_based_on (const DBusString   *filename,
 
       ++i;
     }
-  
+
+  printf ("        removing one byte 50 times\n");
   i = 0;
   while (i < 50)
     {
@@ -424,6 +553,7 @@ find_breaks_based_on (const DBusString   *filename,
       ++i;
     }
 
+  printf ("        adding one byte 50 times\n");
   i = 0;
   while (i < 50)
     {
@@ -432,7 +562,28 @@ find_breaks_based_on (const DBusString   *filename,
 
       ++i;
     }
-  
+
+  printf ("        changing ints to boundary values 50 times\n");
+  i = 0;
+  while (i < 50)
+    {
+      randomly_set_extreme_ints (&orig_data, &mutated);
+      try_mutated_data (&mutated);
+
+      ++i;
+    }
+
+  printf ("        changing typecodes 50 times\n");
+  i = 0;
+  while (i < 50)
+    {
+      randomly_change_one_type (&orig_data, &mutated);
+      try_mutated_data (&mutated);
+
+      ++i;
+    }
+
+  printf ("        changing message length 15 times\n");
   i = 0;
   while (i < 15)
     {
@@ -442,6 +593,7 @@ find_breaks_based_on (const DBusString   *filename,
       ++i;
     }
 
+  printf ("        randomly making 2 of above modifications 42 times\n");
   i = 0;
   while (i < 42)
     {
@@ -451,6 +603,7 @@ find_breaks_based_on (const DBusString   *filename,
       ++i;
     }
 
+  printf ("        randomly making 3 of above modifications 42 times\n");
   i = 0;
   while (i < 42)
     {
@@ -460,6 +613,7 @@ find_breaks_based_on (const DBusString   *filename,
       ++i;
     }
 
+  printf ("        randomly making 4 of above modifications 42 times\n");
   i = 0;
   while (i < 42)
     {
@@ -490,7 +644,7 @@ get_random_seed (void)
 
   seed = 0;
 
-  if (!_dbus_string_init (&bytes, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&bytes))
     exit (1);
 
   fd = open ("/dev/urandom", O_RDONLY);
@@ -502,7 +656,7 @@ get_random_seed (void)
 
   close (fd);
 
-  _dbus_string_get_const_data (&bytes, &s);
+  s = _dbus_string_get_const_data (&bytes);
 
   seed = * (unsigned int*) s;
   goto out;
@@ -513,7 +667,7 @@ get_random_seed (void)
 
     fprintf (stderr, "could not open/read /dev/urandom, using current time for seed\n");
 
-    _dbus_get_current_time (NULL, &tv_usec);
+    _dbus_get_monotonic_time (NULL, &tv_usec);
 
     seed = tv_usec;
   }
@@ -543,7 +697,7 @@ main (int    argc,
   total_failures_found = 0;
   total_attempts = 0;
 
-  if (!_dbus_string_init (&failure_dir, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&failure_dir))
     return 1;
 
   /* so you can leave it overnight safely */
@@ -565,7 +719,7 @@ main (int    argc,
       if (!_dbus_string_append_uint (&failure_dir, seed))
         return 1;
 
-      _dbus_string_get_const_data (&failure_dir, &failure_dir_c);
+      failure_dir_c = _dbus_string_get_const_data (&failure_dir);
 
       if (mkdir (failure_dir_c, 0700) < 0)
         {
@@ -588,6 +742,16 @@ main (int    argc,
           return 1;
         }
 
+      printf ("  did %d random mutations: %d %d %d %d %d %d %d\n",
+              _DBUS_N_ELEMENTS (times_we_did_each_thing),
+              times_we_did_each_thing[0],
+              times_we_did_each_thing[1],
+              times_we_did_each_thing[2],
+              times_we_did_each_thing[3],
+              times_we_did_each_thing[4],
+              times_we_did_each_thing[5],
+              times_we_did_each_thing[6]);
+      
       printf ("Found %d failures with seed %u stored in %s\n",
               failures_this_iteration, seed, failure_dir_c);