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 DBUS_TYPE_UNIX_FD,
01018 255
01019 };
01020
01021 static dbus_bool_t
01022 generate_typecode_changed (DBusMessageDataIter *iter,
01023 DBusString *data,
01024 DBusValidity *expected_validity)
01025 {
01026 int byte_seq;
01027 int typecode_seq;
01028 int base_depth;
01029
01030 base_depth = iter->depth;
01031
01032 restart:
01033 _dbus_assert (iter->depth == (base_depth + 0));
01034 _dbus_string_set_length (data, 0);
01035
01036 if (!find_next_typecode (iter, data, expected_validity))
01037 return FALSE;
01038
01039 iter_recurse (iter);
01040 byte_seq = iter_get_sequence (iter);
01041
01042 _dbus_assert (byte_seq < _dbus_string_get_length (data));
01043
01044 iter_recurse (iter);
01045 typecode_seq = iter_get_sequence (iter);
01046 iter_next (iter);
01047
01048 _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes));
01049
01050 if (typecode_seq == _DBUS_N_ELEMENTS (typecodes))
01051 {
01052 _dbus_assert (iter->depth == (base_depth + 2));
01053 iter_set_sequence (iter, 0);
01054 iter_unrecurse (iter);
01055 _dbus_assert (iter->depth == (base_depth + 1));
01056 iter_next (iter);
01057 iter_unrecurse (iter);
01058 _dbus_assert (iter->depth == (base_depth + 0));
01059 goto restart;
01060 }
01061
01062 _dbus_assert (iter->depth == (base_depth + 2));
01063 iter_unrecurse (iter);
01064 _dbus_assert (iter->depth == (base_depth + 1));
01065 iter_unrecurse (iter);
01066 _dbus_assert (iter->depth == (base_depth + 0));
01067
01068 #if 0
01069 printf ("Changing byte %d in message %d to %c\n",
01070 byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]);
01071 #endif
01072
01073 _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]);
01074 *expected_validity = DBUS_VALIDITY_UNKNOWN;
01075 return TRUE;
01076 }
01077
01078 typedef struct
01079 {
01080 ChangeType type;
01081 dbus_uint32_t value;
01082 } UIntChange;
01083
01084 static const UIntChange uint32_changes[] = {
01085 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -1 },
01086 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -2 },
01087 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) -3 },
01088 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 1 },
01089 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 2 },
01090 { CHANGE_TYPE_ADJUST, (dbus_uint32_t) 3 },
01091 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX },
01092 { CHANGE_TYPE_ABSOLUTE, 0 },
01093 { CHANGE_TYPE_ABSOLUTE, 1 },
01094 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 1 },
01095 { CHANGE_TYPE_ABSOLUTE, _DBUS_UINT32_MAX - 5 }
01096 };
01097
01098 static dbus_bool_t
01099 generate_uint32_changed (DBusMessageDataIter *iter,
01100 DBusString *data,
01101 DBusValidity *expected_validity)
01102 {
01103 int body_seq;
01104 int byte_seq;
01105 int change_seq;
01106 dbus_uint32_t v_UINT32;
01107 int byte_order;
01108 const UIntChange *change;
01109 int base_depth;
01110
01111
01112
01113
01114
01115 base_depth = iter->depth;
01116
01117 next_body:
01118 _dbus_assert (iter->depth == (base_depth + 0));
01119 _dbus_string_set_length (data, 0);
01120 body_seq = iter_get_sequence (iter);
01121
01122 if (!generate_many_bodies (iter, data, expected_validity))
01123 return FALSE;
01124
01125 _dbus_assert (iter->depth == (base_depth + 0));
01126
01127 iter_set_sequence (iter, body_seq);
01128 iter_recurse (iter);
01129 next_change:
01130 _dbus_assert (iter->depth == (base_depth + 1));
01131 change_seq = iter_get_sequence (iter);
01132
01133 if (change_seq == _DBUS_N_ELEMENTS (uint32_changes))
01134 {
01135
01136 iter_set_sequence (iter, 0);
01137 iter_unrecurse (iter);
01138 iter_next (iter);
01139 goto next_body;
01140 }
01141
01142 _dbus_assert (iter->depth == (base_depth + 1));
01143
01144 iter_recurse (iter);
01145 _dbus_assert (iter->depth == (base_depth + 2));
01146 byte_seq = iter_get_sequence (iter);
01147
01148 iter_next (iter);
01149 iter_next (iter);
01150 iter_next (iter);
01151 iter_next (iter);
01152 iter_unrecurse (iter);
01153
01154 _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq, 4) == (unsigned) byte_seq);
01155 if (byte_seq >= (_dbus_string_get_length (data) - 4))
01156 {
01157
01158 _dbus_assert (iter->depth == (base_depth + 1));
01159 iter_recurse (iter);
01160 _dbus_assert (iter->depth == (base_depth + 2));
01161 iter_set_sequence (iter, 0);
01162 iter_unrecurse (iter);
01163 _dbus_assert (iter->depth == (base_depth + 1));
01164 iter_next (iter);
01165 goto next_change;
01166 }
01167
01168 _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4));
01169
01170 byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET);
01171
01172 v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL);
01173
01174 change = &uint32_changes[change_seq];
01175
01176 if (change->type == CHANGE_TYPE_ADJUST)
01177 {
01178 v_UINT32 += (int) change->value;
01179 }
01180 else
01181 {
01182 v_UINT32 = change->value;
01183 }
01184
01185 #if 0
01186 printf ("body %d change %d pos %d ",
01187 body_seq, change_seq, byte_seq);
01188
01189 if (change->type == CHANGE_TYPE_ADJUST)
01190 printf ("adjust by %d", (int) change->value);
01191 else
01192 printf ("set to %u", change->value);
01193
01194 printf (" \t%u -> %u\n",
01195 _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL),
01196 v_UINT32);
01197 #endif
01198
01199 _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order);
01200 *expected_validity = DBUS_VALIDITY_UNKNOWN;
01201
01202 _dbus_assert (iter->depth == (base_depth + 1));
01203 iter_unrecurse (iter);
01204 _dbus_assert (iter->depth == (base_depth + 0));
01205
01206 return TRUE;
01207 }
01208
01209 typedef struct
01210 {
01211 const char *name;
01212 DBusMessageGeneratorFunc func;
01213 } DBusMessageGenerator;
01214
01215 static const DBusMessageGenerator generators[] = {
01216 { "trivial example of each message type", generate_trivial },
01217 { "assorted arguments", generate_many_bodies },
01218 { "assorted special cases", generate_special },
01219 { "each uint32 modified", generate_uint32_changed },
01220 { "wrong body lengths", generate_wrong_length },
01221 { "each byte modified", generate_byte_changed },
01222 #if 0
01223
01224 { "change each typecode", generate_typecode_changed }
01225 #endif
01226 };
01227
01228 void
01229 _dbus_message_data_free (DBusMessageData *data)
01230 {
01231 _dbus_string_free (&data->data);
01232 }
01233
01234 void
01235 _dbus_message_data_iter_init (DBusMessageDataIter *iter)
01236 {
01237 int i;
01238
01239 iter->depth = 0;
01240 i = 0;
01241 while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
01242 {
01243 iter->sequence_nos[i] = 0;
01244 ++i;
01245 }
01246 iter->count = 0;
01247 }
01248
01249 dbus_bool_t
01250 _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
01251 DBusMessageData *data)
01252 {
01253 DBusMessageGeneratorFunc func;
01254 int generator;
01255
01256 restart:
01257 generator = iter_get_sequence (iter);
01258
01259 if (generator == _DBUS_N_ELEMENTS (generators))
01260 return FALSE;
01261
01262 iter_recurse (iter);
01263
01264 if (iter_first_in_series (iter))
01265 {
01266 printf (" testing message loading: %s ", generators[generator].name);
01267 fflush (stdout);
01268 }
01269
01270 func = generators[generator].func;
01271
01272 if (!_dbus_string_init (&data->data))
01273 _dbus_assert_not_reached ("oom");
01274
01275 if ((*func)(iter, &data->data, &data->expected_validity))
01276 ;
01277 else
01278 {
01279 iter_set_sequence (iter, 0);
01280 iter_unrecurse (iter);
01281 iter_next (iter);
01282 _dbus_string_free (&data->data);
01283 printf ("%d test loads cumulative\n", iter->count);
01284 goto restart;
01285 }
01286 iter_unrecurse (iter);
01287
01288 iter->count += 1;
01289 return TRUE;
01290 }
01291
01292 #endif
01293
01294 #endif