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