-/* -*- 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>
#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;
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, '/'))
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 */
}
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
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))
_DBUS_UINT_MAX - 1,
_DBUS_INT_MAX - 2,
_DBUS_UINT_MAX - 2,
- (unsigned int) (_DBUS_INT_MAX + 1),
- (unsigned int) (_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,
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))
extreme_ints[which]);
}
-static int times_we_did_each_thing[6] = { 0, };
+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,
randomly_add_one_byte,
randomly_remove_one_byte,
randomly_modify_length,
- randomly_set_extreme_ints
+ randomly_set_extreme_ints,
+ randomly_change_one_type
};
_dbus_string_set_length (mutated, 0);
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,
goto failed;
}
+ printf (" changing one random byte 100 times\n");
i = 0;
while (i < 100)
{
++i;
}
+ printf (" changing length 50 times\n");
i = 0;
while (i < 50)
{
++i;
}
-
+
+ printf (" removing one byte 50 times\n");
i = 0;
while (i < 50)
{
++i;
}
+ printf (" adding one byte 50 times\n");
i = 0;
while (i < 50)
{
++i;
}
+ printf (" changing ints to boundary values 50 times\n");
i = 0;
while (i < 50)
{
++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)
{
++i;
}
+ printf (" randomly making 2 of above modifications 42 times\n");
i = 0;
while (i < 42)
{
++i;
}
+ printf (" randomly making 3 of above modifications 42 times\n");
i = 0;
while (i < 42)
{
++i;
}
+ printf (" randomly making 4 of above modifications 42 times\n");
i = 0;
while (i < 42)
{
seed = 0;
- if (!_dbus_string_init (&bytes, _DBUS_INT_MAX))
+ if (!_dbus_string_init (&bytes))
exit (1);
fd = open ("/dev/urandom", O_RDONLY);
close (fd);
- _dbus_string_get_const_data (&bytes, &s);
+ s = _dbus_string_get_const_data (&bytes);
seed = * (unsigned int*) s;
goto out;
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 */
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)
{
return 1;
}
- printf (" did %d random mutations: %d %d %d %d %d %d\n",
+ 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[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);