summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--dbus/dbus-marshal-header.c16
-rw-r--r--dbus/dbus-marshal-validate.c12
-rw-r--r--dbus/dbus-marshal-validate.h35
-rw-r--r--dbus/dbus-message-factory.c519
-rw-r--r--dbus/dbus-message-util.c55
-rw-r--r--dbus/dbus-message.c8
-rw-r--r--dbus/dbus-string-util.c43
8 files changed, 654 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index 1d35dd0c..cbde9ade 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2005-02-05 Havoc Pennington <hp@redhat.com>
+ * dbus/dbus-message-factory.c (generate_special): more test cases,
+ increasing coverage
+
+ * dbus/dbus-marshal-validate.c (validate_body_helper): return the
+ reason why a signature was invalid
+
+ * dbus/dbus-marshal-header.c (load_and_validate_field): fix to
+ skip the length of the string before we look at it in validation
+
+ * dbus/dbus-string-util.c (_dbus_string_test): add tests for
+ equal_substring
+
+ * dbus/dbus-message.c (_dbus_message_loader_new): default
+ max_message_length to DBUS_MAXIMUM_MESSAGE_LENGTH
+
+2005-02-05 Havoc Pennington <hp@redhat.com>
+
* dbus/dbus-marshal-validate.c (validate_body_helper): fix crash
if the signature of a variant was empty
(_dbus_validate_signature_with_reason): catch "(a)" (array inside
diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c
index f32e7aa8..10d9e20b 100644
--- a/dbus/dbus-marshal-header.c
+++ b/dbus/dbus-marshal-header.c
@@ -773,6 +773,7 @@ load_and_validate_field (DBusHeader *header,
int expected_type;
const DBusString *value_str;
int value_pos;
+ int str_data_pos;
dbus_uint32_t v_UINT32;
int bad_string_code;
dbus_bool_t (* string_validation_func) (const DBusString *str,
@@ -812,6 +813,7 @@ load_and_validate_field (DBusHeader *header,
v_UINT32 = 0;
value_str = NULL;
value_pos = -1;
+ str_data_pos = -1;
bad_string_code = DBUS_VALID;
if (expected_type == DBUS_TYPE_UINT32)
@@ -825,6 +827,7 @@ load_and_validate_field (DBusHeader *header,
{
_dbus_header_get_field_raw (header, field,
&value_str, &value_pos);
+ str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
}
else
{
@@ -844,7 +847,7 @@ load_and_validate_field (DBusHeader *header,
if (_dbus_string_equal_substring (&_dbus_local_interface_str,
0,
_dbus_string_get_length (&_dbus_local_interface_str),
- value_str, value_pos))
+ value_str, str_data_pos))
{
_dbus_verbose ("Message is on the local interface\n");
return DBUS_INVALID_USES_LOCAL_INTERFACE;
@@ -870,13 +873,10 @@ load_and_validate_field (DBusHeader *header,
/* OBJECT_PATH was validated generically due to its type */
string_validation_func = NULL;
- _dbus_verbose ("value_str %p value_pos %d value_str_len %d\n",
- value_str, value_pos,
- _dbus_string_get_length (value_str));
if (_dbus_string_equal_substring (&_dbus_local_path_str,
0,
_dbus_string_get_length (&_dbus_local_path_str),
- value_str, value_pos))
+ value_str, str_data_pos))
{
_dbus_verbose ("Message is from the local path\n");
return DBUS_INVALID_USES_LOCAL_PATH;
@@ -910,7 +910,11 @@ load_and_validate_field (DBusHeader *header,
len = _dbus_marshal_read_uint32 (value_str, value_pos,
header->byte_order, NULL);
- if (!(*string_validation_func) (value_str, value_pos + 4, len))
+#if 0
+ _dbus_verbose ("Validating string header field; code %d if fails\n",
+ bad_string_code);
+#endif
+ if (!(*string_validation_func) (value_str, str_data_pos, len))
return bad_string_code;
}
diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c
index f7b46c0b..c1d95820 100644
--- a/dbus/dbus-marshal-validate.c
+++ b/dbus/dbus-marshal-validate.c
@@ -335,6 +335,7 @@ validate_body_helper (DBusTypeReader *reader,
{
dbus_uint32_t claimed_len;
DBusString str;
+ DBusValidity validity;
claimed_len = *p;
++p;
@@ -344,9 +345,12 @@ validate_body_helper (DBusTypeReader *reader,
return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
_dbus_string_init_const_len (&str, p, claimed_len);
- if (!_dbus_validate_signature (&str, 0,
- _dbus_string_get_length (&str)))
- return DBUS_INVALID_BAD_SIGNATURE;
+ validity =
+ _dbus_validate_signature_with_reason (&str, 0,
+ _dbus_string_get_length (&str));
+
+ if (validity != DBUS_VALID)
+ return validity;
p += claimed_len;
@@ -389,7 +393,7 @@ validate_body_helper (DBusTypeReader *reader,
return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
p += claimed_len;
-
+
if (*p != DBUS_TYPE_INVALID)
return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
++p;
diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h
index 55739d31..8989d508 100644
--- a/dbus/dbus-marshal-validate.h
+++ b/dbus/dbus-marshal-validate.h
@@ -48,6 +48,7 @@ typedef enum
*/
typedef enum
{
+#define _DBUS_NEGATIVE_VALIDITY_COUNT 3
DBUS_INVALID_FOR_UNKNOWN_REASON = -3,
DBUS_VALID_BUT_INCOMPLETE = -2,
DBUS_VALIDITY_UNKNOWN = -1,
@@ -91,23 +92,23 @@ typedef enum
DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM = 37,
DBUS_INVALID_BAD_PATH = 38,
DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 39,
- DBUS_INVALID_BAD_SIGNATURE = 40,
- DBUS_INVALID_BAD_UTF8_IN_STRING = 41,
- DBUS_INVALID_ARRAY_LENGTH_INCORRECT = 42,
- DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 43,
- DBUS_INVALID_VARIANT_SIGNATURE_BAD = 44,
- DBUS_INVALID_VARIANT_SIGNATURE_EMPTY = 45,
- DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES = 46,
- DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL = 47,
- DBUS_INVALID_STRING_MISSING_NUL = 48,
- DBUS_INVALID_SIGNATURE_MISSING_NUL = 49,
- DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION = 50,
- DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED = 51,
- DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED = 52,
- DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS = 53,
- DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD = 54,
- DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS = 55,
- DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY = 56
+ DBUS_INVALID_BAD_UTF8_IN_STRING = 40,
+ DBUS_INVALID_ARRAY_LENGTH_INCORRECT = 41,
+ DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 42,
+ DBUS_INVALID_VARIANT_SIGNATURE_BAD = 43,
+ DBUS_INVALID_VARIANT_SIGNATURE_EMPTY = 44,
+ DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES = 45,
+ DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL = 46,
+ DBUS_INVALID_STRING_MISSING_NUL = 47,
+ DBUS_INVALID_SIGNATURE_MISSING_NUL = 48,
+ DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION = 49,
+ DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED = 50,
+ DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED = 51,
+ DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS = 52,
+ DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD = 53,
+ DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS = 54,
+ DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY = 55,
+ DBUS_VALIDITY_LAST
} DBusValidity;
DBusValidity _dbus_validate_signature_with_reason (const DBusString *type_str,
diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c
index 26109815..adcb9b2e 100644
--- a/dbus/dbus-message-factory.c
+++ b/dbus/dbus-message-factory.c
@@ -35,7 +35,9 @@ typedef enum
} ChangeType;
#define BYTE_ORDER_OFFSET 0
+#define TYPE_OFFSET 1
#define BODY_LENGTH_OFFSET 4
+#define FIELDS_ARRAY_LENGTH_OFFSET 12
static void
iter_recurse (DBusMessageDataIter *iter)
@@ -165,11 +167,12 @@ generate_many_bodies_inner (DBusMessageDataIter *iter,
DBusMessage *message;
DBusString signature;
DBusString body;
-
- message = dbus_message_new_method_call ("org.freedesktop.Foo",
+
+ /* Keeping this small makes things go faster */
+ message = dbus_message_new_method_call ("o.z.F",
"/",
- "org.freedesktop.Blah",
- "NahNahNah");
+ "o.z.B",
+ "Nah");
if (message == NULL)
_dbus_assert_not_reached ("oom");
@@ -212,6 +215,26 @@ generate_many_bodies_inner (DBusMessageDataIter *iter,
return *message_p != NULL;
}
+static void
+generate_from_message (DBusString *data,
+ DBusValidity *expected_validity,
+ DBusMessage *message)
+{
+ _dbus_message_set_serial (message, 1);
+ _dbus_message_lock (message);
+
+ *expected_validity = DBUS_VALID;
+
+ /* move for efficiency, since we'll nuke the message anyway */
+ if (!_dbus_string_move (&message->header.data, 0,
+ data, 0))
+ _dbus_assert_not_reached ("oom");
+
+ if (!_dbus_string_copy (&message->body, 0,
+ data, _dbus_string_get_length (data)))
+ _dbus_assert_not_reached ("oom");
+}
+
static dbus_bool_t
generate_outer (DBusMessageDataIter *iter,
DBusString *data,
@@ -228,19 +251,7 @@ generate_outer (DBusMessageDataIter *iter,
_dbus_assert (message != NULL);
- _dbus_message_set_serial (message, 1);
- _dbus_message_lock (message);
-
- *expected_validity = DBUS_VALID;
-
- /* move for efficiency, since we'll nuke the message anyway */
- if (!_dbus_string_move (&message->header.data, 0,
- data, 0))
- _dbus_assert_not_reached ("oom");
-
- if (!_dbus_string_copy (&message->body, 0,
- data, _dbus_string_get_length (data)))
- _dbus_assert_not_reached ("oom");
+ generate_from_message (data, expected_validity, message);
dbus_message_unref (message);
@@ -265,6 +276,334 @@ generate_many_bodies (DBusMessageDataIter *iter,
generate_many_bodies_inner);
}
+static DBusMessage*
+simple_method_call (void)
+{
+ DBusMessage *message;
+ /* Keeping this small makes stuff go faster */
+ message = dbus_message_new_method_call ("o.b.Q",
+ "/f/b",
+ "o.b.Z",
+ "Fro");
+ if (message == NULL)
+ _dbus_assert_not_reached ("oom");
+ return message;
+}
+
+static DBusMessage*
+simple_signal (void)
+{
+ DBusMessage *message;
+ message = dbus_message_new_signal ("/f/b",
+ "o.b.Z",
+ "Fro");
+ if (message == NULL)
+ _dbus_assert_not_reached ("oom");
+ return message;
+}
+
+static DBusMessage*
+simple_method_return (void)
+{
+ DBusMessage *message;
+ message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ if (message == NULL)
+ _dbus_assert_not_reached ("oom");
+
+ set_reply_serial (message);
+
+ return message;
+}
+
+static dbus_bool_t
+generate_special (DBusMessageDataIter *iter,
+ DBusString *data,
+ DBusValidity *expected_validity)
+{
+ int item_seq;
+ DBusMessage *message;
+ int pos;
+ dbus_int32_t v_INT32;
+
+ _dbus_assert (_dbus_string_get_length (data) == 0);
+
+ message = NULL;
+ pos = -1;
+ v_INT32 = 42;
+ item_seq = iter_get_sequence (iter);
+
+ if (item_seq == 0)
+ {
+ message = simple_method_call ();
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INVALID))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_header_get_field_raw (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ NULL, &pos);
+ generate_from_message (data, expected_validity, message);
+
+ /* set an invalid typecode */
+ _dbus_string_set_byte (data, pos + 1, '$');
+
+ *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
+ }
+ else if (item_seq == 1)
+ {
+ char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+1];
+ const char *v_STRING;
+ int i;
+
+ message = simple_method_call ();
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INVALID))
+ _dbus_assert_not_reached ("oom");
+
+ i = 0;
+ while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
+ {
+ long_sig[i] = DBUS_TYPE_ARRAY;
+ ++i;
+ }
+
+ v_STRING = long_sig;
+ if (!_dbus_header_set_field_basic (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ DBUS_TYPE_SIGNATURE,
+ &v_STRING))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_header_get_field_raw (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ NULL, &pos);
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
+ }
+ else if (item_seq == 2)
+ {
+ char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+3];
+ const char *v_STRING;
+ int i;
+
+ message = simple_method_call ();
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INVALID))
+ _dbus_assert_not_reached ("oom");
+
+ i = 0;
+ while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
+ {
+ long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
+ ++i;
+ }
+
+ long_sig[i] = DBUS_TYPE_INT32;
+ ++i;
+
+ while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
+ {
+ long_sig[i] = DBUS_STRUCT_END_CHAR;
+ ++i;
+ }
+
+ v_STRING = long_sig;
+ if (!_dbus_header_set_field_basic (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ DBUS_TYPE_SIGNATURE,
+ &v_STRING))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_header_get_field_raw (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ NULL, &pos);
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
+ }
+ else if (item_seq == 3)
+ {
+ message = simple_method_call ();
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INVALID))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_header_get_field_raw (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ NULL, &pos);
+ generate_from_message (data, expected_validity, message);
+
+ _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
+
+ *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
+ }
+ else if (item_seq == 4)
+ {
+ message = simple_method_call ();
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INVALID))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_header_get_field_raw (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ NULL, &pos);
+ generate_from_message (data, expected_validity, message);
+
+ _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
+
+ *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
+ }
+ else if (item_seq == 5)
+ {
+ message = simple_method_call ();
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INT32, &v_INT32,
+ DBUS_TYPE_INVALID))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_header_get_field_raw (&message->header,
+ DBUS_HEADER_FIELD_SIGNATURE,
+ NULL, &pos);
+ generate_from_message (data, expected_validity, message);
+
+ _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
+ _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
+
+ *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
+ }
+ else if (item_seq == 6)
+ {
+ message = simple_method_call ();
+ generate_from_message (data, expected_validity, message);
+
+ _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
+
+ *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
+ }
+ else if (item_seq == 7)
+ {
+ /* Messages of unknown type are considered valid */
+ message = simple_method_call ();
+ generate_from_message (data, expected_validity, message);
+
+ _dbus_string_set_byte (data, TYPE_OFFSET, 100);
+
+ *expected_validity = DBUS_VALID;
+ }
+ else if (item_seq == 8)
+ {
+ message = simple_method_call ();
+ generate_from_message (data, expected_validity, message);
+
+ _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
+ DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
+ message->byte_order);
+ _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
+ DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
+ message->byte_order);
+ *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
+ }
+ else if (item_seq == 9)
+ {
+ const char *v_STRING = "not a valid bus name";
+ message = simple_method_call ();
+
+ if (!_dbus_header_set_field_basic (&message->header,
+ DBUS_HEADER_FIELD_SENDER,
+ DBUS_TYPE_STRING, &v_STRING))
+ _dbus_assert_not_reached ("oom");
+
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_INVALID_BAD_SENDER;
+ }
+ else if (item_seq == 10)
+ {
+ message = simple_method_call ();
+
+ if (!dbus_message_set_interface (message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
+ _dbus_assert_not_reached ("oom");
+
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
+ }
+ else if (item_seq == 11)
+ {
+ message = simple_method_call ();
+
+ if (!dbus_message_set_path (message, DBUS_PATH_ORG_FREEDESKTOP_LOCAL))
+ _dbus_assert_not_reached ("oom");
+
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
+ }
+ else if (item_seq == 12)
+ {
+ /* Method calls don't have to have interface */
+ message = simple_method_call ();
+
+ if (!dbus_message_set_interface (message, NULL))
+ _dbus_assert_not_reached ("oom");
+
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_VALID;
+ }
+ else if (item_seq == 13)
+ {
+ /* Signals require an interface */
+ message = simple_signal ();
+
+ if (!dbus_message_set_interface (message, NULL))
+ _dbus_assert_not_reached ("oom");
+
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_INVALID_MISSING_INTERFACE;
+ }
+ else if (item_seq == 14)
+ {
+ message = simple_method_return ();
+
+ if (!_dbus_header_delete_field (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL))
+ _dbus_assert_not_reached ("oom");
+
+ generate_from_message (data, expected_validity, message);
+
+ *expected_validity = DBUS_INVALID_MISSING_REPLY_SERIAL;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (message)
+ dbus_message_unref (message);
+
+ iter_next (iter);
+ return TRUE;
+}
+
static dbus_bool_t
generate_wrong_length (DBusMessageDataIter *iter,
DBusString *data,
@@ -388,6 +727,145 @@ generate_byte_changed (DBusMessageDataIter *iter,
return TRUE;
}
+static dbus_bool_t
+find_next_typecode (DBusMessageDataIter *iter,
+ DBusString *data,
+ DBusValidity *expected_validity)
+{
+ int body_seq;
+ int byte_seq;
+ int base_depth;
+
+ base_depth = iter->depth;
+
+ restart:
+ _dbus_assert (iter->depth == (base_depth + 0));
+ _dbus_string_set_length (data, 0);
+
+ body_seq = iter_get_sequence (iter);
+
+ if (!generate_many_bodies (iter, data, expected_validity))
+ return FALSE;
+ /* Undo the "next" in generate_many_bodies */
+ iter_set_sequence (iter, body_seq);
+
+ iter_recurse (iter);
+ while (TRUE)
+ {
+ _dbus_assert (iter->depth == (base_depth + 1));
+
+ byte_seq = iter_get_sequence (iter);
+
+ _dbus_assert (byte_seq <= _dbus_string_get_length (data));
+
+ if (byte_seq == _dbus_string_get_length (data))
+ {
+ /* reset byte count */
+ iter_set_sequence (iter, 0);
+ iter_unrecurse (iter);
+ _dbus_assert (iter->depth == (base_depth + 0));
+ iter_next (iter); /* go to the next body */
+ goto restart;
+ }
+
+ _dbus_assert (byte_seq < _dbus_string_get_length (data));
+
+ if (_dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq)))
+ break;
+ else
+ iter_next (iter);
+ }
+
+ _dbus_assert (byte_seq == iter_get_sequence (iter));
+ _dbus_assert (byte_seq < _dbus_string_get_length (data));
+
+ iter_unrecurse (iter);
+
+ _dbus_assert (iter->depth == (base_depth + 0));
+
+ return TRUE;
+}
+
+static const int typecodes[] = {
+ DBUS_TYPE_INVALID,
+ DBUS_TYPE_BYTE,
+ DBUS_TYPE_BOOLEAN,
+ DBUS_TYPE_INT16,
+ DBUS_TYPE_UINT16,
+ DBUS_TYPE_INT32,
+ DBUS_TYPE_UINT32,
+ DBUS_TYPE_INT64,
+ DBUS_TYPE_UINT64,
+ DBUS_TYPE_DOUBLE,
+ DBUS_TYPE_STRING,
+ DBUS_TYPE_OBJECT_PATH,
+ DBUS_TYPE_SIGNATURE,
+ DBUS_TYPE_ARRAY,
+ DBUS_TYPE_VARIANT,
+ DBUS_STRUCT_BEGIN_CHAR,
+ DBUS_STRUCT_END_CHAR,
+ DBUS_DICT_ENTRY_BEGIN_CHAR,
+ DBUS_DICT_ENTRY_END_CHAR,
+ 255 /* random invalid typecode */
+};
+
+static dbus_bool_t
+generate_typecode_changed (DBusMessageDataIter *iter,
+ DBusString *data,
+ DBusValidity *expected_validity)
+{
+ int byte_seq;
+ int typecode_seq;
+ int base_depth;
+
+ base_depth = iter->depth;
+
+ restart:
+ _dbus_assert (iter->depth == (base_depth + 0));
+ _dbus_string_set_length (data, 0);
+
+ if (!find_next_typecode (iter, data, expected_validity))
+ return FALSE;
+
+ iter_recurse (iter);
+ byte_seq = iter_get_sequence (iter);
+
+ _dbus_assert (byte_seq < _dbus_string_get_length (data));
+
+ iter_recurse (iter);
+ typecode_seq = iter_get_sequence (iter);
+ iter_next (iter);
+
+ _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes));
+
+ if (typecode_seq == _DBUS_N_ELEMENTS (typecodes))
+ {
+ _dbus_assert (iter->depth == (base_depth + 2));
+ iter_set_sequence (iter, 0); /* reset typecode sequence */
+ iter_unrecurse (iter);
+ _dbus_assert (iter->depth == (base_depth + 1));
+ iter_next (iter); /* go to the next byte_seq */
+ iter_unrecurse (iter);
+ _dbus_assert (iter->depth == (base_depth + 0));
+ goto restart;
+ }
+
+ _dbus_assert (iter->depth == (base_depth + 2));
+ iter_unrecurse (iter);
+ _dbus_assert (iter->depth == (base_depth + 1));
+ iter_unrecurse (iter);
+ _dbus_assert (iter->depth == (base_depth + 0));
+
+#if 0
+ printf ("Changing byte %d in message %d to %c\n",
+ byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]);
+#endif
+
+ _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]);
+ *expected_validity = DBUS_VALIDITY_UNKNOWN;
+ return TRUE;
+}
+
typedef struct
{
ChangeType type;
@@ -528,9 +1006,14 @@ typedef struct
static const DBusMessageGenerator generators[] = {
{ "trivial example of each message type", generate_trivial },
{ "assorted arguments", generate_many_bodies },
+ { "assorted special cases", generate_special },
{ "each uint32 modified", generate_uint32_changed },
{ "wrong body lengths", generate_wrong_length },
- { "each byte modified", generate_byte_changed }
+ { "each byte modified", generate_byte_changed },
+#if 0
+ /* This is really expensive and doesn't add too much coverage */
+ { "change each typecode", generate_typecode_changed }
+#endif
};
void
diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c
index c646ebf9..69db2019 100644
--- a/dbus/dbus-message-util.c
+++ b/dbus/dbus-message-util.c
@@ -78,6 +78,45 @@ dbus_message_iter_get_args (DBusMessageIter *iter,
#include <stdio.h>
#include <stdlib.h>
+static int validities_seen[DBUS_VALIDITY_LAST + _DBUS_NEGATIVE_VALIDITY_COUNT];
+
+static void
+reset_validities_seen (void)
+{
+ int i;
+ i = 0;
+ while (i < _DBUS_N_ELEMENTS (validities_seen))
+ {
+ validities_seen[i] = 0;
+ ++i;
+ }
+}
+
+static void
+record_validity_seen (DBusValidity validity)
+{
+ validities_seen[validity + _DBUS_NEGATIVE_VALIDITY_COUNT] += 1;
+}
+
+static void
+print_validities_seen (dbus_bool_t not_seen)
+{
+ int i;
+ i = 0;
+ while (i < _DBUS_N_ELEMENTS (validities_seen))
+ {
+ if ((i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_VALIDITY_UNKNOWN ||
+ (i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_INVALID_FOR_UNKNOWN_REASON)
+ ;
+ else if ((not_seen && validities_seen[i] == 0) ||
+ (!not_seen && validities_seen[i] > 0))
+ printf ("validity %3d seen %d times\n",
+ i - _DBUS_NEGATIVE_VALIDITY_COUNT,
+ validities_seen[i]);
+ ++i;
+ }
+}
+
static void
check_memleaks (void)
{
@@ -130,6 +169,8 @@ check_have_valid_message (DBusMessageLoader *loader)
goto failed;
#endif
+ record_validity_seen (DBUS_VALID);
+
retval = TRUE;
failed:
@@ -153,6 +194,8 @@ check_invalid_message (DBusMessageLoader *loader,
goto failed;
}
+ record_validity_seen (loader->corruption_reason);
+
if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON &&
loader->corruption_reason != expected_validity)
{
@@ -190,6 +233,7 @@ check_incomplete_message (DBusMessageLoader *loader)
goto failed;
}
+ record_validity_seen (DBUS_VALID_BUT_INCOMPLETE);
retval = TRUE;
failed:
@@ -212,8 +256,12 @@ check_loader_results (DBusMessageLoader *loader,
else if (expected_validity == DBUS_VALIDITY_UNKNOWN)
{
/* here we just know we didn't segfault and that was the
- * only test
+ * only test. Also, we record that we got coverage
+ * for the validity reason.
*/
+ if (_dbus_message_loader_get_is_corrupted (loader))
+ record_validity_seen (loader->corruption_reason);
+
return TRUE;
}
else
@@ -1170,6 +1218,8 @@ _dbus_message_test (const char *test_data_dir)
DBusMessageData mdata;
int count;
+ reset_validities_seen ();
+
count = 0;
_dbus_message_data_iter_init (&diter);
@@ -1190,6 +1240,9 @@ _dbus_message_test (const char *test_data_dir)
}
printf ("%d sample messages tested\n", count);
+
+ print_validities_seen (FALSE);
+ print_validities_seen (TRUE);
}
check_memleaks ();
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index 46a30b6f..a2852558 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -2957,11 +2957,9 @@ _dbus_message_loader_new (void)
loader->corrupted = FALSE;
loader->corruption_reason = DBUS_VALID;
-
- /* Try to cap message size at something that won't *totally* hose
- * the system if we have a couple of them.
- */
- loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
+
+ /* this can be configured by the app, but defaults to the protocol max */
+ loader->max_message_size = DBUS_MAXIMUM_MESSAGE_LENGTH;
if (!_dbus_string_init (&loader->data))
{
diff --git a/dbus/dbus-string-util.c b/dbus/dbus-string-util.c
index 1ff2ec67..0610c66d 100644
--- a/dbus/dbus-string-util.c
+++ b/dbus/dbus-string-util.c
@@ -377,6 +377,49 @@ _dbus_string_test (void)
++i;
}
+ /* Test equality */
+ if (!_dbus_string_init (&str))
+ _dbus_assert_not_reached ("oom");
+
+ if (!_dbus_string_append (&str, "Hello World"))
+ _dbus_assert_not_reached ("oom");
+
+ _dbus_string_init_const (&other, "H");
+ _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
+ _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
+ _dbus_string_init_const (&other, "Hello");
+ _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
+ _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
+ _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
+ _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
+ _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
+ _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
+
+ _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
+ _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
+ _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
+ _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
+ _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
+ _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
+
+
+ _dbus_string_init_const (&other, "World");
+ _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0));
+ _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1));
+ _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2));
+ _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3));
+ _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
+ _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
+
+ _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
+ _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
+ _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
+ _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
+ _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
+ _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
+
+ _dbus_string_free (&str);
+
/* Test appending data */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");