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_ENABLE_EMBEDDED_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 iter2;
143 const char *v_STRING = "This is an error";
145 dbus_message_iter_init_append (message, &iter2);
146 if (!dbus_message_iter_append_basic (&iter2,
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;
175 /* Keeping this small makes things go faster */
176 message = dbus_message_new_method_call ("o.z.F",
181 _dbus_assert_not_reached ("oom");
183 byte_order = _dbus_header_get_byte_order (&message->header);
185 set_reply_serial (message);
187 if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
188 _dbus_assert_not_reached ("oom");
190 if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter),
194 const char *v_SIGNATURE;
196 v_SIGNATURE = _dbus_string_get_const_data (&signature);
197 if (!_dbus_header_set_field_basic (&message->header,
198 DBUS_HEADER_FIELD_SIGNATURE,
201 _dbus_assert_not_reached ("oom");
203 if (!_dbus_string_move (&body, 0, &message->body, 0))
204 _dbus_assert_not_reached ("oom");
206 _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET,
207 _dbus_string_get_length (&message->body),
210 *message_p = message;
214 dbus_message_unref (message);
218 _dbus_string_free (&signature);
219 _dbus_string_free (&body);
221 return *message_p != NULL;
225 generate_from_message (DBusString *data,
226 DBusValidity *expected_validity,
227 DBusMessage *message)
229 dbus_message_set_serial (message, 1);
230 dbus_message_lock (message);
232 *expected_validity = DBUS_VALID;
234 /* move for efficiency, since we'll nuke the message anyway */
235 if (!_dbus_string_move (&message->header.data, 0,
237 _dbus_assert_not_reached ("oom");
239 if (!_dbus_string_copy (&message->body, 0,
240 data, _dbus_string_get_length (data)))
241 _dbus_assert_not_reached ("oom");
245 generate_outer (DBusMessageDataIter *iter,
247 DBusValidity *expected_validity,
248 DBusInnerGeneratorFunc func)
250 DBusMessage *message;
253 if (!(*func)(iter, &message))
258 _dbus_assert (message != NULL);
260 generate_from_message (data, expected_validity, message);
262 dbus_message_unref (message);
268 generate_trivial (DBusMessageDataIter *iter,
270 DBusValidity *expected_validity)
272 return generate_outer (iter, data, expected_validity,
273 generate_trivial_inner);
277 generate_many_bodies (DBusMessageDataIter *iter,
279 DBusValidity *expected_validity)
281 return generate_outer (iter, data, expected_validity,
282 generate_many_bodies_inner);
286 simple_method_call (void)
288 DBusMessage *message;
289 /* Keeping this small makes stuff go faster */
290 message = dbus_message_new_method_call ("o.b.Q",
295 _dbus_assert_not_reached ("oom");
302 DBusMessage *message;
303 message = dbus_message_new_signal ("/f/b",
307 _dbus_assert_not_reached ("oom");
312 simple_method_return (void)
314 DBusMessage *message;
315 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
317 _dbus_assert_not_reached ("oom");
319 set_reply_serial (message);
327 DBusMessage *message;
328 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
330 _dbus_assert_not_reached ("oom");
332 if (!dbus_message_set_error_name (message, "foo.bar"))
333 _dbus_assert_not_reached ("oom");
335 set_reply_serial (message);
341 message_with_nesting_levels (int levels)
343 DBusMessage *message;
344 dbus_int32_t v_INT32;
345 DBusMessageIter *parents;
346 DBusMessageIter *children;
349 /* If levels is higher it breaks sig_refcount in DBusMessageRealIter
350 * in dbus-message.c, this assert is just to help you know you need
351 * to fix that if you hit it
353 _dbus_assert (levels < 256);
355 parents = dbus_new(DBusMessageIter, levels + 1);
356 children = dbus_new(DBusMessageIter, levels + 1);
359 message = simple_method_call ();
362 dbus_message_iter_init_append (message, &parents[i]);
365 if (!dbus_message_iter_open_container (&parents[i], DBUS_TYPE_VARIANT,
367 DBUS_TYPE_INT32_AS_STRING :
368 DBUS_TYPE_VARIANT_AS_STRING,
370 _dbus_assert_not_reached ("oom");
372 parents[i] = children[i-1];
376 if (!dbus_message_iter_append_basic (&children[i], DBUS_TYPE_INT32, &v_INT32))
377 _dbus_assert_not_reached ("oom");
381 if (!dbus_message_iter_close_container (&parents[i], &children[i]))
382 _dbus_assert_not_reached ("oom");
393 generate_special (DBusMessageDataIter *iter,
395 DBusValidity *expected_validity)
398 DBusMessage *message;
400 dbus_int32_t v_INT32;
402 _dbus_assert (_dbus_string_get_length (data) == 0);
407 item_seq = iter_get_sequence (iter);
411 message = simple_method_call ();
412 if (!dbus_message_append_args (message,
413 DBUS_TYPE_INT32, &v_INT32,
414 DBUS_TYPE_INT32, &v_INT32,
415 DBUS_TYPE_INT32, &v_INT32,
417 _dbus_assert_not_reached ("oom");
419 _dbus_header_get_field_raw (&message->header,
420 DBUS_HEADER_FIELD_SIGNATURE,
422 generate_from_message (data, expected_validity, message);
424 /* set an invalid typecode */
425 _dbus_string_set_byte (data, pos + 1, '$');
427 *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
429 else if (item_seq == 1)
431 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2];
432 const char *v_STRING;
435 message = simple_method_call ();
436 if (!dbus_message_append_args (message,
437 DBUS_TYPE_INT32, &v_INT32,
438 DBUS_TYPE_INT32, &v_INT32,
439 DBUS_TYPE_INT32, &v_INT32,
441 _dbus_assert_not_reached ("oom");
444 while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
446 long_sig[i] = DBUS_TYPE_ARRAY;
449 long_sig[i] = DBUS_TYPE_INVALID;
452 if (!_dbus_header_set_field_basic (&message->header,
453 DBUS_HEADER_FIELD_SIGNATURE,
456 _dbus_assert_not_reached ("oom");
458 _dbus_header_get_field_raw (&message->header,
459 DBUS_HEADER_FIELD_SIGNATURE,
461 generate_from_message (data, expected_validity, message);
463 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
465 else if (item_seq == 2)
467 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4];
468 const char *v_STRING;
471 message = simple_method_call ();
472 if (!dbus_message_append_args (message,
473 DBUS_TYPE_INT32, &v_INT32,
474 DBUS_TYPE_INT32, &v_INT32,
475 DBUS_TYPE_INT32, &v_INT32,
477 _dbus_assert_not_reached ("oom");
480 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
482 long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
486 long_sig[i] = DBUS_TYPE_INT32;
489 while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
491 long_sig[i] = DBUS_STRUCT_END_CHAR;
494 long_sig[i] = DBUS_TYPE_INVALID;
497 if (!_dbus_header_set_field_basic (&message->header,
498 DBUS_HEADER_FIELD_SIGNATURE,
501 _dbus_assert_not_reached ("oom");
503 _dbus_header_get_field_raw (&message->header,
504 DBUS_HEADER_FIELD_SIGNATURE,
506 generate_from_message (data, expected_validity, message);
508 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
510 else if (item_seq == 3)
512 message = simple_method_call ();
513 if (!dbus_message_append_args (message,
514 DBUS_TYPE_INT32, &v_INT32,
515 DBUS_TYPE_INT32, &v_INT32,
516 DBUS_TYPE_INT32, &v_INT32,
518 _dbus_assert_not_reached ("oom");
520 _dbus_header_get_field_raw (&message->header,
521 DBUS_HEADER_FIELD_SIGNATURE,
523 generate_from_message (data, expected_validity, message);
525 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
527 *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
529 else if (item_seq == 4)
531 message = simple_method_call ();
532 if (!dbus_message_append_args (message,
533 DBUS_TYPE_INT32, &v_INT32,
534 DBUS_TYPE_INT32, &v_INT32,
535 DBUS_TYPE_INT32, &v_INT32,
537 _dbus_assert_not_reached ("oom");
539 _dbus_header_get_field_raw (&message->header,
540 DBUS_HEADER_FIELD_SIGNATURE,
542 generate_from_message (data, expected_validity, message);
544 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
546 *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
548 else if (item_seq == 5)
550 message = simple_method_call ();
551 if (!dbus_message_append_args (message,
552 DBUS_TYPE_INT32, &v_INT32,
553 DBUS_TYPE_INT32, &v_INT32,
554 DBUS_TYPE_INT32, &v_INT32,
556 _dbus_assert_not_reached ("oom");
558 _dbus_header_get_field_raw (&message->header,
559 DBUS_HEADER_FIELD_SIGNATURE,
561 generate_from_message (data, expected_validity, message);
563 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
564 _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
566 *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
568 else if (item_seq == 6)
570 message = simple_method_call ();
571 generate_from_message (data, expected_validity, message);
573 _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
575 *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
577 else if (item_seq == 7)
579 /* Messages of unknown type are considered valid */
580 message = simple_method_call ();
581 generate_from_message (data, expected_validity, message);
583 _dbus_string_set_byte (data, TYPE_OFFSET, 100);
585 *expected_validity = DBUS_VALID;
587 else if (item_seq == 8)
591 message = simple_method_call ();
592 byte_order = _dbus_header_get_byte_order (&message->header);
593 generate_from_message (data, expected_validity, message);
595 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
596 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
598 _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
599 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
601 *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
603 else if (item_seq == 9)
605 const char *v_STRING = "not a valid bus name";
606 message = simple_method_call ();
608 if (!_dbus_header_set_field_basic (&message->header,
609 DBUS_HEADER_FIELD_SENDER,
610 DBUS_TYPE_STRING, &v_STRING))
611 _dbus_assert_not_reached ("oom");
613 generate_from_message (data, expected_validity, message);
615 *expected_validity = DBUS_INVALID_BAD_SENDER;
617 else if (item_seq == 10)
619 message = simple_method_call ();
621 if (!dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL))
622 _dbus_assert_not_reached ("oom");
624 generate_from_message (data, expected_validity, message);
626 *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
628 else if (item_seq == 11)
630 message = simple_method_call ();
632 if (!dbus_message_set_path (message, DBUS_PATH_LOCAL))
633 _dbus_assert_not_reached ("oom");
635 generate_from_message (data, expected_validity, message);
637 *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
639 else if (item_seq == 12)
641 /* Method calls don't have to have interface */
642 message = simple_method_call ();
644 if (!dbus_message_set_interface (message, NULL))
645 _dbus_assert_not_reached ("oom");
647 generate_from_message (data, expected_validity, message);
649 *expected_validity = DBUS_VALID;
651 else if (item_seq == 13)
653 /* Signals require an interface */
654 message = simple_signal ();
656 if (!dbus_message_set_interface (message, NULL))
657 _dbus_assert_not_reached ("oom");
659 generate_from_message (data, expected_validity, message);
661 *expected_validity = DBUS_INVALID_MISSING_INTERFACE;
663 else if (item_seq == 14)
665 message = simple_method_return ();
667 if (!_dbus_header_delete_field (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL))
668 _dbus_assert_not_reached ("oom");
670 generate_from_message (data, expected_validity, message);
672 *expected_validity = DBUS_INVALID_MISSING_REPLY_SERIAL;
674 else if (item_seq == 15)
676 message = simple_error ();
678 if (!dbus_message_set_error_name (message, NULL))
679 _dbus_assert_not_reached ("oom");
681 generate_from_message (data, expected_validity, message);
683 *expected_validity = DBUS_INVALID_MISSING_ERROR_NAME;
685 else if (item_seq == 16)
687 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*4+10];
688 const char *v_STRING;
692 message = simple_method_call ();
693 if (!dbus_message_append_args (message,
694 DBUS_TYPE_INT32, &v_INT32,
695 DBUS_TYPE_INT32, &v_INT32,
696 DBUS_TYPE_INT32, &v_INT32,
698 _dbus_assert_not_reached ("oom");
701 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*3 + 3))
703 long_sig[i] = DBUS_TYPE_ARRAY;
705 long_sig[i] = DBUS_DICT_ENTRY_BEGIN_CHAR;
707 long_sig[i] = DBUS_TYPE_INT32;
712 long_sig[i] = DBUS_TYPE_INT32;
717 long_sig[i] = DBUS_DICT_ENTRY_END_CHAR;
721 long_sig[i] = DBUS_TYPE_INVALID;
724 if (!_dbus_header_set_field_basic (&message->header,
725 DBUS_HEADER_FIELD_SIGNATURE,
728 _dbus_assert_not_reached ("oom");
730 _dbus_header_get_field_raw (&message->header,
731 DBUS_HEADER_FIELD_SIGNATURE,
733 generate_from_message (data, expected_validity, message);
735 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
737 else if (item_seq == 17)
739 message = simple_method_call ();
740 if (!dbus_message_append_args (message,
741 DBUS_TYPE_INT32, &v_INT32,
742 DBUS_TYPE_INT32, &v_INT32,
743 DBUS_TYPE_INT32, &v_INT32,
745 _dbus_assert_not_reached ("oom");
747 _dbus_header_get_field_raw (&message->header,
748 DBUS_HEADER_FIELD_SIGNATURE,
750 generate_from_message (data, expected_validity, message);
752 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
753 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
755 *expected_validity = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
757 else if (item_seq == 18)
759 message = simple_method_call ();
760 if (!dbus_message_append_args (message,
761 DBUS_TYPE_INT32, &v_INT32,
762 DBUS_TYPE_INT32, &v_INT32,
763 DBUS_TYPE_INT32, &v_INT32,
765 _dbus_assert_not_reached ("oom");
767 _dbus_header_get_field_raw (&message->header,
768 DBUS_HEADER_FIELD_SIGNATURE,
770 generate_from_message (data, expected_validity, message);
772 _dbus_string_set_byte (data, pos + 1, DBUS_DICT_ENTRY_END_CHAR);
774 *expected_validity = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
776 else if (item_seq == 19)
778 message = simple_method_call ();
779 if (!dbus_message_append_args (message,
780 DBUS_TYPE_INT32, &v_INT32,
781 DBUS_TYPE_INT32, &v_INT32,
782 DBUS_TYPE_INT32, &v_INT32,
784 _dbus_assert_not_reached ("oom");
786 _dbus_header_get_field_raw (&message->header,
787 DBUS_HEADER_FIELD_SIGNATURE,
789 generate_from_message (data, expected_validity, message);
791 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
792 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
793 _dbus_string_set_byte (data, pos + 3, DBUS_DICT_ENTRY_END_CHAR);
795 *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
797 else if (item_seq == 20)
799 /* 64 levels of nesting is OK */
800 message = message_with_nesting_levels(64);
802 generate_from_message (data, expected_validity, message);
804 *expected_validity = DBUS_VALID;
806 else if (item_seq == 21)
808 /* 65 levels of nesting is not OK */
809 message = message_with_nesting_levels(65);
811 generate_from_message (data, expected_validity, message);
813 *expected_validity = DBUS_INVALID_NESTED_TOO_DEEPLY;
821 dbus_message_unref (message);
828 generate_wrong_length (DBusMessageDataIter *iter,
830 DBusValidity *expected_validity)
832 int lengths[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1,
833 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 };
838 len_seq = iter_get_sequence (iter);
839 if (len_seq == _DBUS_N_ELEMENTS (lengths))
842 _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths));
845 if (!generate_many_bodies (iter, data, expected_validity))
847 iter_set_sequence (iter, 0); /* reset to first body */
848 iter_unrecurse (iter);
849 iter_next (iter); /* next length adjustment */
852 iter_unrecurse (iter);
854 adjust = lengths[len_seq];
858 if ((_dbus_string_get_length (data) + adjust) < DBUS_MINIMUM_HEADER_SIZE)
859 _dbus_string_set_length (data, DBUS_MINIMUM_HEADER_SIZE);
861 _dbus_string_shorten (data, - adjust);
862 *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON;
866 if (!_dbus_string_lengthen (data, adjust))
867 _dbus_assert_not_reached ("oom");
868 *expected_validity = DBUS_INVALID_TOO_MUCH_DATA;
877 _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE);
879 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
880 old_body_len = _dbus_marshal_read_uint32 (data,
884 _dbus_assert (old_body_len < _dbus_string_get_length (data));
885 new_body_len = old_body_len + adjust;
886 if (new_body_len < 0)
889 /* we just munged the header, and aren't sure how */
890 *expected_validity = DBUS_VALIDITY_UNKNOWN;
893 _dbus_verbose ("changing body len from %u to %u by adjust %d\n",
894 old_body_len, new_body_len, adjust);
896 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
905 generate_byte_changed (DBusMessageDataIter *iter,
907 DBusValidity *expected_validity)
912 /* This is a little convoluted to make the bodies the
913 * outer loop and each byte of each body the inner
918 if (!generate_many_bodies (iter, data, expected_validity))
922 byte_seq = iter_get_sequence (iter);
924 iter_unrecurse (iter);
926 if (byte_seq == _dbus_string_get_length (data))
928 _dbus_string_set_length (data, 0);
929 /* reset byte count */
931 iter_set_sequence (iter, 0);
932 iter_unrecurse (iter);
937 /* Undo the "next" in generate_many_bodies */
938 iter_set_sequence (iter, iter_get_sequence (iter) - 1);
941 _dbus_assert (byte_seq < _dbus_string_get_length (data));
942 v_BYTE = _dbus_string_get_byte (data, byte_seq);
943 v_BYTE += byte_seq; /* arbitrary but deterministic change to the byte */
944 _dbus_string_set_byte (data, byte_seq, v_BYTE);
945 *expected_validity = DBUS_VALIDITY_UNKNOWN;
951 /* This is really expensive and doesn't add too much coverage */
954 find_next_typecode (DBusMessageDataIter *iter,
956 DBusValidity *expected_validity)
962 base_depth = iter->depth;
965 _dbus_assert (iter->depth == (base_depth + 0));
966 _dbus_string_set_length (data, 0);
968 body_seq = iter_get_sequence (iter);
970 if (!generate_many_bodies (iter, data, expected_validity))
972 /* Undo the "next" in generate_many_bodies */
973 iter_set_sequence (iter, body_seq);
978 _dbus_assert (iter->depth == (base_depth + 1));
980 byte_seq = iter_get_sequence (iter);
982 _dbus_assert (byte_seq <= _dbus_string_get_length (data));
984 if (byte_seq == _dbus_string_get_length (data))
986 /* reset byte count */
987 iter_set_sequence (iter, 0);
988 iter_unrecurse (iter);
989 _dbus_assert (iter->depth == (base_depth + 0));
990 iter_next (iter); /* go to the next body */
994 _dbus_assert (byte_seq < _dbus_string_get_length (data));
996 if (dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq)))
1002 _dbus_assert (byte_seq == iter_get_sequence (iter));
1003 _dbus_assert (byte_seq < _dbus_string_get_length (data));
1005 iter_unrecurse (iter);
1007 _dbus_assert (iter->depth == (base_depth + 0));
1012 static const int typecodes[] = {
1024 DBUS_TYPE_OBJECT_PATH,
1025 DBUS_TYPE_SIGNATURE,
1028 DBUS_STRUCT_BEGIN_CHAR,
1029 DBUS_STRUCT_END_CHAR,
1030 DBUS_DICT_ENTRY_BEGIN_CHAR,
1031 DBUS_DICT_ENTRY_END_CHAR,
1033 255 /* random invalid typecode */
1037 generate_typecode_changed (DBusMessageDataIter *iter,
1039 DBusValidity *expected_validity)
1045 base_depth = iter->depth;
1048 _dbus_assert (iter->depth == (base_depth + 0));
1049 _dbus_string_set_length (data, 0);
1051 if (!find_next_typecode (iter, data, expected_validity))
1054 iter_recurse (iter);
1055 byte_seq = iter_get_sequence (iter);
1057 _dbus_assert (byte_seq < _dbus_string_get_length (data));
1059 iter_recurse (iter);
1060 typecode_seq = iter_get_sequence (iter);
1063 _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes));
1065 if (typecode_seq == _DBUS_N_ELEMENTS (typecodes))
1067 _dbus_assert (iter->depth == (base_depth + 2));
1068 iter_set_sequence (iter, 0); /* reset typecode sequence */
1069 iter_unrecurse (iter);
1070 _dbus_assert (iter->depth == (base_depth + 1));
1071 iter_next (iter); /* go to the next byte_seq */
1072 iter_unrecurse (iter);
1073 _dbus_assert (iter->depth == (base_depth + 0));
1077 _dbus_assert (iter->depth == (base_depth + 2));
1078 iter_unrecurse (iter);
1079 _dbus_assert (iter->depth == (base_depth + 1));
1080 iter_unrecurse (iter);
1081 _dbus_assert (iter->depth == (base_depth + 0));
1084 printf ("Changing byte %d in message %d to %c\n",
1085 byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]);
1088 _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]);
1089 *expected_validity = DBUS_VALIDITY_UNKNOWN;
1097 dbus_uint32_t value; /* cast to signed for adjusts */
1100 static const UIntChange uint32_changes[] = {
1101 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -1 },
1102 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -2 },
1103 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -3 },
1104 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 1 },
1105 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 2 },
1106 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 3 },
1107 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX },
1108 { CHANGE_TYPE_ABSOLUTE, 0 },
1109 { CHANGE_TYPE_ABSOLUTE, 1 },
1110 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 1 },
1111 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 5 }
1115 generate_uint32_changed (DBusMessageDataIter *iter,
1117 DBusValidity *expected_validity)
1122 dbus_uint32_t v_UINT32;
1124 const UIntChange *change;
1127 /* Outer loop is each body, next loop is each change,
1128 * inner loop is each change location
1131 base_depth = iter->depth;
1134 _dbus_assert (iter->depth == (base_depth + 0));
1135 _dbus_string_set_length (data, 0);
1136 body_seq = iter_get_sequence (iter);
1138 if (!generate_many_bodies (iter, data, expected_validity))
1141 _dbus_assert (iter->depth == (base_depth + 0));
1143 iter_set_sequence (iter, body_seq); /* undo the "next" from generate_many_bodies */
1144 iter_recurse (iter);
1146 _dbus_assert (iter->depth == (base_depth + 1));
1147 change_seq = iter_get_sequence (iter);
1149 if (change_seq == _DBUS_N_ELEMENTS (uint32_changes))
1151 /* Reset change count */
1152 iter_set_sequence (iter, 0);
1153 iter_unrecurse (iter);
1158 _dbus_assert (iter->depth == (base_depth + 1));
1160 iter_recurse (iter);
1161 _dbus_assert (iter->depth == (base_depth + 2));
1162 byte_seq = iter_get_sequence (iter);
1163 /* skip 4 bytes at a time */
1168 iter_unrecurse (iter);
1170 _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq, 4) == (unsigned) byte_seq);
1171 if (byte_seq >= (_dbus_string_get_length (data) - 4))
1173 /* reset byte count */
1174 _dbus_assert (iter->depth == (base_depth + 1));
1175 iter_recurse (iter);
1176 _dbus_assert (iter->depth == (base_depth + 2));
1177 iter_set_sequence (iter, 0);
1178 iter_unrecurse (iter);
1179 _dbus_assert (iter->depth == (base_depth + 1));
1184 _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4));
1186 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
1188 v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL);
1190 change = &uint32_changes[change_seq];
1192 if (change->type == CHANGE_TYPE_ADJUST)
1194 v_UINT32 += (int) change->value;
1198 v_UINT32 = change->value;
1202 printf ("body %d change %d pos %d ",
1203 body_seq, change_seq, byte_seq);
1205 if (change->type == CHANGE_TYPE_ADJUST)
1206 printf ("adjust by %d", (int) change->value);
1208 printf ("set to %u", change->value);
1210 printf (" \t%u -> %u\n",
1211 _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL),
1215 _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order);
1216 *expected_validity = DBUS_VALIDITY_UNKNOWN;
1218 _dbus_assert (iter->depth == (base_depth + 1));
1219 iter_unrecurse (iter);
1220 _dbus_assert (iter->depth == (base_depth + 0));
1228 DBusMessageGeneratorFunc func;
1229 } DBusMessageGenerator;
1231 static const DBusMessageGenerator generators[] = {
1232 { "trivial example of each message type", generate_trivial },
1233 { "assorted arguments", generate_many_bodies },
1234 { "assorted special cases", generate_special },
1235 { "each uint32 modified", generate_uint32_changed },
1236 { "wrong body lengths", generate_wrong_length },
1237 { "each byte modified", generate_byte_changed },
1239 /* This is really expensive and doesn't add too much coverage */
1240 { "change each typecode", generate_typecode_changed }
1245 _dbus_message_data_free (DBusMessageData *data)
1247 _dbus_string_free (&data->data);
1251 _dbus_message_data_iter_init (DBusMessageDataIter *iter)
1257 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
1259 iter->sequence_nos[i] = 0;
1266 _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
1267 DBusMessageData *data)
1269 DBusMessageGeneratorFunc func;
1273 generator = iter_get_sequence (iter);
1275 if (generator == _DBUS_N_ELEMENTS (generators))
1278 iter_recurse (iter);
1280 if (iter_first_in_series (iter))
1282 printf (" testing message loading: %s ", generators[generator].name);
1286 func = generators[generator].func;
1288 if (!_dbus_string_init (&data->data))
1289 _dbus_assert_not_reached ("oom");
1291 if ((*func)(iter, &data->data, &data->expected_validity))
1295 iter_set_sequence (iter, 0);
1296 iter_unrecurse (iter);
1297 iter_next (iter); /* next generator */
1298 _dbus_string_free (&data->data);
1299 printf ("%d test loads cumulative\n", iter->count);
1302 iter_unrecurse (iter);
1308 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */
1310 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */