1 /* -*- mode: C; c-file-style: "gnu" -*- */
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #ifdef DBUS_BUILD_TESTS
26 #include "dbus-message-factory.h"
27 #include "dbus-message-private.h"
28 #include "dbus-test.h"
37 #define BYTE_ORDER_OFFSET 0
39 #define BODY_LENGTH_OFFSET 4
40 #define FIELDS_ARRAY_LENGTH_OFFSET 12
43 iter_recurse (DBusMessageDataIter *iter)
46 _dbus_assert (iter->depth < _DBUS_MESSAGE_DATA_MAX_NESTING);
47 _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
51 iter_get_sequence (DBusMessageDataIter *iter)
53 _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
54 return iter->sequence_nos[iter->depth];
58 iter_set_sequence (DBusMessageDataIter *iter,
61 _dbus_assert (sequence >= 0);
62 iter->sequence_nos[iter->depth] = sequence;
66 iter_unrecurse (DBusMessageDataIter *iter)
69 _dbus_assert (iter->depth >= 0);
73 iter_next (DBusMessageDataIter *iter)
75 iter->sequence_nos[iter->depth] += 1;
79 iter_first_in_series (DBusMessageDataIter *iter)
84 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
86 if (iter->sequence_nos[i] != 0)
93 typedef dbus_bool_t (* DBusInnerGeneratorFunc) (DBusMessageDataIter *iter,
94 DBusMessage **message_p);
95 typedef dbus_bool_t (* DBusMessageGeneratorFunc) (DBusMessageDataIter *iter,
97 DBusValidity *expected_validity);
100 set_reply_serial (DBusMessage *message)
103 _dbus_assert_not_reached ("oom");
104 if (!dbus_message_set_reply_serial (message, 100))
105 _dbus_assert_not_reached ("oom");
109 generate_trivial_inner (DBusMessageDataIter *iter,
110 DBusMessage **message_p)
112 DBusMessage *message;
114 switch (iter_get_sequence (iter))
117 message = dbus_message_new_method_call ("org.freedesktop.TextEditor",
119 "org.freedesktop.DocumentFactory",
123 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
124 set_reply_serial (message);
127 message = dbus_message_new_signal ("/foo/bar",
128 "org.freedesktop.DocumentFactory",
132 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
134 if (!dbus_message_set_error_name (message,
135 "org.freedesktop.TestErrorName"))
136 _dbus_assert_not_reached ("oom");
139 DBusMessageIter iter;
140 const char *v_STRING = "This is an error";
142 dbus_message_iter_init_append (message, &iter);
143 if (!dbus_message_iter_append_basic (&iter,
146 _dbus_assert_not_reached ("oom");
149 set_reply_serial (message);
156 _dbus_assert_not_reached ("oom");
158 *message_p = message;
164 generate_many_bodies_inner (DBusMessageDataIter *iter,
165 DBusMessage **message_p)
167 DBusMessage *message;
168 DBusString signature;
171 /* Keeping this small makes things go faster */
172 message = dbus_message_new_method_call ("o.z.F",
177 _dbus_assert_not_reached ("oom");
179 set_reply_serial (message);
181 if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
182 _dbus_assert_not_reached ("oom");
184 if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter),
188 const char *v_SIGNATURE;
190 v_SIGNATURE = _dbus_string_get_const_data (&signature);
191 if (!_dbus_header_set_field_basic (&message->header,
192 DBUS_HEADER_FIELD_SIGNATURE,
195 _dbus_assert_not_reached ("oom");
197 if (!_dbus_string_move (&body, 0, &message->body, 0))
198 _dbus_assert_not_reached ("oom");
200 _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET,
201 _dbus_string_get_length (&message->body),
202 message->byte_order);
204 *message_p = message;
208 dbus_message_unref (message);
212 _dbus_string_free (&signature);
213 _dbus_string_free (&body);
215 return *message_p != NULL;
219 generate_from_message (DBusString *data,
220 DBusValidity *expected_validity,
221 DBusMessage *message)
223 _dbus_message_set_serial (message, 1);
224 _dbus_message_lock (message);
226 *expected_validity = DBUS_VALID;
228 /* move for efficiency, since we'll nuke the message anyway */
229 if (!_dbus_string_move (&message->header.data, 0,
231 _dbus_assert_not_reached ("oom");
233 if (!_dbus_string_copy (&message->body, 0,
234 data, _dbus_string_get_length (data)))
235 _dbus_assert_not_reached ("oom");
239 generate_outer (DBusMessageDataIter *iter,
241 DBusValidity *expected_validity,
242 DBusInnerGeneratorFunc func)
244 DBusMessage *message;
247 if (!(*func)(iter, &message))
252 _dbus_assert (message != NULL);
254 generate_from_message (data, expected_validity, message);
256 dbus_message_unref (message);
262 generate_trivial (DBusMessageDataIter *iter,
264 DBusValidity *expected_validity)
266 return generate_outer (iter, data, expected_validity,
267 generate_trivial_inner);
271 generate_many_bodies (DBusMessageDataIter *iter,
273 DBusValidity *expected_validity)
275 return generate_outer (iter, data, expected_validity,
276 generate_many_bodies_inner);
280 simple_method_call (void)
282 DBusMessage *message;
283 /* Keeping this small makes stuff go faster */
284 message = dbus_message_new_method_call ("o.b.Q",
289 _dbus_assert_not_reached ("oom");
296 DBusMessage *message;
297 message = dbus_message_new_signal ("/f/b",
301 _dbus_assert_not_reached ("oom");
306 simple_method_return (void)
308 DBusMessage *message;
309 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
311 _dbus_assert_not_reached ("oom");
313 set_reply_serial (message);
321 DBusMessage *message;
322 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
324 _dbus_assert_not_reached ("oom");
326 if (!dbus_message_set_error_name (message, "foo.bar"))
327 _dbus_assert_not_reached ("oom");
329 set_reply_serial (message);
335 generate_special (DBusMessageDataIter *iter,
337 DBusValidity *expected_validity)
340 DBusMessage *message;
342 dbus_int32_t v_INT32;
344 _dbus_assert (_dbus_string_get_length (data) == 0);
349 item_seq = iter_get_sequence (iter);
353 message = simple_method_call ();
354 if (!dbus_message_append_args (message,
355 DBUS_TYPE_INT32, &v_INT32,
356 DBUS_TYPE_INT32, &v_INT32,
357 DBUS_TYPE_INT32, &v_INT32,
359 _dbus_assert_not_reached ("oom");
361 _dbus_header_get_field_raw (&message->header,
362 DBUS_HEADER_FIELD_SIGNATURE,
364 generate_from_message (data, expected_validity, message);
366 /* set an invalid typecode */
367 _dbus_string_set_byte (data, pos + 1, '$');
369 *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
371 else if (item_seq == 1)
373 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2];
374 const char *v_STRING;
377 message = simple_method_call ();
378 if (!dbus_message_append_args (message,
379 DBUS_TYPE_INT32, &v_INT32,
380 DBUS_TYPE_INT32, &v_INT32,
381 DBUS_TYPE_INT32, &v_INT32,
383 _dbus_assert_not_reached ("oom");
386 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
388 long_sig[i] = DBUS_TYPE_ARRAY;
391 long_sig[i] = DBUS_TYPE_INVALID;
394 if (!_dbus_header_set_field_basic (&message->header,
395 DBUS_HEADER_FIELD_SIGNATURE,
398 _dbus_assert_not_reached ("oom");
400 _dbus_header_get_field_raw (&message->header,
401 DBUS_HEADER_FIELD_SIGNATURE,
403 generate_from_message (data, expected_validity, message);
405 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
407 else if (item_seq == 2)
409 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4];
410 const char *v_STRING;
413 message = simple_method_call ();
414 if (!dbus_message_append_args (message,
415 DBUS_TYPE_INT32, &v_INT32,
416 DBUS_TYPE_INT32, &v_INT32,
417 DBUS_TYPE_INT32, &v_INT32,
419 _dbus_assert_not_reached ("oom");
422 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
424 long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
428 long_sig[i] = DBUS_TYPE_INT32;
431 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
433 long_sig[i] = DBUS_STRUCT_END_CHAR;
436 long_sig[i] = DBUS_TYPE_INVALID;
439 if (!_dbus_header_set_field_basic (&message->header,
440 DBUS_HEADER_FIELD_SIGNATURE,
443 _dbus_assert_not_reached ("oom");
445 _dbus_header_get_field_raw (&message->header,
446 DBUS_HEADER_FIELD_SIGNATURE,
448 generate_from_message (data, expected_validity, message);
450 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
452 else if (item_seq == 3)
454 message = simple_method_call ();
455 if (!dbus_message_append_args (message,
456 DBUS_TYPE_INT32, &v_INT32,
457 DBUS_TYPE_INT32, &v_INT32,
458 DBUS_TYPE_INT32, &v_INT32,
460 _dbus_assert_not_reached ("oom");
462 _dbus_header_get_field_raw (&message->header,
463 DBUS_HEADER_FIELD_SIGNATURE,
465 generate_from_message (data, expected_validity, message);
467 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
469 *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
471 else if (item_seq == 4)
473 message = simple_method_call ();
474 if (!dbus_message_append_args (message,
475 DBUS_TYPE_INT32, &v_INT32,
476 DBUS_TYPE_INT32, &v_INT32,
477 DBUS_TYPE_INT32, &v_INT32,
479 _dbus_assert_not_reached ("oom");
481 _dbus_header_get_field_raw (&message->header,
482 DBUS_HEADER_FIELD_SIGNATURE,
484 generate_from_message (data, expected_validity, message);
486 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
488 *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
490 else if (item_seq == 5)
492 message = simple_method_call ();
493 if (!dbus_message_append_args (message,
494 DBUS_TYPE_INT32, &v_INT32,
495 DBUS_TYPE_INT32, &v_INT32,
496 DBUS_TYPE_INT32, &v_INT32,
498 _dbus_assert_not_reached ("oom");
500 _dbus_header_get_field_raw (&message->header,
501 DBUS_HEADER_FIELD_SIGNATURE,
503 generate_from_message (data, expected_validity, message);
505 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
506 _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
508 *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
510 else if (item_seq == 6)
512 message = simple_method_call ();
513 generate_from_message (data, expected_validity, message);
515 _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
517 *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
519 else if (item_seq == 7)
521 /* Messages of unknown type are considered valid */
522 message = simple_method_call ();
523 generate_from_message (data, expected_validity, message);
525 _dbus_string_set_byte (data, TYPE_OFFSET, 100);
527 *expected_validity = DBUS_VALID;
529 else if (item_seq == 8)
531 message = simple_method_call ();
532 generate_from_message (data, expected_validity, message);
534 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
535 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
536 message->byte_order);
537 _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
538 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
539 message->byte_order);
540 *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
542 else if (item_seq == 9)
544 const char *v_STRING = "not a valid bus name";
545 message = simple_method_call ();
547 if (!_dbus_header_set_field_basic (&message->header,
548 DBUS_HEADER_FIELD_SENDER,
549 DBUS_TYPE_STRING, &v_STRING))
550 _dbus_assert_not_reached ("oom");
552 generate_from_message (data, expected_validity, message);
554 *expected_validity = DBUS_INVALID_BAD_SENDER;
556 else if (item_seq == 10)
558 message = simple_method_call ();
560 if (!dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL))
561 _dbus_assert_not_reached ("oom");
563 generate_from_message (data, expected_validity, message);
565 *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
567 else if (item_seq == 11)
569 message = simple_method_call ();
571 if (!dbus_message_set_path (message, DBUS_PATH_LOCAL))
572 _dbus_assert_not_reached ("oom");
574 generate_from_message (data, expected_validity, message);
576 *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
578 else if (item_seq == 12)
580 /* Method calls don't have to have interface */
581 message = simple_method_call ();
583 if (!dbus_message_set_interface (message, NULL))
584 _dbus_assert_not_reached ("oom");
586 generate_from_message (data, expected_validity, message);
588 *expected_validity = DBUS_VALID;
590 else if (item_seq == 13)
592 /* Signals require an interface */
593 message = simple_signal ();
595 if (!dbus_message_set_interface (message, NULL))
596 _dbus_assert_not_reached ("oom");
598 generate_from_message (data, expected_validity, message);
600 *expected_validity = DBUS_INVALID_MISSING_INTERFACE;
602 else if (item_seq == 14)
604 message = simple_method_return ();
606 if (!_dbus_header_delete_field (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL))
607 _dbus_assert_not_reached ("oom");
609 generate_from_message (data, expected_validity, message);
611 *expected_validity = DBUS_INVALID_MISSING_REPLY_SERIAL;
613 else if (item_seq == 15)
615 message = simple_error ();
617 if (!dbus_message_set_error_name (message, NULL))
618 _dbus_assert_not_reached ("oom");
620 generate_from_message (data, expected_validity, message);
622 *expected_validity = DBUS_INVALID_MISSING_ERROR_NAME;
624 else if (item_seq == 16)
626 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*4+8];
627 const char *v_STRING;
631 message = simple_method_call ();
632 if (!dbus_message_append_args (message,
633 DBUS_TYPE_INT32, &v_INT32,
634 DBUS_TYPE_INT32, &v_INT32,
635 DBUS_TYPE_INT32, &v_INT32,
637 _dbus_assert_not_reached ("oom");
640 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*3 + 3))
642 long_sig[i] = DBUS_TYPE_ARRAY;
644 long_sig[i] = DBUS_DICT_ENTRY_BEGIN_CHAR;
646 long_sig[i] = DBUS_TYPE_INT32;
651 long_sig[i] = DBUS_TYPE_INT32;
656 long_sig[i] = DBUS_DICT_ENTRY_END_CHAR;
660 long_sig[i] = DBUS_TYPE_INVALID;
663 if (!_dbus_header_set_field_basic (&message->header,
664 DBUS_HEADER_FIELD_SIGNATURE,
667 _dbus_assert_not_reached ("oom");
669 _dbus_header_get_field_raw (&message->header,
670 DBUS_HEADER_FIELD_SIGNATURE,
672 generate_from_message (data, expected_validity, message);
674 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
676 else if (item_seq == 17)
678 message = simple_method_call ();
679 if (!dbus_message_append_args (message,
680 DBUS_TYPE_INT32, &v_INT32,
681 DBUS_TYPE_INT32, &v_INT32,
682 DBUS_TYPE_INT32, &v_INT32,
684 _dbus_assert_not_reached ("oom");
686 _dbus_header_get_field_raw (&message->header,
687 DBUS_HEADER_FIELD_SIGNATURE,
689 generate_from_message (data, expected_validity, message);
691 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
692 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
694 *expected_validity = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
696 else if (item_seq == 18)
698 message = simple_method_call ();
699 if (!dbus_message_append_args (message,
700 DBUS_TYPE_INT32, &v_INT32,
701 DBUS_TYPE_INT32, &v_INT32,
702 DBUS_TYPE_INT32, &v_INT32,
704 _dbus_assert_not_reached ("oom");
706 _dbus_header_get_field_raw (&message->header,
707 DBUS_HEADER_FIELD_SIGNATURE,
709 generate_from_message (data, expected_validity, message);
711 _dbus_string_set_byte (data, pos + 1, DBUS_DICT_ENTRY_END_CHAR);
713 *expected_validity = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
715 else if (item_seq == 19)
717 message = simple_method_call ();
718 if (!dbus_message_append_args (message,
719 DBUS_TYPE_INT32, &v_INT32,
720 DBUS_TYPE_INT32, &v_INT32,
721 DBUS_TYPE_INT32, &v_INT32,
723 _dbus_assert_not_reached ("oom");
725 _dbus_header_get_field_raw (&message->header,
726 DBUS_HEADER_FIELD_SIGNATURE,
728 generate_from_message (data, expected_validity, message);
730 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
731 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
732 _dbus_string_set_byte (data, pos + 3, DBUS_DICT_ENTRY_END_CHAR);
734 *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
742 dbus_message_unref (message);
749 generate_wrong_length (DBusMessageDataIter *iter,
751 DBusValidity *expected_validity)
753 int lengths[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1,
754 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 };
759 len_seq = iter_get_sequence (iter);
760 if (len_seq == _DBUS_N_ELEMENTS (lengths))
763 _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths));
766 if (!generate_many_bodies (iter, data, expected_validity))
768 iter_set_sequence (iter, 0); /* reset to first body */
769 iter_unrecurse (iter);
770 iter_next (iter); /* next length adjustment */
773 iter_unrecurse (iter);
775 adjust = lengths[len_seq];
779 if ((_dbus_string_get_length (data) + adjust) < DBUS_MINIMUM_HEADER_SIZE)
780 _dbus_string_set_length (data, DBUS_MINIMUM_HEADER_SIZE);
782 _dbus_string_shorten (data, - adjust);
783 *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON;
787 if (!_dbus_string_lengthen (data, adjust))
788 _dbus_assert_not_reached ("oom");
789 *expected_validity = DBUS_INVALID_TOO_MUCH_DATA;
798 _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE);
800 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
801 old_body_len = _dbus_marshal_read_uint32 (data,
805 _dbus_assert (old_body_len < _dbus_string_get_length (data));
806 new_body_len = old_body_len + adjust;
807 if (new_body_len < 0)
810 /* we just munged the header, and aren't sure how */
811 *expected_validity = DBUS_VALIDITY_UNKNOWN;
814 _dbus_verbose ("changing body len from %u to %u by adjust %d\n",
815 old_body_len, new_body_len, adjust);
817 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
826 generate_byte_changed (DBusMessageDataIter *iter,
828 DBusValidity *expected_validity)
833 /* This is a little convoluted to make the bodies the
834 * outer loop and each byte of each body the inner
839 if (!generate_many_bodies (iter, data, expected_validity))
843 byte_seq = iter_get_sequence (iter);
845 iter_unrecurse (iter);
847 if (byte_seq == _dbus_string_get_length (data))
849 _dbus_string_set_length (data, 0);
850 /* reset byte count */
852 iter_set_sequence (iter, 0);
853 iter_unrecurse (iter);
858 /* Undo the "next" in generate_many_bodies */
859 iter_set_sequence (iter, iter_get_sequence (iter) - 1);
862 _dbus_assert (byte_seq < _dbus_string_get_length (data));
863 v_BYTE = _dbus_string_get_byte (data, byte_seq);
864 v_BYTE += byte_seq; /* arbitrary but deterministic change to the byte */
865 _dbus_string_set_byte (data, byte_seq, v_BYTE);
866 *expected_validity = DBUS_VALIDITY_UNKNOWN;
872 find_next_typecode (DBusMessageDataIter *iter,
874 DBusValidity *expected_validity)
880 base_depth = iter->depth;
883 _dbus_assert (iter->depth == (base_depth + 0));
884 _dbus_string_set_length (data, 0);
886 body_seq = iter_get_sequence (iter);
888 if (!generate_many_bodies (iter, data, expected_validity))
890 /* Undo the "next" in generate_many_bodies */
891 iter_set_sequence (iter, body_seq);
896 _dbus_assert (iter->depth == (base_depth + 1));
898 byte_seq = iter_get_sequence (iter);
900 _dbus_assert (byte_seq <= _dbus_string_get_length (data));
902 if (byte_seq == _dbus_string_get_length (data))
904 /* reset byte count */
905 iter_set_sequence (iter, 0);
906 iter_unrecurse (iter);
907 _dbus_assert (iter->depth == (base_depth + 0));
908 iter_next (iter); /* go to the next body */
912 _dbus_assert (byte_seq < _dbus_string_get_length (data));
914 if (_dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq)))
920 _dbus_assert (byte_seq == iter_get_sequence (iter));
921 _dbus_assert (byte_seq < _dbus_string_get_length (data));
923 iter_unrecurse (iter);
925 _dbus_assert (iter->depth == (base_depth + 0));
930 static const int typecodes[] = {
942 DBUS_TYPE_OBJECT_PATH,
946 DBUS_STRUCT_BEGIN_CHAR,
947 DBUS_STRUCT_END_CHAR,
948 DBUS_DICT_ENTRY_BEGIN_CHAR,
949 DBUS_DICT_ENTRY_END_CHAR,
950 255 /* random invalid typecode */
954 generate_typecode_changed (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 if (!find_next_typecode (iter, data, expected_validity))
972 byte_seq = iter_get_sequence (iter);
974 _dbus_assert (byte_seq < _dbus_string_get_length (data));
977 typecode_seq = iter_get_sequence (iter);
980 _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes));
982 if (typecode_seq == _DBUS_N_ELEMENTS (typecodes))
984 _dbus_assert (iter->depth == (base_depth + 2));
985 iter_set_sequence (iter, 0); /* reset typecode sequence */
986 iter_unrecurse (iter);
987 _dbus_assert (iter->depth == (base_depth + 1));
988 iter_next (iter); /* go to the next byte_seq */
989 iter_unrecurse (iter);
990 _dbus_assert (iter->depth == (base_depth + 0));
994 _dbus_assert (iter->depth == (base_depth + 2));
995 iter_unrecurse (iter);
996 _dbus_assert (iter->depth == (base_depth + 1));
997 iter_unrecurse (iter);
998 _dbus_assert (iter->depth == (base_depth + 0));
1001 printf ("Changing byte %d in message %d to %c\n",
1002 byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]);
1005 _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]);
1006 *expected_validity = DBUS_VALIDITY_UNKNOWN;
1013 dbus_uint32_t value; /* cast to signed for adjusts */
1016 static const UIntChange uint32_changes[] = {
1017 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -1 },
1018 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -2 },
1019 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -3 },
1020 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 1 },
1021 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 2 },
1022 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 3 },
1023 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX },
1024 { CHANGE_TYPE_ABSOLUTE, 0 },
1025 { CHANGE_TYPE_ABSOLUTE, 1 },
1026 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 1 },
1027 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 5 }
1031 generate_uint32_changed (DBusMessageDataIter *iter,
1033 DBusValidity *expected_validity)
1038 dbus_uint32_t v_UINT32;
1040 const UIntChange *change;
1043 /* Outer loop is each body, next loop is each change,
1044 * inner loop is each change location
1047 base_depth = iter->depth;
1050 _dbus_assert (iter->depth == (base_depth + 0));
1051 _dbus_string_set_length (data, 0);
1052 body_seq = iter_get_sequence (iter);
1054 if (!generate_many_bodies (iter, data, expected_validity))
1057 _dbus_assert (iter->depth == (base_depth + 0));
1059 iter_set_sequence (iter, body_seq); /* undo the "next" from generate_many_bodies */
1060 iter_recurse (iter);
1062 _dbus_assert (iter->depth == (base_depth + 1));
1063 change_seq = iter_get_sequence (iter);
1065 if (change_seq == _DBUS_N_ELEMENTS (uint32_changes))
1067 /* Reset change count */
1068 iter_set_sequence (iter, 0);
1069 iter_unrecurse (iter);
1074 _dbus_assert (iter->depth == (base_depth + 1));
1076 iter_recurse (iter);
1077 _dbus_assert (iter->depth == (base_depth + 2));
1078 byte_seq = iter_get_sequence (iter);
1079 /* skip 4 bytes at a time */
1084 iter_unrecurse (iter);
1086 _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq, 4) == (unsigned) byte_seq);
1087 if (byte_seq >= (_dbus_string_get_length (data) - 4))
1089 /* reset byte count */
1090 _dbus_assert (iter->depth == (base_depth + 1));
1091 iter_recurse (iter);
1092 _dbus_assert (iter->depth == (base_depth + 2));
1093 iter_set_sequence (iter, 0);
1094 iter_unrecurse (iter);
1095 _dbus_assert (iter->depth == (base_depth + 1));
1100 _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4));
1102 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
1104 v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL);
1106 change = &uint32_changes[change_seq];
1108 if (change->type == CHANGE_TYPE_ADJUST)
1110 v_UINT32 += (int) change->value;
1114 v_UINT32 = change->value;
1118 printf ("body %d change %d pos %d ",
1119 body_seq, change_seq, byte_seq);
1121 if (change->type == CHANGE_TYPE_ADJUST)
1122 printf ("adjust by %d", (int) change->value);
1124 printf ("set to %u", change->value);
1126 printf (" \t%u -> %u\n",
1127 _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL),
1131 _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order);
1132 *expected_validity = DBUS_VALIDITY_UNKNOWN;
1134 _dbus_assert (iter->depth == (base_depth + 1));
1135 iter_unrecurse (iter);
1136 _dbus_assert (iter->depth == (base_depth + 0));
1144 DBusMessageGeneratorFunc func;
1145 } DBusMessageGenerator;
1147 static const DBusMessageGenerator generators[] = {
1148 { "trivial example of each message type", generate_trivial },
1149 { "assorted arguments", generate_many_bodies },
1150 { "assorted special cases", generate_special },
1151 { "each uint32 modified", generate_uint32_changed },
1152 { "wrong body lengths", generate_wrong_length },
1153 { "each byte modified", generate_byte_changed },
1155 /* This is really expensive and doesn't add too much coverage */
1156 { "change each typecode", generate_typecode_changed }
1161 _dbus_message_data_free (DBusMessageData *data)
1163 _dbus_string_free (&data->data);
1167 _dbus_message_data_iter_init (DBusMessageDataIter *iter)
1173 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
1175 iter->sequence_nos[i] = 0;
1182 _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
1183 DBusMessageData *data)
1185 DBusMessageGeneratorFunc func;
1189 generator = iter_get_sequence (iter);
1191 if (generator == _DBUS_N_ELEMENTS (generators))
1194 iter_recurse (iter);
1196 if (iter_first_in_series (iter))
1198 printf (" testing message loading: %s ", generators[generator].name);
1202 func = generators[generator].func;
1204 if (!_dbus_string_init (&data->data))
1205 _dbus_assert_not_reached ("oom");
1207 if ((*func)(iter, &data->data, &data->expected_validity))
1211 iter_set_sequence (iter, 0);
1212 iter_unrecurse (iter);
1213 iter_next (iter); /* next generator */
1214 _dbus_string_free (&data->data);
1215 printf ("%d test loads cumulative\n", iter->count);
1218 iter_unrecurse (iter);
1224 #endif /* DBUS_BUILD_TESTS */