1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message-factory.c Generator of valid and invalid message data for test suite
4 * Copyright (C) 2005 Red Hat Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #ifndef DOXYGEN_SHOULD_SKIP_THIS
27 #ifdef DBUS_BUILD_TESTS
28 #include "dbus-message-factory.h"
29 #include "dbus-message-private.h"
30 #include "dbus-signature.h"
31 #include "dbus-test.h"
40 #define BYTE_ORDER_OFFSET 0
42 #define BODY_LENGTH_OFFSET 4
43 #define FIELDS_ARRAY_LENGTH_OFFSET 12
46 iter_recurse (DBusMessageDataIter *iter)
49 _dbus_assert (iter->depth < _DBUS_MESSAGE_DATA_MAX_NESTING);
50 _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
54 iter_get_sequence (DBusMessageDataIter *iter)
56 _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
57 return iter->sequence_nos[iter->depth];
61 iter_set_sequence (DBusMessageDataIter *iter,
64 _dbus_assert (sequence >= 0);
65 iter->sequence_nos[iter->depth] = sequence;
69 iter_unrecurse (DBusMessageDataIter *iter)
72 _dbus_assert (iter->depth >= 0);
76 iter_next (DBusMessageDataIter *iter)
78 iter->sequence_nos[iter->depth] += 1;
82 iter_first_in_series (DBusMessageDataIter *iter)
87 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
89 if (iter->sequence_nos[i] != 0)
96 typedef dbus_bool_t (* DBusInnerGeneratorFunc) (DBusMessageDataIter *iter,
97 DBusMessage **message_p);
98 typedef dbus_bool_t (* DBusMessageGeneratorFunc) (DBusMessageDataIter *iter,
100 DBusValidity *expected_validity);
103 set_reply_serial (DBusMessage *message)
106 _dbus_assert_not_reached ("oom");
107 if (!dbus_message_set_reply_serial (message, 100))
108 _dbus_assert_not_reached ("oom");
112 generate_trivial_inner (DBusMessageDataIter *iter,
113 DBusMessage **message_p)
115 DBusMessage *message;
117 switch (iter_get_sequence (iter))
120 message = dbus_message_new_method_call ("org.freedesktop.TextEditor",
122 "org.freedesktop.DocumentFactory",
126 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
127 set_reply_serial (message);
130 message = dbus_message_new_signal ("/foo/bar",
131 "org.freedesktop.DocumentFactory",
135 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
137 if (!dbus_message_set_error_name (message,
138 "org.freedesktop.TestErrorName"))
139 _dbus_assert_not_reached ("oom");
142 DBusMessageIter iter;
143 const char *v_STRING = "This is an error";
145 dbus_message_iter_init_append (message, &iter);
146 if (!dbus_message_iter_append_basic (&iter,
149 _dbus_assert_not_reached ("oom");
152 set_reply_serial (message);
159 _dbus_assert_not_reached ("oom");
161 *message_p = message;
167 generate_many_bodies_inner (DBusMessageDataIter *iter,
168 DBusMessage **message_p)
170 DBusMessage *message;
171 DBusString signature;
174 /* Keeping this small makes things go faster */
175 message = dbus_message_new_method_call ("o.z.F",
180 _dbus_assert_not_reached ("oom");
182 set_reply_serial (message);
184 if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
185 _dbus_assert_not_reached ("oom");
187 if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter),
191 const char *v_SIGNATURE;
193 v_SIGNATURE = _dbus_string_get_const_data (&signature);
194 if (!_dbus_header_set_field_basic (&message->header,
195 DBUS_HEADER_FIELD_SIGNATURE,
198 _dbus_assert_not_reached ("oom");
200 if (!_dbus_string_move (&body, 0, &message->body, 0))
201 _dbus_assert_not_reached ("oom");
203 _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET,
204 _dbus_string_get_length (&message->body),
205 message->byte_order);
207 *message_p = message;
211 dbus_message_unref (message);
215 _dbus_string_free (&signature);
216 _dbus_string_free (&body);
218 return *message_p != NULL;
222 generate_from_message (DBusString *data,
223 DBusValidity *expected_validity,
224 DBusMessage *message)
226 dbus_message_set_serial (message, 1);
227 dbus_message_lock (message);
229 *expected_validity = DBUS_VALID;
231 /* move for efficiency, since we'll nuke the message anyway */
232 if (!_dbus_string_move (&message->header.data, 0,
234 _dbus_assert_not_reached ("oom");
236 if (!_dbus_string_copy (&message->body, 0,
237 data, _dbus_string_get_length (data)))
238 _dbus_assert_not_reached ("oom");
242 generate_outer (DBusMessageDataIter *iter,
244 DBusValidity *expected_validity,
245 DBusInnerGeneratorFunc func)
247 DBusMessage *message;
250 if (!(*func)(iter, &message))
255 _dbus_assert (message != NULL);
257 generate_from_message (data, expected_validity, message);
259 dbus_message_unref (message);
265 generate_trivial (DBusMessageDataIter *iter,
267 DBusValidity *expected_validity)
269 return generate_outer (iter, data, expected_validity,
270 generate_trivial_inner);
274 generate_many_bodies (DBusMessageDataIter *iter,
276 DBusValidity *expected_validity)
278 return generate_outer (iter, data, expected_validity,
279 generate_many_bodies_inner);
283 simple_method_call (void)
285 DBusMessage *message;
286 /* Keeping this small makes stuff go faster */
287 message = dbus_message_new_method_call ("o.b.Q",
292 _dbus_assert_not_reached ("oom");
299 DBusMessage *message;
300 message = dbus_message_new_signal ("/f/b",
304 _dbus_assert_not_reached ("oom");
309 simple_method_return (void)
311 DBusMessage *message;
312 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
314 _dbus_assert_not_reached ("oom");
316 set_reply_serial (message);
324 DBusMessage *message;
325 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
327 _dbus_assert_not_reached ("oom");
329 if (!dbus_message_set_error_name (message, "foo.bar"))
330 _dbus_assert_not_reached ("oom");
332 set_reply_serial (message);
338 message_with_nesting_levels (int levels)
340 DBusMessage *message;
341 dbus_int32_t v_INT32;
342 DBusMessageIter *parents;
343 DBusMessageIter *children;
346 /* If levels is higher it breaks sig_refcount in DBusMessageRealIter
347 * in dbus-message.c, this assert is just to help you know you need
348 * to fix that if you hit it
350 _dbus_assert (levels < 256);
352 parents = dbus_new(DBusMessageIter, levels + 1);
353 children = dbus_new(DBusMessageIter, levels + 1);
356 message = simple_method_call ();
359 dbus_message_iter_init_append (message, &parents[i]);
362 dbus_message_iter_open_container (&parents[i], DBUS_TYPE_VARIANT,
364 DBUS_TYPE_INT32_AS_STRING :
365 DBUS_TYPE_VARIANT_AS_STRING,
368 parents[i] = children[i-1];
371 dbus_message_iter_append_basic (&children[i], DBUS_TYPE_INT32, &v_INT32);
374 dbus_message_iter_close_container (&parents[i], &children[i]);
385 generate_special (DBusMessageDataIter *iter,
387 DBusValidity *expected_validity)
390 DBusMessage *message;
392 dbus_int32_t v_INT32;
394 _dbus_assert (_dbus_string_get_length (data) == 0);
399 item_seq = iter_get_sequence (iter);
403 message = simple_method_call ();
404 if (!dbus_message_append_args (message,
405 DBUS_TYPE_INT32, &v_INT32,
406 DBUS_TYPE_INT32, &v_INT32,
407 DBUS_TYPE_INT32, &v_INT32,
409 _dbus_assert_not_reached ("oom");
411 _dbus_header_get_field_raw (&message->header,
412 DBUS_HEADER_FIELD_SIGNATURE,
414 generate_from_message (data, expected_validity, message);
416 /* set an invalid typecode */
417 _dbus_string_set_byte (data, pos + 1, '$');
419 *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
421 else if (item_seq == 1)
423 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2];
424 const char *v_STRING;
427 message = simple_method_call ();
428 if (!dbus_message_append_args (message,
429 DBUS_TYPE_INT32, &v_INT32,
430 DBUS_TYPE_INT32, &v_INT32,
431 DBUS_TYPE_INT32, &v_INT32,
433 _dbus_assert_not_reached ("oom");
436 while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
438 long_sig[i] = DBUS_TYPE_ARRAY;
441 long_sig[i] = DBUS_TYPE_INVALID;
444 if (!_dbus_header_set_field_basic (&message->header,
445 DBUS_HEADER_FIELD_SIGNATURE,
448 _dbus_assert_not_reached ("oom");
450 _dbus_header_get_field_raw (&message->header,
451 DBUS_HEADER_FIELD_SIGNATURE,
453 generate_from_message (data, expected_validity, message);
455 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
457 else if (item_seq == 2)
459 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4];
460 const char *v_STRING;
463 message = simple_method_call ();
464 if (!dbus_message_append_args (message,
465 DBUS_TYPE_INT32, &v_INT32,
466 DBUS_TYPE_INT32, &v_INT32,
467 DBUS_TYPE_INT32, &v_INT32,
469 _dbus_assert_not_reached ("oom");
472 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
474 long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
478 long_sig[i] = DBUS_TYPE_INT32;
481 while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
483 long_sig[i] = DBUS_STRUCT_END_CHAR;
486 long_sig[i] = DBUS_TYPE_INVALID;
489 if (!_dbus_header_set_field_basic (&message->header,
490 DBUS_HEADER_FIELD_SIGNATURE,
493 _dbus_assert_not_reached ("oom");
495 _dbus_header_get_field_raw (&message->header,
496 DBUS_HEADER_FIELD_SIGNATURE,
498 generate_from_message (data, expected_validity, message);
500 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
502 else if (item_seq == 3)
504 message = simple_method_call ();
505 if (!dbus_message_append_args (message,
506 DBUS_TYPE_INT32, &v_INT32,
507 DBUS_TYPE_INT32, &v_INT32,
508 DBUS_TYPE_INT32, &v_INT32,
510 _dbus_assert_not_reached ("oom");
512 _dbus_header_get_field_raw (&message->header,
513 DBUS_HEADER_FIELD_SIGNATURE,
515 generate_from_message (data, expected_validity, message);
517 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
519 *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
521 else if (item_seq == 4)
523 message = simple_method_call ();
524 if (!dbus_message_append_args (message,
525 DBUS_TYPE_INT32, &v_INT32,
526 DBUS_TYPE_INT32, &v_INT32,
527 DBUS_TYPE_INT32, &v_INT32,
529 _dbus_assert_not_reached ("oom");
531 _dbus_header_get_field_raw (&message->header,
532 DBUS_HEADER_FIELD_SIGNATURE,
534 generate_from_message (data, expected_validity, message);
536 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
538 *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
540 else if (item_seq == 5)
542 message = simple_method_call ();
543 if (!dbus_message_append_args (message,
544 DBUS_TYPE_INT32, &v_INT32,
545 DBUS_TYPE_INT32, &v_INT32,
546 DBUS_TYPE_INT32, &v_INT32,
548 _dbus_assert_not_reached ("oom");
550 _dbus_header_get_field_raw (&message->header,
551 DBUS_HEADER_FIELD_SIGNATURE,
553 generate_from_message (data, expected_validity, message);
555 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
556 _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
558 *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
560 else if (item_seq == 6)
562 message = simple_method_call ();
563 generate_from_message (data, expected_validity, message);
565 _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
567 *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
569 else if (item_seq == 7)
571 /* Messages of unknown type are considered valid */
572 message = simple_method_call ();
573 generate_from_message (data, expected_validity, message);
575 _dbus_string_set_byte (data, TYPE_OFFSET, 100);
577 *expected_validity = DBUS_VALID;
579 else if (item_seq == 8)
581 message = simple_method_call ();
582 generate_from_message (data, expected_validity, message);
584 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
585 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
586 message->byte_order);
587 _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
588 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
589 message->byte_order);
590 *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
592 else if (item_seq == 9)
594 const char *v_STRING = "not a valid bus name";
595 message = simple_method_call ();
597 if (!_dbus_header_set_field_basic (&message->header,
598 DBUS_HEADER_FIELD_SENDER,
599 DBUS_TYPE_STRING, &v_STRING))
600 _dbus_assert_not_reached ("oom");
602 generate_from_message (data, expected_validity, message);
604 *expected_validity = DBUS_INVALID_BAD_SENDER;
606 else if (item_seq == 10)
608 message = simple_method_call ();
610 if (!dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL))
611 _dbus_assert_not_reached ("oom");
613 generate_from_message (data, expected_validity, message);
615 *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
617 else if (item_seq == 11)
619 message = simple_method_call ();
621 if (!dbus_message_set_path (message, DBUS_PATH_LOCAL))
622 _dbus_assert_not_reached ("oom");
624 generate_from_message (data, expected_validity, message);
626 *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
628 else if (item_seq == 12)
630 /* Method calls don't have to have interface */
631 message = simple_method_call ();
633 if (!dbus_message_set_interface (message, NULL))
634 _dbus_assert_not_reached ("oom");
636 generate_from_message (data, expected_validity, message);
638 *expected_validity = DBUS_VALID;
640 else if (item_seq == 13)
642 /* Signals require an interface */
643 message = simple_signal ();
645 if (!dbus_message_set_interface (message, NULL))
646 _dbus_assert_not_reached ("oom");
648 generate_from_message (data, expected_validity, message);
650 *expected_validity = DBUS_INVALID_MISSING_INTERFACE;
652 else if (item_seq == 14)
654 message = simple_method_return ();
656 if (!_dbus_header_delete_field (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL))
657 _dbus_assert_not_reached ("oom");
659 generate_from_message (data, expected_validity, message);
661 *expected_validity = DBUS_INVALID_MISSING_REPLY_SERIAL;
663 else if (item_seq == 15)
665 message = simple_error ();
667 if (!dbus_message_set_error_name (message, NULL))
668 _dbus_assert_not_reached ("oom");
670 generate_from_message (data, expected_validity, message);
672 *expected_validity = DBUS_INVALID_MISSING_ERROR_NAME;
674 else if (item_seq == 16)
676 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*4+10];
677 const char *v_STRING;
681 message = simple_method_call ();
682 if (!dbus_message_append_args (message,
683 DBUS_TYPE_INT32, &v_INT32,
684 DBUS_TYPE_INT32, &v_INT32,
685 DBUS_TYPE_INT32, &v_INT32,
687 _dbus_assert_not_reached ("oom");
690 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*3 + 3))
692 long_sig[i] = DBUS_TYPE_ARRAY;
694 long_sig[i] = DBUS_DICT_ENTRY_BEGIN_CHAR;
696 long_sig[i] = DBUS_TYPE_INT32;
701 long_sig[i] = DBUS_TYPE_INT32;
706 long_sig[i] = DBUS_DICT_ENTRY_END_CHAR;
710 long_sig[i] = DBUS_TYPE_INVALID;
713 if (!_dbus_header_set_field_basic (&message->header,
714 DBUS_HEADER_FIELD_SIGNATURE,
717 _dbus_assert_not_reached ("oom");
719 _dbus_header_get_field_raw (&message->header,
720 DBUS_HEADER_FIELD_SIGNATURE,
722 generate_from_message (data, expected_validity, message);
724 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
726 else if (item_seq == 17)
728 message = simple_method_call ();
729 if (!dbus_message_append_args (message,
730 DBUS_TYPE_INT32, &v_INT32,
731 DBUS_TYPE_INT32, &v_INT32,
732 DBUS_TYPE_INT32, &v_INT32,
734 _dbus_assert_not_reached ("oom");
736 _dbus_header_get_field_raw (&message->header,
737 DBUS_HEADER_FIELD_SIGNATURE,
739 generate_from_message (data, expected_validity, message);
741 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
742 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
744 *expected_validity = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
746 else if (item_seq == 18)
748 message = simple_method_call ();
749 if (!dbus_message_append_args (message,
750 DBUS_TYPE_INT32, &v_INT32,
751 DBUS_TYPE_INT32, &v_INT32,
752 DBUS_TYPE_INT32, &v_INT32,
754 _dbus_assert_not_reached ("oom");
756 _dbus_header_get_field_raw (&message->header,
757 DBUS_HEADER_FIELD_SIGNATURE,
759 generate_from_message (data, expected_validity, message);
761 _dbus_string_set_byte (data, pos + 1, DBUS_DICT_ENTRY_END_CHAR);
763 *expected_validity = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
765 else if (item_seq == 19)
767 message = simple_method_call ();
768 if (!dbus_message_append_args (message,
769 DBUS_TYPE_INT32, &v_INT32,
770 DBUS_TYPE_INT32, &v_INT32,
771 DBUS_TYPE_INT32, &v_INT32,
773 _dbus_assert_not_reached ("oom");
775 _dbus_header_get_field_raw (&message->header,
776 DBUS_HEADER_FIELD_SIGNATURE,
778 generate_from_message (data, expected_validity, message);
780 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
781 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
782 _dbus_string_set_byte (data, pos + 3, DBUS_DICT_ENTRY_END_CHAR);
784 *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
786 else if (item_seq == 20)
788 /* 64 levels of nesting is OK */
789 message = message_with_nesting_levels(64);
791 generate_from_message (data, expected_validity, message);
793 *expected_validity = DBUS_VALID;
795 else if (item_seq == 21)
797 /* 65 levels of nesting is not OK */
798 message = message_with_nesting_levels(65);
800 generate_from_message (data, expected_validity, message);
802 *expected_validity = DBUS_INVALID_NESTED_TOO_DEEPLY;
810 dbus_message_unref (message);
817 generate_wrong_length (DBusMessageDataIter *iter,
819 DBusValidity *expected_validity)
821 int lengths[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1,
822 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 };
827 len_seq = iter_get_sequence (iter);
828 if (len_seq == _DBUS_N_ELEMENTS (lengths))
831 _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths));
834 if (!generate_many_bodies (iter, data, expected_validity))
836 iter_set_sequence (iter, 0); /* reset to first body */
837 iter_unrecurse (iter);
838 iter_next (iter); /* next length adjustment */
841 iter_unrecurse (iter);
843 adjust = lengths[len_seq];
847 if ((_dbus_string_get_length (data) + adjust) < DBUS_MINIMUM_HEADER_SIZE)
848 _dbus_string_set_length (data, DBUS_MINIMUM_HEADER_SIZE);
850 _dbus_string_shorten (data, - adjust);
851 *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON;
855 if (!_dbus_string_lengthen (data, adjust))
856 _dbus_assert_not_reached ("oom");
857 *expected_validity = DBUS_INVALID_TOO_MUCH_DATA;
866 _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE);
868 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
869 old_body_len = _dbus_marshal_read_uint32 (data,
873 _dbus_assert (old_body_len < _dbus_string_get_length (data));
874 new_body_len = old_body_len + adjust;
875 if (new_body_len < 0)
878 /* we just munged the header, and aren't sure how */
879 *expected_validity = DBUS_VALIDITY_UNKNOWN;
882 _dbus_verbose ("changing body len from %u to %u by adjust %d\n",
883 old_body_len, new_body_len, adjust);
885 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
894 generate_byte_changed (DBusMessageDataIter *iter,
896 DBusValidity *expected_validity)
901 /* This is a little convoluted to make the bodies the
902 * outer loop and each byte of each body the inner
907 if (!generate_many_bodies (iter, data, expected_validity))
911 byte_seq = iter_get_sequence (iter);
913 iter_unrecurse (iter);
915 if (byte_seq == _dbus_string_get_length (data))
917 _dbus_string_set_length (data, 0);
918 /* reset byte count */
920 iter_set_sequence (iter, 0);
921 iter_unrecurse (iter);
926 /* Undo the "next" in generate_many_bodies */
927 iter_set_sequence (iter, iter_get_sequence (iter) - 1);
930 _dbus_assert (byte_seq < _dbus_string_get_length (data));
931 v_BYTE = _dbus_string_get_byte (data, byte_seq);
932 v_BYTE += byte_seq; /* arbitrary but deterministic change to the byte */
933 _dbus_string_set_byte (data, byte_seq, v_BYTE);
934 *expected_validity = DBUS_VALIDITY_UNKNOWN;
940 find_next_typecode (DBusMessageDataIter *iter,
942 DBusValidity *expected_validity)
948 base_depth = iter->depth;
951 _dbus_assert (iter->depth == (base_depth + 0));
952 _dbus_string_set_length (data, 0);
954 body_seq = iter_get_sequence (iter);
956 if (!generate_many_bodies (iter, data, expected_validity))
958 /* Undo the "next" in generate_many_bodies */
959 iter_set_sequence (iter, body_seq);
964 _dbus_assert (iter->depth == (base_depth + 1));
966 byte_seq = iter_get_sequence (iter);
968 _dbus_assert (byte_seq <= _dbus_string_get_length (data));
970 if (byte_seq == _dbus_string_get_length (data))
972 /* reset byte count */
973 iter_set_sequence (iter, 0);
974 iter_unrecurse (iter);
975 _dbus_assert (iter->depth == (base_depth + 0));
976 iter_next (iter); /* go to the next body */
980 _dbus_assert (byte_seq < _dbus_string_get_length (data));
982 if (dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq)))
988 _dbus_assert (byte_seq == iter_get_sequence (iter));
989 _dbus_assert (byte_seq < _dbus_string_get_length (data));
991 iter_unrecurse (iter);
993 _dbus_assert (iter->depth == (base_depth + 0));
998 static const int typecodes[] = {
1010 DBUS_TYPE_OBJECT_PATH,
1011 DBUS_TYPE_SIGNATURE,
1014 DBUS_STRUCT_BEGIN_CHAR,
1015 DBUS_STRUCT_END_CHAR,
1016 DBUS_DICT_ENTRY_BEGIN_CHAR,
1017 DBUS_DICT_ENTRY_END_CHAR,
1019 255 /* random invalid typecode */
1023 generate_typecode_changed (DBusMessageDataIter *iter,
1025 DBusValidity *expected_validity)
1031 base_depth = iter->depth;
1034 _dbus_assert (iter->depth == (base_depth + 0));
1035 _dbus_string_set_length (data, 0);
1037 if (!find_next_typecode (iter, data, expected_validity))
1040 iter_recurse (iter);
1041 byte_seq = iter_get_sequence (iter);
1043 _dbus_assert (byte_seq < _dbus_string_get_length (data));
1045 iter_recurse (iter);
1046 typecode_seq = iter_get_sequence (iter);
1049 _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes));
1051 if (typecode_seq == _DBUS_N_ELEMENTS (typecodes))
1053 _dbus_assert (iter->depth == (base_depth + 2));
1054 iter_set_sequence (iter, 0); /* reset typecode sequence */
1055 iter_unrecurse (iter);
1056 _dbus_assert (iter->depth == (base_depth + 1));
1057 iter_next (iter); /* go to the next byte_seq */
1058 iter_unrecurse (iter);
1059 _dbus_assert (iter->depth == (base_depth + 0));
1063 _dbus_assert (iter->depth == (base_depth + 2));
1064 iter_unrecurse (iter);
1065 _dbus_assert (iter->depth == (base_depth + 1));
1066 iter_unrecurse (iter);
1067 _dbus_assert (iter->depth == (base_depth + 0));
1070 printf ("Changing byte %d in message %d to %c\n",
1071 byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]);
1074 _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]);
1075 *expected_validity = DBUS_VALIDITY_UNKNOWN;
1082 dbus_uint32_t value; /* cast to signed for adjusts */
1085 static const UIntChange uint32_changes[] = {
1086 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -1 },
1087 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -2 },
1088 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -3 },
1089 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 1 },
1090 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 2 },
1091 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 3 },
1092 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX },
1093 { CHANGE_TYPE_ABSOLUTE, 0 },
1094 { CHANGE_TYPE_ABSOLUTE, 1 },
1095 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 1 },
1096 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 5 }
1100 generate_uint32_changed (DBusMessageDataIter *iter,
1102 DBusValidity *expected_validity)
1107 dbus_uint32_t v_UINT32;
1109 const UIntChange *change;
1112 /* Outer loop is each body, next loop is each change,
1113 * inner loop is each change location
1116 base_depth = iter->depth;
1119 _dbus_assert (iter->depth == (base_depth + 0));
1120 _dbus_string_set_length (data, 0);
1121 body_seq = iter_get_sequence (iter);
1123 if (!generate_many_bodies (iter, data, expected_validity))
1126 _dbus_assert (iter->depth == (base_depth + 0));
1128 iter_set_sequence (iter, body_seq); /* undo the "next" from generate_many_bodies */
1129 iter_recurse (iter);
1131 _dbus_assert (iter->depth == (base_depth + 1));
1132 change_seq = iter_get_sequence (iter);
1134 if (change_seq == _DBUS_N_ELEMENTS (uint32_changes))
1136 /* Reset change count */
1137 iter_set_sequence (iter, 0);
1138 iter_unrecurse (iter);
1143 _dbus_assert (iter->depth == (base_depth + 1));
1145 iter_recurse (iter);
1146 _dbus_assert (iter->depth == (base_depth + 2));
1147 byte_seq = iter_get_sequence (iter);
1148 /* skip 4 bytes at a time */
1153 iter_unrecurse (iter);
1155 _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq, 4) == (unsigned) byte_seq);
1156 if (byte_seq >= (_dbus_string_get_length (data) - 4))
1158 /* reset byte count */
1159 _dbus_assert (iter->depth == (base_depth + 1));
1160 iter_recurse (iter);
1161 _dbus_assert (iter->depth == (base_depth + 2));
1162 iter_set_sequence (iter, 0);
1163 iter_unrecurse (iter);
1164 _dbus_assert (iter->depth == (base_depth + 1));
1169 _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4));
1171 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
1173 v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL);
1175 change = &uint32_changes[change_seq];
1177 if (change->type == CHANGE_TYPE_ADJUST)
1179 v_UINT32 += (int) change->value;
1183 v_UINT32 = change->value;
1187 printf ("body %d change %d pos %d ",
1188 body_seq, change_seq, byte_seq);
1190 if (change->type == CHANGE_TYPE_ADJUST)
1191 printf ("adjust by %d", (int) change->value);
1193 printf ("set to %u", change->value);
1195 printf (" \t%u -> %u\n",
1196 _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL),
1200 _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order);
1201 *expected_validity = DBUS_VALIDITY_UNKNOWN;
1203 _dbus_assert (iter->depth == (base_depth + 1));
1204 iter_unrecurse (iter);
1205 _dbus_assert (iter->depth == (base_depth + 0));
1213 DBusMessageGeneratorFunc func;
1214 } DBusMessageGenerator;
1216 static const DBusMessageGenerator generators[] = {
1217 { "trivial example of each message type", generate_trivial },
1218 { "assorted arguments", generate_many_bodies },
1219 { "assorted special cases", generate_special },
1220 { "each uint32 modified", generate_uint32_changed },
1221 { "wrong body lengths", generate_wrong_length },
1222 { "each byte modified", generate_byte_changed },
1224 /* This is really expensive and doesn't add too much coverage */
1225 { "change each typecode", generate_typecode_changed }
1230 _dbus_message_data_free (DBusMessageData *data)
1232 _dbus_string_free (&data->data);
1236 _dbus_message_data_iter_init (DBusMessageDataIter *iter)
1242 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
1244 iter->sequence_nos[i] = 0;
1251 _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
1252 DBusMessageData *data)
1254 DBusMessageGeneratorFunc func;
1258 generator = iter_get_sequence (iter);
1260 if (generator == _DBUS_N_ELEMENTS (generators))
1263 iter_recurse (iter);
1265 if (iter_first_in_series (iter))
1267 printf (" testing message loading: %s ", generators[generator].name);
1271 func = generators[generator].func;
1273 if (!_dbus_string_init (&data->data))
1274 _dbus_assert_not_reached ("oom");
1276 if ((*func)(iter, &data->data, &data->expected_validity))
1280 iter_set_sequence (iter, 0);
1281 iter_unrecurse (iter);
1282 iter_next (iter); /* next generator */
1283 _dbus_string_free (&data->data);
1284 printf ("%d test loads cumulative\n", iter->count);
1287 iter_unrecurse (iter);
1293 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */
1295 #endif /* DBUS_BUILD_TESTS */