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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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-test.h"
39 #define BYTE_ORDER_OFFSET 0
41 #define BODY_LENGTH_OFFSET 4
42 #define FIELDS_ARRAY_LENGTH_OFFSET 12
45 iter_recurse (DBusMessageDataIter
*iter
)
48 _dbus_assert (iter
->depth
< _DBUS_MESSAGE_DATA_MAX_NESTING
);
49 _dbus_assert (iter
->sequence_nos
[iter
->depth
] >= 0);
53 iter_get_sequence (DBusMessageDataIter
*iter
)
55 _dbus_assert (iter
->sequence_nos
[iter
->depth
] >= 0);
56 return iter
->sequence_nos
[iter
->depth
];
60 iter_set_sequence (DBusMessageDataIter
*iter
,
63 _dbus_assert (sequence
>= 0);
64 iter
->sequence_nos
[iter
->depth
] = sequence
;
68 iter_unrecurse (DBusMessageDataIter
*iter
)
71 _dbus_assert (iter
->depth
>= 0);
75 iter_next (DBusMessageDataIter
*iter
)
77 iter
->sequence_nos
[iter
->depth
] += 1;
81 iter_first_in_series (DBusMessageDataIter
*iter
)
86 while (i
< _DBUS_MESSAGE_DATA_MAX_NESTING
)
88 if (iter
->sequence_nos
[i
] != 0)
95 typedef dbus_bool_t (* DBusInnerGeneratorFunc
) (DBusMessageDataIter
*iter
,
96 DBusMessage
**message_p
);
97 typedef dbus_bool_t (* DBusMessageGeneratorFunc
) (DBusMessageDataIter
*iter
,
99 DBusValidity
*expected_validity
);
102 set_reply_serial (DBusMessage
*message
)
105 _dbus_assert_not_reached ("oom");
106 if (!dbus_message_set_reply_serial (message
, 100))
107 _dbus_assert_not_reached ("oom");
111 generate_trivial_inner (DBusMessageDataIter
*iter
,
112 DBusMessage
**message_p
)
114 DBusMessage
*message
;
116 switch (iter_get_sequence (iter
))
119 message
= dbus_message_new_method_call ("org.freedesktop.TextEditor",
121 "org.freedesktop.DocumentFactory",
125 message
= dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN
);
126 set_reply_serial (message
);
129 message
= dbus_message_new_signal ("/foo/bar",
130 "org.freedesktop.DocumentFactory",
134 message
= dbus_message_new (DBUS_MESSAGE_TYPE_ERROR
);
136 if (!dbus_message_set_error_name (message
,
137 "org.freedesktop.TestErrorName"))
138 _dbus_assert_not_reached ("oom");
141 DBusMessageIter iter
;
142 const char *v_STRING
= "This is an error";
144 dbus_message_iter_init_append (message
, &iter
);
145 if (!dbus_message_iter_append_basic (&iter
,
148 _dbus_assert_not_reached ("oom");
151 set_reply_serial (message
);
158 _dbus_assert_not_reached ("oom");
160 *message_p
= message
;
166 generate_many_bodies_inner (DBusMessageDataIter
*iter
,
167 DBusMessage
**message_p
)
169 DBusMessage
*message
;
170 DBusString signature
;
173 /* Keeping this small makes things go faster */
174 message
= dbus_message_new_method_call ("o.z.F",
179 _dbus_assert_not_reached ("oom");
181 set_reply_serial (message
);
183 if (!_dbus_string_init (&signature
) || !_dbus_string_init (&body
))
184 _dbus_assert_not_reached ("oom");
186 if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter
),
190 const char *v_SIGNATURE
;
192 v_SIGNATURE
= _dbus_string_get_const_data (&signature
);
193 if (!_dbus_header_set_field_basic (&message
->header
,
194 DBUS_HEADER_FIELD_SIGNATURE
,
197 _dbus_assert_not_reached ("oom");
199 if (!_dbus_string_move (&body
, 0, &message
->body
, 0))
200 _dbus_assert_not_reached ("oom");
202 _dbus_marshal_set_uint32 (&message
->header
.data
, BODY_LENGTH_OFFSET
,
203 _dbus_string_get_length (&message
->body
),
204 message
->byte_order
);
206 *message_p
= message
;
210 dbus_message_unref (message
);
214 _dbus_string_free (&signature
);
215 _dbus_string_free (&body
);
217 return *message_p
!= NULL
;
221 generate_from_message (DBusString
*data
,
222 DBusValidity
*expected_validity
,
223 DBusMessage
*message
)
225 dbus_message_set_serial (message
, 1);
226 dbus_message_lock (message
);
228 *expected_validity
= DBUS_VALID
;
230 /* move for efficiency, since we'll nuke the message anyway */
231 if (!_dbus_string_move (&message
->header
.data
, 0,
233 _dbus_assert_not_reached ("oom");
235 if (!_dbus_string_copy (&message
->body
, 0,
236 data
, _dbus_string_get_length (data
)))
237 _dbus_assert_not_reached ("oom");
241 generate_outer (DBusMessageDataIter
*iter
,
243 DBusValidity
*expected_validity
,
244 DBusInnerGeneratorFunc func
)
246 DBusMessage
*message
;
249 if (!(*func
)(iter
, &message
))
254 _dbus_assert (message
!= NULL
);
256 generate_from_message (data
, expected_validity
, message
);
258 dbus_message_unref (message
);
264 generate_trivial (DBusMessageDataIter
*iter
,
266 DBusValidity
*expected_validity
)
268 return generate_outer (iter
, data
, expected_validity
,
269 generate_trivial_inner
);
273 generate_many_bodies (DBusMessageDataIter
*iter
,
275 DBusValidity
*expected_validity
)
277 return generate_outer (iter
, data
, expected_validity
,
278 generate_many_bodies_inner
);
282 simple_method_call (void)
284 DBusMessage
*message
;
285 /* Keeping this small makes stuff go faster */
286 message
= dbus_message_new_method_call ("o.b.Q",
291 _dbus_assert_not_reached ("oom");
298 DBusMessage
*message
;
299 message
= dbus_message_new_signal ("/f/b",
303 _dbus_assert_not_reached ("oom");
308 simple_method_return (void)
310 DBusMessage
*message
;
311 message
= dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN
);
313 _dbus_assert_not_reached ("oom");
315 set_reply_serial (message
);
323 DBusMessage
*message
;
324 message
= dbus_message_new (DBUS_MESSAGE_TYPE_ERROR
);
326 _dbus_assert_not_reached ("oom");
328 if (!dbus_message_set_error_name (message
, "foo.bar"))
329 _dbus_assert_not_reached ("oom");
331 set_reply_serial (message
);
337 generate_special (DBusMessageDataIter
*iter
,
339 DBusValidity
*expected_validity
)
342 DBusMessage
*message
;
344 dbus_int32_t v_INT32
;
346 _dbus_assert (_dbus_string_get_length (data
) == 0);
351 item_seq
= iter_get_sequence (iter
);
355 message
= simple_method_call ();
356 if (!dbus_message_append_args (message
,
357 DBUS_TYPE_INT32
, &v_INT32
,
358 DBUS_TYPE_INT32
, &v_INT32
,
359 DBUS_TYPE_INT32
, &v_INT32
,
361 _dbus_assert_not_reached ("oom");
363 _dbus_header_get_field_raw (&message
->header
,
364 DBUS_HEADER_FIELD_SIGNATURE
,
366 generate_from_message (data
, expected_validity
, message
);
368 /* set an invalid typecode */
369 _dbus_string_set_byte (data
, pos
+ 1, '$');
371 *expected_validity
= DBUS_INVALID_UNKNOWN_TYPECODE
;
373 else if (item_seq
== 1)
375 char long_sig
[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH
+2];
376 const char *v_STRING
;
379 message
= simple_method_call ();
380 if (!dbus_message_append_args (message
,
381 DBUS_TYPE_INT32
, &v_INT32
,
382 DBUS_TYPE_INT32
, &v_INT32
,
383 DBUS_TYPE_INT32
, &v_INT32
,
385 _dbus_assert_not_reached ("oom");
388 while (i
< (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH
+ 1))
390 long_sig
[i
] = DBUS_TYPE_ARRAY
;
393 long_sig
[i
] = DBUS_TYPE_INVALID
;
396 if (!_dbus_header_set_field_basic (&message
->header
,
397 DBUS_HEADER_FIELD_SIGNATURE
,
400 _dbus_assert_not_reached ("oom");
402 _dbus_header_get_field_raw (&message
->header
,
403 DBUS_HEADER_FIELD_SIGNATURE
,
405 generate_from_message (data
, expected_validity
, message
);
407 *expected_validity
= DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION
;
409 else if (item_seq
== 2)
411 char long_sig
[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH
*2+4];
412 const char *v_STRING
;
415 message
= simple_method_call ();
416 if (!dbus_message_append_args (message
,
417 DBUS_TYPE_INT32
, &v_INT32
,
418 DBUS_TYPE_INT32
, &v_INT32
,
419 DBUS_TYPE_INT32
, &v_INT32
,
421 _dbus_assert_not_reached ("oom");
424 while (i
<= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH
+ 1))
426 long_sig
[i
] = DBUS_STRUCT_BEGIN_CHAR
;
430 long_sig
[i
] = DBUS_TYPE_INT32
;
433 while (i
< (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH
*2 + 3))
435 long_sig
[i
] = DBUS_STRUCT_END_CHAR
;
438 long_sig
[i
] = DBUS_TYPE_INVALID
;
441 if (!_dbus_header_set_field_basic (&message
->header
,
442 DBUS_HEADER_FIELD_SIGNATURE
,
445 _dbus_assert_not_reached ("oom");
447 _dbus_header_get_field_raw (&message
->header
,
448 DBUS_HEADER_FIELD_SIGNATURE
,
450 generate_from_message (data
, expected_validity
, message
);
452 *expected_validity
= DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION
;
454 else if (item_seq
== 3)
456 message
= simple_method_call ();
457 if (!dbus_message_append_args (message
,
458 DBUS_TYPE_INT32
, &v_INT32
,
459 DBUS_TYPE_INT32
, &v_INT32
,
460 DBUS_TYPE_INT32
, &v_INT32
,
462 _dbus_assert_not_reached ("oom");
464 _dbus_header_get_field_raw (&message
->header
,
465 DBUS_HEADER_FIELD_SIGNATURE
,
467 generate_from_message (data
, expected_validity
, message
);
469 _dbus_string_set_byte (data
, pos
+ 1, DBUS_STRUCT_BEGIN_CHAR
);
471 *expected_validity
= DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED
;
473 else if (item_seq
== 4)
475 message
= simple_method_call ();
476 if (!dbus_message_append_args (message
,
477 DBUS_TYPE_INT32
, &v_INT32
,
478 DBUS_TYPE_INT32
, &v_INT32
,
479 DBUS_TYPE_INT32
, &v_INT32
,
481 _dbus_assert_not_reached ("oom");
483 _dbus_header_get_field_raw (&message
->header
,
484 DBUS_HEADER_FIELD_SIGNATURE
,
486 generate_from_message (data
, expected_validity
, message
);
488 _dbus_string_set_byte (data
, pos
+ 1, DBUS_STRUCT_END_CHAR
);
490 *expected_validity
= DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED
;
492 else if (item_seq
== 5)
494 message
= simple_method_call ();
495 if (!dbus_message_append_args (message
,
496 DBUS_TYPE_INT32
, &v_INT32
,
497 DBUS_TYPE_INT32
, &v_INT32
,
498 DBUS_TYPE_INT32
, &v_INT32
,
500 _dbus_assert_not_reached ("oom");
502 _dbus_header_get_field_raw (&message
->header
,
503 DBUS_HEADER_FIELD_SIGNATURE
,
505 generate_from_message (data
, expected_validity
, message
);
507 _dbus_string_set_byte (data
, pos
+ 1, DBUS_STRUCT_BEGIN_CHAR
);
508 _dbus_string_set_byte (data
, pos
+ 2, DBUS_STRUCT_END_CHAR
);
510 *expected_validity
= DBUS_INVALID_STRUCT_HAS_NO_FIELDS
;
512 else if (item_seq
== 6)
514 message
= simple_method_call ();
515 generate_from_message (data
, expected_validity
, message
);
517 _dbus_string_set_byte (data
, TYPE_OFFSET
, DBUS_MESSAGE_TYPE_INVALID
);
519 *expected_validity
= DBUS_INVALID_BAD_MESSAGE_TYPE
;
521 else if (item_seq
== 7)
523 /* Messages of unknown type are considered valid */
524 message
= simple_method_call ();
525 generate_from_message (data
, expected_validity
, message
);
527 _dbus_string_set_byte (data
, TYPE_OFFSET
, 100);
529 *expected_validity
= DBUS_VALID
;
531 else if (item_seq
== 8)
533 message
= simple_method_call ();
534 generate_from_message (data
, expected_validity
, message
);
536 _dbus_marshal_set_uint32 (data
, BODY_LENGTH_OFFSET
,
537 DBUS_MAXIMUM_MESSAGE_LENGTH
/ 2 + 4,
538 message
->byte_order
);
539 _dbus_marshal_set_uint32 (data
, FIELDS_ARRAY_LENGTH_OFFSET
,
540 DBUS_MAXIMUM_MESSAGE_LENGTH
/ 2 + 4,
541 message
->byte_order
);
542 *expected_validity
= DBUS_INVALID_MESSAGE_TOO_LONG
;
544 else if (item_seq
== 9)
546 const char *v_STRING
= "not a valid bus name";
547 message
= simple_method_call ();
549 if (!_dbus_header_set_field_basic (&message
->header
,
550 DBUS_HEADER_FIELD_SENDER
,
551 DBUS_TYPE_STRING
, &v_STRING
))
552 _dbus_assert_not_reached ("oom");
554 generate_from_message (data
, expected_validity
, message
);
556 *expected_validity
= DBUS_INVALID_BAD_SENDER
;
558 else if (item_seq
== 10)
560 message
= simple_method_call ();
562 if (!dbus_message_set_interface (message
, DBUS_INTERFACE_LOCAL
))
563 _dbus_assert_not_reached ("oom");
565 generate_from_message (data
, expected_validity
, message
);
567 *expected_validity
= DBUS_INVALID_USES_LOCAL_INTERFACE
;
569 else if (item_seq
== 11)
571 message
= simple_method_call ();
573 if (!dbus_message_set_path (message
, DBUS_PATH_LOCAL
))
574 _dbus_assert_not_reached ("oom");
576 generate_from_message (data
, expected_validity
, message
);
578 *expected_validity
= DBUS_INVALID_USES_LOCAL_PATH
;
580 else if (item_seq
== 12)
582 /* Method calls don't have to have interface */
583 message
= simple_method_call ();
585 if (!dbus_message_set_interface (message
, NULL
))
586 _dbus_assert_not_reached ("oom");
588 generate_from_message (data
, expected_validity
, message
);
590 *expected_validity
= DBUS_VALID
;
592 else if (item_seq
== 13)
594 /* Signals require an interface */
595 message
= simple_signal ();
597 if (!dbus_message_set_interface (message
, NULL
))
598 _dbus_assert_not_reached ("oom");
600 generate_from_message (data
, expected_validity
, message
);
602 *expected_validity
= DBUS_INVALID_MISSING_INTERFACE
;
604 else if (item_seq
== 14)
606 message
= simple_method_return ();
608 if (!_dbus_header_delete_field (&message
->header
, DBUS_HEADER_FIELD_REPLY_SERIAL
))
609 _dbus_assert_not_reached ("oom");
611 generate_from_message (data
, expected_validity
, message
);
613 *expected_validity
= DBUS_INVALID_MISSING_REPLY_SERIAL
;
615 else if (item_seq
== 15)
617 message
= simple_error ();
619 if (!dbus_message_set_error_name (message
, NULL
))
620 _dbus_assert_not_reached ("oom");
622 generate_from_message (data
, expected_validity
, message
);
624 *expected_validity
= DBUS_INVALID_MISSING_ERROR_NAME
;
626 else if (item_seq
== 16)
628 char long_sig
[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH
*4+10];
629 const char *v_STRING
;
633 message
= simple_method_call ();
634 if (!dbus_message_append_args (message
,
635 DBUS_TYPE_INT32
, &v_INT32
,
636 DBUS_TYPE_INT32
, &v_INT32
,
637 DBUS_TYPE_INT32
, &v_INT32
,
639 _dbus_assert_not_reached ("oom");
642 while (i
<= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH
*3 + 3))
644 long_sig
[i
] = DBUS_TYPE_ARRAY
;
646 long_sig
[i
] = DBUS_DICT_ENTRY_BEGIN_CHAR
;
648 long_sig
[i
] = DBUS_TYPE_INT32
;
653 long_sig
[i
] = DBUS_TYPE_INT32
;
658 long_sig
[i
] = DBUS_DICT_ENTRY_END_CHAR
;
662 long_sig
[i
] = DBUS_TYPE_INVALID
;
665 if (!_dbus_header_set_field_basic (&message
->header
,
666 DBUS_HEADER_FIELD_SIGNATURE
,
669 _dbus_assert_not_reached ("oom");
671 _dbus_header_get_field_raw (&message
->header
,
672 DBUS_HEADER_FIELD_SIGNATURE
,
674 generate_from_message (data
, expected_validity
, message
);
676 *expected_validity
= DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION
;
678 else if (item_seq
== 17)
680 message
= simple_method_call ();
681 if (!dbus_message_append_args (message
,
682 DBUS_TYPE_INT32
, &v_INT32
,
683 DBUS_TYPE_INT32
, &v_INT32
,
684 DBUS_TYPE_INT32
, &v_INT32
,
686 _dbus_assert_not_reached ("oom");
688 _dbus_header_get_field_raw (&message
->header
,
689 DBUS_HEADER_FIELD_SIGNATURE
,
691 generate_from_message (data
, expected_validity
, message
);
693 _dbus_string_set_byte (data
, pos
+ 1, DBUS_TYPE_ARRAY
);
694 _dbus_string_set_byte (data
, pos
+ 2, DBUS_DICT_ENTRY_BEGIN_CHAR
);
696 *expected_validity
= DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED
;
698 else if (item_seq
== 18)
700 message
= simple_method_call ();
701 if (!dbus_message_append_args (message
,
702 DBUS_TYPE_INT32
, &v_INT32
,
703 DBUS_TYPE_INT32
, &v_INT32
,
704 DBUS_TYPE_INT32
, &v_INT32
,
706 _dbus_assert_not_reached ("oom");
708 _dbus_header_get_field_raw (&message
->header
,
709 DBUS_HEADER_FIELD_SIGNATURE
,
711 generate_from_message (data
, expected_validity
, message
);
713 _dbus_string_set_byte (data
, pos
+ 1, DBUS_DICT_ENTRY_END_CHAR
);
715 *expected_validity
= DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED
;
717 else if (item_seq
== 19)
719 message
= simple_method_call ();
720 if (!dbus_message_append_args (message
,
721 DBUS_TYPE_INT32
, &v_INT32
,
722 DBUS_TYPE_INT32
, &v_INT32
,
723 DBUS_TYPE_INT32
, &v_INT32
,
725 _dbus_assert_not_reached ("oom");
727 _dbus_header_get_field_raw (&message
->header
,
728 DBUS_HEADER_FIELD_SIGNATURE
,
730 generate_from_message (data
, expected_validity
, message
);
732 _dbus_string_set_byte (data
, pos
+ 1, DBUS_TYPE_ARRAY
);
733 _dbus_string_set_byte (data
, pos
+ 2, DBUS_DICT_ENTRY_BEGIN_CHAR
);
734 _dbus_string_set_byte (data
, pos
+ 3, DBUS_DICT_ENTRY_END_CHAR
);
736 *expected_validity
= DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS
;
744 dbus_message_unref (message
);
751 generate_wrong_length (DBusMessageDataIter
*iter
,
753 DBusValidity
*expected_validity
)
755 int lengths
[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1,
756 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 };
761 len_seq
= iter_get_sequence (iter
);
762 if (len_seq
== _DBUS_N_ELEMENTS (lengths
))
765 _dbus_assert (len_seq
< _DBUS_N_ELEMENTS (lengths
));
768 if (!generate_many_bodies (iter
, data
, expected_validity
))
770 iter_set_sequence (iter
, 0); /* reset to first body */
771 iter_unrecurse (iter
);
772 iter_next (iter
); /* next length adjustment */
775 iter_unrecurse (iter
);
777 adjust
= lengths
[len_seq
];
781 if ((_dbus_string_get_length (data
) + adjust
) < DBUS_MINIMUM_HEADER_SIZE
)
782 _dbus_string_set_length (data
, DBUS_MINIMUM_HEADER_SIZE
);
784 _dbus_string_shorten (data
, - adjust
);
785 *expected_validity
= DBUS_INVALID_FOR_UNKNOWN_REASON
;
789 if (!_dbus_string_lengthen (data
, adjust
))
790 _dbus_assert_not_reached ("oom");
791 *expected_validity
= DBUS_INVALID_TOO_MUCH_DATA
;
800 _dbus_assert (_dbus_string_get_length (data
) >= DBUS_MINIMUM_HEADER_SIZE
);
802 byte_order
= _dbus_string_get_byte (data
, BYTE_ORDER_OFFSET
);
803 old_body_len
= _dbus_marshal_read_uint32 (data
,
807 _dbus_assert (old_body_len
< _dbus_string_get_length (data
));
808 new_body_len
= old_body_len
+ adjust
;
809 if (new_body_len
< 0)
812 /* we just munged the header, and aren't sure how */
813 *expected_validity
= DBUS_VALIDITY_UNKNOWN
;
816 _dbus_verbose ("changing body len from %u to %u by adjust %d\n",
817 old_body_len
, new_body_len
, adjust
);
819 _dbus_marshal_set_uint32 (data
, BODY_LENGTH_OFFSET
,
828 generate_byte_changed (DBusMessageDataIter
*iter
,
830 DBusValidity
*expected_validity
)
835 /* This is a little convoluted to make the bodies the
836 * outer loop and each byte of each body the inner
841 if (!generate_many_bodies (iter
, data
, expected_validity
))
845 byte_seq
= iter_get_sequence (iter
);
847 iter_unrecurse (iter
);
849 if (byte_seq
== _dbus_string_get_length (data
))
851 _dbus_string_set_length (data
, 0);
852 /* reset byte count */
854 iter_set_sequence (iter
, 0);
855 iter_unrecurse (iter
);
860 /* Undo the "next" in generate_many_bodies */
861 iter_set_sequence (iter
, iter_get_sequence (iter
) - 1);
864 _dbus_assert (byte_seq
< _dbus_string_get_length (data
));
865 v_BYTE
= _dbus_string_get_byte (data
, byte_seq
);
866 v_BYTE
+= byte_seq
; /* arbitrary but deterministic change to the byte */
867 _dbus_string_set_byte (data
, byte_seq
, v_BYTE
);
868 *expected_validity
= DBUS_VALIDITY_UNKNOWN
;
874 find_next_typecode (DBusMessageDataIter
*iter
,
876 DBusValidity
*expected_validity
)
882 base_depth
= iter
->depth
;
885 _dbus_assert (iter
->depth
== (base_depth
+ 0));
886 _dbus_string_set_length (data
, 0);
888 body_seq
= iter_get_sequence (iter
);
890 if (!generate_many_bodies (iter
, data
, expected_validity
))
892 /* Undo the "next" in generate_many_bodies */
893 iter_set_sequence (iter
, body_seq
);
898 _dbus_assert (iter
->depth
== (base_depth
+ 1));
900 byte_seq
= iter_get_sequence (iter
);
902 _dbus_assert (byte_seq
<= _dbus_string_get_length (data
));
904 if (byte_seq
== _dbus_string_get_length (data
))
906 /* reset byte count */
907 iter_set_sequence (iter
, 0);
908 iter_unrecurse (iter
);
909 _dbus_assert (iter
->depth
== (base_depth
+ 0));
910 iter_next (iter
); /* go to the next body */
914 _dbus_assert (byte_seq
< _dbus_string_get_length (data
));
916 if (_dbus_type_is_valid (_dbus_string_get_byte (data
, byte_seq
)))
922 _dbus_assert (byte_seq
== iter_get_sequence (iter
));
923 _dbus_assert (byte_seq
< _dbus_string_get_length (data
));
925 iter_unrecurse (iter
);
927 _dbus_assert (iter
->depth
== (base_depth
+ 0));
932 static const int typecodes
[] = {
944 DBUS_TYPE_OBJECT_PATH
,
948 DBUS_STRUCT_BEGIN_CHAR
,
949 DBUS_STRUCT_END_CHAR
,
950 DBUS_DICT_ENTRY_BEGIN_CHAR
,
951 DBUS_DICT_ENTRY_END_CHAR
,
952 255 /* random invalid typecode */
956 generate_typecode_changed (DBusMessageDataIter
*iter
,
958 DBusValidity
*expected_validity
)
964 base_depth
= iter
->depth
;
967 _dbus_assert (iter
->depth
== (base_depth
+ 0));
968 _dbus_string_set_length (data
, 0);
970 if (!find_next_typecode (iter
, data
, expected_validity
))
974 byte_seq
= iter_get_sequence (iter
);
976 _dbus_assert (byte_seq
< _dbus_string_get_length (data
));
979 typecode_seq
= iter_get_sequence (iter
);
982 _dbus_assert (typecode_seq
<= _DBUS_N_ELEMENTS (typecodes
));
984 if (typecode_seq
== _DBUS_N_ELEMENTS (typecodes
))
986 _dbus_assert (iter
->depth
== (base_depth
+ 2));
987 iter_set_sequence (iter
, 0); /* reset typecode sequence */
988 iter_unrecurse (iter
);
989 _dbus_assert (iter
->depth
== (base_depth
+ 1));
990 iter_next (iter
); /* go to the next byte_seq */
991 iter_unrecurse (iter
);
992 _dbus_assert (iter
->depth
== (base_depth
+ 0));
996 _dbus_assert (iter
->depth
== (base_depth
+ 2));
997 iter_unrecurse (iter
);
998 _dbus_assert (iter
->depth
== (base_depth
+ 1));
999 iter_unrecurse (iter
);
1000 _dbus_assert (iter
->depth
== (base_depth
+ 0));
1003 printf ("Changing byte %d in message %d to %c\n",
1004 byte_seq
, iter_get_sequence (iter
), typecodes
[typecode_seq
]);
1007 _dbus_string_set_byte (data
, byte_seq
, typecodes
[typecode_seq
]);
1008 *expected_validity
= DBUS_VALIDITY_UNKNOWN
;
1015 dbus_uint32_t value
; /* cast to signed for adjusts */
1018 static const UIntChange uint32_changes
[] = {
1019 { CHANGE_TYPE_ADJUST
, (dbus_uint32_t
) -1 },
1020 { CHANGE_TYPE_ADJUST
, (dbus_uint32_t
) -2 },
1021 { CHANGE_TYPE_ADJUST
, (dbus_uint32_t
) -3 },
1022 { CHANGE_TYPE_ADJUST
, (dbus_uint32_t
) 1 },
1023 { CHANGE_TYPE_ADJUST
, (dbus_uint32_t
) 2 },
1024 { CHANGE_TYPE_ADJUST
, (dbus_uint32_t
) 3 },
1025 { CHANGE_TYPE_ABSOLUTE
, _DBUS_UINT32_MAX
},
1026 { CHANGE_TYPE_ABSOLUTE
, 0 },
1027 { CHANGE_TYPE_ABSOLUTE
, 1 },
1028 { CHANGE_TYPE_ABSOLUTE
, _DBUS_UINT32_MAX
- 1 },
1029 { CHANGE_TYPE_ABSOLUTE
, _DBUS_UINT32_MAX
- 5 }
1033 generate_uint32_changed (DBusMessageDataIter
*iter
,
1035 DBusValidity
*expected_validity
)
1040 dbus_uint32_t v_UINT32
;
1042 const UIntChange
*change
;
1045 /* Outer loop is each body, next loop is each change,
1046 * inner loop is each change location
1049 base_depth
= iter
->depth
;
1052 _dbus_assert (iter
->depth
== (base_depth
+ 0));
1053 _dbus_string_set_length (data
, 0);
1054 body_seq
= iter_get_sequence (iter
);
1056 if (!generate_many_bodies (iter
, data
, expected_validity
))
1059 _dbus_assert (iter
->depth
== (base_depth
+ 0));
1061 iter_set_sequence (iter
, body_seq
); /* undo the "next" from generate_many_bodies */
1062 iter_recurse (iter
);
1064 _dbus_assert (iter
->depth
== (base_depth
+ 1));
1065 change_seq
= iter_get_sequence (iter
);
1067 if (change_seq
== _DBUS_N_ELEMENTS (uint32_changes
))
1069 /* Reset change count */
1070 iter_set_sequence (iter
, 0);
1071 iter_unrecurse (iter
);
1076 _dbus_assert (iter
->depth
== (base_depth
+ 1));
1078 iter_recurse (iter
);
1079 _dbus_assert (iter
->depth
== (base_depth
+ 2));
1080 byte_seq
= iter_get_sequence (iter
);
1081 /* skip 4 bytes at a time */
1086 iter_unrecurse (iter
);
1088 _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq
, 4) == (unsigned) byte_seq
);
1089 if (byte_seq
>= (_dbus_string_get_length (data
) - 4))
1091 /* reset byte count */
1092 _dbus_assert (iter
->depth
== (base_depth
+ 1));
1093 iter_recurse (iter
);
1094 _dbus_assert (iter
->depth
== (base_depth
+ 2));
1095 iter_set_sequence (iter
, 0);
1096 iter_unrecurse (iter
);
1097 _dbus_assert (iter
->depth
== (base_depth
+ 1));
1102 _dbus_assert (byte_seq
<= (_dbus_string_get_length (data
) - 4));
1104 byte_order
= _dbus_string_get_byte (data
, BYTE_ORDER_OFFSET
);
1106 v_UINT32
= _dbus_marshal_read_uint32 (data
, byte_seq
, byte_order
, NULL
);
1108 change
= &uint32_changes
[change_seq
];
1110 if (change
->type
== CHANGE_TYPE_ADJUST
)
1112 v_UINT32
+= (int) change
->value
;
1116 v_UINT32
= change
->value
;
1120 printf ("body %d change %d pos %d ",
1121 body_seq
, change_seq
, byte_seq
);
1123 if (change
->type
== CHANGE_TYPE_ADJUST
)
1124 printf ("adjust by %d", (int) change
->value
);
1126 printf ("set to %u", change
->value
);
1128 printf (" \t%u -> %u\n",
1129 _dbus_marshal_read_uint32 (data
, byte_seq
, byte_order
, NULL
),
1133 _dbus_marshal_set_uint32 (data
, byte_seq
, v_UINT32
, byte_order
);
1134 *expected_validity
= DBUS_VALIDITY_UNKNOWN
;
1136 _dbus_assert (iter
->depth
== (base_depth
+ 1));
1137 iter_unrecurse (iter
);
1138 _dbus_assert (iter
->depth
== (base_depth
+ 0));
1146 DBusMessageGeneratorFunc func
;
1147 } DBusMessageGenerator
;
1149 static const DBusMessageGenerator generators
[] = {
1150 { "trivial example of each message type", generate_trivial
},
1151 { "assorted arguments", generate_many_bodies
},
1152 { "assorted special cases", generate_special
},
1153 { "each uint32 modified", generate_uint32_changed
},
1154 { "wrong body lengths", generate_wrong_length
},
1155 { "each byte modified", generate_byte_changed
},
1157 /* This is really expensive and doesn't add too much coverage */
1158 { "change each typecode", generate_typecode_changed
}
1163 _dbus_message_data_free (DBusMessageData
*data
)
1165 _dbus_string_free (&data
->data
);
1169 _dbus_message_data_iter_init (DBusMessageDataIter
*iter
)
1175 while (i
< _DBUS_MESSAGE_DATA_MAX_NESTING
)
1177 iter
->sequence_nos
[i
] = 0;
1184 _dbus_message_data_iter_get_and_next (DBusMessageDataIter
*iter
,
1185 DBusMessageData
*data
)
1187 DBusMessageGeneratorFunc func
;
1191 generator
= iter_get_sequence (iter
);
1193 if (generator
== _DBUS_N_ELEMENTS (generators
))
1196 iter_recurse (iter
);
1198 if (iter_first_in_series (iter
))
1200 printf (" testing message loading: %s ", generators
[generator
].name
);
1204 func
= generators
[generator
].func
;
1206 if (!_dbus_string_init (&data
->data
))
1207 _dbus_assert_not_reached ("oom");
1209 if ((*func
)(iter
, &data
->data
, &data
->expected_validity
))
1213 iter_set_sequence (iter
, 0);
1214 iter_unrecurse (iter
);
1215 iter_next (iter
); /* next generator */
1216 _dbus_string_free (&data
->data
);
1217 printf ("%d test loads cumulative\n", iter
->count
);
1220 iter_unrecurse (iter
);
1226 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */
1228 #endif /* DBUS_BUILD_TESTS */