diff options
author | Havoc Pennington <hp@redhat.com> | 2005-01-24 05:56:25 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2005-01-24 05:56:25 +0000 |
commit | 72c433f80ba964f03688b61ff754b1c93d0fb4ad (patch) | |
tree | 0247b62780feaa20358679b9fce9a0e2c8b74a44 /dbus/dbus-message-factory.c | |
parent | 9d21554dd3b560952cd5aa607c4ec07898c0b260 (diff) |
2005-01-24 Havoc Pennington <hp@redhat.com>
* dbus/dbus-message-factory.c: more testing of message validation
* dbus/dbus-protocol.h (DBUS_MINIMUM_HEADER_SIZE): move to this
header
Diffstat (limited to 'dbus/dbus-message-factory.c')
-rw-r--r-- | dbus/dbus-message-factory.c | 311 |
1 files changed, 289 insertions, 22 deletions
diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c index d4b89565..b1b90d47 100644 --- a/dbus/dbus-message-factory.c +++ b/dbus/dbus-message-factory.c @@ -25,12 +25,65 @@ #ifdef DBUS_BUILD_TESTS #include "dbus-message-factory.h" #include "dbus-message-private.h" +#include "dbus-test.h" +#include <stdio.h> -typedef dbus_bool_t (* DBusInnerGeneratorFunc) (int sequence, - DBusMessage **message_p); -typedef dbus_bool_t (* DBusMessageGeneratorFunc) (int sequence, - DBusString *data, - DBusValidity *expected_validity); +#define BYTE_ORDER_OFFSET 0 +#define BODY_LENGTH_OFFSET 4 + +static void +iter_recurse (DBusMessageDataIter *iter) +{ + iter->depth += 1; + _dbus_assert (iter->depth < _DBUS_MESSAGE_DATA_MAX_NESTING); +} + +static int +iter_get_sequence (DBusMessageDataIter *iter) +{ + return iter->sequence_nos[iter->depth]; +} + +static void +iter_set_sequence (DBusMessageDataIter *iter, + int sequence) +{ + iter->sequence_nos[iter->depth] = sequence; +} + +static void +iter_unrecurse (DBusMessageDataIter *iter) +{ + iter->depth -= 1; + _dbus_assert (iter->depth >= 0); +} + +static void +iter_next (DBusMessageDataIter *iter) +{ + iter->sequence_nos[iter->depth] += 1; +} + +static dbus_bool_t +iter_first_in_series (DBusMessageDataIter *iter) +{ + int i; + + i = iter->depth; + while (i < _DBUS_MESSAGE_DATA_MAX_NESTING) + { + if (iter->sequence_nos[i] != 0) + return FALSE; + ++i; + } + return TRUE; +} + +typedef dbus_bool_t (* DBusInnerGeneratorFunc) (DBusMessageDataIter *iter, + DBusMessage **message_p); +typedef dbus_bool_t (* DBusMessageGeneratorFunc) (DBusMessageDataIter *iter, + DBusString *data, + DBusValidity *expected_validity); static void set_reply_serial (DBusMessage *message) @@ -42,12 +95,12 @@ set_reply_serial (DBusMessage *message) } static dbus_bool_t -generate_trivial_inner (int sequence, - DBusMessage **message_p) +generate_trivial_inner (DBusMessageDataIter *iter, + DBusMessage **message_p) { DBusMessage *message; - switch (sequence) + switch (iter_get_sequence (iter)) { case 0: message = dbus_message_new_method_call ("org.freedesktop.TextEditor", @@ -97,7 +150,61 @@ generate_trivial_inner (int sequence, } static dbus_bool_t -generate_outer (int sequence, +generate_many_bodies_inner (DBusMessageDataIter *iter, + DBusMessage **message_p) +{ + DBusMessage *message; + DBusString signature; + DBusString body; + + message = dbus_message_new_method_call ("org.freedesktop.Foo", + "/", + "org.freedesktop.Blah", + "NahNahNah"); + if (message == NULL) + _dbus_assert_not_reached ("oom"); + + set_reply_serial (message); + + if (!_dbus_string_init (&signature) || !_dbus_string_init (&body)) + _dbus_assert_not_reached ("oom"); + + if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter), + message->byte_order, + &signature, &body)) + { + const char *v_SIGNATURE; + + v_SIGNATURE = _dbus_string_get_const_data (&signature); + if (!_dbus_header_set_field_basic (&message->header, + DBUS_HEADER_FIELD_SIGNATURE, + DBUS_TYPE_SIGNATURE, + &v_SIGNATURE)) + _dbus_assert_not_reached ("oom"); + + if (!_dbus_string_move (&body, 0, &message->body, 0)) + _dbus_assert_not_reached ("oom"); + + _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET, + _dbus_string_get_length (&message->body), + message->byte_order); + + *message_p = message; + } + else + { + dbus_message_unref (message); + *message_p = NULL; + } + + _dbus_string_free (&signature); + _dbus_string_free (&body); + + return *message_p != NULL; +} + +static dbus_bool_t +generate_outer (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity, DBusInnerGeneratorFunc func) @@ -105,9 +212,11 @@ generate_outer (int sequence, DBusMessage *message; message = NULL; - if (!(*func)(sequence, &message)) + if (!(*func)(iter, &message)) return FALSE; + iter_next (iter); + _dbus_assert (message != NULL); _dbus_message_set_serial (message, 1); @@ -130,16 +239,157 @@ generate_outer (int sequence, } static dbus_bool_t -generate_trivial (int sequence, +generate_trivial (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { - return generate_outer (sequence, data, expected_validity, + return generate_outer (iter, data, expected_validity, generate_trivial_inner); } -static const DBusMessageGeneratorFunc generators[] = { - generate_trivial +static dbus_bool_t +generate_many_bodies (DBusMessageDataIter *iter, + DBusString *data, + DBusValidity *expected_validity) +{ + return generate_outer (iter, data, expected_validity, + generate_many_bodies_inner); +} + +static dbus_bool_t +generate_wrong_length (DBusMessageDataIter *iter, + DBusString *data, + DBusValidity *expected_validity) +{ + int lengths[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 }; + int adjust; + int len_seq; + + restart: + len_seq = iter_get_sequence (iter); + if (len_seq == _DBUS_N_ELEMENTS (lengths)) + return FALSE; + + _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths)); + + iter_recurse (iter); + if (!generate_many_bodies (iter, data, expected_validity)) + { + iter_set_sequence (iter, 0); /* reset to first body */ + iter_unrecurse (iter); + iter_next (iter); /* next length adjustment */ + goto restart; + } + iter_unrecurse (iter); + + adjust = lengths[len_seq]; + + if (adjust < 0) + { + if ((_dbus_string_get_length (data) + adjust) < DBUS_MINIMUM_HEADER_SIZE) + _dbus_string_set_length (data, DBUS_MINIMUM_HEADER_SIZE); + else + _dbus_string_shorten (data, - adjust); + *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON; + } + else + { + if (!_dbus_string_lengthen (data, adjust)) + _dbus_assert_not_reached ("oom"); + *expected_validity = DBUS_INVALID_TOO_MUCH_DATA; + } + + /* Fixup lengths */ + { + int old_body_len; + int new_body_len; + int byte_order; + + _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE); + + byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET); + old_body_len = _dbus_marshal_read_uint32 (data, + BODY_LENGTH_OFFSET, + byte_order, + NULL); + _dbus_assert (old_body_len < _dbus_string_get_length (data)); + new_body_len = old_body_len + adjust; + if (new_body_len < 0) + { + new_body_len = 0; + /* we just munged the header, and aren't sure how */ + *expected_validity = DBUS_VALIDITY_UNKNOWN; + } + + _dbus_verbose ("changing body len from %u to %u by adjust %d\n", + old_body_len, new_body_len, adjust); + + _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET, + new_body_len, + byte_order); + } + + return TRUE; +} + +static dbus_bool_t +generate_byte_changed (DBusMessageDataIter *iter, + DBusString *data, + DBusValidity *expected_validity) +{ + int byte_seq; + int v_BYTE; + + /* This is a little convoluted to make the bodies the + * outer loop and each byte of each body the inner + * loop + */ + + restart: + if (!generate_many_bodies (iter, data, expected_validity)) + return FALSE; + + iter_recurse (iter); + byte_seq = iter_get_sequence (iter); + iter_next (iter); + iter_unrecurse (iter); + + if (byte_seq == _dbus_string_get_length (data)) + { + _dbus_string_set_length (data, 0); + /* reset byte count */ + iter_recurse (iter); + iter_set_sequence (iter, 0); + iter_unrecurse (iter); + goto restart; + } + else + { + /* Undo the "next" in generate_many_bodies */ + iter_set_sequence (iter, iter_get_sequence (iter) - 1); + } + + _dbus_assert (byte_seq < _dbus_string_get_length (data)); + v_BYTE = _dbus_string_get_byte (data, byte_seq); + v_BYTE += byte_seq; /* arbitrary but deterministic change to the byte */ + _dbus_string_set_byte (data, byte_seq, v_BYTE); + *expected_validity = DBUS_VALIDITY_UNKNOWN; + + return TRUE; +} + +typedef struct +{ + const char *name; + DBusMessageGeneratorFunc func; +} DBusMessageGenerator; + +static const DBusMessageGenerator generators[] = { + { "trivial example of each message type", generate_trivial }, + { "assorted arguments", generate_many_bodies }, + { "wrong body lengths", generate_wrong_length }, + { "each byte modified", generate_byte_changed } }; void @@ -151,8 +401,15 @@ _dbus_message_data_free (DBusMessageData *data) void _dbus_message_data_iter_init (DBusMessageDataIter *iter) { - iter->generator = 0; - iter->sequence = 0; + int i; + + iter->depth = 0; + i = 0; + while (i < _DBUS_MESSAGE_DATA_MAX_NESTING) + { + iter->sequence_nos[i] = 0; + ++i; + } } dbus_bool_t @@ -160,25 +417,35 @@ _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter, DBusMessageData *data) { DBusMessageGeneratorFunc func; + int generator; restart: - if (iter->generator == _DBUS_N_ELEMENTS (generators)) + generator = iter_get_sequence (iter); + + if (generator == _DBUS_N_ELEMENTS (generators)) return FALSE; + + iter_recurse (iter); + + if (iter_first_in_series (iter)) + printf (" testing message loading: %s\n", generators[generator].name); - func = generators[iter->generator]; + func = generators[generator].func; if (!_dbus_string_init (&data->data)) _dbus_assert_not_reached ("oom"); - if ((*func)(iter->sequence, &data->data, &data->expected_validity)) - iter->sequence += 1; + if ((*func)(iter, &data->data, &data->expected_validity)) + ; else { - iter->generator += 1; - iter->sequence = 0; + iter_set_sequence (iter, 0); + iter_unrecurse (iter); + iter_next (iter); /* next generator */ _dbus_string_free (&data->data); goto restart; } + iter_unrecurse (iter); return TRUE; } |