00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00026
00027 #ifdef DBUS_BUILD_TESTS
00028 #include "dbus-message-factory.h"
00029 #include "dbus-message-private.h"
00030 #include "dbus-test.h"
00031 #include <stdio.h>
00032
00033 typedef enum
00034 {
00035 CHANGE_TYPE_ADJUST,
00036 CHANGE_TYPE_ABSOLUTE
00037 } ChangeType;
00038
00039 #define BYTE_ORDER_OFFSET 0
00040 #define TYPE_OFFSET 1
00041 #define BODY_LENGTH_OFFSET 4
00042 #define FIELDS_ARRAY_LENGTH_OFFSET 12
00043
00044 static void
00045 iter_recurse (DBusMessageDataIter *iter)
00046 {
00047 iter->depth += 1;
00048 _dbus_assert (iter->depth < _DBUS_MESSAGE_DATA_MAX_NESTING);
00049 _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
00050 }
00051
00052 static int
00053 iter_get_sequence (DBusMessageDataIter *iter)
00054 {
00055 _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
00056 return iter->sequence_nos[iter->depth];
00057 }
00058
00059 static void
00060 iter_set_sequence (DBusMessageDataIter *iter,
00061 int sequence)
00062 {
00063 _dbus_assert (sequence >= 0);
00064 iter->sequence_nos[iter->depth] = sequence;
00065 }
00066
00067 static void
00068 iter_unrecurse (DBusMessageDataIter *iter)
00069 {
00070 iter->depth -= 1;
00071 _dbus_assert (iter->depth >= 0);
00072 }
00073
00074 static void
00075 iter_next (DBusMessageDataIter *iter)
00076 {
00077 iter->sequence_nos[iter->depth] += 1;
00078 }
00079
00080 static dbus_bool_t
00081 iter_first_in_series (DBusMessageDataIter *iter)
00082 {
00083 int i;
00084
00085 i = iter->depth;
00086 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
00087 {
00088 if (iter->sequence_nos[i] != 0)
00089 return FALSE;
00090 ++i;
00091 }
00092 return TRUE;
00093 }
00094
00095 typedef dbus_bool_t (* DBusInnerGeneratorFunc) (DBusMessageDataIter *iter,
00096 DBusMessage **message_p);
00097 typedef dbus_bool_t (* DBusMessageGeneratorFunc) (DBusMessageDataIter *iter,
00098 DBusString *data,
00099 DBusValidity *expected_validity);
00100
00101 static void
00102 set_reply_serial (DBusMessage *message)
00103 {
00104 if (message == NULL)
00105 _dbus_assert_not_reached ("oom");
00106 if (!dbus_message_set_reply_serial (message, 100))
00107 _dbus_assert_not_reached ("oom");
00108 }
00109
00110 static dbus_bool_t
00111 generate_trivial_inner (DBusMessageDataIter *iter,
00112 DBusMessage **message_p)
00113 {
00114 DBusMessage *message;
00115
00116 switch (iter_get_sequence (iter))
00117 {
00118 case 0:
00119 message = dbus_message_new_method_call ("org.freedesktop.TextEditor",
00120 "/foo/bar",
00121 "org.freedesktop.DocumentFactory",
00122 "Create");
00123 break;
00124 case 1:
00125 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
00126 set_reply_serial (message);
00127 break;
00128 case 2:
00129 message = dbus_message_new_signal ("/foo/bar",
00130 "org.freedesktop.DocumentFactory",
00131 "Created");
00132 break;
00133 case 3:
00134 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
00135
00136 if (!dbus_message_set_error_name (message,
00137 "org.freedesktop.TestErrorName"))
00138 _dbus_assert_not_reached ("oom");
00139
00140 {
00141 DBusMessageIter iter;
00142 const char *v_STRING = "This is an error";
00143
00144 dbus_message_iter_init_append (message, &iter);
00145 if (!dbus_message_iter_append_basic (&iter,
00146 DBUS_TYPE_STRING,
00147 &v_STRING))
00148 _dbus_assert_not_reached ("oom");
00149 }
00150
00151 set_reply_serial (message);
00152 break;
00153 default:
00154 return FALSE;
00155 }
00156
00157 if (message == NULL)
00158 _dbus_assert_not_reached ("oom");
00159
00160 *message_p = message;
00161
00162 return TRUE;
00163 }
00164
00165 static dbus_bool_t
00166 generate_many_bodies_inner (DBusMessageDataIter *iter,
00167 DBusMessage **message_p)
00168 {
00169 DBusMessage *message;
00170 DBusString signature;
00171 DBusString body;
00172
00173
00174 message = dbus_message_new_method_call ("o.z.F",
00175 "/",
00176 "o.z.B",
00177 "Nah");
00178 if (message == NULL)
00179 _dbus_assert_not_reached ("oom");
00180
00181 set_reply_serial (message);
00182
00183 if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
00184 _dbus_assert_not_reached ("oom");
00185
00186 if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter),
00187 message->byte_order,
00188 &signature, &body))
00189 {
00190 const char *v_SIGNATURE;
00191
00192 v_SIGNATURE = _dbus_string_get_const_data (&signature);
00193 if (!_dbus_header_set_field_basic (&message->header,
00194 DBUS_HEADER_FIELD_SIGNATURE,
00195 DBUS_TYPE_SIGNATURE,
00196 &v_SIGNATURE))
00197 _dbus_assert_not_reached ("oom");
00198
00199 if (!_dbus_string_move (&body, 0, &message->body, 0))
00200 _dbus_assert_not_reached ("oom");
00201
00202 _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET,
00203 _dbus_string_get_length (&message->body),
00204 message->byte_order);
00205
00206 *message_p = message;
00207 }
00208 else
00209 {
00210 dbus_message_unref (message);
00211 *message_p = NULL;
00212 }
00213
00214 _dbus_string_free (&signature);
00215 _dbus_string_free (&body);
00216
00217 return *message_p != NULL;
00218 }
00219
00220 static void
00221 generate_from_message (DBusString *data,
00222 DBusValidity *expected_validity,
00223 DBusMessage *message)
00224 {
00225 dbus_message_set_serial (message, 1);
00226 dbus_message_lock (message);
00227
00228 *expected_validity = DBUS_VALID;
00229
00230
00231 if (!_dbus_string_move (&message->header.data, 0,
00232 data, 0))
00233 _dbus_assert_not_reached ("oom");
00234
00235 if (!_dbus_string_copy (&message->body, 0,
00236 data, _dbus_string_get_length (data)))
00237 _dbus_assert_not_reached ("oom");
00238 }
00239
00240 static dbus_bool_t
00241 generate_outer (DBusMessageDataIter *iter,
00242 DBusString *data,
00243 DBusValidity *expected_validity,
00244 DBusInnerGeneratorFunc func)
00245 {
00246 DBusMessage *message;
00247
00248 message = NULL;
00249 if (!(*func)(iter, &message))
00250 return FALSE;
00251
00252 iter_next (iter);
00253
00254 _dbus_assert (message != NULL);
00255
00256 generate_from_message (data, expected_validity, message);
00257
00258 dbus_message_unref (message);
00259
00260 return TRUE;
00261 }
00262
00263 static dbus_bool_t
00264 generate_trivial (DBusMessageDataIter *iter,
00265 DBusString *data,
00266 DBusValidity *expected_validity)
00267 {
00268 return generate_outer (iter, data, expected_validity,
00269 generate_trivial_inner);
00270 }
00271
00272 static dbus_bool_t
00273 generate_many_bodies (DBusMessageDataIter *iter,
00274 DBusString *data,
00275 DBusValidity *expected_validity)
00276 {
00277 return generate_outer (iter, data, expected_validity,
00278 generate_many_bodies_inner);
00279 }
00280
00281 static DBusMessage*
00282 simple_method_call (void)
00283 {
00284 DBusMessage *message;
00285
00286 message = dbus_message_new_method_call ("o.b.Q",
00287 "/f/b",
00288 "o.b.Z",
00289 "Fro");
00290 if (message == NULL)
00291 _dbus_assert_not_reached ("oom");
00292 return message;
00293 }
00294
00295 static DBusMessage*
00296 simple_signal (void)
00297 {
00298 DBusMessage *message;
00299 message = dbus_message_new_signal ("/f/b",
00300 "o.b.Z",
00301 "Fro");
00302 if (message == NULL)
00303 _dbus_assert_not_reached ("oom");
00304 return message;
00305 }
00306
00307 static DBusMessage*
00308 simple_method_return (void)
00309 {
00310 DBusMessage *message;
00311 message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
00312 if (message == NULL)
00313 _dbus_assert_not_reached ("oom");
00314
00315 set_reply_serial (message);
00316
00317 return message;
00318 }
00319
00320 static DBusMessage*
00321 simple_error (void)
00322 {
00323 DBusMessage *message;
00324 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
00325 if (message == NULL)
00326 _dbus_assert_not_reached ("oom");
00327
00328 if (!dbus_message_set_error_name (message, "foo.bar"))
00329 _dbus_assert_not_reached ("oom");
00330
00331 set_reply_serial (message);
00332
00333 return message;
00334 }
00335
00336 static DBusMessage*
00337 message_with_nesting_levels (int levels)
00338 {
00339 DBusMessage *message;
00340 dbus_int32_t v_INT32;
00341 DBusMessageIter *parents;
00342 DBusMessageIter *children;
00343 int i;
00344
00345
00346
00347
00348
00349 _dbus_assert (levels < 256);
00350
00351 parents = dbus_new(DBusMessageIter, levels + 1);
00352 children = dbus_new(DBusMessageIter, levels + 1);
00353
00354 v_INT32 = 42;
00355 message = simple_method_call ();
00356
00357 i = 0;
00358 dbus_message_iter_init_append (message, &parents[i]);
00359 while (i < levels)
00360 {
00361 dbus_message_iter_open_container (&parents[i], DBUS_TYPE_VARIANT,
00362 i == (levels - 1) ?
00363 DBUS_TYPE_INT32_AS_STRING :
00364 DBUS_TYPE_VARIANT_AS_STRING,
00365 &children[i]);
00366 ++i;
00367 parents[i] = children[i-1];
00368 }
00369 --i;
00370 dbus_message_iter_append_basic (&children[i], DBUS_TYPE_INT32, &v_INT32);
00371 while (i >= 0)
00372 {
00373 dbus_message_iter_close_container (&parents[i], &children[i]);
00374 --i;
00375 }
00376
00377 dbus_free(parents);
00378 dbus_free(children);
00379
00380 return message;
00381 }
00382
00383 static dbus_bool_t
00384 generate_special (DBusMessageDataIter *iter,
00385 DBusString *data,
00386 DBusValidity *expected_validity)
00387 {
00388 int item_seq;
00389 DBusMessage *message;
00390 int pos;
00391 dbus_int32_t v_INT32;
00392
00393 _dbus_assert (_dbus_string_get_length (data) == 0);
00394
00395 message = NULL;
00396 pos = -1;
00397 v_INT32 = 42;
00398 item_seq = iter_get_sequence (iter);
00399
00400 if (item_seq == 0)
00401 {
00402 message = simple_method_call ();
00403 if (!dbus_message_append_args (message,
00404 DBUS_TYPE_INT32, &v_INT32,
00405 DBUS_TYPE_INT32, &v_INT32,
00406 DBUS_TYPE_INT32, &v_INT32,
00407 DBUS_TYPE_INVALID))
00408 _dbus_assert_not_reached ("oom");
00409
00410 _dbus_header_get_field_raw (&message->header,
00411 DBUS_HEADER_FIELD_SIGNATURE,
00412 NULL, &pos);
00413 generate_from_message (data, expected_validity, message);
00414
00415
00416 _dbus_string_set_byte (data, pos + 1, '$');
00417
00418 *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
00419 }
00420 else if (item_seq == 1)
00421 {
00422 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2];
00423 const char *v_STRING;
00424 int i;
00425
00426 message = simple_method_call ();
00427 if (!dbus_message_append_args (message,
00428 DBUS_TYPE_INT32, &v_INT32,
00429 DBUS_TYPE_INT32, &v_INT32,
00430 DBUS_TYPE_INT32, &v_INT32,
00431 DBUS_TYPE_INVALID))
00432 _dbus_assert_not_reached ("oom");
00433
00434 i = 0;
00435 while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
00436 {
00437 long_sig[i] = DBUS_TYPE_ARRAY;
00438 ++i;
00439 }
00440 long_sig[i] = DBUS_TYPE_INVALID;
00441
00442 v_STRING = long_sig;
00443 if (!_dbus_header_set_field_basic (&message->header,
00444 DBUS_HEADER_FIELD_SIGNATURE,
00445 DBUS_TYPE_SIGNATURE,
00446 &v_STRING))
00447 _dbus_assert_not_reached ("oom");
00448
00449 _dbus_header_get_field_raw (&message->header,
00450 DBUS_HEADER_FIELD_SIGNATURE,
00451 NULL, &pos);
00452 generate_from_message (data, expected_validity, message);
00453
00454 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
00455 }
00456 else if (item_seq == 2)
00457 {
00458 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4];
00459 const char *v_STRING;
00460 int i;
00461
00462 message = simple_method_call ();
00463 if (!dbus_message_append_args (message,
00464 DBUS_TYPE_INT32, &v_INT32,
00465 DBUS_TYPE_INT32, &v_INT32,
00466 DBUS_TYPE_INT32, &v_INT32,
00467 DBUS_TYPE_INVALID))
00468 _dbus_assert_not_reached ("oom");
00469
00470 i = 0;
00471 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
00472 {
00473 long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
00474 ++i;
00475 }
00476
00477 long_sig[i] = DBUS_TYPE_INT32;
00478 ++i;
00479
00480 while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
00481 {
00482 long_sig[i] = DBUS_STRUCT_END_CHAR;
00483 ++i;
00484 }
00485 long_sig[i] = DBUS_TYPE_INVALID;
00486
00487 v_STRING = long_sig;
00488 if (!_dbus_header_set_field_basic (&message->header,
00489 DBUS_HEADER_FIELD_SIGNATURE,
00490 DBUS_TYPE_SIGNATURE,
00491 &v_STRING))
00492 _dbus_assert_not_reached ("oom");
00493
00494 _dbus_header_get_field_raw (&message->header,
00495 DBUS_HEADER_FIELD_SIGNATURE,
00496 NULL, &pos);
00497 generate_from_message (data, expected_validity, message);
00498
00499 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
00500 }
00501 else if (item_seq == 3)
00502 {
00503 message = simple_method_call ();
00504 if (!dbus_message_append_args (message,
00505 DBUS_TYPE_INT32, &v_INT32,
00506 DBUS_TYPE_INT32, &v_INT32,
00507 DBUS_TYPE_INT32, &v_INT32,
00508 DBUS_TYPE_INVALID))
00509 _dbus_assert_not_reached ("oom");
00510
00511 _dbus_header_get_field_raw (&message->header,
00512 DBUS_HEADER_FIELD_SIGNATURE,
00513 NULL, &pos);
00514 generate_from_message (data, expected_validity, message);
00515
00516 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
00517
00518 *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
00519 }
00520 else if (item_seq == 4)
00521 {
00522 message = simple_method_call ();
00523 if (!dbus_message_append_args (message,
00524 DBUS_TYPE_INT32, &v_INT32,
00525 DBUS_TYPE_INT32, &v_INT32,
00526 DBUS_TYPE_INT32, &v_INT32,
00527 DBUS_TYPE_INVALID))
00528 _dbus_assert_not_reached ("oom");
00529
00530 _dbus_header_get_field_raw (&message->header,
00531 DBUS_HEADER_FIELD_SIGNATURE,
00532 NULL, &pos);
00533 generate_from_message (data, expected_validity, message);
00534
00535 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
00536
00537 *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
00538 }
00539 else if (item_seq == 5)
00540 {
00541 message = simple_method_call ();
00542 if (!dbus_message_append_args (message,
00543 DBUS_TYPE_INT32, &v_INT32,
00544 DBUS_TYPE_INT32, &v_INT32,
00545 DBUS_TYPE_INT32, &v_INT32,
00546 DBUS_TYPE_INVALID))
00547 _dbus_assert_not_reached ("oom");
00548
00549 _dbus_header_get_field_raw (&message->header,
00550 DBUS_HEADER_FIELD_SIGNATURE,
00551 NULL, &pos);
00552 generate_from_message (data, expected_validity, message);
00553
00554 _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
00555 _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
00556
00557 *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
00558 }
00559 else if (item_seq == 6)
00560 {
00561 message = simple_method_call ();
00562 generate_from_message (data, expected_validity, message);
00563
00564 _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
00565
00566 *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
00567 }
00568 else if (item_seq == 7)
00569 {
00570
00571 message = simple_method_call ();
00572 generate_from_message (data, expected_validity, message);
00573
00574 _dbus_string_set_byte (data, TYPE_OFFSET, 100);
00575
00576 *expected_validity = DBUS_VALID;
00577 }
00578 else if (item_seq == 8)
00579 {
00580 message = simple_method_call ();
00581 generate_from_message (data, expected_validity, message);
00582
00583 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
00584 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
00585 message->byte_order);
00586 _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
00587 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
00588 message->byte_order);
00589 *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
00590 }
00591 else if (item_seq == 9)
00592 {
00593 const char *v_STRING = "not a valid bus name";
00594 message = simple_method_call ();
00595
00596 if (!_dbus_header_set_field_basic (&message->header,
00597 DBUS_HEADER_FIELD_SENDER,
00598 DBUS_TYPE_STRING, &v_STRING))
00599 _dbus_assert_not_reached ("oom");
00600
00601 generate_from_message (data, expected_validity, message);
00602
00603 *expected_validity = DBUS_INVALID_BAD_SENDER;
00604 }
00605 else if (item_seq == 10)
00606 {
00607 message = simple_method_call ();
00608
00609 if (!dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL))
00610 _dbus_assert_not_reached ("oom");
00611
00612 generate_from_message (data, expected_validity, message);
00613
00614 *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
00615 }
00616 else if (item_seq == 11)
00617 {
00618 message = simple_method_call ();
00619
00620 if (!dbus_message_set_path (message, DBUS_PATH_LOCAL))
00621 _dbus_assert_not_reached ("oom");
00622
00623 generate_from_message (data, expected_validity, message);
00624
00625 *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
00626 }
00627 else if (item_seq == 12)
00628 {
00629
00630 message = simple_method_call ();
00631
00632 if (!dbus_message_set_interface (message, NULL))
00633 _dbus_assert_not_reached ("oom");
00634
00635 generate_from_message (data, expected_validity, message);
00636
00637 *expected_validity = DBUS_VALID;
00638 }
00639 else if (item_seq == 13)
00640 {
00641
00642 message = simple_signal ();
00643
00644 if (!dbus_message_set_interface (message, NULL))
00645 _dbus_assert_not_reached ("oom");
00646
00647 generate_from_message (data, expected_validity, message);
00648
00649 *expected_validity = DBUS_INVALID_MISSING_INTERFACE;
00650 }
00651 else if (item_seq == 14)
00652 {
00653 message = simple_method_return ();
00654
00655 if (!_dbus_header_delete_field (&message->header, DBUS_HEADER_FIELD_REPLY_SERIAL))
00656 _dbus_assert_not_reached ("oom");
00657
00658 generate_from_message (data, expected_validity, message);
00659
00660 *expected_validity = DBUS_INVALID_MISSING_REPLY_SERIAL;
00661 }
00662 else if (item_seq == 15)
00663 {
00664 message = simple_error ();
00665
00666 if (!dbus_message_set_error_name (message, NULL))
00667 _dbus_assert_not_reached ("oom");
00668
00669 generate_from_message (data, expected_validity, message);
00670
00671 *expected_validity = DBUS_INVALID_MISSING_ERROR_NAME;
00672 }
00673 else if (item_seq == 16)
00674 {
00675 char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*4+10];
00676 const char *v_STRING;
00677 int i;
00678 int n_begins;
00679
00680 message = simple_method_call ();
00681 if (!dbus_message_append_args (message,
00682 DBUS_TYPE_INT32, &v_INT32,
00683 DBUS_TYPE_INT32, &v_INT32,
00684 DBUS_TYPE_INT32, &v_INT32,
00685 DBUS_TYPE_INVALID))
00686 _dbus_assert_not_reached ("oom");
00687
00688 i = 0;
00689 while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*3 + 3))
00690 {
00691 long_sig[i] = DBUS_TYPE_ARRAY;
00692 ++i;
00693 long_sig[i] = DBUS_DICT_ENTRY_BEGIN_CHAR;
00694 ++i;
00695 long_sig[i] = DBUS_TYPE_INT32;
00696 ++i;
00697 }
00698 n_begins = i / 3;
00699
00700 long_sig[i] = DBUS_TYPE_INT32;
00701 ++i;
00702
00703 while (n_begins > 0)
00704 {
00705 long_sig[i] = DBUS_DICT_ENTRY_END_CHAR;
00706 ++i;
00707 n_begins -= 1;
00708 }
00709 long_sig[i] = DBUS_TYPE_INVALID;
00710
00711 v_STRING = long_sig;
00712 if (!_dbus_header_set_field_basic (&message->header,
00713 DBUS_HEADER_FIELD_SIGNATURE,
00714 DBUS_TYPE_SIGNATURE,
00715 &v_STRING))
00716 _dbus_assert_not_reached ("oom");
00717
00718 _dbus_header_get_field_raw (&message->header,
00719 DBUS_HEADER_FIELD_SIGNATURE,
00720 NULL, &pos);
00721 generate_from_message (data, expected_validity, message);
00722
00723 *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
00724 }
00725 else if (item_seq == 17)
00726 {
00727 message = simple_method_call ();
00728 if (!dbus_message_append_args (message,
00729 DBUS_TYPE_INT32, &v_INT32,
00730 DBUS_TYPE_INT32, &v_INT32,
00731 DBUS_TYPE_INT32, &v_INT32,
00732 DBUS_TYPE_INVALID))
00733 _dbus_assert_not_reached ("oom");
00734
00735 _dbus_header_get_field_raw (&message->header,
00736 DBUS_HEADER_FIELD_SIGNATURE,
00737 NULL, &pos);
00738 generate_from_message (data, expected_validity, message);
00739
00740 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
00741 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
00742
00743 *expected_validity = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
00744 }
00745 else if (item_seq == 18)
00746 {
00747 message = simple_method_call ();
00748 if (!dbus_message_append_args (message,
00749 DBUS_TYPE_INT32, &v_INT32,
00750 DBUS_TYPE_INT32, &v_INT32,
00751 DBUS_TYPE_INT32, &v_INT32,
00752 DBUS_TYPE_INVALID))
00753 _dbus_assert_not_reached ("oom");
00754
00755 _dbus_header_get_field_raw (&message->header,
00756 DBUS_HEADER_FIELD_SIGNATURE,
00757 NULL, &pos);
00758 generate_from_message (data, expected_validity, message);
00759
00760 _dbus_string_set_byte (data, pos + 1, DBUS_DICT_ENTRY_END_CHAR);
00761
00762 *expected_validity = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
00763 }
00764 else if (item_seq == 19)
00765 {
00766 message = simple_method_call ();
00767 if (!dbus_message_append_args (message,
00768 DBUS_TYPE_INT32, &v_INT32,
00769 DBUS_TYPE_INT32, &v_INT32,
00770 DBUS_TYPE_INT32, &v_INT32,
00771 DBUS_TYPE_INVALID))
00772 _dbus_assert_not_reached ("oom");
00773
00774 _dbus_header_get_field_raw (&message->header,
00775 DBUS_HEADER_FIELD_SIGNATURE,
00776 NULL, &pos);
00777 generate_from_message (data, expected_validity, message);
00778
00779 _dbus_string_set_byte (data, pos + 1, DBUS_TYPE_ARRAY);
00780 _dbus_string_set_byte (data, pos + 2, DBUS_DICT_ENTRY_BEGIN_CHAR);
00781 _dbus_string_set_byte (data, pos + 3, DBUS_DICT_ENTRY_END_CHAR);
00782
00783 *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
00784 }
00785 else if (item_seq == 20)
00786 {
00787
00788 message = message_with_nesting_levels(64);
00789
00790 generate_from_message (data, expected_validity, message);
00791
00792 *expected_validity = DBUS_VALID;
00793 }
00794 else if (item_seq == 21)
00795 {
00796
00797 message = message_with_nesting_levels(65);
00798
00799 generate_from_message (data, expected_validity, message);
00800
00801 *expected_validity = DBUS_INVALID_NESTED_TOO_DEEPLY;
00802 }
00803 else
00804 {
00805 return FALSE;
00806 }
00807
00808 if (message)
00809 dbus_message_unref (message);
00810
00811 iter_next (iter);
00812 return TRUE;
00813 }
00814
00815 static dbus_bool_t
00816 generate_wrong_length (DBusMessageDataIter *iter,
00817 DBusString *data,
00818 DBusValidity *expected_validity)
00819 {
00820 int lengths[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1,
00821 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 };
00822 int adjust;
00823 int len_seq;
00824
00825 restart:
00826 len_seq = iter_get_sequence (iter);
00827 if (len_seq == _DBUS_N_ELEMENTS (lengths))
00828 return FALSE;
00829
00830 _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths));
00831
00832 iter_recurse (iter);
00833 if (!generate_many_bodies (iter, data, expected_validity))
00834 {
00835 iter_set_sequence (iter, 0);
00836 iter_unrecurse (iter);
00837 iter_next (iter);
00838 goto restart;
00839 }
00840 iter_unrecurse (iter);
00841
00842 adjust = lengths[len_seq];
00843
00844 if (adjust < 0)
00845 {
00846 if ((_dbus_string_get_length (data) + adjust) < DBUS_MINIMUM_HEADER_SIZE)
00847 _dbus_string_set_length (data, DBUS_MINIMUM_HEADER_SIZE);
00848 else
00849 _dbus_string_shorten (data, - adjust);
00850 *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON;
00851 }
00852 else
00853 {
00854 if (!_dbus_string_lengthen (data, adjust))
00855 _dbus_assert_not_reached ("oom");
00856 *expected_validity = DBUS_INVALID_TOO_MUCH_DATA;
00857 }
00858
00859
00860 {
00861 int old_body_len;
00862 int new_body_len;
00863 int byte_order;
00864
00865 _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE);
00866
00867 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
00868 old_body_len = _dbus_marshal_read_uint32 (data,
00869 BODY_LENGTH_OFFSET,
00870 byte_order,
00871 NULL);
00872 _dbus_assert (old_body_len < _dbus_string_get_length (data));
00873 new_body_len = old_body_len + adjust;
00874 if (new_body_len < 0)
00875 {
00876 new_body_len = 0;
00877
00878 *expected_validity = DBUS_VALIDITY_UNKNOWN;
00879 }
00880
00881 _dbus_verbose ("changing body len from %u to %u by adjust %d\n",
00882 old_body_len, new_body_len, adjust);
00883
00884 _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
00885 new_body_len,
00886 byte_order);
00887 }
00888
00889 return TRUE;
00890 }
00891
00892 static dbus_bool_t
00893 generate_byte_changed (DBusMessageDataIter *iter,
00894 DBusString *data,
00895 DBusValidity *expected_validity)
00896 {
00897 int byte_seq;
00898 int v_BYTE;
00899
00900
00901
00902
00903
00904
00905 restart:
00906 if (!generate_many_bodies (iter, data, expected_validity))
00907 return FALSE;
00908
00909 iter_recurse (iter);
00910 byte_seq = iter_get_sequence (iter);
00911 iter_next (iter);
00912 iter_unrecurse (iter);
00913
00914 if (byte_seq == _dbus_string_get_length (data))
00915 {
00916 _dbus_string_set_length (data, 0);
00917
00918 iter_recurse (iter);
00919 iter_set_sequence (iter, 0);
00920 iter_unrecurse (iter);
00921 goto restart;
00922 }
00923 else
00924 {
00925
00926 iter_set_sequence (iter, iter_get_sequence (iter) - 1);
00927 }
00928
00929 _dbus_assert (byte_seq < _dbus_string_get_length (data));
00930 v_BYTE = _dbus_string_get_byte (data, byte_seq);
00931 v_BYTE += byte_seq;
00932 _dbus_string_set_byte (data, byte_seq, v_BYTE);
00933 *expected_validity = DBUS_VALIDITY_UNKNOWN;
00934
00935 return TRUE;
00936 }
00937
00938 static dbus_bool_t
00939 find_next_typecode (DBusMessageDataIter *iter,
00940 DBusString *data,
00941 DBusValidity *expected_validity)
00942 {
00943 int body_seq;
00944 int byte_seq;
00945 int base_depth;
00946
00947 base_depth = iter->depth;
00948
00949 restart:
00950 _dbus_assert (iter->depth == (base_depth + 0));
00951 _dbus_string_set_length (data, 0);
00952
00953 body_seq = iter_get_sequence (iter);
00954
00955 if (!generate_many_bodies (iter, data, expected_validity))
00956 return FALSE;
00957
00958 iter_set_sequence (iter, body_seq);
00959
00960 iter_recurse (iter);
00961 while (TRUE)
00962 {
00963 _dbus_assert (iter->depth == (base_depth + 1));
00964
00965 byte_seq = iter_get_sequence (iter);
00966
00967 _dbus_assert (byte_seq <= _dbus_string_get_length (data));
00968
00969 if (byte_seq == _dbus_string_get_length (data))
00970 {
00971
00972 iter_set_sequence (iter, 0);
00973 iter_unrecurse (iter);
00974 _dbus_assert (iter->depth == (base_depth + 0));
00975 iter_next (iter);
00976 goto restart;
00977 }
00978
00979 _dbus_assert (byte_seq < _dbus_string_get_length (data));
00980
00981 if (_dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq)))
00982 break;
00983 else
00984 iter_next (iter);
00985 }
00986
00987 _dbus_assert (byte_seq == iter_get_sequence (iter));
00988 _dbus_assert (byte_seq < _dbus_string_get_length (data));
00989
00990 iter_unrecurse (iter);
00991
00992 _dbus_assert (iter->depth == (base_depth + 0));
00993
00994 return TRUE;
00995 }
00996
00997 static const int typecodes[] = {
00998 DBUS_TYPE_INVALID,
00999 DBUS_TYPE_BYTE,
01000 DBUS_TYPE_BOOLEAN,
01001 DBUS_TYPE_INT16,
01002 DBUS_TYPE_UINT16,
01003 DBUS_TYPE_INT32,
01004 DBUS_TYPE_UINT32,
01005 DBUS_TYPE_INT64,
01006 DBUS_TYPE_UINT64,
01007 DBUS_TYPE_DOUBLE,
01008 DBUS_TYPE_STRING,
01009 DBUS_TYPE_OBJECT_PATH,
01010 DBUS_TYPE_SIGNATURE,
01011 DBUS_TYPE_ARRAY,
01012 DBUS_TYPE_VARIANT,
01013 DBUS_STRUCT_BEGIN_CHAR,
01014 DBUS_STRUCT_END_CHAR,
01015 DBUS_DICT_ENTRY_BEGIN_CHAR,
01016 DBUS_DICT_ENTRY_END_CHAR,
01017 255
01018 };
01019
01020 static dbus_bool_t
01021 generate_typecode_changed (DBusMessageDataIter *iter,
01022 DBusString *data,
01023 DBusValidity *expected_validity)
01024 {
01025 int byte_seq;
01026 int typecode_seq;
01027 int base_depth;
01028
01029 base_depth = iter->depth;
01030
01031 restart:
01032 _dbus_assert (iter->depth == (base_depth + 0));
01033 _dbus_string_set_length (data, 0);
01034
01035 if (!find_next_typecode (iter, data, expected_validity))
01036 return FALSE;
01037
01038 iter_recurse (iter);
01039 byte_seq = iter_get_sequence (iter);
01040
01041 _dbus_assert (byte_seq < _dbus_string_get_length (data));
01042
01043 iter_recurse (iter);
01044 typecode_seq = iter_get_sequence (iter);
01045 iter_next (iter);
01046
01047 _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes));
01048
01049 if (typecode_seq == _DBUS_N_ELEMENTS (typecodes))
01050 {
01051 _dbus_assert (iter->depth == (base_depth + 2));
01052 iter_set_sequence (iter, 0);
01053 iter_unrecurse (iter);
01054 _dbus_assert (iter->depth == (base_depth + 1));
01055 iter_next (iter);
01056 iter_unrecurse (iter);
01057 _dbus_assert (iter->depth == (base_depth + 0));
01058 goto restart;
01059 }
01060
01061 _dbus_assert (iter->depth == (base_depth + 2));
01062 iter_unrecurse (iter);
01063 _dbus_assert (iter->depth == (base_depth + 1));
01064 iter_unrecurse (iter);
01065 _dbus_assert (iter->depth == (base_depth + 0));
01066
01067 #if 0
01068 printf ("Changing byte %d in message %d to %c\n",
01069 byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]);
01070 #endif
01071
01072 _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]);
01073 *expected_validity = DBUS_VALIDITY_UNKNOWN;
01074 return TRUE;
01075 }
01076
01077 typedef struct
01078 {
01079 ChangeType type;
01080 dbus_uint32_t value;
01081 } UIntChange;
01082
01083 static const UIntChange uint32_changes[] = {
01084 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -1 },
01085 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -2 },
01086 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -3 },
01087 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 1 },
01088 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 2 },
01089 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 3 },
01090 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX },
01091 { CHANGE_TYPE_ABSOLUTE, 0 },
01092 { CHANGE_TYPE_ABSOLUTE, 1 },
01093 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 1 },
01094 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 5 }
01095 };
01096
01097 static dbus_bool_t
01098 generate_uint32_changed (DBusMessageDataIter *iter,
01099 DBusString *data,
01100 DBusValidity *expected_validity)
01101 {
01102 int body_seq;
01103 int byte_seq;
01104 int change_seq;
01105 dbus_uint32_t v_UINT32;
01106 int byte_order;
01107 const UIntChange *change;
01108 int base_depth;
01109
01110
01111
01112
01113
01114 base_depth = iter->depth;
01115
01116 next_body:
01117 _dbus_assert (iter->depth == (base_depth + 0));
01118 _dbus_string_set_length (data, 0);
01119 body_seq = iter_get_sequence (iter);
01120
01121 if (!generate_many_bodies (iter, data, expected_validity))
01122 return FALSE;
01123
01124 _dbus_assert (iter->depth == (base_depth + 0));
01125
01126 iter_set_sequence (iter, body_seq);
01127 iter_recurse (iter);
01128 next_change:
01129 _dbus_assert (iter->depth == (base_depth + 1));
01130 change_seq = iter_get_sequence (iter);
01131
01132 if (change_seq == _DBUS_N_ELEMENTS (uint32_changes))
01133 {
01134
01135 iter_set_sequence (iter, 0);
01136 iter_unrecurse (iter);
01137 iter_next (iter);
01138 goto next_body;
01139 }
01140
01141 _dbus_assert (iter->depth == (base_depth + 1));
01142
01143 iter_recurse (iter);
01144 _dbus_assert (iter->depth == (base_depth + 2));
01145 byte_seq = iter_get_sequence (iter);
01146
01147 iter_next (iter);
01148 iter_next (iter);
01149 iter_next (iter);
01150 iter_next (iter);
01151 iter_unrecurse (iter);
01152
01153 _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq, 4) == (unsigned) byte_seq);
01154 if (byte_seq >= (_dbus_string_get_length (data) - 4))
01155 {
01156
01157 _dbus_assert (iter->depth == (base_depth + 1));
01158 iter_recurse (iter);
01159 _dbus_assert (iter->depth == (base_depth + 2));
01160 iter_set_sequence (iter, 0);
01161 iter_unrecurse (iter);
01162 _dbus_assert (iter->depth == (base_depth + 1));
01163 iter_next (iter);
01164 goto next_change;
01165 }
01166
01167 _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4));
01168
01169 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
01170
01171 v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL);
01172
01173 change = &uint32_changes[change_seq];
01174
01175 if (change->type == CHANGE_TYPE_ADJUST)
01176 {
01177 v_UINT32 += (int) change->value;
01178 }
01179 else
01180 {
01181 v_UINT32 = change->value;
01182 }
01183
01184 #if 0
01185 printf ("body %d change %d pos %d ",
01186 body_seq, change_seq, byte_seq);
01187
01188 if (change->type == CHANGE_TYPE_ADJUST)
01189 printf ("adjust by %d", (int) change->value);
01190 else
01191 printf ("set to %u", change->value);
01192
01193 printf (" \t%u -> %u\n",
01194 _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL),
01195 v_UINT32);
01196 #endif
01197
01198 _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order);
01199 *expected_validity = DBUS_VALIDITY_UNKNOWN;
01200
01201 _dbus_assert (iter->depth == (base_depth + 1));
01202 iter_unrecurse (iter);
01203 _dbus_assert (iter->depth == (base_depth + 0));
01204
01205 return TRUE;
01206 }
01207
01208 typedef struct
01209 {
01210 const char *name;
01211 DBusMessageGeneratorFunc func;
01212 } DBusMessageGenerator;
01213
01214 static const DBusMessageGenerator generators[] = {
01215 { "trivial example of each message type", generate_trivial },
01216 { "assorted arguments", generate_many_bodies },
01217 { "assorted special cases", generate_special },
01218 { "each uint32 modified", generate_uint32_changed },
01219 { "wrong body lengths", generate_wrong_length },
01220 { "each byte modified", generate_byte_changed },
01221 #if 0
01222
01223 { "change each typecode", generate_typecode_changed }
01224 #endif
01225 };
01226
01227 void
01228 _dbus_message_data_free (DBusMessageData *data)
01229 {
01230 _dbus_string_free (&data->data);
01231 }
01232
01233 void
01234 _dbus_message_data_iter_init (DBusMessageDataIter *iter)
01235 {
01236 int i;
01237
01238 iter->depth = 0;
01239 i = 0;
01240 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
01241 {
01242 iter->sequence_nos[i] = 0;
01243 ++i;
01244 }
01245 iter->count = 0;
01246 }
01247
01248 dbus_bool_t
01249 _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
01250 DBusMessageData *data)
01251 {
01252 DBusMessageGeneratorFunc func;
01253 int generator;
01254
01255 restart:
01256 generator = iter_get_sequence (iter);
01257
01258 if (generator == _DBUS_N_ELEMENTS (generators))
01259 return FALSE;
01260
01261 iter_recurse (iter);
01262
01263 if (iter_first_in_series (iter))
01264 {
01265 printf (" testing message loading: %s ", generators[generator].name);
01266 fflush (stdout);
01267 }
01268
01269 func = generators[generator].func;
01270
01271 if (!_dbus_string_init (&data->data))
01272 _dbus_assert_not_reached ("oom");
01273
01274 if ((*func)(iter, &data->data, &data->expected_validity))
01275 ;
01276 else
01277 {
01278 iter_set_sequence (iter, 0);
01279 iter_unrecurse (iter);
01280 iter_next (iter);
01281 _dbus_string_free (&data->data);
01282 printf ("%d test loads cumulative\n", iter->count);
01283 goto restart;
01284 }
01285 iter_unrecurse (iter);
01286
01287 iter->count += 1;
01288 return TRUE;
01289 }
01290
01291 #endif
01292
01293 #endif