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