mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-04-22 04:40:41 +02:00
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
This commit is contained in:
parent
0e53d4eed3
commit
8f04e1e01f
8 changed files with 654 additions and 51 deletions
17
ChangeLog
17
ChangeLog
|
|
@ -1,3 +1,20 @@
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue