Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

dbus-message.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */ 00002 /* dbus-message.c DBusMessage object 00003 * 00004 * Copyright (C) 2002, 2003, 2004 Red Hat Inc. 00005 * Copyright (C) 2002, 2003 CodeFactory AB 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 * 00023 */ 00024 00025 #include "dbus-internals.h" 00026 #include "dbus-marshal.h" 00027 #include "dbus-message.h" 00028 #include "dbus-message-internal.h" 00029 #include "dbus-memory.h" 00030 #include "dbus-list.h" 00031 #include "dbus-message-builder.h" 00032 #include "dbus-dataslot.h" 00033 #include <string.h> 00034 00048 typedef struct 00049 { 00050 int name_offset; 00051 int value_offset; 00052 } HeaderField; 00053 00055 #define BYTE_ORDER_OFFSET 0 00056 00057 #define TYPE_OFFSET 1 00058 00059 #define FLAGS_OFFSET 2 00060 00061 #define VERSION_OFFSET 3 00062 00063 #define HEADER_LENGTH_OFFSET 4 00064 00065 #define BODY_LENGTH_OFFSET 8 00066 00067 #define CLIENT_SERIAL_OFFSET 12 00068 00069 00077 struct DBusMessage 00078 { 00079 DBusAtomic refcount; 00081 DBusString header; 00086 HeaderField header_fields[DBUS_HEADER_FIELD_LAST + 1]; 00090 dbus_uint32_t client_serial; 00091 dbus_uint32_t reply_serial; 00093 int header_padding; 00095 DBusString body; 00097 char byte_order; 00099 DBusList *size_counters; 00100 long size_counter_delta; 00102 dbus_uint32_t changed_stamp; 00104 unsigned int locked : 1; 00106 DBusDataSlotList slot_list; 00107 }; 00108 00109 enum { 00110 DBUS_MESSAGE_ITER_TYPE_MESSAGE, 00111 DBUS_MESSAGE_ITER_TYPE_ARRAY, 00112 DBUS_MESSAGE_ITER_TYPE_DICT 00113 }; 00114 00116 typedef struct DBusMessageRealIter DBusMessageRealIter; 00117 00123 struct DBusMessageRealIter 00124 { 00125 DBusMessageRealIter *parent_iter; 00126 DBusMessage *message; 00127 dbus_uint32_t changed_stamp; 00129 /* This is an int instead of an enum to get a guaranteed size for the dummy: */ 00130 int type; 00132 int pos; 00133 int end; 00134 int container_start; 00135 int container_length_pos; 00137 int wrote_dict_key; 00139 int array_type_pos; 00140 int array_type_done; 00141 }; 00142 00153 void 00154 _dbus_message_get_network_data (DBusMessage *message, 00155 const DBusString **header, 00156 const DBusString **body) 00157 { 00158 _dbus_assert (message->locked); 00159 00160 *header = &message->header; 00161 *body = &message->body; 00162 } 00163 00164 static void 00165 clear_header_padding (DBusMessage *message) 00166 { 00167 _dbus_string_shorten (&message->header, 00168 message->header_padding); 00169 message->header_padding = 0; 00170 } 00171 00172 #ifdef DBUS_DISABLE_CHECKS 00173 #define is_valid_error_name(x) TRUE 00174 #else 00175 static dbus_bool_t 00176 is_valid_error_name (const char *error_name) 00177 { 00178 DBusString the_error_name; 00179 00180 if (error_name == NULL) 00181 return FALSE; 00182 00183 _dbus_string_init_const (&the_error_name, error_name); 00184 return _dbus_string_validate_error_name (&the_error_name, 0, 00185 _dbus_string_get_length (&the_error_name)); 00186 } 00187 #endif 00188 00189 static dbus_bool_t 00190 append_header_padding (DBusMessage *message) 00191 { 00192 int old_len; 00193 old_len = _dbus_string_get_length (&message->header); 00194 if (!_dbus_string_align_length (&message->header, 8)) 00195 return FALSE; 00196 00197 message->header_padding = _dbus_string_get_length (&message->header) - old_len; 00198 00199 return TRUE; 00200 } 00201 00202 #ifdef DBUS_BUILD_TESTS 00203 /* tests-only until it's actually used */ 00204 static dbus_int32_t 00205 get_int_field (DBusMessage *message, 00206 int field) 00207 { 00208 int offset; 00209 00210 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00211 00212 offset = message->header_fields[field].value_offset; 00213 00214 if (offset < 0) 00215 return -1; /* useless if -1 is a valid value of course */ 00216 00217 return _dbus_demarshal_int32 (&message->header, 00218 message->byte_order, 00219 offset, 00220 NULL); 00221 } 00222 #endif 00223 00224 static dbus_uint32_t 00225 get_uint_field (DBusMessage *message, 00226 int field) 00227 { 00228 int offset; 00229 00230 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00231 00232 offset = message->header_fields[field].value_offset; 00233 00234 if (offset < 0) 00235 return 0; /* useless if 0 is a valid value of course */ 00236 00237 return _dbus_demarshal_uint32 (&message->header, 00238 message->byte_order, 00239 offset, 00240 NULL); 00241 } 00242 00243 static const char* 00244 get_string_field (DBusMessage *message, 00245 int field, 00246 int *len) 00247 { 00248 int offset; 00249 const char *data; 00250 00251 offset = message->header_fields[field].value_offset; 00252 00253 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00254 00255 if (offset < 0) 00256 return NULL; 00257 00258 /* offset points to string length, string data follows it */ 00259 /* FIXME _dbus_demarshal_const_string() that returned 00260 * a reference to the string plus its len might be nice. 00261 */ 00262 00263 if (len) 00264 *len = _dbus_demarshal_uint32 (&message->header, 00265 message->byte_order, 00266 offset, 00267 NULL); 00268 00269 data = _dbus_string_get_const_data (&message->header); 00270 00271 return data + (offset + 4); 00272 } 00273 00274 /* returns FALSE if no memory, TRUE with NULL path if no field */ 00275 static dbus_bool_t 00276 get_path_field_decomposed (DBusMessage *message, 00277 int field, 00278 char ***path) 00279 { 00280 int offset; 00281 00282 offset = message->header_fields[field].value_offset; 00283 00284 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 00285 00286 if (offset < 0) 00287 { 00288 *path = NULL; 00289 return TRUE; 00290 } 00291 00292 return _dbus_demarshal_object_path (&message->header, 00293 message->byte_order, 00294 offset, 00295 NULL, 00296 path, NULL); 00297 } 00298 00299 #ifdef DBUS_BUILD_TESTS 00300 static dbus_bool_t 00301 append_int_field (DBusMessage *message, 00302 int field, 00303 int value) 00304 { 00305 _dbus_assert (!message->locked); 00306 00307 clear_header_padding (message); 00308 00309 message->header_fields[field].name_offset = 00310 _dbus_string_get_length (&message->header); 00311 00312 if (!_dbus_string_append_byte (&message->header, field)) 00313 goto failed; 00314 00315 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32)) 00316 goto failed; 00317 00318 if (!_dbus_string_align_length (&message->header, 4)) 00319 goto failed; 00320 00321 message->header_fields[field].value_offset = 00322 _dbus_string_get_length (&message->header); 00323 00324 if (!_dbus_marshal_int32 (&message->header, message->byte_order, 00325 value)) 00326 goto failed; 00327 00328 if (!append_header_padding (message)) 00329 goto failed; 00330 00331 return TRUE; 00332 00333 failed: 00334 _dbus_string_set_length (&message->header, 00335 message->header_fields[field].name_offset); 00336 message->header_fields[field].name_offset = -1; 00337 message->header_fields[field].value_offset = -1; 00338 00339 /* this must succeed because it was allocated on function entry and 00340 * DBusString doesn't ever realloc smaller 00341 */ 00342 if (!append_header_padding (message)) 00343 _dbus_assert_not_reached ("failed to reappend header padding"); 00344 return FALSE; 00345 } 00346 #endif 00347 00348 static dbus_bool_t 00349 append_uint_field (DBusMessage *message, 00350 int field, 00351 int value) 00352 { 00353 _dbus_assert (!message->locked); 00354 00355 clear_header_padding (message); 00356 00357 message->header_fields[field].name_offset = 00358 _dbus_string_get_length (&message->header); 00359 00360 if (!_dbus_string_append_byte (&message->header, field)) 00361 goto failed; 00362 00363 if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32)) 00364 goto failed; 00365 00366 if (!_dbus_string_align_length (&message->header, 4)) 00367 goto failed; 00368 00369 message->header_fields[field].value_offset = 00370 _dbus_string_get_length (&message->header); 00371 00372 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 00373 value)) 00374 goto failed; 00375 00376 if (!append_header_padding (message)) 00377 goto failed; 00378 00379 return TRUE; 00380 00381 failed: 00382 _dbus_string_set_length (&message->header, 00383 message->header_fields[field].name_offset); 00384 message->header_fields[field].name_offset = -1; 00385 message->header_fields[field].value_offset = -1; 00386 00387 /* this must succeed because it was allocated on function entry and 00388 * DBusString doesn't ever realloc smaller 00389 */ 00390 if (!append_header_padding (message)) 00391 _dbus_assert_not_reached ("failed to reappend header padding"); 00392 return FALSE; 00393 } 00394 00398 #define MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING (1 + 1 + 3 + 4 + 1 + 8) 00399 00400 static dbus_bool_t 00401 append_string_field_len (DBusMessage *message, 00402 int field, 00403 int type, 00404 const char *value, 00405 int value_len) 00406 { 00407 _dbus_assert (!message->locked); 00408 00409 clear_header_padding (message); 00410 00411 message->header_fields[field].name_offset = 00412 _dbus_string_get_length (&message->header); 00413 00414 if (!_dbus_string_append_byte (&message->header, field)) 00415 goto failed; 00416 00417 if (!_dbus_string_append_byte (&message->header, type)) 00418 goto failed; 00419 00420 if (!_dbus_string_align_length (&message->header, 4)) 00421 goto failed; 00422 00423 message->header_fields[field].value_offset = 00424 _dbus_string_get_length (&message->header); 00425 00426 if (!_dbus_marshal_string_len (&message->header, message->byte_order, 00427 value, value_len)) 00428 goto failed; 00429 00430 if (!append_header_padding (message)) 00431 goto failed; 00432 00433 return TRUE; 00434 00435 failed: 00436 _dbus_string_set_length (&message->header, 00437 message->header_fields[field].name_offset); 00438 message->header_fields[field].name_offset = -1; 00439 message->header_fields[field].value_offset = -1; 00440 00441 /* this must succeed because it was allocated on function entry and 00442 * DBusString doesn't ever realloc smaller 00443 */ 00444 if (!append_header_padding (message)) 00445 _dbus_assert_not_reached ("failed to reappend header padding"); 00446 00447 return FALSE; 00448 } 00449 00450 static dbus_bool_t 00451 append_string_field (DBusMessage *message, 00452 int field, 00453 int type, 00454 const char *value) 00455 { 00456 int value_len; 00457 00458 value_len = strlen (value); 00459 00460 return append_string_field_len (message, field, type, value, value_len); 00461 } 00462 00463 static int 00464 get_type_alignment (int type) 00465 { 00466 int alignment; 00467 00468 switch (type) 00469 { 00470 case DBUS_TYPE_NIL: 00471 case DBUS_TYPE_BYTE: 00472 case DBUS_TYPE_BOOLEAN: 00473 alignment = 0; 00474 break; 00475 00476 case DBUS_TYPE_INT32: 00477 case DBUS_TYPE_UINT32: 00478 case DBUS_TYPE_STRING: 00479 case DBUS_TYPE_OBJECT_PATH: 00480 /* These are aligned 4 because they have a length as the 00481 * first field; 00482 */ 00483 case DBUS_TYPE_CUSTOM: 00484 case DBUS_TYPE_DICT: 00485 alignment = 4; 00486 break; 00487 00488 case DBUS_TYPE_INT64: 00489 case DBUS_TYPE_UINT64: 00490 case DBUS_TYPE_DOUBLE: 00491 alignment = 8; 00492 break; 00493 00494 case DBUS_TYPE_ARRAY: 00495 _dbus_assert_not_reached ("passed an ARRAY type to get_type_alignment()"); 00496 break; 00497 00498 case DBUS_TYPE_INVALID: 00499 default: 00500 _dbus_assert_not_reached ("passed an invalid or unknown type to get_type_alignment()"); 00501 break; 00502 } 00503 00504 return alignment; 00505 } 00506 00507 static dbus_bool_t 00508 iterate_one_field (const DBusString *str, 00509 int byte_order, 00510 int name_offset, 00511 int *next_offset_p, 00512 int *field_name_p, 00513 DBusString *append_copy_to, 00514 int *copy_name_offset_p, 00515 int *copy_value_offset_p) 00516 { 00517 int name, type, array_type; 00518 int alignment; 00519 int type_len; 00520 int type_pos; 00521 int value_pos; 00522 int value_len; 00523 int value_end; 00524 int pos; 00525 00526 _dbus_verbose ("%s: name_offset=%d, append to %p\n", 00527 _DBUS_FUNCTION_NAME, name_offset, append_copy_to); 00528 00529 pos = name_offset; 00530 00531 name = _dbus_string_get_byte (str, name_offset); 00532 pos++; 00533 00534 type_pos = pos; 00535 type = _dbus_string_get_byte (str, type_pos); 00536 pos++; 00537 type_len = 1; 00538 00539 array_type = type; 00540 /* find out the type of our array */ 00541 while (array_type == DBUS_TYPE_ARRAY) 00542 { 00543 pos++; 00544 type_len++; 00545 array_type = _dbus_string_get_byte (str, pos); 00546 } 00547 00548 _dbus_verbose ("%s: name %d, type '%c' %d at %d len %d, array type '%c' %d\n", 00549 _DBUS_FUNCTION_NAME, 00550 name, type, type, type_pos, type_len, array_type, array_type); 00551 00552 #ifndef DBUS_DISABLE_ASSERT 00553 if (!_dbus_type_is_valid (array_type)) 00554 { 00555 _dbus_warn ("type '%c' %d is not valid in %s\n", 00556 array_type, array_type, _DBUS_FUNCTION_NAME); 00557 _dbus_assert_not_reached ("invalid type"); 00558 } 00559 #endif 00560 00561 alignment = get_type_alignment (array_type); 00562 00563 if (alignment > 0) 00564 pos = _DBUS_ALIGN_VALUE (pos, alignment); 00565 00566 _dbus_verbose ("%s: alignment %d value at pos %d\n", 00567 _DBUS_FUNCTION_NAME, alignment, pos); 00568 00569 /* pos now points to our value */ 00570 if (!_dbus_marshal_get_arg_end_pos (str, byte_order, 00571 type, pos, &value_end)) 00572 _dbus_assert_not_reached ("failed to get the byte after this header"); 00573 00574 value_pos = pos; 00575 value_len = value_end - value_pos; 00576 00577 _dbus_verbose ("%s: value_pos %d value_len %d value_end %d\n", 00578 _DBUS_FUNCTION_NAME, value_pos, value_len, value_end); 00579 00580 if (next_offset_p) 00581 *next_offset_p = pos + value_len; 00582 00583 if (field_name_p) 00584 *field_name_p = name; 00585 00586 if (append_copy_to) 00587 { 00588 int orig_len; 00589 00590 orig_len = _dbus_string_get_length (append_copy_to); 00591 00592 if (copy_name_offset_p) 00593 *copy_name_offset_p = orig_len; 00594 00595 if (!_dbus_string_append_byte (append_copy_to, name)) 00596 goto failed_copy; 00597 00598 if (!_dbus_string_copy_len (str, type_pos, type_len, 00599 append_copy_to, 00600 _dbus_string_get_length (append_copy_to))) 00601 goto failed_copy; 00602 00603 if (!_dbus_string_align_length (append_copy_to, alignment)) 00604 goto failed_copy; 00605 00606 if (copy_value_offset_p) 00607 *copy_value_offset_p = _dbus_string_get_length (append_copy_to); 00608 00609 if (!_dbus_string_copy_len (str, value_pos, value_len, 00610 append_copy_to, 00611 _dbus_string_get_length (append_copy_to))) 00612 goto failed_copy; 00613 00614 return TRUE; 00615 00616 failed_copy: 00617 _dbus_verbose ("%s: Failed copying old fields to new string\n", 00618 _DBUS_FUNCTION_NAME); 00619 _dbus_string_set_length (append_copy_to, orig_len); 00620 return FALSE; 00621 } 00622 else 00623 return TRUE; 00624 } 00625 00626 #ifndef DBUS_DISABLE_ASSERT 00627 static void 00628 verify_header_fields (DBusMessage *message) 00629 { 00630 int i; 00631 i = 0; 00632 while (i < DBUS_HEADER_FIELD_LAST) 00633 { 00634 if (message->header_fields[i].name_offset >= 0) 00635 _dbus_assert (_dbus_string_get_byte (&message->header, 00636 message->header_fields[i].name_offset) == 00637 i); 00638 ++i; 00639 } 00640 } 00641 #else /* DBUS_DISABLE_ASSERT */ 00642 #define verify_header_fields(x) 00643 #endif /* DBUS_DISABLE_ASSERT */ 00644 00645 /* In this function we delete one field and re-align all the fields 00646 * following it. 00647 */ 00648 static dbus_bool_t 00649 delete_one_and_re_align (DBusMessage *message, 00650 int name_offset_to_delete) 00651 { 00652 DBusString copy; 00653 int new_fields_front_padding; 00654 int next_offset; 00655 int field_name; 00656 dbus_bool_t retval; 00657 HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST]; 00658 00659 _dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header)); 00660 verify_header_fields (message); 00661 00662 _dbus_verbose ("%s: Deleting one field at offset %d\n", 00663 _DBUS_FUNCTION_NAME, 00664 name_offset_to_delete); 00665 00666 retval = FALSE; 00667 00668 clear_header_padding (message); 00669 00670 if (!_dbus_string_init_preallocated (&copy, 00671 _dbus_string_get_length (&message->header) - 00672 name_offset_to_delete + 8)) 00673 { 00674 _dbus_verbose ("%s: Failed to init string to hold copy of fields\n", 00675 _DBUS_FUNCTION_NAME); 00676 goto out_0; 00677 } 00678 00679 /* Align the name offset of the first field in the same way it's 00680 * aligned in the real header 00681 */ 00682 new_fields_front_padding = name_offset_to_delete % 8; 00683 00684 if (!_dbus_string_insert_bytes (&copy, 0, new_fields_front_padding, 00685 '\0')) 00686 _dbus_assert_not_reached ("Should not have failed to insert bytes into preallocated string\n"); 00687 00688 memcpy (new_header_fields, message->header_fields, 00689 sizeof (new_header_fields)); 00690 00691 /* Now just re-marshal each field in the header to our temporary 00692 * buffer, skipping the first one. The tricky part is that the 00693 * fields are padded as if for previous_name_offset, but are in fact 00694 * at unaligned_name_offset 00695 */ 00696 00697 if (!iterate_one_field (&message->header, 00698 message->byte_order, 00699 name_offset_to_delete, 00700 &next_offset, 00701 &field_name, NULL, NULL, NULL)) 00702 _dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field"); 00703 00704 if (field_name < DBUS_HEADER_FIELD_LAST) 00705 { 00706 new_header_fields[field_name].name_offset = -1; 00707 new_header_fields[field_name].value_offset = -1; 00708 } 00709 00710 while (next_offset < _dbus_string_get_length (&message->header)) 00711 { 00712 int copy_name_offset; 00713 int copy_value_offset; 00714 00715 if (!iterate_one_field (&message->header, 00716 message->byte_order, 00717 next_offset, 00718 &next_offset, 00719 &field_name, 00720 &copy, 00721 &copy_name_offset, 00722 &copy_value_offset)) 00723 { 00724 _dbus_verbose ("%s: OOM iterating one field\n", 00725 _DBUS_FUNCTION_NAME); 00726 goto out_1; 00727 } 00728 00729 if (field_name < DBUS_HEADER_FIELD_LAST) 00730 { 00731 new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete; 00732 new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete; 00733 } 00734 } 00735 00736 if (!_dbus_string_replace_len (&copy, 00737 new_fields_front_padding, 00738 _dbus_string_get_length (&copy) - new_fields_front_padding, 00739 &message->header, 00740 name_offset_to_delete, 00741 _dbus_string_get_length (&message->header) - name_offset_to_delete)) 00742 { 00743 _dbus_verbose ("%s: OOM moving copy back into header\n", 00744 _DBUS_FUNCTION_NAME); 00745 goto out_1; 00746 } 00747 00748 memcpy (message->header_fields, new_header_fields, 00749 sizeof (new_header_fields)); 00750 verify_header_fields (message); 00751 00752 retval = TRUE; 00753 00754 out_1: 00755 _dbus_string_free (&copy); 00756 00757 out_0: 00758 if (!append_header_padding (message)) 00759 _dbus_assert_not_reached ("Failed to re-append header padding in re_align_field_recurse()"); 00760 00761 return retval; 00762 } 00763 00764 static dbus_bool_t 00765 delete_field (DBusMessage *message, 00766 int field, 00767 int prealloc_header_space) 00768 { 00769 int offset; 00770 00771 _dbus_assert (!message->locked); 00772 00773 /* Prealloc */ 00774 if (!_dbus_string_lengthen (&message->header, prealloc_header_space)) 00775 { 00776 _dbus_verbose ("failed to prealloc %d bytes header space\n", 00777 prealloc_header_space); 00778 return FALSE; 00779 } 00780 _dbus_string_shorten (&message->header, prealloc_header_space); 00781 00782 /* Delete */ 00783 offset = message->header_fields[field].name_offset; 00784 if (offset < 0) 00785 { 00786 _dbus_verbose ("header field didn't exist, no need to delete\n"); 00787 return TRUE; /* field didn't exist */ 00788 } 00789 00790 return delete_one_and_re_align (message, offset); 00791 } 00792 00793 #ifdef DBUS_BUILD_TESTS 00794 static dbus_bool_t 00795 set_int_field (DBusMessage *message, 00796 int field, 00797 int value) 00798 { 00799 int offset = message->header_fields[field].value_offset; 00800 00801 _dbus_assert (!message->locked); 00802 00803 if (offset < 0) 00804 { 00805 /* need to append the field */ 00806 return append_int_field (message, field, value); 00807 } 00808 else 00809 { 00810 _dbus_marshal_set_int32 (&message->header, 00811 message->byte_order, 00812 offset, value); 00813 00814 return TRUE; 00815 } 00816 } 00817 #endif 00818 00819 static dbus_bool_t 00820 set_uint_field (DBusMessage *message, 00821 int field, 00822 dbus_uint32_t value) 00823 { 00824 int offset = message->header_fields[field].value_offset; 00825 00826 _dbus_assert (!message->locked); 00827 00828 if (offset < 0) 00829 { 00830 /* need to append the field */ 00831 return append_uint_field (message, field, value); 00832 } 00833 else 00834 { 00835 _dbus_marshal_set_uint32 (&message->header, 00836 message->byte_order, 00837 offset, value); 00838 00839 return TRUE; 00840 } 00841 } 00842 00843 static dbus_bool_t 00844 set_string_field (DBusMessage *message, 00845 int field, 00846 int type, 00847 const char *value) 00848 { 00849 int prealloc; 00850 int value_len; 00851 00852 _dbus_assert (!message->locked); 00853 00854 value_len = value ? strlen (value) : 0; 00855 00856 /* the prealloc is so the append_string_field() 00857 * below won't fail, leaving us in inconsistent state 00858 */ 00859 prealloc = value_len + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING; 00860 00861 _dbus_verbose ("set_string_field() field %d prealloc %d\n", 00862 field, prealloc); 00863 00864 if (!delete_field (message, field, prealloc)) 00865 return FALSE; 00866 00867 if (value != NULL) 00868 { 00869 /* need to append the field */ 00870 if (!append_string_field_len (message, field, type, value, value_len)) 00871 _dbus_assert_not_reached ("Appending string field shouldn't have failed, due to preallocation"); 00872 } 00873 00874 return TRUE; 00875 } 00876 00884 void 00885 _dbus_message_set_serial (DBusMessage *message, 00886 dbus_int32_t serial) 00887 { 00888 _dbus_assert (!message->locked); 00889 _dbus_assert (dbus_message_get_serial (message) == 0); 00890 00891 _dbus_marshal_set_uint32 (&message->header, 00892 message->byte_order, 00893 CLIENT_SERIAL_OFFSET, 00894 serial); 00895 00896 message->client_serial = serial; 00897 } 00898 00907 dbus_bool_t 00908 dbus_message_set_reply_serial (DBusMessage *message, 00909 dbus_uint32_t reply_serial) 00910 { 00911 _dbus_assert (!message->locked); 00912 00913 if (set_uint_field (message, 00914 DBUS_HEADER_FIELD_REPLY_SERIAL, 00915 reply_serial)) 00916 { 00917 message->reply_serial = reply_serial; 00918 return TRUE; 00919 } 00920 else 00921 return FALSE; 00922 } 00923 00934 dbus_uint32_t 00935 dbus_message_get_serial (DBusMessage *message) 00936 { 00937 return message->client_serial; 00938 } 00939 00946 dbus_uint32_t 00947 dbus_message_get_reply_serial (DBusMessage *message) 00948 { 00949 return message->reply_serial; 00950 } 00951 00964 void 00965 _dbus_message_add_size_counter_link (DBusMessage *message, 00966 DBusList *link) 00967 { 00968 /* right now we don't recompute the delta when message 00969 * size changes, and that's OK for current purposes 00970 * I think, but could be important to change later. 00971 * Do recompute it whenever there are no outstanding counters, 00972 * since it's basically free. 00973 */ 00974 if (message->size_counters == NULL) 00975 { 00976 message->size_counter_delta = 00977 _dbus_string_get_length (&message->header) + 00978 _dbus_string_get_length (&message->body); 00979 00980 #if 0 00981 _dbus_verbose ("message has size %ld\n", 00982 message->size_counter_delta); 00983 #endif 00984 } 00985 00986 _dbus_list_append_link (&message->size_counters, link); 00987 00988 _dbus_counter_adjust (link->data, message->size_counter_delta); 00989 } 00990 01000 dbus_bool_t 01001 _dbus_message_add_size_counter (DBusMessage *message, 01002 DBusCounter *counter) 01003 { 01004 DBusList *link; 01005 01006 link = _dbus_list_alloc_link (counter); 01007 if (link == NULL) 01008 return FALSE; 01009 01010 _dbus_counter_ref (counter); 01011 _dbus_message_add_size_counter_link (message, link); 01012 01013 return TRUE; 01014 } 01015 01024 void 01025 _dbus_message_remove_size_counter (DBusMessage *message, 01026 DBusCounter *counter, 01027 DBusList **link_return) 01028 { 01029 DBusList *link; 01030 01031 link = _dbus_list_find_last (&message->size_counters, 01032 counter); 01033 _dbus_assert (link != NULL); 01034 01035 _dbus_list_unlink (&message->size_counters, 01036 link); 01037 if (link_return) 01038 *link_return = link; 01039 else 01040 _dbus_list_free_link (link); 01041 01042 _dbus_counter_adjust (counter, - message->size_counter_delta); 01043 01044 _dbus_counter_unref (counter); 01045 } 01046 01047 static dbus_bool_t 01048 dbus_message_create_header (DBusMessage *message, 01049 int type, 01050 const char *service, 01051 const char *path, 01052 const char *interface, 01053 const char *member, 01054 const char *error_name) 01055 { 01056 unsigned int flags; 01057 01058 _dbus_assert ((interface && member) || 01059 (error_name) || 01060 !(interface || member || error_name)); 01061 _dbus_assert (error_name == NULL || is_valid_error_name (error_name)); 01062 01063 if (!_dbus_string_append_byte (&message->header, message->byte_order)) 01064 return FALSE; 01065 01066 if (!_dbus_string_append_byte (&message->header, type)) 01067 return FALSE; 01068 01069 flags = 0; 01070 if (!_dbus_string_append_byte (&message->header, flags)) 01071 return FALSE; 01072 01073 if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION)) 01074 return FALSE; 01075 01076 /* header length */ 01077 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0)) 01078 return FALSE; 01079 01080 /* body length */ 01081 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0)) 01082 return FALSE; 01083 01084 /* serial */ 01085 if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0)) 01086 return FALSE; 01087 01088 /* Marshal all the fields (Marshall Fields?) */ 01089 01090 if (path != NULL) 01091 { 01092 if (!append_string_field (message, 01093 DBUS_HEADER_FIELD_PATH, 01094 DBUS_TYPE_OBJECT_PATH, 01095 path)) 01096 return FALSE; 01097 } 01098 01099 if (service != NULL) 01100 { 01101 if (!append_string_field (message, 01102 DBUS_HEADER_FIELD_DESTINATION, 01103 DBUS_TYPE_STRING, 01104 service)) 01105 return FALSE; 01106 } 01107 01108 if (interface != NULL) 01109 { 01110 if (!append_string_field (message, 01111 DBUS_HEADER_FIELD_INTERFACE, 01112 DBUS_TYPE_STRING, 01113 interface)) 01114 return FALSE; 01115 } 01116 01117 if (member != NULL) 01118 { 01119 if (!append_string_field (message, 01120 DBUS_HEADER_FIELD_MEMBER, 01121 DBUS_TYPE_STRING, 01122 member)) 01123 return FALSE; 01124 } 01125 01126 if (error_name != NULL) 01127 { 01128 if (!append_string_field (message, 01129 DBUS_HEADER_FIELD_ERROR_NAME, 01130 DBUS_TYPE_STRING, 01131 error_name)) 01132 return FALSE; 01133 } 01134 01135 /* @todo if we make signature optional when body is empty, we don't 01136 * need to do this here. 01137 */ 01138 if (!append_string_field (message, 01139 DBUS_HEADER_FIELD_SIGNATURE, 01140 DBUS_TYPE_STRING, 01141 "")) 01142 return FALSE; 01143 01144 return TRUE; 01145 } 01146 01156 void 01157 _dbus_message_lock (DBusMessage *message) 01158 { 01159 if (!message->locked) 01160 { 01161 /* Fill in our lengths */ 01162 _dbus_marshal_set_uint32 (&message->header, 01163 message->byte_order, 01164 HEADER_LENGTH_OFFSET, 01165 _dbus_string_get_length (&message->header)); 01166 01167 _dbus_marshal_set_uint32 (&message->header, 01168 message->byte_order, 01169 BODY_LENGTH_OFFSET, 01170 _dbus_string_get_length (&message->body)); 01171 01172 message->locked = TRUE; 01173 } 01174 } 01175 01207 static dbus_bool_t 01208 dbus_message_set_signature (DBusMessage *message, 01209 const char *signature) 01210 { 01211 _dbus_return_val_if_fail (message != NULL, FALSE); 01212 _dbus_return_val_if_fail (!message->locked, FALSE); 01213 01214 return set_string_field (message, 01215 DBUS_HEADER_FIELD_SIGNATURE, 01216 DBUS_TYPE_STRING, 01217 signature); 01218 } 01219 01228 static dbus_bool_t 01229 dbus_message_append_to_signature (DBusMessage *message, 01230 const char *append_bytes) 01231 { 01232 const char *signature; 01233 DBusString append_str; 01234 dbus_bool_t retval; 01235 01236 _dbus_return_val_if_fail (append_bytes != NULL, FALSE); 01237 _dbus_return_val_if_fail (message != NULL, FALSE); 01238 _dbus_return_val_if_fail (!message->locked, FALSE); 01239 01240 retval = FALSE; 01241 01242 /* FIXME Just really inefficient for the moment; later we could 01243 * speed it up a lot by poking more directly at the header data 01244 */ 01245 signature = dbus_message_get_signature (message); 01246 01247 if (!_dbus_string_init (&append_str)) 01248 return FALSE; 01249 01250 if (signature && !_dbus_string_append (&append_str, signature)) 01251 goto out; 01252 01253 if (!_dbus_string_append (&append_str, append_bytes)) 01254 goto out; 01255 01256 if (!set_string_field (message, 01257 DBUS_HEADER_FIELD_SIGNATURE, 01258 DBUS_TYPE_STRING, 01259 _dbus_string_get_const_data (&append_str))) 01260 goto out; 01261 01262 retval = TRUE; 01263 01264 out: 01265 01266 _dbus_string_free (&append_str); 01267 01268 return retval; 01269 } 01270 01279 static dbus_bool_t 01280 _dbus_message_append_byte_to_signature (DBusMessage *message, 01281 unsigned char append_byte) 01282 { 01283 char buf[2]; 01284 01285 _dbus_return_val_if_fail (message != NULL, FALSE); 01286 _dbus_return_val_if_fail (!message->locked, FALSE); 01287 01288 buf[0] = append_byte; 01289 buf[1] = '\0'; 01290 01291 return dbus_message_append_to_signature (message, buf); 01292 } 01293 01300 static void 01301 _dbus_message_remove_byte_from_signature (DBusMessage *message) 01302 { 01303 const char *signature; 01304 01305 _dbus_return_if_fail (message != NULL); 01306 _dbus_return_if_fail (!message->locked); 01307 01308 signature = dbus_message_get_signature (message); 01309 01310 _dbus_return_if_fail (signature != NULL); 01311 01312 if (!delete_field (message, 01313 DBUS_HEADER_FIELD_SIGNATURE, 01314 0)) 01315 _dbus_assert_not_reached ("failed to delete signature field"); 01316 01317 /* reappend one shorter (could this be any less efficient? the code will 01318 * go away later anyhow) 01319 */ 01320 if (!append_string_field_len (message, DBUS_HEADER_FIELD_SIGNATURE, 01321 DBUS_TYPE_STRING, signature, 01322 strlen (signature) - 1)) 01323 _dbus_assert_not_reached ("reappending shorter signature shouldn't have failed"); 01324 } 01325 01333 static DBusMessage* 01334 dbus_message_new_empty_header (void) 01335 { 01336 DBusMessage *message; 01337 int i; 01338 01339 message = dbus_new0 (DBusMessage, 1); 01340 if (message == NULL) 01341 return NULL; 01342 01343 message->refcount.value = 1; 01344 message->byte_order = DBUS_COMPILER_BYTE_ORDER; 01345 message->client_serial = 0; 01346 message->reply_serial = 0; 01347 01348 _dbus_data_slot_list_init (&message->slot_list); 01349 01350 i = 0; 01351 while (i <= DBUS_HEADER_FIELD_LAST) 01352 { 01353 message->header_fields[i].name_offset = -1; 01354 message->header_fields[i].value_offset = -1; 01355 ++i; 01356 } 01357 01358 if (!_dbus_string_init_preallocated (&message->header, 64)) 01359 { 01360 dbus_free (message); 01361 return NULL; 01362 } 01363 01364 if (!_dbus_string_init_preallocated (&message->body, 64)) 01365 { 01366 _dbus_string_free (&message->header); 01367 dbus_free (message); 01368 return NULL; 01369 } 01370 01371 return message; 01372 } 01373 01382 DBusMessage* 01383 dbus_message_new (int message_type) 01384 { 01385 DBusMessage *message; 01386 01387 _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL); 01388 01389 message = dbus_message_new_empty_header (); 01390 if (message == NULL) 01391 return NULL; 01392 01393 if (!dbus_message_create_header (message, 01394 message_type, 01395 NULL, NULL, NULL, NULL, NULL)) 01396 { 01397 dbus_message_unref (message); 01398 return NULL; 01399 } 01400 01401 return message; 01402 } 01403 01421 DBusMessage* 01422 dbus_message_new_method_call (const char *service, 01423 const char *path, 01424 const char *interface, 01425 const char *method) 01426 { 01427 DBusMessage *message; 01428 01429 _dbus_return_val_if_fail (path != NULL, NULL); 01430 _dbus_return_val_if_fail (method != NULL, NULL); 01431 01432 message = dbus_message_new_empty_header (); 01433 if (message == NULL) 01434 return NULL; 01435 01436 if (!dbus_message_create_header (message, 01437 DBUS_MESSAGE_TYPE_METHOD_CALL, 01438 service, path, interface, method, NULL)) 01439 { 01440 dbus_message_unref (message); 01441 return NULL; 01442 } 01443 01444 return message; 01445 } 01446 01456 DBusMessage* 01457 dbus_message_new_method_return (DBusMessage *method_call) 01458 { 01459 DBusMessage *message; 01460 const char *sender; 01461 01462 _dbus_return_val_if_fail (method_call != NULL, NULL); 01463 01464 sender = get_string_field (method_call, 01465 DBUS_HEADER_FIELD_SENDER, 01466 NULL); 01467 01468 /* sender is allowed to be null here in peer-to-peer case */ 01469 01470 message = dbus_message_new_empty_header (); 01471 if (message == NULL) 01472 return NULL; 01473 01474 if (!dbus_message_create_header (message, 01475 DBUS_MESSAGE_TYPE_METHOD_RETURN, 01476 sender, NULL, NULL, NULL, NULL)) 01477 { 01478 dbus_message_unref (message); 01479 return NULL; 01480 } 01481 01482 dbus_message_set_no_reply (message, TRUE); 01483 01484 if (!dbus_message_set_reply_serial (message, 01485 dbus_message_get_serial (method_call))) 01486 { 01487 dbus_message_unref (message); 01488 return NULL; 01489 } 01490 01491 return message; 01492 } 01493 01506 DBusMessage* 01507 dbus_message_new_signal (const char *path, 01508 const char *interface, 01509 const char *name) 01510 { 01511 DBusMessage *message; 01512 01513 _dbus_return_val_if_fail (path != NULL, NULL); 01514 _dbus_return_val_if_fail (interface != NULL, NULL); 01515 _dbus_return_val_if_fail (name != NULL, NULL); 01516 01517 message = dbus_message_new_empty_header (); 01518 if (message == NULL) 01519 return NULL; 01520 01521 if (!dbus_message_create_header (message, 01522 DBUS_MESSAGE_TYPE_SIGNAL, 01523 NULL, path, interface, name, NULL)) 01524 { 01525 dbus_message_unref (message); 01526 return NULL; 01527 } 01528 01529 dbus_message_set_no_reply (message, TRUE); 01530 01531 return message; 01532 } 01533 01543 DBusMessage* 01544 dbus_message_new_error (DBusMessage *reply_to, 01545 const char *error_name, 01546 const char *error_message) 01547 { 01548 DBusMessage *message; 01549 const char *sender; 01550 DBusMessageIter iter; 01551 01552 _dbus_return_val_if_fail (reply_to != NULL, NULL); 01553 _dbus_return_val_if_fail (error_name != NULL, NULL); 01554 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL); 01555 01556 sender = get_string_field (reply_to, 01557 DBUS_HEADER_FIELD_SENDER, 01558 NULL); 01559 01560 /* sender may be NULL for non-message-bus case or 01561 * when the message bus is dealing with an unregistered 01562 * connection. 01563 */ 01564 message = dbus_message_new_empty_header (); 01565 if (message == NULL) 01566 return NULL; 01567 01568 if (!dbus_message_create_header (message, 01569 DBUS_MESSAGE_TYPE_ERROR, 01570 sender, NULL, NULL, NULL, error_name)) 01571 { 01572 dbus_message_unref (message); 01573 return NULL; 01574 } 01575 01576 dbus_message_set_no_reply (message, TRUE); 01577 01578 if (!dbus_message_set_reply_serial (message, 01579 dbus_message_get_serial (reply_to))) 01580 { 01581 dbus_message_unref (message); 01582 return NULL; 01583 } 01584 01585 if (error_message != NULL) 01586 { 01587 dbus_message_append_iter_init (message, &iter); 01588 if (!dbus_message_iter_append_string (&iter, error_message)) 01589 { 01590 dbus_message_unref (message); 01591 return NULL; 01592 } 01593 } 01594 01595 return message; 01596 } 01597 01608 DBusMessage* 01609 dbus_message_new_error_printf (DBusMessage *reply_to, 01610 const char *error_name, 01611 const char *error_format, 01612 ...) 01613 { 01614 va_list args; 01615 DBusString str; 01616 DBusMessage *message; 01617 01618 _dbus_return_val_if_fail (reply_to != NULL, NULL); 01619 _dbus_return_val_if_fail (error_name != NULL, NULL); 01620 _dbus_return_val_if_fail (is_valid_error_name (error_name), NULL); 01621 01622 if (!_dbus_string_init (&str)) 01623 return NULL; 01624 01625 va_start (args, error_format); 01626 01627 if (_dbus_string_append_printf_valist (&str, error_format, args)) 01628 message = dbus_message_new_error (reply_to, error_name, 01629 _dbus_string_get_const_data (&str)); 01630 else 01631 message = NULL; 01632 01633 _dbus_string_free (&str); 01634 01635 va_end (args); 01636 01637 return message; 01638 } 01639 01640 01648 DBusMessage * 01649 dbus_message_copy (const DBusMessage *message) 01650 { 01651 DBusMessage *retval; 01652 int i; 01653 01654 _dbus_return_val_if_fail (message != NULL, NULL); 01655 01656 retval = dbus_new0 (DBusMessage, 1); 01657 if (retval == NULL) 01658 return NULL; 01659 01660 retval->refcount.value = 1; 01661 retval->byte_order = message->byte_order; 01662 retval->client_serial = message->client_serial; 01663 retval->reply_serial = message->reply_serial; 01664 retval->header_padding = message->header_padding; 01665 retval->locked = FALSE; 01666 01667 if (!_dbus_string_init_preallocated (&retval->header, 01668 _dbus_string_get_length (&message->header))) 01669 { 01670 dbus_free (retval); 01671 return NULL; 01672 } 01673 01674 if (!_dbus_string_init_preallocated (&retval->body, 01675 _dbus_string_get_length (&message->body))) 01676 { 01677 _dbus_string_free (&retval->header); 01678 dbus_free (retval); 01679 return NULL; 01680 } 01681 01682 if (!_dbus_string_copy (&message->header, 0, 01683 &retval->header, 0)) 01684 goto failed_copy; 01685 01686 if (!_dbus_string_copy (&message->body, 0, 01687 &retval->body, 0)) 01688 goto failed_copy; 01689 01690 for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++) 01691 { 01692 retval->header_fields[i] = message->header_fields[i]; 01693 } 01694 01695 return retval; 01696 01697 failed_copy: 01698 _dbus_string_free (&retval->header); 01699 _dbus_string_free (&retval->body); 01700 dbus_free (retval); 01701 01702 return NULL; 01703 } 01704 01705 01713 DBusMessage * 01714 dbus_message_ref (DBusMessage *message) 01715 { 01716 dbus_int32_t old_refcount; 01717 01718 _dbus_return_val_if_fail (message != NULL, NULL); 01719 01720 old_refcount = _dbus_atomic_inc (&message->refcount); 01721 _dbus_assert (old_refcount >= 1); 01722 01723 return message; 01724 } 01725 01726 static void 01727 free_size_counter (void *element, 01728 void *data) 01729 { 01730 DBusCounter *counter = element; 01731 DBusMessage *message = data; 01732 01733 _dbus_counter_adjust (counter, - message->size_counter_delta); 01734 01735 _dbus_counter_unref (counter); 01736 } 01737 01744 void 01745 dbus_message_unref (DBusMessage *message) 01746 { 01747 dbus_int32_t old_refcount; 01748 01749 _dbus_return_if_fail (message != NULL); 01750 01751 old_refcount = _dbus_atomic_dec (&message->refcount); 01752 01753 _dbus_assert (old_refcount >= 0); 01754 01755 if (old_refcount == 1) 01756 { 01757 /* This calls application callbacks! */ 01758 _dbus_data_slot_list_free (&message->slot_list); 01759 01760 _dbus_list_foreach (&message->size_counters, 01761 free_size_counter, message); 01762 _dbus_list_clear (&message->size_counters); 01763 01764 _dbus_string_free (&message->header); 01765 _dbus_string_free (&message->body); 01766 01767 dbus_free (message); 01768 } 01769 } 01770 01782 int 01783 dbus_message_get_type (DBusMessage *message) 01784 { 01785 int type; 01786 01787 type = _dbus_string_get_byte (&message->header, 1); 01788 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID); 01789 01790 return type; 01791 } 01792 01802 dbus_bool_t 01803 dbus_message_set_path (DBusMessage *message, 01804 const char *object_path) 01805 { 01806 _dbus_return_val_if_fail (message != NULL, FALSE); 01807 _dbus_return_val_if_fail (!message->locked, FALSE); 01808 01809 return set_string_field (message, 01810 DBUS_HEADER_FIELD_PATH, 01811 DBUS_TYPE_OBJECT_PATH, 01812 object_path); 01813 } 01814 01823 const char* 01824 dbus_message_get_path (DBusMessage *message) 01825 { 01826 _dbus_return_val_if_fail (message != NULL, NULL); 01827 01828 return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL); 01829 } 01830 01846 dbus_bool_t 01847 dbus_message_get_path_decomposed (DBusMessage *message, 01848 char ***path) 01849 { 01850 _dbus_return_val_if_fail (message != NULL, FALSE); 01851 _dbus_return_val_if_fail (path != NULL, FALSE); 01852 01853 return get_path_field_decomposed (message, 01854 DBUS_HEADER_FIELD_PATH, 01855 path); 01856 } 01857 01868 dbus_bool_t 01869 dbus_message_set_interface (DBusMessage *message, 01870 const char *interface) 01871 { 01872 _dbus_return_val_if_fail (message != NULL, FALSE); 01873 _dbus_return_val_if_fail (!message->locked, FALSE); 01874 01875 return set_string_field (message, 01876 DBUS_HEADER_FIELD_INTERFACE, 01877 DBUS_TYPE_STRING, 01878 interface); 01879 } 01880 01890 const char* 01891 dbus_message_get_interface (DBusMessage *message) 01892 { 01893 _dbus_return_val_if_fail (message != NULL, NULL); 01894 01895 return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL); 01896 } 01897 01908 dbus_bool_t 01909 dbus_message_set_member (DBusMessage *message, 01910 const char *member) 01911 { 01912 _dbus_return_val_if_fail (message != NULL, FALSE); 01913 _dbus_return_val_if_fail (!message->locked, FALSE); 01914 01915 return set_string_field (message, 01916 DBUS_HEADER_FIELD_MEMBER, 01917 DBUS_TYPE_STRING, 01918 member); 01919 } 01920 01929 const char* 01930 dbus_message_get_member (DBusMessage *message) 01931 { 01932 _dbus_return_val_if_fail (message != NULL, NULL); 01933 01934 return get_string_field (message, 01935 DBUS_HEADER_FIELD_MEMBER, 01936 NULL); 01937 } 01938 01947 dbus_bool_t 01948 dbus_message_set_error_name (DBusMessage *message, 01949 const char *error_name) 01950 { 01951 _dbus_return_val_if_fail (message != NULL, FALSE); 01952 _dbus_return_val_if_fail (!message->locked, FALSE); 01953 _dbus_return_val_if_fail (error_name == NULL || is_valid_error_name (error_name), FALSE); 01954 01955 return set_string_field (message, 01956 DBUS_HEADER_FIELD_ERROR_NAME, 01957 DBUS_TYPE_STRING, 01958 error_name); 01959 } 01960 01967 const char* 01968 dbus_message_get_error_name (DBusMessage *message) 01969 { 01970 _dbus_return_val_if_fail (message != NULL, NULL); 01971 01972 return get_string_field (message, 01973 DBUS_HEADER_FIELD_ERROR_NAME, 01974 NULL); 01975 } 01976 01984 dbus_bool_t 01985 dbus_message_set_destination (DBusMessage *message, 01986 const char *destination) 01987 { 01988 _dbus_return_val_if_fail (message != NULL, FALSE); 01989 _dbus_return_val_if_fail (!message->locked, FALSE); 01990 01991 return set_string_field (message, 01992 DBUS_HEADER_FIELD_DESTINATION, 01993 DBUS_TYPE_STRING, 01994 destination); 01995 } 01996 02003 const char* 02004 dbus_message_get_destination (DBusMessage *message) 02005 { 02006 _dbus_return_val_if_fail (message != NULL, NULL); 02007 02008 return get_string_field (message, 02009 DBUS_HEADER_FIELD_DESTINATION, 02010 NULL); 02011 } 02012 02031 dbus_bool_t 02032 dbus_message_append_args (DBusMessage *message, 02033 int first_arg_type, 02034 ...) 02035 { 02036 dbus_bool_t retval; 02037 va_list var_args; 02038 02039 _dbus_return_val_if_fail (message != NULL, FALSE); 02040 02041 va_start (var_args, first_arg_type); 02042 retval = dbus_message_append_args_valist (message, 02043 first_arg_type, 02044 var_args); 02045 va_end (var_args); 02046 02047 return retval; 02048 } 02049 02062 dbus_bool_t 02063 dbus_message_get_args (DBusMessage *message, 02064 DBusError *error, 02065 int first_arg_type, 02066 ...) 02067 { 02068 dbus_bool_t retval; 02069 va_list var_args; 02070 02071 _dbus_return_val_if_fail (message != NULL, FALSE); 02072 _dbus_return_val_if_error_is_set (error, FALSE); 02073 02074 va_start (var_args, first_arg_type); 02075 retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args); 02076 va_end (var_args); 02077 02078 return retval; 02079 } 02080 02093 dbus_bool_t 02094 dbus_message_get_args_valist (DBusMessage *message, 02095 DBusError *error, 02096 int first_arg_type, 02097 va_list var_args) 02098 { 02099 DBusMessageIter iter; 02100 02101 _dbus_return_val_if_fail (message != NULL, FALSE); 02102 _dbus_return_val_if_error_is_set (error, FALSE); 02103 02104 dbus_message_iter_init (message, &iter); 02105 return dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args); 02106 } 02107 02120 dbus_bool_t 02121 dbus_message_iter_get_args (DBusMessageIter *iter, 02122 DBusError *error, 02123 int first_arg_type, 02124 ...) 02125 { 02126 dbus_bool_t retval; 02127 va_list var_args; 02128 02129 _dbus_return_val_if_fail (iter != NULL, FALSE); 02130 _dbus_return_val_if_error_is_set (error, FALSE); 02131 02132 va_start (var_args, first_arg_type); 02133 retval = dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args); 02134 va_end (var_args); 02135 02136 return retval; 02137 } 02138 02147 dbus_bool_t 02148 dbus_message_iter_init (DBusMessage *message, 02149 DBusMessageIter *iter) 02150 { 02151 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02152 02153 _dbus_return_val_if_fail (message != NULL, FALSE); 02154 _dbus_return_val_if_fail (iter != NULL, FALSE); 02155 02156 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter)); 02157 02158 real->message = message; 02159 real->parent_iter = NULL; 02160 real->changed_stamp = message->changed_stamp; 02161 02162 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE; 02163 real->pos = 0; 02164 real->end = _dbus_string_get_length (&message->body); 02165 02166 real->container_start = 0; 02167 real->container_length_pos = 0; 02168 real->wrote_dict_key = 0; 02169 real->array_type_pos = 0; 02170 02171 return real->end > real->pos; 02172 } 02173 02174 #ifndef DBUS_DISABLE_CHECKS 02175 static dbus_bool_t 02176 dbus_message_iter_check (DBusMessageRealIter *iter) 02177 { 02178 if (iter == NULL) 02179 { 02180 _dbus_warn ("dbus iterator check failed: iterator is NULL\n"); 02181 return FALSE; 02182 } 02183 02184 if (iter->changed_stamp != iter->message->changed_stamp) 02185 { 02186 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message\n"); 02187 return FALSE; 02188 } 02189 02190 if (iter->pos < 0 || iter->pos > iter->end) 02191 { 02192 _dbus_warn ("dbus iterator check failed: invalid position\n"); 02193 return FALSE; 02194 } 02195 02196 return TRUE; 02197 } 02198 #endif /* DBUS_DISABLE_CHECKS */ 02199 02200 static int 02201 skip_array_type (DBusMessageRealIter *iter, int pos) 02202 { 02203 const char *data; 02204 02205 do 02206 { 02207 data = _dbus_string_get_const_data_len (&iter->message->body, 02208 pos++, 1); 02209 } 02210 while (*data == DBUS_TYPE_ARRAY); 02211 02212 return pos; 02213 } 02214 02215 /* FIXME what are these _dbus_type_is_valid() checks for? 02216 * haven't we validated the message? 02217 */ 02218 static int 02219 dbus_message_iter_get_data_start (DBusMessageRealIter *iter, int *type) 02220 { 02221 const char *data; 02222 int pos, len; 02223 02224 switch (iter->type) 02225 { 02226 case DBUS_MESSAGE_ITER_TYPE_MESSAGE: 02227 data = _dbus_string_get_const_data_len (&iter->message->body, 02228 iter->pos, 1); 02229 if (_dbus_type_is_valid (*data)) 02230 *type = *data; 02231 else 02232 *type = DBUS_TYPE_INVALID; 02233 02234 return skip_array_type (iter, iter->pos); 02235 02236 case DBUS_MESSAGE_ITER_TYPE_ARRAY: 02237 data = _dbus_string_get_const_data_len (&iter->message->body, 02238 iter->array_type_pos, 1); 02239 if (_dbus_type_is_valid (*data)) 02240 *type = *data; 02241 else 02242 *type = DBUS_TYPE_INVALID; 02243 02244 return iter->pos; 02245 02246 case DBUS_MESSAGE_ITER_TYPE_DICT: 02247 /* Get the length of the string */ 02248 len = _dbus_demarshal_uint32 (&iter->message->body, 02249 iter->message->byte_order, 02250 iter->pos, &pos); 02251 pos = pos + len + 1; 02252 02253 data = _dbus_string_get_const_data_len (&iter->message->body, 02254 pos, 1); 02255 if (_dbus_type_is_valid (*data)) 02256 *type = *data; 02257 else 02258 *type = DBUS_TYPE_INVALID; 02259 02260 return skip_array_type (iter, pos); 02261 02262 default: 02263 _dbus_assert_not_reached ("Invalid iter type"); 02264 break; 02265 } 02266 *type = DBUS_TYPE_INVALID; 02267 return iter->pos; 02268 } 02269 02270 02278 dbus_bool_t 02279 dbus_message_iter_has_next (DBusMessageIter *iter) 02280 { 02281 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02282 int end_pos; 02283 int type, pos; 02284 02285 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 02286 02287 if (real->pos >= real->end) 02288 return FALSE; 02289 02290 pos = dbus_message_iter_get_data_start (real, &type); 02291 02292 if (!_dbus_marshal_get_arg_end_pos (&real->message->body, 02293 real->message->byte_order, 02294 type, pos, &end_pos)) 02295 return FALSE; 02296 02297 if (end_pos >= real->end) 02298 return FALSE; 02299 02300 return TRUE; 02301 } 02302 02309 dbus_bool_t 02310 dbus_message_iter_next (DBusMessageIter *iter) 02311 { 02312 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02313 int end_pos; 02314 int type, pos; 02315 02316 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 02317 02318 pos = dbus_message_iter_get_data_start (real, &type); 02319 02320 if (!_dbus_marshal_get_arg_end_pos (&real->message->body, 02321 real->message->byte_order, 02322 type, pos, &end_pos)) 02323 return FALSE; 02324 02325 if (end_pos >= real->end) 02326 return FALSE; 02327 02328 real->pos = end_pos; 02329 02330 return TRUE; 02331 } 02332 02340 int 02341 dbus_message_iter_get_arg_type (DBusMessageIter *iter) 02342 { 02343 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02344 int type, pos; 02345 02346 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID); 02347 02348 if (real->pos >= real->end) 02349 { 02350 _dbus_verbose (" iterator at or beyond end of message\n"); 02351 return DBUS_TYPE_INVALID; 02352 } 02353 02354 pos = dbus_message_iter_get_data_start (real, &type); 02355 02356 return type; 02357 } 02358 02359 /* FIXME why do we validate the typecode in here, hasn't the message 02360 * already been verified? 02361 */ 02362 static int 02363 iter_get_array_type (DBusMessageRealIter *iter, int *array_type_pos) 02364 { 02365 const char *data; 02366 int _array_type_pos; 02367 int len, pos; 02368 02369 switch (iter->type) 02370 { 02371 case DBUS_MESSAGE_ITER_TYPE_MESSAGE: 02372 _array_type_pos = iter->pos + 1; 02373 break; 02374 case DBUS_MESSAGE_ITER_TYPE_ARRAY: 02375 _array_type_pos = iter->array_type_pos + 1; 02376 break; 02377 case DBUS_MESSAGE_ITER_TYPE_DICT: 02378 /* Get the length of the string */ 02379 len = _dbus_demarshal_uint32 (&iter->message->body, 02380 iter->message->byte_order, 02381 iter->pos, &pos); 02382 pos = pos + len + 1; 02383 data = _dbus_string_get_const_data_len (&iter->message->body, 02384 pos + 1, 1); 02385 _array_type_pos = pos + 1; 02386 break; 02387 default: 02388 _dbus_assert_not_reached ("wrong iter type"); 02389 return DBUS_TYPE_INVALID; 02390 } 02391 02392 if (array_type_pos != NULL) 02393 *array_type_pos = _array_type_pos; 02394 02395 data = _dbus_string_get_const_data_len (&iter->message->body, 02396 _array_type_pos, 1); 02397 if (_dbus_type_is_valid (*data)) 02398 return *data; 02399 02400 return DBUS_TYPE_INVALID; 02401 } 02402 02403 02413 int 02414 dbus_message_iter_get_array_type (DBusMessageIter *iter) 02415 { 02416 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02417 int type, pos; 02418 02419 _dbus_return_val_if_fail (dbus_message_iter_check (real), DBUS_TYPE_INVALID); 02420 02421 if (real->pos >= real->end) 02422 return DBUS_TYPE_INVALID; 02423 02424 pos = dbus_message_iter_get_data_start (real, &type); 02425 02426 _dbus_assert (type == DBUS_TYPE_ARRAY); 02427 02428 return iter_get_array_type (real, NULL); 02429 } 02430 02431 02441 char * 02442 dbus_message_iter_get_string (DBusMessageIter *iter) 02443 { 02444 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02445 int type, pos; 02446 02447 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL); 02448 pos = dbus_message_iter_get_data_start (real, &type); 02449 02450 _dbus_assert (type == DBUS_TYPE_STRING); 02451 02452 return _dbus_demarshal_string (&real->message->body, real->message->byte_order, 02453 pos, NULL); 02454 } 02455 02465 char * 02466 dbus_message_iter_get_object_path (DBusMessageIter *iter) 02467 { 02468 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02469 int type, pos; 02470 02471 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL); 02472 02473 pos = dbus_message_iter_get_data_start (real, &type); 02474 02475 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH); 02476 02477 return _dbus_demarshal_string (&real->message->body, real->message->byte_order, 02478 pos, NULL); 02479 } 02480 02494 dbus_bool_t 02495 dbus_message_iter_get_custom (DBusMessageIter *iter, 02496 char **name, 02497 unsigned char **value, 02498 int *len) 02499 { 02500 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02501 int type, pos; 02502 char *_name; 02503 02504 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 02505 02506 pos = dbus_message_iter_get_data_start (real, &type); 02507 02508 _dbus_assert (type == DBUS_TYPE_CUSTOM); 02509 02510 _name = _dbus_demarshal_string (&real->message->body, real->message->byte_order, 02511 pos, &pos); 02512 02513 if (_name == NULL) 02514 return FALSE; 02515 02516 if (!_dbus_demarshal_byte_array (&real->message->body, real->message->byte_order, 02517 pos, NULL, value, len)) 02518 { 02519 dbus_free (_name); 02520 return FALSE; 02521 } 02522 02523 *name = _name; 02524 02525 return TRUE; 02526 } 02527 02528 static void 02529 _dbus_message_iter_get_basic_type (DBusMessageIter *iter, 02530 char type, 02531 void *value) 02532 { 02533 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02534 int item_type, pos; 02535 02536 _dbus_return_if_fail (dbus_message_iter_check (real)); 02537 02538 pos = dbus_message_iter_get_data_start (real, &item_type); 02539 02540 _dbus_assert (type == item_type); 02541 02542 _dbus_demarshal_basic_type (&real->message->body, 02543 type, value, 02544 real->message->byte_order, 02545 &pos); 02546 } 02547 02548 02571 dbus_bool_t 02572 dbus_message_iter_get_args_valist (DBusMessageIter *iter, 02573 DBusError *error, 02574 int first_arg_type, 02575 va_list var_args) 02576 { 02577 int spec_type, msg_type, i; 02578 dbus_bool_t retval; 02579 02580 _dbus_return_val_if_fail (iter != NULL, FALSE); 02581 _dbus_return_val_if_error_is_set (error, FALSE); 02582 02583 retval = FALSE; 02584 02585 spec_type = first_arg_type; 02586 i = 0; 02587 02588 while (spec_type != DBUS_TYPE_INVALID) 02589 { 02590 msg_type = dbus_message_iter_get_arg_type (iter); 02591 02592 if (msg_type != spec_type) 02593 { 02594 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 02595 "Argument %d is specified to be of type \"%s\", but " 02596 "is actually of type \"%s\"\n", i, 02597 _dbus_type_to_string (spec_type), 02598 _dbus_type_to_string (msg_type)); 02599 02600 goto out; 02601 } 02602 02603 switch (spec_type) 02604 { 02605 case DBUS_TYPE_NIL: 02606 break; 02607 case DBUS_TYPE_BOOLEAN: 02608 { 02609 dbus_bool_t *ptr; 02610 02611 ptr = va_arg (var_args, dbus_bool_t *); 02612 02613 *ptr = dbus_message_iter_get_boolean (iter); 02614 break; 02615 } 02616 case DBUS_TYPE_BYTE: 02617 case DBUS_TYPE_INT32: 02618 case DBUS_TYPE_UINT32: 02619 #ifdef DBUS_HAVE_INT64 02620 case DBUS_TYPE_INT64: 02621 case DBUS_TYPE_UINT64: 02622 #endif /* DBUS_HAVE_INT64 */ 02623 case DBUS_TYPE_DOUBLE: 02624 { 02625 void *ptr = va_arg (var_args, double *); 02626 _dbus_message_iter_get_basic_type (iter, spec_type, ptr); 02627 break; 02628 } 02629 02630 case DBUS_TYPE_STRING: 02631 { 02632 char **ptr; 02633 02634 ptr = va_arg (var_args, char **); 02635 02636 *ptr = dbus_message_iter_get_string (iter); 02637 02638 if (!*ptr) 02639 { 02640 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02641 goto out; 02642 } 02643 02644 break; 02645 } 02646 02647 case DBUS_TYPE_OBJECT_PATH: 02648 { 02649 char **ptr; 02650 02651 ptr = va_arg (var_args, char **); 02652 02653 *ptr = dbus_message_iter_get_object_path (iter); 02654 02655 if (!*ptr) 02656 { 02657 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02658 goto out; 02659 } 02660 02661 break; 02662 } 02663 02664 case DBUS_TYPE_CUSTOM: 02665 { 02666 char **name; 02667 unsigned char **data; 02668 int *len; 02669 02670 name = va_arg (var_args, char **); 02671 data = va_arg (var_args, unsigned char **); 02672 len = va_arg (var_args, int *); 02673 02674 if (!dbus_message_iter_get_custom (iter, name, data, len)) 02675 { 02676 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02677 goto out; 02678 } 02679 } 02680 break; 02681 case DBUS_TYPE_ARRAY: 02682 { 02683 void **data; 02684 int *len, type; 02685 dbus_bool_t err = FALSE; 02686 02687 type = va_arg (var_args, int); 02688 data = va_arg (var_args, void *); 02689 len = va_arg (var_args, int *); 02690 02691 _dbus_return_val_if_fail (data != NULL, FALSE); 02692 _dbus_return_val_if_fail (len != NULL, FALSE); 02693 02694 if (dbus_message_iter_get_array_type (iter) != type) 02695 { 02696 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 02697 "Argument %d is specified to be of type \"array of %s\", but " 02698 "is actually of type \"array of %s\"\n", i, 02699 _dbus_type_to_string (type), 02700 _dbus_type_to_string (dbus_message_iter_get_array_type (iter))); 02701 goto out; 02702 } 02703 02704 switch (type) 02705 { 02706 case DBUS_TYPE_BYTE: 02707 err = !dbus_message_iter_get_byte_array (iter, (unsigned char **)data, len); 02708 break; 02709 case DBUS_TYPE_BOOLEAN: 02710 err = !dbus_message_iter_get_boolean_array (iter, (unsigned char **)data, len); 02711 break; 02712 case DBUS_TYPE_INT32: 02713 err = !dbus_message_iter_get_int32_array (iter, (dbus_int32_t **)data, len); 02714 break; 02715 case DBUS_TYPE_UINT32: 02716 err = !dbus_message_iter_get_uint32_array (iter, (dbus_uint32_t **)data, len); 02717 break; 02718 #ifdef DBUS_HAVE_INT64 02719 case DBUS_TYPE_INT64: 02720 err = !dbus_message_iter_get_int64_array (iter, (dbus_int64_t **)data, len); 02721 break; 02722 case DBUS_TYPE_UINT64: 02723 err = !dbus_message_iter_get_uint64_array (iter, (dbus_uint64_t **)data, len); 02724 break; 02725 #endif /* DBUS_HAVE_INT64 */ 02726 case DBUS_TYPE_DOUBLE: 02727 err = !dbus_message_iter_get_double_array (iter, (double **)data, len); 02728 break; 02729 case DBUS_TYPE_STRING: 02730 err = !dbus_message_iter_get_string_array (iter, (char ***)data, len); 02731 break; 02732 case DBUS_TYPE_OBJECT_PATH: 02733 err = !dbus_message_iter_get_object_path_array (iter, (char ***)data, len); 02734 break; 02735 02736 case DBUS_TYPE_NIL: 02737 case DBUS_TYPE_ARRAY: 02738 case DBUS_TYPE_CUSTOM: 02739 case DBUS_TYPE_DICT: 02740 _dbus_warn ("dbus_message_get_args_valist doesn't support recursive arrays\n"); 02741 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); 02742 goto out; 02743 default: 02744 _dbus_warn ("Unknown field type %d\n", type); 02745 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); 02746 goto out; 02747 } 02748 if (err) 02749 { 02750 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02751 goto out; 02752 } 02753 } 02754 break; 02755 case DBUS_TYPE_DICT: 02756 _dbus_warn ("dbus_message_get_args_valist doesn't support dicts\n"); 02757 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); 02758 goto out; 02759 default: 02760 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, NULL); 02761 _dbus_warn ("Unknown field type %d\n", spec_type); 02762 goto out; 02763 } 02764 02765 spec_type = va_arg (var_args, int); 02766 if (!dbus_message_iter_next (iter) && spec_type != DBUS_TYPE_INVALID) 02767 { 02768 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 02769 "Message has only %d arguments, but more were expected", i); 02770 goto out; 02771 } 02772 02773 i++; 02774 } 02775 02776 retval = TRUE; 02777 02778 out: 02779 02780 return retval; 02781 } 02782 02792 unsigned char 02793 dbus_message_iter_get_byte (DBusMessageIter *iter) 02794 { 02795 unsigned char value = 0; 02796 02797 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BYTE, &value); 02798 02799 return value; 02800 } 02801 02811 dbus_bool_t 02812 dbus_message_iter_get_boolean (DBusMessageIter *iter) 02813 { 02814 unsigned char value = 0; 02815 02816 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_BOOLEAN, &value); 02817 02818 return (value != FALSE); 02819 } 02820 02830 dbus_int32_t 02831 dbus_message_iter_get_int32 (DBusMessageIter *iter) 02832 { 02833 dbus_int32_t value = 0; 02834 02835 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT32, &value); 02836 02837 return value; 02838 } 02839 02849 dbus_uint32_t 02850 dbus_message_iter_get_uint32 (DBusMessageIter *iter) 02851 { 02852 dbus_int32_t value = 0; 02853 02854 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT32, &value); 02855 02856 return value; 02857 } 02858 02859 #ifdef DBUS_HAVE_INT64 02860 02872 dbus_int64_t 02873 dbus_message_iter_get_int64 (DBusMessageIter *iter) 02874 { 02875 dbus_int64_t value = 0; 02876 02877 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_INT64, &value); 02878 02879 return value; 02880 } 02881 02893 dbus_uint64_t 02894 dbus_message_iter_get_uint64 (DBusMessageIter *iter) 02895 { 02896 dbus_uint64_t value = 0; 02897 02898 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_UINT64, &value); 02899 02900 return value; 02901 } 02902 02903 #endif /* DBUS_HAVE_INT64 */ 02904 02914 double 02915 dbus_message_iter_get_double (DBusMessageIter *iter) 02916 { 02917 double value = 0.0; 02918 02919 _dbus_message_iter_get_basic_type (iter, DBUS_TYPE_DOUBLE, &value); 02920 02921 return value; 02922 } 02923 02937 dbus_bool_t 02938 dbus_message_iter_init_array_iterator (DBusMessageIter *iter, 02939 DBusMessageIter *array_iter, 02940 int *array_type) 02941 { 02942 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02943 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter; 02944 int type, pos, len_pos, len, array_type_pos; 02945 int _array_type; 02946 02947 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 02948 02949 pos = dbus_message_iter_get_data_start (real, &type); 02950 02951 _dbus_assert (type == DBUS_TYPE_ARRAY); 02952 02953 _array_type = iter_get_array_type (real, &array_type_pos); 02954 02955 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)); 02956 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order, 02957 pos, &pos); 02958 02959 array_real->parent_iter = real; 02960 array_real->message = real->message; 02961 array_real->changed_stamp = real->message->changed_stamp; 02962 02963 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY; 02964 array_real->pos = pos; 02965 array_real->end = pos + len; 02966 02967 array_real->container_start = pos; 02968 array_real->container_length_pos = len_pos; 02969 array_real->wrote_dict_key = 0; 02970 array_real->array_type_pos = array_type_pos; 02971 array_real->array_type_done = TRUE; 02972 02973 if (array_type != NULL) 02974 *array_type = _array_type; 02975 02976 return len > 0; 02977 } 02978 02979 02989 dbus_bool_t 02990 dbus_message_iter_init_dict_iterator (DBusMessageIter *iter, 02991 DBusMessageIter *dict_iter) 02992 { 02993 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 02994 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter; 02995 int type, pos, len_pos, len; 02996 02997 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 02998 02999 pos = dbus_message_iter_get_data_start (real, &type); 03000 03001 _dbus_assert (type == DBUS_TYPE_DICT); 03002 03003 len_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)); 03004 len = _dbus_demarshal_uint32 (&real->message->body, real->message->byte_order, 03005 pos, &pos); 03006 03007 dict_real->parent_iter = real; 03008 dict_real->message = real->message; 03009 dict_real->changed_stamp = real->message->changed_stamp; 03010 03011 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT; 03012 dict_real->pos = pos; 03013 dict_real->end = pos + len; 03014 03015 dict_real->container_start = pos; 03016 dict_real->container_length_pos = len_pos; 03017 dict_real->wrote_dict_key = 0; 03018 03019 return len > 0; 03020 } 03021 03022 static dbus_bool_t 03023 _dbus_message_iter_get_basic_type_array (DBusMessageIter *iter, 03024 char type, 03025 void **array, 03026 int *array_len) 03027 { 03028 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03029 int item_type, pos; 03030 03031 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 03032 03033 pos = dbus_message_iter_get_data_start (real, &item_type); 03034 03035 _dbus_assert (item_type == DBUS_TYPE_ARRAY); 03036 03037 item_type = iter_get_array_type (real, NULL); 03038 03039 _dbus_assert (type == item_type); 03040 03041 return _dbus_demarshal_basic_type_array (&real->message->body, 03042 item_type, array, array_len, 03043 real->message->byte_order, &pos); 03044 } 03045 03056 dbus_bool_t 03057 dbus_message_iter_get_byte_array (DBusMessageIter *iter, 03058 unsigned char **value, 03059 int *len) 03060 { 03061 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BYTE, 03062 (void **) value, len); 03063 } 03064 03075 dbus_bool_t 03076 dbus_message_iter_get_boolean_array (DBusMessageIter *iter, 03077 unsigned char **value, 03078 int *len) 03079 { 03080 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_BOOLEAN, 03081 (void **) value, len); 03082 } 03083 03094 dbus_bool_t 03095 dbus_message_iter_get_int32_array (DBusMessageIter *iter, 03096 dbus_int32_t **value, 03097 int *len) 03098 { 03099 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT32, 03100 (void **) value, len); 03101 } 03102 03113 dbus_bool_t 03114 dbus_message_iter_get_uint32_array (DBusMessageIter *iter, 03115 dbus_uint32_t **value, 03116 int *len) 03117 { 03118 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT32, 03119 (void **) value, len); 03120 } 03121 03122 #ifdef DBUS_HAVE_INT64 03123 03136 dbus_bool_t 03137 dbus_message_iter_get_int64_array (DBusMessageIter *iter, 03138 dbus_int64_t **value, 03139 int *len) 03140 { 03141 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_INT64, 03142 (void **) value, len); 03143 } 03144 03157 dbus_bool_t 03158 dbus_message_iter_get_uint64_array (DBusMessageIter *iter, 03159 dbus_uint64_t **value, 03160 int *len) 03161 { 03162 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_UINT64, 03163 (void **) value, len); 03164 } 03165 03166 #endif /* DBUS_HAVE_INT64 */ 03167 03178 dbus_bool_t 03179 dbus_message_iter_get_double_array (DBusMessageIter *iter, 03180 double **value, 03181 int *len) 03182 { 03183 return _dbus_message_iter_get_basic_type_array (iter, DBUS_TYPE_DOUBLE, 03184 (void **) value, len); 03185 } 03186 03202 dbus_bool_t 03203 dbus_message_iter_get_string_array (DBusMessageIter *iter, 03204 char ***value, 03205 int *len) 03206 { 03207 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03208 int type, pos; 03209 03210 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 03211 03212 pos = dbus_message_iter_get_data_start (real, &type); 03213 03214 _dbus_assert (type == DBUS_TYPE_ARRAY); 03215 03216 type = iter_get_array_type (real, NULL); 03217 _dbus_assert (type == DBUS_TYPE_STRING); 03218 03219 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order, 03220 pos, NULL, value, len)) 03221 return FALSE; 03222 else 03223 return TRUE; 03224 } 03225 03241 dbus_bool_t 03242 dbus_message_iter_get_object_path_array (DBusMessageIter *iter, 03243 char ***value, 03244 int *len) 03245 { 03246 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03247 int type, pos; 03248 03249 _dbus_return_val_if_fail (dbus_message_iter_check (real), FALSE); 03250 03251 pos = dbus_message_iter_get_data_start (real, &type); 03252 03253 _dbus_assert (type == DBUS_TYPE_ARRAY); 03254 03255 type = iter_get_array_type (real, NULL); 03256 _dbus_assert (type == DBUS_TYPE_OBJECT_PATH); 03257 03258 if (!_dbus_demarshal_string_array (&real->message->body, real->message->byte_order, 03259 pos, NULL, value, len)) 03260 return FALSE; 03261 else 03262 return TRUE; 03263 } 03264 03274 char * 03275 dbus_message_iter_get_dict_key (DBusMessageIter *iter) 03276 { 03277 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03278 03279 _dbus_return_val_if_fail (dbus_message_iter_check (real), NULL); 03280 03281 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT); 03282 03283 return _dbus_demarshal_string (&real->message->body, real->message->byte_order, 03284 real->pos, NULL); 03285 } 03286 03295 void 03296 dbus_message_append_iter_init (DBusMessage *message, 03297 DBusMessageIter *iter) 03298 { 03299 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03300 03301 _dbus_return_if_fail (message != NULL); 03302 _dbus_return_if_fail (iter != NULL); 03303 03304 real->message = message; 03305 real->parent_iter = NULL; 03306 real->changed_stamp = message->changed_stamp; 03307 03308 real->type = DBUS_MESSAGE_ITER_TYPE_MESSAGE; 03309 real->end = _dbus_string_get_length (&real->message->body); 03310 real->pos = real->end; 03311 03312 real->container_length_pos = 0; 03313 real->wrote_dict_key = 0; 03314 } 03315 03316 #ifndef DBUS_DISABLE_CHECKS 03317 static dbus_bool_t 03318 dbus_message_iter_append_check (DBusMessageRealIter *iter) 03319 { 03320 if (iter == NULL) 03321 { 03322 _dbus_warn ("dbus iterator check failed: NULL iterator\n"); 03323 return FALSE; 03324 } 03325 03326 if (iter->message->locked) 03327 { 03328 _dbus_warn ("dbus iterator check failed: message is locked (has already been sent)\n"); 03329 return FALSE; 03330 } 03331 03332 if (iter->changed_stamp != iter->message->changed_stamp) 03333 { 03334 _dbus_warn ("dbus iterator check failed: invalid iterator, must re-initialize it after modifying the message"); 03335 return FALSE; 03336 } 03337 03338 if (iter->pos != iter->end) 03339 { 03340 _dbus_warn ("dbus iterator check failed: can only append at end of message"); 03341 return FALSE; 03342 } 03343 03344 if (iter->pos != _dbus_string_get_length (&iter->message->body)) 03345 { 03346 _dbus_warn ("dbus iterator check failed: append pos not at end of message string"); 03347 return FALSE; 03348 } 03349 03350 return TRUE; 03351 } 03352 #endif /* DBUS_DISABLE_CHECKS */ 03353 03354 static dbus_bool_t 03355 dbus_message_iter_append_type (DBusMessageRealIter *iter, 03356 int type) 03357 { 03358 const char *data; 03359 03360 switch (iter->type) 03361 { 03362 case DBUS_MESSAGE_ITER_TYPE_MESSAGE: 03363 if (!_dbus_string_append_byte (&iter->message->body, type)) 03364 return FALSE; 03365 03366 if (!_dbus_message_append_byte_to_signature (iter->message, type)) 03367 { 03368 _dbus_string_shorten (&iter->message->body, 1); 03369 return FALSE; 03370 } 03371 break; 03372 03373 case DBUS_MESSAGE_ITER_TYPE_ARRAY: 03374 data = _dbus_string_get_const_data_len (&iter->message->body, 03375 iter->array_type_pos, 1); 03376 if (type != *data) 03377 { 03378 _dbus_warn ("Appended element of wrong type for array\n"); 03379 return FALSE; 03380 } 03381 break; 03382 03383 case DBUS_MESSAGE_ITER_TYPE_DICT: 03384 if (!iter->wrote_dict_key) 03385 { 03386 _dbus_warn ("Appending dict data before key name\n"); 03387 return FALSE; 03388 } 03389 03390 if (!_dbus_string_append_byte (&iter->message->body, type)) 03391 return FALSE; 03392 03393 break; 03394 03395 default: 03396 _dbus_assert_not_reached ("Invalid iter type"); 03397 break; 03398 } 03399 03400 return TRUE; 03401 } 03402 03403 static void 03404 dbus_message_iter_update_after_change (DBusMessageRealIter *iter) 03405 { 03406 iter->changed_stamp = iter->message->changed_stamp; 03407 03408 /* Set new end of iter */ 03409 iter->end = _dbus_string_get_length (&iter->message->body); 03410 iter->pos = iter->end; 03411 03412 /* Set container length */ 03413 if (iter->type == DBUS_MESSAGE_ITER_TYPE_DICT || 03414 (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && iter->array_type_done)) 03415 _dbus_marshal_set_uint32 (&iter->message->body, 03416 iter->message->byte_order, 03417 iter->container_length_pos, 03418 iter->end - iter->container_start); 03419 03420 if (iter->parent_iter) 03421 dbus_message_iter_update_after_change (iter->parent_iter); 03422 } 03423 03424 static void 03425 dbus_message_iter_append_done (DBusMessageRealIter *iter) 03426 { 03427 iter->message->changed_stamp++; 03428 dbus_message_iter_update_after_change (iter); 03429 iter->wrote_dict_key = FALSE; 03430 } 03431 03438 dbus_bool_t 03439 dbus_message_iter_append_nil (DBusMessageIter *iter) 03440 { 03441 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03442 03443 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03444 03445 if (!dbus_message_iter_append_type (real, DBUS_TYPE_NIL)) 03446 return FALSE; 03447 03448 dbus_message_iter_append_done (real); 03449 03450 return TRUE; 03451 } 03452 03453 static dbus_bool_t 03454 dbus_message_iter_append_basic (DBusMessageIter *iter, 03455 char type, 03456 void *value) 03457 { 03458 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03459 03460 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03461 03462 if (!dbus_message_iter_append_type (real, type)) 03463 return FALSE; 03464 03465 if (!_dbus_marshal_basic_type (&real->message->body, 03466 type, value, 03467 real->message->byte_order)) 03468 { 03469 _dbus_string_set_length (&real->message->body, real->pos); 03470 return FALSE; 03471 } 03472 03473 dbus_message_iter_append_done (real); 03474 03475 return TRUE; 03476 } 03477 03485 dbus_bool_t 03486 dbus_message_iter_append_boolean (DBusMessageIter *iter, 03487 dbus_bool_t value) 03488 { 03489 unsigned char val = (value != FALSE); 03490 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &val); 03491 } 03492 03500 dbus_bool_t 03501 dbus_message_iter_append_byte (DBusMessageIter *iter, 03502 unsigned char value) 03503 { 03504 return dbus_message_iter_append_basic (iter, DBUS_TYPE_BYTE, &value); 03505 } 03506 03514 dbus_bool_t 03515 dbus_message_iter_append_int32 (DBusMessageIter *iter, 03516 dbus_int32_t value) 03517 { 03518 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &value); 03519 } 03520 03528 dbus_bool_t 03529 dbus_message_iter_append_uint32 (DBusMessageIter *iter, 03530 dbus_uint32_t value) 03531 { 03532 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT32, &value); 03533 } 03534 03535 #ifdef DBUS_HAVE_INT64 03536 03546 dbus_bool_t 03547 dbus_message_iter_append_int64 (DBusMessageIter *iter, 03548 dbus_int64_t value) 03549 { 03550 return dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value); 03551 } 03552 03562 dbus_bool_t 03563 dbus_message_iter_append_uint64 (DBusMessageIter *iter, 03564 dbus_uint64_t value) 03565 { 03566 return dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &value); 03567 } 03568 03569 #endif /* DBUS_HAVE_INT64 */ 03570 03578 dbus_bool_t 03579 dbus_message_iter_append_double (DBusMessageIter *iter, 03580 double value) 03581 { 03582 return dbus_message_iter_append_basic (iter, DBUS_TYPE_DOUBLE, &value); 03583 } 03584 03594 dbus_bool_t 03595 dbus_message_iter_append_string (DBusMessageIter *iter, 03596 const char *value) 03597 { 03598 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03599 03600 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03601 03602 if (!dbus_message_iter_append_type (real, DBUS_TYPE_STRING)) 03603 return FALSE; 03604 03605 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value)) 03606 { 03607 _dbus_string_set_length (&real->message->body, real->pos); 03608 return FALSE; 03609 } 03610 03611 dbus_message_iter_append_done (real); 03612 03613 return TRUE; 03614 } 03615 03625 dbus_bool_t 03626 dbus_message_iter_append_object_path (DBusMessageIter *iter, 03627 const char *value) 03628 { 03629 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03630 03631 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03632 03633 if (!dbus_message_iter_append_type (real, DBUS_TYPE_OBJECT_PATH)) 03634 return FALSE; 03635 03636 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value)) 03637 { 03638 _dbus_string_set_length (&real->message->body, real->pos); 03639 return FALSE; 03640 } 03641 03642 dbus_message_iter_append_done (real); 03643 03644 return TRUE; 03645 } 03646 03659 dbus_bool_t 03660 dbus_message_iter_append_custom (DBusMessageIter *iter, 03661 const char *name, 03662 const unsigned char *data, 03663 int len) 03664 { 03665 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03666 03667 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03668 03669 if (!dbus_message_iter_append_type (real, DBUS_TYPE_CUSTOM)) 03670 return FALSE; 03671 03672 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, name)) 03673 { 03674 _dbus_string_set_length (&real->message->body, real->pos); 03675 return FALSE; 03676 } 03677 03678 if (!_dbus_marshal_byte_array (&real->message->body, real->message->byte_order, data, len)) 03679 { 03680 _dbus_string_set_length (&real->message->body, real->pos); 03681 return FALSE; 03682 } 03683 03684 dbus_message_iter_append_done (real); 03685 03686 return TRUE; 03687 } 03688 03689 03698 dbus_bool_t 03699 dbus_message_iter_append_dict_key (DBusMessageIter *iter, 03700 const char *value) 03701 { 03702 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03703 03704 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03705 _dbus_assert (real->type == DBUS_MESSAGE_ITER_TYPE_DICT); 03706 03707 if (real->wrote_dict_key) 03708 { 03709 _dbus_warn ("Appending multiple dict key names\n"); 03710 return FALSE; 03711 } 03712 03713 if (!_dbus_marshal_string (&real->message->body, real->message->byte_order, value)) 03714 { 03715 return FALSE; 03716 } 03717 03718 dbus_message_iter_append_done (real); 03719 real->wrote_dict_key = TRUE; 03720 03721 return TRUE; 03722 } 03723 03724 static dbus_bool_t 03725 array_iter_type_mark_done (DBusMessageRealIter *iter) 03726 { 03727 int len_pos; 03728 03729 if (iter->type == DBUS_MESSAGE_ITER_TYPE_ARRAY) 03730 array_iter_type_mark_done (iter->parent_iter); 03731 else 03732 return TRUE; 03733 03734 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&iter->message->body), 03735 sizeof (dbus_uint32_t)); 03736 03737 /* Empty length for now, backfill later */ 03738 if (!_dbus_marshal_uint32 (&iter->message->body, iter->message->byte_order, 0)) 03739 { 03740 _dbus_string_set_length (&iter->message->body, iter->pos); 03741 return FALSE; 03742 } 03743 03744 iter->container_start = _dbus_string_get_length (&iter->message->body); 03745 iter->container_length_pos = len_pos; 03746 iter->array_type_done = TRUE; 03747 03748 return TRUE; 03749 } 03750 03751 static dbus_bool_t 03752 append_array_type (DBusMessageRealIter *real, 03753 int element_type, 03754 dbus_bool_t *array_type_done, 03755 int *array_type_pos) 03756 { 03757 int existing_element_type; 03758 03759 if (!dbus_message_iter_append_type (real, DBUS_TYPE_ARRAY)) 03760 return FALSE; 03761 03762 if (real->type == DBUS_MESSAGE_ITER_TYPE_ARRAY && 03763 real->array_type_done) 03764 { 03765 existing_element_type = iter_get_array_type (real, array_type_pos); 03766 if (existing_element_type != element_type) 03767 { 03768 _dbus_warn ("Appending array of %s, when expecting array of %s\n", 03769 _dbus_type_to_string (element_type), 03770 _dbus_type_to_string (existing_element_type)); 03771 _dbus_string_set_length (&real->message->body, real->pos); 03772 return FALSE; 03773 } 03774 if (array_type_done != NULL) 03775 *array_type_done = TRUE; 03776 } 03777 else 03778 { 03779 if (array_type_pos != NULL) 03780 *array_type_pos = _dbus_string_get_length (&real->message->body); 03781 03782 03783 if (!_dbus_message_append_byte_to_signature (real->message, element_type)) 03784 { 03785 _dbus_string_set_length (&real->message->body, real->pos); 03786 return FALSE; 03787 } 03788 03789 /* Append element type */ 03790 if (!_dbus_string_append_byte (&real->message->body, element_type)) 03791 { 03792 _dbus_message_remove_byte_from_signature (real->message); 03793 _dbus_string_set_length (&real->message->body, real->pos); 03794 return FALSE; 03795 } 03796 03797 if (array_type_done != NULL) 03798 *array_type_done = element_type != DBUS_TYPE_ARRAY; 03799 03800 if (element_type != DBUS_TYPE_ARRAY && 03801 !array_iter_type_mark_done (real)) 03802 { 03803 _dbus_message_remove_byte_from_signature (real->message); 03804 return FALSE; 03805 } 03806 } 03807 03808 return TRUE; 03809 } 03810 03820 dbus_bool_t 03821 dbus_message_iter_append_array (DBusMessageIter *iter, 03822 DBusMessageIter *array_iter, 03823 int element_type) 03824 { 03825 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03826 DBusMessageRealIter *array_real = (DBusMessageRealIter *)array_iter; 03827 int len_pos; 03828 int array_type_pos; 03829 dbus_bool_t array_type_done; 03830 03831 if (element_type == DBUS_TYPE_NIL) 03832 { 03833 _dbus_warn ("Can't create NIL arrays\n"); 03834 return FALSE; 03835 } 03836 03837 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03838 03839 if (!append_array_type (real, element_type, &array_type_done, &array_type_pos)) 03840 return FALSE; 03841 03842 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t)); 03843 03844 if (array_type_done) 03845 { 03846 /* Empty length for now, backfill later */ 03847 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0)) 03848 { 03849 _dbus_string_set_length (&real->message->body, real->pos); 03850 return FALSE; 03851 } 03852 } 03853 03854 array_real->parent_iter = real; 03855 array_real->message = real->message; 03856 array_real->changed_stamp = real->message->changed_stamp; 03857 03858 array_real->type = DBUS_MESSAGE_ITER_TYPE_ARRAY; 03859 array_real->pos = _dbus_string_get_length (&real->message->body); 03860 array_real->end = array_real->end; 03861 03862 array_real->container_start = array_real->pos; 03863 array_real->container_length_pos = len_pos; 03864 array_real->wrote_dict_key = 0; 03865 array_real->array_type_done = array_type_done; 03866 array_real->array_type_pos = array_type_pos; 03867 03868 dbus_message_iter_append_done (array_real); 03869 03870 return TRUE; 03871 } 03872 03881 dbus_bool_t 03882 dbus_message_iter_append_dict (DBusMessageIter *iter, 03883 DBusMessageIter *dict_iter) 03884 { 03885 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03886 DBusMessageRealIter *dict_real = (DBusMessageRealIter *)dict_iter; 03887 int len_pos; 03888 03889 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03890 03891 if (!dbus_message_iter_append_type (real, DBUS_TYPE_DICT)) 03892 return FALSE; 03893 03894 len_pos = _DBUS_ALIGN_VALUE (_dbus_string_get_length (&real->message->body), sizeof (dbus_uint32_t)); 03895 03896 /* Empty length for now, backfill later */ 03897 if (!_dbus_marshal_uint32 (&real->message->body, real->message->byte_order, 0)) 03898 { 03899 _dbus_string_set_length (&real->message->body, real->pos); 03900 return FALSE; 03901 } 03902 03903 dict_real->parent_iter = real; 03904 dict_real->message = real->message; 03905 dict_real->changed_stamp = real->message->changed_stamp; 03906 03907 dict_real->type = DBUS_MESSAGE_ITER_TYPE_DICT; 03908 dict_real->pos = _dbus_string_get_length (&real->message->body); 03909 dict_real->end = dict_real->end; 03910 03911 dict_real->container_start = dict_real->pos; 03912 dict_real->container_length_pos = len_pos; 03913 dict_real->wrote_dict_key = 0; 03914 03915 dbus_message_iter_append_done (dict_real); 03916 03917 real->wrote_dict_key = FALSE; 03918 03919 return TRUE; 03920 } 03921 03922 static dbus_bool_t 03923 _dbus_message_iter_append_basic_array (DBusMessageIter *iter, 03924 char type, 03925 const void *value, 03926 int len) 03927 { 03928 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 03929 03930 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 03931 03932 if (!append_array_type (real, type, NULL, NULL)) 03933 return FALSE; 03934 03935 if (!_dbus_marshal_basic_type_array (&real->message->body, 03936 type, value, len, 03937 real->message->byte_order)) 03938 { 03939 _dbus_string_set_length (&real->message->body, real->pos); 03940 return FALSE; 03941 } 03942 03943 dbus_message_iter_append_done (real); 03944 03945 return TRUE; 03946 } 03947 03948 03962 dbus_bool_t 03963 dbus_message_append_args_valist (DBusMessage *message, 03964 int first_arg_type, 03965 va_list var_args) 03966 { 03967 int type, old_len; 03968 DBusMessageIter iter; 03969 03970 _dbus_return_val_if_fail (message != NULL, FALSE); 03971 03972 old_len = _dbus_string_get_length (&message->body); 03973 03974 type = first_arg_type; 03975 03976 dbus_message_append_iter_init (message, &iter); 03977 03978 while (type != DBUS_TYPE_INVALID) 03979 { 03980 switch (type) 03981 { 03982 case DBUS_TYPE_NIL: 03983 if (!dbus_message_iter_append_nil (&iter)) 03984 goto errorout; 03985 break; 03986 case DBUS_TYPE_BYTE: 03987 /* Read an int from varargs, because the original unsigned 03988 * char has been promoted to int. */ 03989 if (!dbus_message_iter_append_byte (&iter, va_arg (var_args, int))) 03990 goto errorout; 03991 break; 03992 case DBUS_TYPE_BOOLEAN: 03993 if (!dbus_message_iter_append_boolean (&iter, va_arg (var_args, dbus_bool_t))) 03994 goto errorout; 03995 break; 03996 case DBUS_TYPE_INT32: 03997 /* FIXME this is probably wrong, because an int passed in probably gets 03998 * converted to plain "int" not necessarily 32-bit. 03999 */ 04000 if (!dbus_message_iter_append_int32 (&iter, va_arg (var_args, dbus_int32_t))) 04001 goto errorout; 04002 break; 04003 case DBUS_TYPE_UINT32: 04004 /* FIXME this is probably wrong, because an int passed in probably gets 04005 * converted to plain "int" not necessarily 32-bit. 04006 */ 04007 if (!dbus_message_iter_append_uint32 (&iter, va_arg (var_args, dbus_uint32_t))) 04008 goto errorout; 04009 break; 04010 #ifdef DBUS_HAVE_INT64 04011 case DBUS_TYPE_INT64: 04012 if (!dbus_message_iter_append_int64 (&iter, va_arg (var_args, dbus_int64_t))) 04013 goto errorout; 04014 break; 04015 case DBUS_TYPE_UINT64: 04016 if (!dbus_message_iter_append_uint64 (&iter, va_arg (var_args, dbus_uint64_t))) 04017 goto errorout; 04018 break; 04019 #endif /* DBUS_HAVE_INT64 */ 04020 case DBUS_TYPE_DOUBLE: 04021 if (!dbus_message_iter_append_double (&iter, va_arg (var_args, double))) 04022 goto errorout; 04023 break; 04024 case DBUS_TYPE_STRING: 04025 if (!dbus_message_iter_append_string (&iter, va_arg (var_args, const char *))) 04026 goto errorout; 04027 break; 04028 case DBUS_TYPE_OBJECT_PATH: 04029 if (!dbus_message_iter_append_object_path (&iter, va_arg (var_args, const char*))) 04030 goto errorout; 04031 break; 04032 case DBUS_TYPE_CUSTOM: 04033 { 04034 const char *name; 04035 unsigned char *data; 04036 int len; 04037 04038 name = va_arg (var_args, const char *); 04039 data = va_arg (var_args, unsigned char *); 04040 len = va_arg (var_args, int); 04041 04042 if (!dbus_message_iter_append_custom (&iter, name, data, len)) 04043 goto errorout; 04044 break; 04045 } 04046 case DBUS_TYPE_ARRAY: 04047 { 04048 void *data; 04049 int len, type; 04050 04051 type = va_arg (var_args, int); 04052 data = va_arg (var_args, void *); 04053 len = va_arg (var_args, int); 04054 04055 switch (type) 04056 { 04057 case DBUS_TYPE_BYTE: 04058 case DBUS_TYPE_BOOLEAN: 04059 case DBUS_TYPE_INT32: 04060 case DBUS_TYPE_UINT32: 04061 #ifdef DBUS_HAVE_INT64 04062 case DBUS_TYPE_INT64: 04063 case DBUS_TYPE_UINT64: 04064 #endif /* DBUS_HAVE_INT64 */ 04065 case DBUS_TYPE_DOUBLE: 04066 if (!_dbus_message_iter_append_basic_array (&iter, type, data, len)) 04067 goto errorout; 04068 break; 04069 case DBUS_TYPE_STRING: 04070 if (!dbus_message_iter_append_string_array (&iter, (const char **)data, len)) 04071 goto errorout; 04072 break; 04073 case DBUS_TYPE_OBJECT_PATH: 04074 if (!dbus_message_iter_append_object_path_array (&iter, (const char **)data, len)) 04075 goto errorout; 04076 break; 04077 case DBUS_TYPE_NIL: 04078 case DBUS_TYPE_ARRAY: 04079 case DBUS_TYPE_CUSTOM: 04080 case DBUS_TYPE_DICT: 04081 _dbus_warn ("dbus_message_append_args_valist doesn't support recursive arrays\n"); 04082 goto errorout; 04083 default: 04084 _dbus_warn ("Unknown field type %d\n", type); 04085 goto errorout; 04086 } 04087 } 04088 break; 04089 04090 case DBUS_TYPE_DICT: 04091 _dbus_warn ("dbus_message_append_args_valist doesn't support dicts\n"); 04092 goto errorout; 04093 default: 04094 _dbus_warn ("Unknown field type %d\n", type); 04095 goto errorout; 04096 } 04097 04098 type = va_arg (var_args, int); 04099 } 04100 04101 return TRUE; 04102 04103 errorout: 04104 return FALSE; 04105 } 04106 04115 dbus_bool_t 04116 dbus_message_iter_append_boolean_array (DBusMessageIter *iter, 04117 unsigned const char *value, 04118 int len) 04119 { 04120 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BOOLEAN, 04121 value, len); 04122 } 04123 04132 dbus_bool_t 04133 dbus_message_iter_append_int32_array (DBusMessageIter *iter, 04134 const dbus_int32_t *value, 04135 int len) 04136 { 04137 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT32, 04138 value, len); 04139 } 04140 04149 dbus_bool_t 04150 dbus_message_iter_append_uint32_array (DBusMessageIter *iter, 04151 const dbus_uint32_t *value, 04152 int len) 04153 { 04154 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT32, 04155 value, len); 04156 } 04157 04158 #ifdef DBUS_HAVE_INT64 04159 04170 dbus_bool_t 04171 dbus_message_iter_append_int64_array (DBusMessageIter *iter, 04172 const dbus_int64_t *value, 04173 int len) 04174 { 04175 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_INT64, 04176 value, len); 04177 } 04178 04189 dbus_bool_t 04190 dbus_message_iter_append_uint64_array (DBusMessageIter *iter, 04191 const dbus_uint64_t *value, 04192 int len) 04193 { 04194 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_UINT64, 04195 value, len); 04196 } 04197 #endif /* DBUS_HAVE_INT64 */ 04198 04207 dbus_bool_t 04208 dbus_message_iter_append_double_array (DBusMessageIter *iter, 04209 const double *value, 04210 int len) 04211 { 04212 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_DOUBLE, 04213 value, len); 04214 } 04215 04224 dbus_bool_t 04225 dbus_message_iter_append_byte_array (DBusMessageIter *iter, 04226 unsigned const char *value, 04227 int len) 04228 { 04229 return _dbus_message_iter_append_basic_array (iter, DBUS_TYPE_BYTE, 04230 value, len); 04231 } 04232 04241 dbus_bool_t 04242 dbus_message_iter_append_string_array (DBusMessageIter *iter, 04243 const char **value, 04244 int len) 04245 { 04246 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 04247 04248 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 04249 04250 if (!append_array_type (real, DBUS_TYPE_STRING, NULL, NULL)) 04251 return FALSE; 04252 04253 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len)) 04254 { 04255 _dbus_string_set_length (&real->message->body, real->pos); 04256 return FALSE; 04257 } 04258 04259 dbus_message_iter_append_done (real); 04260 04261 return TRUE; 04262 } 04263 04272 dbus_bool_t 04273 dbus_message_iter_append_object_path_array (DBusMessageIter *iter, 04274 const char **value, 04275 int len) 04276 { 04277 DBusMessageRealIter *real = (DBusMessageRealIter *)iter; 04278 04279 _dbus_return_val_if_fail (dbus_message_iter_append_check (real), FALSE); 04280 04281 if (!append_array_type (real, DBUS_TYPE_OBJECT_PATH, NULL, NULL)) 04282 return FALSE; 04283 04284 if (!_dbus_marshal_string_array (&real->message->body, real->message->byte_order, value, len)) 04285 { 04286 _dbus_string_set_length (&real->message->body, real->pos); 04287 return FALSE; 04288 } 04289 04290 dbus_message_iter_append_done (real); 04291 04292 return TRUE; 04293 } 04294 04302 dbus_bool_t 04303 dbus_message_set_sender (DBusMessage *message, 04304 const char *sender) 04305 { 04306 _dbus_return_val_if_fail (message != NULL, FALSE); 04307 _dbus_return_val_if_fail (!message->locked, FALSE); 04308 04309 return set_string_field (message, 04310 DBUS_HEADER_FIELD_SENDER, 04311 DBUS_TYPE_STRING, 04312 sender); 04313 } 04314 04325 void 04326 dbus_message_set_no_reply (DBusMessage *message, 04327 dbus_bool_t no_reply) 04328 { 04329 char *header; 04330 04331 _dbus_return_if_fail (message != NULL); 04332 _dbus_return_if_fail (!message->locked); 04333 04334 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1); 04335 04336 if (no_reply) 04337 *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED; 04338 else 04339 *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED; 04340 } 04341 04349 dbus_bool_t 04350 dbus_message_get_no_reply (DBusMessage *message) 04351 { 04352 const char *header; 04353 04354 _dbus_return_val_if_fail (message != NULL, FALSE); 04355 04356 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1); 04357 04358 return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0; 04359 } 04360 04361 04371 void 04372 dbus_message_set_auto_activation (DBusMessage *message, 04373 dbus_bool_t auto_activation) 04374 { 04375 char *header; 04376 04377 _dbus_return_if_fail (message != NULL); 04378 _dbus_return_if_fail (!message->locked); 04379 04380 header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1); 04381 04382 if (auto_activation) 04383 *header |= DBUS_HEADER_FLAG_AUTO_ACTIVATION; 04384 else 04385 *header &= ~DBUS_HEADER_FLAG_AUTO_ACTIVATION; 04386 } 04387 04395 dbus_bool_t 04396 dbus_message_get_auto_activation (DBusMessage *message) 04397 { 04398 const char *header; 04399 04400 _dbus_return_val_if_fail (message != NULL, FALSE); 04401 04402 header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1); 04403 04404 return (*header & DBUS_HEADER_FLAG_AUTO_ACTIVATION) != 0; 04405 } 04406 04414 const char* 04415 dbus_message_get_sender (DBusMessage *message) 04416 { 04417 _dbus_return_val_if_fail (message != NULL, NULL); 04418 04419 return get_string_field (message, 04420 DBUS_HEADER_FIELD_SENDER, 04421 NULL); 04422 } 04423 04439 const char* 04440 dbus_message_get_signature (DBusMessage *message) 04441 { 04442 _dbus_return_val_if_fail (message != NULL, NULL); 04443 04444 return get_string_field (message, 04445 DBUS_HEADER_FIELD_SIGNATURE, 04446 NULL); 04447 } 04448 04449 static dbus_bool_t 04450 _dbus_message_has_type_interface_member (DBusMessage *message, 04451 int type, 04452 const char *interface, 04453 const char *method) 04454 { 04455 const char *n; 04456 04457 _dbus_assert (message != NULL); 04458 _dbus_assert (interface != NULL); 04459 _dbus_assert (method != NULL); 04460 04461 if (dbus_message_get_type (message) != type) 04462 return FALSE; 04463 04464 /* Optimize by checking the short method name first 04465 * instead of the longer interface name 04466 */ 04467 04468 n = dbus_message_get_member (message); 04469 04470 if (n && strcmp (n, method) == 0) 04471 { 04472 n = dbus_message_get_interface (message); 04473 04474 if (n && strcmp (n, interface) == 0) 04475 return TRUE; 04476 } 04477 04478 return FALSE; 04479 } 04480 04493 dbus_bool_t 04494 dbus_message_is_method_call (DBusMessage *message, 04495 const char *interface, 04496 const char *method) 04497 { 04498 _dbus_return_val_if_fail (message != NULL, FALSE); 04499 _dbus_return_val_if_fail (interface != NULL, FALSE); 04500 _dbus_return_val_if_fail (method != NULL, FALSE); 04501 04502 return _dbus_message_has_type_interface_member (message, 04503 DBUS_MESSAGE_TYPE_METHOD_CALL, 04504 interface, method); 04505 } 04506 04519 dbus_bool_t 04520 dbus_message_is_signal (DBusMessage *message, 04521 const char *interface, 04522 const char *signal_name) 04523 { 04524 _dbus_return_val_if_fail (message != NULL, FALSE); 04525 _dbus_return_val_if_fail (interface != NULL, FALSE); 04526 _dbus_return_val_if_fail (signal_name != NULL, FALSE); 04527 04528 return _dbus_message_has_type_interface_member (message, 04529 DBUS_MESSAGE_TYPE_SIGNAL, 04530 interface, signal_name); 04531 } 04532 04543 dbus_bool_t 04544 dbus_message_is_error (DBusMessage *message, 04545 const char *error_name) 04546 { 04547 const char *n; 04548 04549 _dbus_return_val_if_fail (message != NULL, FALSE); 04550 _dbus_return_val_if_fail (error_name != NULL, FALSE); 04551 _dbus_return_val_if_fail (is_valid_error_name (error_name), FALSE); 04552 04553 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR) 04554 return FALSE; 04555 04556 n = dbus_message_get_error_name (message); 04557 04558 if (n && strcmp (n, error_name) == 0) 04559 return TRUE; 04560 else 04561 return FALSE; 04562 } 04563 04574 dbus_bool_t 04575 dbus_message_has_destination (DBusMessage *message, 04576 const char *service) 04577 { 04578 const char *s; 04579 04580 _dbus_return_val_if_fail (message != NULL, FALSE); 04581 _dbus_return_val_if_fail (service != NULL, FALSE); 04582 04583 s = dbus_message_get_destination (message); 04584 04585 if (s && strcmp (s, service) == 0) 04586 return TRUE; 04587 else 04588 return FALSE; 04589 } 04590 04605 dbus_bool_t 04606 dbus_message_has_sender (DBusMessage *message, 04607 const char *service) 04608 { 04609 const char *s; 04610 04611 _dbus_return_val_if_fail (message != NULL, FALSE); 04612 _dbus_return_val_if_fail (service != NULL, FALSE); 04613 04614 s = dbus_message_get_sender (message); 04615 04616 if (s && strcmp (s, service) == 0) 04617 return TRUE; 04618 else 04619 return FALSE; 04620 } 04621 04631 dbus_bool_t 04632 dbus_message_has_signature (DBusMessage *message, 04633 const char *signature) 04634 { 04635 const char *s; 04636 04637 _dbus_return_val_if_fail (message != NULL, FALSE); 04638 _dbus_return_val_if_fail (signature != NULL, FALSE); 04639 04640 s = dbus_message_get_signature (message); 04641 04642 if (s && strcmp (s, signature) == 0) 04643 return TRUE; 04644 else 04645 return FALSE; 04646 } 04647 04665 dbus_bool_t 04666 dbus_set_error_from_message (DBusError *error, 04667 DBusMessage *message) 04668 { 04669 char *str; 04670 04671 _dbus_return_val_if_fail (message != NULL, FALSE); 04672 _dbus_return_val_if_error_is_set (error, FALSE); 04673 04674 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR) 04675 return FALSE; 04676 04677 str = NULL; 04678 dbus_message_get_args (message, NULL, 04679 DBUS_TYPE_STRING, &str, 04680 DBUS_TYPE_INVALID); 04681 04682 dbus_set_error (error, dbus_message_get_error_name (message), 04683 str ? "%s" : NULL, str); 04684 04685 dbus_free (str); 04686 04687 return TRUE; 04688 } 04689 04714 /* we definitely use signed ints for sizes, so don't exceed 04715 * _DBUS_INT_MAX; and add 16 for paranoia, since a message 04716 * over 128M is pretty nuts anyhow. 04717 */ 04718 04722 #define MAX_SANE_MESSAGE_SIZE (_DBUS_INT_MAX/16) 04723 04728 struct DBusMessageLoader 04729 { 04730 int refcount; 04732 DBusString data; 04734 DBusList *messages; 04736 long max_message_size; 04738 unsigned int buffer_outstanding : 1; 04740 unsigned int corrupted : 1; 04741 }; 04742 04753 #define INITIAL_LOADER_DATA_LEN 32 04754 04761 DBusMessageLoader* 04762 _dbus_message_loader_new (void) 04763 { 04764 DBusMessageLoader *loader; 04765 04766 loader = dbus_new0 (DBusMessageLoader, 1); 04767 if (loader == NULL) 04768 return NULL; 04769 04770 loader->refcount = 1; 04771 04772 /* Try to cap message size at something that won't *totally* hose 04773 * the system if we have a couple of them. 04774 */ 04775 loader->max_message_size = _DBUS_ONE_MEGABYTE * 32; 04776 04777 if (!_dbus_string_init (&loader->data)) 04778 { 04779 dbus_free (loader); 04780 return NULL; 04781 } 04782 04783 /* preallocate the buffer for speed, ignore failure */ 04784 _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN); 04785 _dbus_string_set_length (&loader->data, 0); 04786 04787 return loader; 04788 } 04789 04796 DBusMessageLoader * 04797 _dbus_message_loader_ref (DBusMessageLoader *loader) 04798 { 04799 loader->refcount += 1; 04800 04801 return loader; 04802 } 04803 04810 void 04811 _dbus_message_loader_unref (DBusMessageLoader *loader) 04812 { 04813 loader->refcount -= 1; 04814 if (loader->refcount == 0) 04815 { 04816 _dbus_list_foreach (&loader->messages, 04817 (DBusForeachFunction) dbus_message_unref, 04818 NULL); 04819 _dbus_list_clear (&loader->messages); 04820 _dbus_string_free (&loader->data); 04821 dbus_free (loader); 04822 } 04823 } 04824 04843 void 04844 _dbus_message_loader_get_buffer (DBusMessageLoader *loader, 04845 DBusString **buffer) 04846 { 04847 _dbus_assert (!loader->buffer_outstanding); 04848 04849 *buffer = &loader->data; 04850 04851 loader->buffer_outstanding = TRUE; 04852 } 04853 04858 #define DBUS_MINIMUM_HEADER_SIZE 16 04859 04860 static dbus_bool_t 04861 decode_string_field (const DBusString *data, 04862 int field, 04863 HeaderField *header_field, 04864 DBusString *field_data, 04865 int pos, 04866 int type) 04867 { 04868 int string_data_pos; 04869 04870 _dbus_assert (header_field != NULL); 04871 _dbus_assert (field_data != NULL); 04872 04873 if (header_field->name_offset >= 0) 04874 { 04875 _dbus_verbose ("%s field provided twice\n", 04876 _dbus_header_field_to_string (field)); 04877 return FALSE; 04878 } 04879 04880 if (type != DBUS_TYPE_STRING) 04881 { 04882 _dbus_verbose ("%s field has wrong type %s\n", 04883 _dbus_header_field_to_string (field), 04884 _dbus_type_to_string (type)); 04885 return FALSE; 04886 } 04887 04888 /* skip padding after typecode, skip string length; 04889 * we assume that the string arg has already been validated 04890 * for sanity and UTF-8 04891 */ 04892 string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4; 04893 _dbus_assert (string_data_pos < _dbus_string_get_length (data)); 04894 04895 _dbus_string_init_const (field_data, 04896 _dbus_string_get_const_data (data) + string_data_pos); 04897 04898 header_field->name_offset = pos - 2; 04899 header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4); 04900 04901 #if 0 04902 _dbus_verbose ("Found field %s at offset %d\n", 04903 _dbus_header_field_to_string (field), 04904 header_field->value_offset); 04905 #endif 04906 04907 return TRUE; 04908 } 04909 04910 /* FIXME because the service/interface/member/error names are already 04911 * validated to be in the particular ASCII subset, UTF-8 validating 04912 * them could be skipped as a probably-interesting optimization. 04913 * The UTF-8 validation definitely shows up in profiles. 04914 */ 04915 static dbus_bool_t 04916 decode_header_data (const DBusString *data, 04917 int header_len, 04918 int byte_order, 04919 int message_type, 04920 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1], 04921 int *message_padding) 04922 { 04923 DBusString field_data; 04924 int pos, new_pos; 04925 int i; 04926 int field; 04927 int type; 04928 dbus_bool_t signature_required; 04929 04930 if (header_len < 16) 04931 { 04932 _dbus_verbose ("Header length %d is too short\n", header_len); 04933 return FALSE; 04934 } 04935 04936 i = 0; 04937 while (i <= DBUS_HEADER_FIELD_LAST) 04938 { 04939 fields[i].name_offset = -1; 04940 fields[i].value_offset = -1; 04941 ++i; 04942 } 04943 04944 pos = 16; 04945 while (pos < header_len) 04946 { 04947 field = _dbus_string_get_byte (data, pos); 04948 if (field == DBUS_HEADER_FIELD_INVALID) 04949 break; /* Must be padding */ 04950 pos++; 04951 04952 if (!_dbus_marshal_validate_type (data, pos, &type, &pos)) 04953 { 04954 _dbus_verbose ("Failed to validate type of named header field pos = %d\n", 04955 pos); 04956 return FALSE; 04957 } 04958 04959 if (!_dbus_marshal_validate_arg (data, byte_order, 0, type, -1, pos, &new_pos)) 04960 { 04961 _dbus_verbose ("Failed to validate argument to named header field pos = %d\n", 04962 pos); 04963 return FALSE; 04964 } 04965 04966 if (new_pos > header_len) 04967 { 04968 _dbus_verbose ("Named header field tries to extend beyond header length\n"); 04969 return FALSE; 04970 } 04971 04972 switch (field) 04973 { 04974 case DBUS_HEADER_FIELD_DESTINATION: 04975 if (!decode_string_field (data, field, &fields[field], 04976 &field_data, pos, type)) 04977 return FALSE; 04978 04979 if (!_dbus_string_validate_service (&field_data, 0, 04980 _dbus_string_get_length (&field_data))) 04981 { 04982 _dbus_verbose ("service field has invalid content \"%s\"\n", 04983 _dbus_string_get_const_data (&field_data)); 04984 return FALSE; 04985 } 04986 break; 04987 04988 case DBUS_HEADER_FIELD_INTERFACE: 04989 if (!decode_string_field (data, field, &fields[field], 04990 &field_data, pos, type)) 04991 return FALSE; 04992 04993 if (!_dbus_string_validate_interface (&field_data, 0, 04994 _dbus_string_get_length (&field_data))) 04995 { 04996 _dbus_verbose ("interface field has invalid content \"%s\"\n", 04997 _dbus_string_get_const_data (&field_data)); 04998 return FALSE; 04999 } 05000 05001 if (_dbus_string_equal_c_str (&field_data, 05002 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL)) 05003 { 05004 _dbus_verbose ("Message is on the local interface\n"); 05005 return FALSE; 05006 } 05007 break; 05008 05009 case DBUS_HEADER_FIELD_MEMBER: 05010 if (!decode_string_field (data, field, &fields[field], 05011 &field_data, pos, type)) 05012 return FALSE; 05013 05014 if (!_dbus_string_validate_member (&field_data, 0, 05015 _dbus_string_get_length (&field_data))) 05016 { 05017 _dbus_verbose ("member field has invalid content \"%s\"\n", 05018 _dbus_string_get_const_data (&field_data)); 05019 return FALSE; 05020 } 05021 break; 05022 05023 case DBUS_HEADER_FIELD_ERROR_NAME: 05024 if (!decode_string_field (data, field, &fields[field], 05025 &field_data, pos, type)) 05026 return FALSE; 05027 05028 if (!_dbus_string_validate_error_name (&field_data, 0, 05029 _dbus_string_get_length (&field_data))) 05030 { 05031 _dbus_verbose ("error-name field has invalid content \"%s\"\n", 05032 _dbus_string_get_const_data (&field_data)); 05033 return FALSE; 05034 } 05035 break; 05036 05037 case DBUS_HEADER_FIELD_SENDER: 05038 if (!decode_string_field (data, field, &fields[field], 05039 &field_data, pos, type)) 05040 return FALSE; 05041 05042 if (!_dbus_string_validate_service (&field_data, 0, 05043 _dbus_string_get_length (&field_data))) 05044 { 05045 _dbus_verbose ("sender-service field has invalid content \"%s\"\n", 05046 _dbus_string_get_const_data (&field_data)); 05047 return FALSE; 05048 } 05049 break; 05050 05051 case DBUS_HEADER_FIELD_PATH: 05052 05053 /* Path was already validated as part of standard 05054 * type validation, since there's an OBJECT_PATH 05055 * type. 05056 */ 05057 05058 if (fields[field].name_offset >= 0) 05059 { 05060 _dbus_verbose ("path field provided twice\n"); 05061 return FALSE; 05062 } 05063 if (type != DBUS_TYPE_OBJECT_PATH) 05064 { 05065 _dbus_verbose ("path field has wrong type\n"); 05066 return FALSE; 05067 } 05068 05069 fields[field].name_offset = pos - 2; 05070 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4); 05071 05072 /* No forging signals from the local path */ 05073 { 05074 const char *s; 05075 s = _dbus_string_get_const_data_len (data, 05076 fields[field].value_offset, 05077 _dbus_string_get_length (data) - 05078 fields[field].value_offset); 05079 if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0) 05080 { 05081 _dbus_verbose ("Message is on the local path\n"); 05082 return FALSE; 05083 } 05084 } 05085 05086 _dbus_verbose ("Found path at offset %d\n", 05087 fields[field].value_offset); 05088 break; 05089 05090 case DBUS_HEADER_FIELD_REPLY_SERIAL: 05091 if (fields[field].name_offset >= 0) 05092 { 05093 _dbus_verbose ("reply field provided twice\n"); 05094 return FALSE; 05095 } 05096 05097 if (type != DBUS_TYPE_UINT32) 05098 { 05099 _dbus_verbose ("reply field has wrong type\n"); 05100 return FALSE; 05101 } 05102 05103 fields[field].name_offset = pos - 2; 05104 fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4); 05105 05106 _dbus_verbose ("Found reply serial %u at offset %d\n", 05107 _dbus_demarshal_uint32 (data, 05108 byte_order, 05109 fields[field].value_offset, 05110 NULL), 05111 fields[field].value_offset); 05112 break; 05113 05114 case DBUS_HEADER_FIELD_SIGNATURE: 05115 if (!decode_string_field (data, field, &fields[field], 05116 &field_data, pos, type)) 05117 return FALSE; 05118 05119 #if 0 05120 /* FIXME */ 05121 if (!_dbus_string_validate_signature (&field_data, 0, 05122 _dbus_string_get_length (&field_data))) 05123 { 05124 _dbus_verbose ("signature field has invalid content \"%s\"\n", 05125 _dbus_string_get_const_data (&field_data)); 05126 return FALSE; 05127 } 05128 #endif 05129 break; 05130 05131 default: 05132 _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n", 05133 field, pos); 05134 } 05135 05136 pos = new_pos; 05137 } 05138 05139 if (pos < header_len) 05140 { 05141 /* Alignment padding, verify that it's nul */ 05142 if ((header_len - pos) >= 8) 05143 { 05144 _dbus_verbose ("too much header alignment padding\n"); 05145 return FALSE; 05146 } 05147 05148 if (!_dbus_string_validate_nul (data, 05149 pos, (header_len - pos))) 05150 { 05151 _dbus_verbose ("header alignment padding is not nul\n"); 05152 return FALSE; 05153 } 05154 } 05155 05156 /* Depending on message type, enforce presence of certain fields. */ 05157 signature_required = TRUE; 05158 05159 switch (message_type) 05160 { 05161 case DBUS_MESSAGE_TYPE_SIGNAL: 05162 case DBUS_MESSAGE_TYPE_METHOD_CALL: 05163 if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0) 05164 { 05165 _dbus_verbose ("No path field provided\n"); 05166 return FALSE; 05167 } 05168 /* FIXME make this optional, only for method calls */ 05169 if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0) 05170 { 05171 _dbus_verbose ("No interface field provided\n"); 05172 return FALSE; 05173 } 05174 if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0) 05175 { 05176 _dbus_verbose ("No member field provided\n"); 05177 return FALSE; 05178 } 05179 break; 05180 case DBUS_MESSAGE_TYPE_ERROR: 05181 if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0) 05182 { 05183 _dbus_verbose ("No error-name field provided\n"); 05184 return FALSE; 05185 } 05186 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0) 05187 { 05188 _dbus_verbose ("No reply serial field provided in error\n"); 05189 return FALSE; 05190 } 05191 break; 05192 case DBUS_MESSAGE_TYPE_METHOD_RETURN: 05193 if (fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset < 0) 05194 { 05195 _dbus_verbose ("No reply serial field provided in method return\n"); 05196 return FALSE; 05197 } 05198 break; 05199 default: 05200 /* An unknown type, spec requires us to ignore it */ 05201 signature_required = FALSE; 05202 break; 05203 } 05204 05205 /* FIXME allow omitting signature field for a message with no arguments? */ 05206 if (signature_required) 05207 { 05208 if (fields[DBUS_HEADER_FIELD_SIGNATURE].value_offset < 0) 05209 { 05210 _dbus_verbose ("No signature field provided\n"); 05211 return FALSE; 05212 } 05213 } 05214 05215 if (message_padding) 05216 *message_padding = header_len - pos; 05217 05218 return TRUE; 05219 } 05220 05231 void 05232 _dbus_message_loader_return_buffer (DBusMessageLoader *loader, 05233 DBusString *buffer, 05234 int bytes_read) 05235 { 05236 _dbus_assert (loader->buffer_outstanding); 05237 _dbus_assert (buffer == &loader->data); 05238 05239 loader->buffer_outstanding = FALSE; 05240 } 05241 05242 static dbus_bool_t 05243 load_one_message (DBusMessageLoader *loader, 05244 int byte_order, 05245 int message_type, 05246 int header_len, 05247 int body_len) 05248 { 05249 DBusMessage *message; 05250 HeaderField fields[DBUS_HEADER_FIELD_LAST + 1]; 05251 int i; 05252 int next_arg; 05253 dbus_bool_t oom; 05254 int header_padding; 05255 05256 message = NULL; 05257 oom = FALSE; 05258 05259 #if 0 05260 _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */); 05261 #endif 05262 05263 if (!decode_header_data (&loader->data, 05264 header_len, byte_order, 05265 message_type, 05266 fields, &header_padding)) 05267 { 05268 _dbus_verbose ("Header was invalid\n"); 05269 loader->corrupted = TRUE; 05270 goto failed; 05271 } 05272 05273 next_arg = header_len; 05274 while (next_arg < (header_len + body_len)) 05275 { 05276 int type; 05277 int prev = next_arg; 05278 05279 if (!_dbus_marshal_validate_type (&loader->data, next_arg, 05280 &type, &next_arg)) 05281 { 05282 _dbus_verbose ("invalid typecode at offset %d\n", prev); 05283 loader->corrupted = TRUE; 05284 goto failed; 05285 } 05286 05287 if (!_dbus_marshal_validate_arg (&loader->data, 05288 byte_order, 05289 0, 05290 type, -1, 05291 next_arg, 05292 &next_arg)) 05293 { 05294 _dbus_verbose ("invalid type data at %d, next_arg\n", next_arg); 05295 loader->corrupted = TRUE; 05296 goto failed; 05297 } 05298 05299 _dbus_assert (next_arg > prev); 05300 } 05301 05302 if (next_arg > (header_len + body_len)) 05303 { 05304 _dbus_verbose ("end of last arg at %d but message has len %d+%d=%d\n", 05305 next_arg, header_len, body_len, 05306 header_len + body_len); 05307 loader->corrupted = TRUE; 05308 goto failed; 05309 } 05310 05311 message = dbus_message_new_empty_header (); 05312 if (message == NULL) 05313 { 05314 _dbus_verbose ("Failed to allocate empty message\n"); 05315 oom = TRUE; 05316 goto failed; 05317 } 05318 05319 message->byte_order = byte_order; 05320 message->header_padding = header_padding; 05321 05322 /* Copy in the offsets we found */ 05323 i = 0; 05324 while (i <= DBUS_HEADER_FIELD_LAST) 05325 { 05326 message->header_fields[i] = fields[i]; 05327 ++i; 05328 } 05329 05330 if (!_dbus_list_append (&loader->messages, message)) 05331 { 05332 _dbus_verbose ("Failed to append new message to loader queue\n"); 05333 oom = TRUE; 05334 goto failed; 05335 } 05336 05337 _dbus_assert (_dbus_string_get_length (&message->header) == 0); 05338 _dbus_assert (_dbus_string_get_length (&message->body) == 0); 05339 05340 _dbus_assert (_dbus_string_get_length (&loader->data) >= 05341 (header_len + body_len)); 05342 05343 if (!_dbus_string_move_len (&loader->data, 0, header_len, &message->header, 0)) 05344 { 05345 _dbus_verbose ("Failed to move header into new message\n"); 05346 oom = TRUE; 05347 goto failed; 05348 } 05349 05350 if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0)) 05351 { 05352 _dbus_verbose ("Failed to move body into new message\n"); 05353 05354 oom = TRUE; 05355 goto failed; 05356 } 05357 05358 _dbus_assert (_dbus_string_get_length (&message->header) == header_len); 05359 _dbus_assert (_dbus_string_get_length (&message->body) == body_len); 05360 05361 /* Fill in caches (we checked the types of these fields 05362 * earlier) 05363 */ 05364 message->reply_serial = get_uint_field (message, 05365 DBUS_HEADER_FIELD_REPLY_SERIAL); 05366 05367 message->client_serial = _dbus_demarshal_uint32 (&message->header, 05368 message->byte_order, 05369 CLIENT_SERIAL_OFFSET, 05370 NULL); 05371 if (message->client_serial == 0 || 05372 (message->header_fields[DBUS_HEADER_FIELD_REPLY_SERIAL].value_offset >= 0 && message->reply_serial == 0)) 05373 { 05374 _dbus_verbose ("client_serial = %d reply_serial = %d, one of these no good\n", 05375 message->client_serial, 05376 message->reply_serial); 05377 05378 loader->corrupted = TRUE; 05379 goto failed; 05380 } 05381 05382 _dbus_verbose ("Loaded message %p\n", message); 05383 05384 _dbus_assert (!oom); 05385 _dbus_assert (!loader->corrupted); 05386 05387 return TRUE; 05388 05389 failed: 05390 05391 /* Clean up */ 05392 05393 if (message != NULL) 05394 { 05395 /* Put the data back so we can try again later if it was an OOM issue */ 05396 if (_dbus_string_get_length (&message->body) > 0) 05397 { 05398 dbus_bool_t result; 05399 05400 result = _dbus_string_copy_len (&message->body, 0, body_len, 05401 &loader->data, 0); 05402 05403 _dbus_assert (result); /* because DBusString never reallocs smaller */ 05404 } 05405 05406 if (_dbus_string_get_length (&message->header) > 0) 05407 { 05408 dbus_bool_t result; 05409 05410 result = _dbus_string_copy_len (&message->header, 0, header_len, 05411 &loader->data, 0); 05412 05413 _dbus_assert (result); /* because DBusString never reallocs smaller */ 05414 } 05415 05416 /* does nothing if the message isn't in the list */ 05417 _dbus_list_remove_last (&loader->messages, message); 05418 05419 dbus_message_unref (message); 05420 } 05421 05422 05423 return !oom; 05424 } 05425 05439 dbus_bool_t 05440 _dbus_message_loader_queue_messages (DBusMessageLoader *loader) 05441 { 05442 while (!loader->corrupted && _dbus_string_get_length (&loader->data) >= 16) 05443 { 05444 const char *header_data; 05445 int byte_order, message_type, header_len, body_len; 05446 dbus_uint32_t header_len_unsigned, body_len_unsigned; 05447 05448 header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16); 05449 05450 _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data); 05451 05452 if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION) 05453 { 05454 _dbus_verbose ("Message has protocol version %d ours is %d\n", 05455 (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION); 05456 loader->corrupted = TRUE; 05457 return TRUE; 05458 } 05459 05460 byte_order = header_data[BYTE_ORDER_OFFSET]; 05461 05462 if (byte_order != DBUS_LITTLE_ENDIAN && 05463 byte_order != DBUS_BIG_ENDIAN) 05464 { 05465 _dbus_verbose ("Message with bad byte order '%c' received\n", 05466 byte_order); 05467 loader->corrupted = TRUE; 05468 return TRUE; 05469 } 05470 05471 /* Unknown types are ignored, but INVALID is 05472 * disallowed 05473 */ 05474 message_type = header_data[TYPE_OFFSET]; 05475 if (message_type == DBUS_MESSAGE_TYPE_INVALID) 05476 { 05477 _dbus_verbose ("Message with bad type '%d' received\n", 05478 message_type); 05479 loader->corrupted = TRUE; 05480 return TRUE; 05481 } 05482 05483 header_len_unsigned = _dbus_unpack_uint32 (byte_order, 05484 (const unsigned char *) header_data + 4); 05485 body_len_unsigned = _dbus_unpack_uint32 (byte_order, 05486 (const unsigned char *) header_data + 8); 05487 05488 if (header_len_unsigned < 16) 05489 { 05490 _dbus_verbose ("Message had broken too-small header length %u\n", 05491 header_len_unsigned); 05492 loader->corrupted = TRUE; 05493 return TRUE; 05494 } 05495 05496 if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE || 05497 body_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE) 05498 { 05499 _dbus_verbose ("Header or body length too large (%u %u)\n", 05500 header_len_unsigned, 05501 body_len_unsigned); 05502 loader->corrupted = TRUE; 05503 return TRUE; 05504 } 05505 05506 /* Now that we know the values are in signed range, get 05507 * rid of stupid unsigned, just causes bugs 05508 */ 05509 header_len = header_len_unsigned; 05510 body_len = body_len_unsigned; 05511 05512 if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned) 05513 { 05514 05515 _dbus_verbose ("header length %d is not aligned to 8 bytes\n", 05516 header_len); 05517 loader->corrupted = TRUE; 05518 return TRUE; 05519 } 05520 05521 if (header_len + body_len > loader->max_message_size) 05522 { 05523 _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n", 05524 header_len, body_len, loader->max_message_size); 05525 loader->corrupted = TRUE; 05526 return TRUE; 05527 } 05528 05529 if (_dbus_string_get_length (&loader->data) >= (header_len + body_len)) 05530 { 05531 if (!load_one_message (loader, byte_order, message_type, 05532 header_len, body_len)) 05533 return FALSE; 05534 } 05535 else 05536 return TRUE; 05537 } 05538 05539 return TRUE; 05540 } 05541 05549 DBusMessage* 05550 _dbus_message_loader_peek_message (DBusMessageLoader *loader) 05551 { 05552 if (loader->messages) 05553 return loader->messages->data; 05554 else 05555 return NULL; 05556 } 05557 05566 DBusMessage* 05567 _dbus_message_loader_pop_message (DBusMessageLoader *loader) 05568 { 05569 return _dbus_list_pop_first (&loader->messages); 05570 } 05571 05580 DBusList* 05581 _dbus_message_loader_pop_message_link (DBusMessageLoader *loader) 05582 { 05583 return _dbus_list_pop_first_link (&loader->messages); 05584 } 05585 05592 void 05593 _dbus_message_loader_putback_message_link (DBusMessageLoader *loader, 05594 DBusList *link) 05595 { 05596 _dbus_list_prepend_link (&loader->messages, link); 05597 } 05598 05608 dbus_bool_t 05609 _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader) 05610 { 05611 return loader->corrupted; 05612 } 05613 05620 void 05621 _dbus_message_loader_set_max_message_size (DBusMessageLoader *loader, 05622 long size) 05623 { 05624 if (size > MAX_SANE_MESSAGE_SIZE) 05625 { 05626 _dbus_verbose ("clamping requested max message size %ld to %d\n", 05627 size, MAX_SANE_MESSAGE_SIZE); 05628 size = MAX_SANE_MESSAGE_SIZE; 05629 } 05630 loader->max_message_size = size; 05631 } 05632 05639 long 05640 _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader) 05641 { 05642 return loader->max_message_size; 05643 } 05644 05645 static DBusDataSlotAllocator slot_allocator; 05646 _DBUS_DEFINE_GLOBAL_LOCK (message_slots); 05647 05662 dbus_bool_t 05663 dbus_message_allocate_data_slot (dbus_int32_t *slot_p) 05664 { 05665 return _dbus_data_slot_allocator_alloc (&slot_allocator, 05666 _DBUS_LOCK_NAME (message_slots), 05667 slot_p); 05668 } 05669 05681 void 05682 dbus_message_free_data_slot (dbus_int32_t *slot_p) 05683 { 05684 _dbus_return_if_fail (*slot_p >= 0); 05685 05686 _dbus_data_slot_allocator_free (&slot_allocator, slot_p); 05687 } 05688 05702 dbus_bool_t 05703 dbus_message_set_data (DBusMessage *message, 05704 dbus_int32_t slot, 05705 void *data, 05706 DBusFreeFunction free_data_func) 05707 { 05708 DBusFreeFunction old_free_func; 05709 void *old_data; 05710 dbus_bool_t retval; 05711 05712 _dbus_return_val_if_fail (message != NULL, FALSE); 05713 _dbus_return_val_if_fail (slot >= 0, FALSE); 05714 05715 retval = _dbus_data_slot_list_set (&slot_allocator, 05716 &message->slot_list, 05717 slot, data, free_data_func, 05718 &old_free_func, &old_data); 05719 05720 if (retval) 05721 { 05722 /* Do the actual free outside the message lock */ 05723 if (old_free_func) 05724 (* old_free_func) (old_data); 05725 } 05726 05727 return retval; 05728 } 05729 05738 void* 05739 dbus_message_get_data (DBusMessage *message, 05740 dbus_int32_t slot) 05741 { 05742 void *res; 05743 05744 _dbus_return_val_if_fail (message != NULL, NULL); 05745 05746 res = _dbus_data_slot_list_get (&slot_allocator, 05747 &message->slot_list, 05748 slot); 05749 05750 return res; 05751 } 05752 05766 int 05767 dbus_message_type_from_string (const char *type_str) 05768 { 05769 if (strcmp (type_str, "method_call") == 0) 05770 return DBUS_MESSAGE_TYPE_METHOD_CALL; 05771 if (strcmp (type_str, "method_return") == 0) 05772 return DBUS_MESSAGE_TYPE_METHOD_RETURN; 05773 else if (strcmp (type_str, "signal") == 0) 05774 return DBUS_MESSAGE_TYPE_SIGNAL; 05775 else if (strcmp (type_str, "error") == 0) 05776 return DBUS_MESSAGE_TYPE_ERROR; 05777 else 05778 return DBUS_MESSAGE_TYPE_INVALID; 05779 } 05780 05782 #ifdef DBUS_BUILD_TESTS 05783 #include "dbus-test.h" 05784 #include <stdio.h> 05785 #include <stdlib.h> 05786 05787 static void 05788 message_iter_test (DBusMessage *message) 05789 { 05790 DBusMessageIter iter, dict, dict2, array, array2; 05791 char *str; 05792 unsigned char *data; 05793 dbus_int32_t *our_int_array; 05794 int len; 05795 05796 dbus_message_iter_init (message, &iter); 05797 05798 /* String tests */ 05799 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) 05800 _dbus_assert_not_reached ("Argument type isn't string"); 05801 05802 str = dbus_message_iter_get_string (&iter); 05803 if (strcmp (str, "Test string") != 0) 05804 _dbus_assert_not_reached ("Strings differ"); 05805 dbus_free (str); 05806 05807 if (!dbus_message_iter_next (&iter)) 05808 _dbus_assert_not_reached ("Reached end of arguments"); 05809 05810 /* Signed integer tests */ 05811 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT32) 05812 _dbus_assert_not_reached ("Argument type isn't int32"); 05813 05814 if (dbus_message_iter_get_int32 (&iter) != -0x12345678) 05815 _dbus_assert_not_reached ("Signed integers differ"); 05816 05817 if (!dbus_message_iter_next (&iter)) 05818 _dbus_assert_not_reached ("Reached end of fields"); 05819 05820 /* Unsigned integer tests */ 05821 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) 05822 _dbus_assert_not_reached ("Argument type isn't int32"); 05823 05824 if (dbus_message_iter_get_uint32 (&iter) != 0xedd1e) 05825 _dbus_assert_not_reached ("Unsigned integers differ"); 05826 05827 if (!dbus_message_iter_next (&iter)) 05828 _dbus_assert_not_reached ("Reached end of arguments"); 05829 05830 /* Double tests */ 05831 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DOUBLE) 05832 _dbus_assert_not_reached ("Argument type isn't double"); 05833 05834 if (dbus_message_iter_get_double (&iter) != 3.14159) 05835 _dbus_assert_not_reached ("Doubles differ"); 05836 05837 if (!dbus_message_iter_next (&iter)) 05838 _dbus_assert_not_reached ("Reached end of arguments"); 05839 05840 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 05841 _dbus_assert_not_reached ("Argument type not an array"); 05842 05843 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_DOUBLE) 05844 _dbus_assert_not_reached ("Array type not double"); 05845 05846 05847 dbus_message_iter_init_array_iterator (&iter, &array, NULL); 05848 05849 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE) 05850 _dbus_assert_not_reached ("Argument type isn't double"); 05851 05852 if (dbus_message_iter_get_double (&array) != 1.5) 05853 _dbus_assert_not_reached ("Unsigned integers differ"); 05854 05855 if (!dbus_message_iter_next (&array)) 05856 _dbus_assert_not_reached ("Reached end of arguments"); 05857 05858 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_DOUBLE) 05859 _dbus_assert_not_reached ("Argument type isn't double"); 05860 05861 if (dbus_message_iter_get_double (&array) != 2.5) 05862 _dbus_assert_not_reached ("Unsigned integers differ"); 05863 05864 if (dbus_message_iter_next (&array)) 05865 _dbus_assert_not_reached ("Didn't reach end of arguments"); 05866 05867 if (!dbus_message_iter_next (&iter)) 05868 _dbus_assert_not_reached ("Reached end of arguments"); 05869 05870 05871 /* dict */ 05872 05873 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT) 05874 _dbus_assert_not_reached ("not dict type"); 05875 05876 dbus_message_iter_init_dict_iterator (&iter, &dict); 05877 05878 str = dbus_message_iter_get_dict_key (&dict); 05879 if (str == NULL || strcmp (str, "test") != 0) 05880 _dbus_assert_not_reached ("wrong dict key"); 05881 dbus_free (str); 05882 05883 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32) 05884 _dbus_assert_not_reached ("wrong dict entry type"); 05885 05886 if (dbus_message_iter_get_uint32 (&dict) != 0xDEADBEEF) 05887 _dbus_assert_not_reached ("wrong dict entry value"); 05888 05889 /* dict (in dict) */ 05890 05891 if (!dbus_message_iter_next (&dict)) 05892 _dbus_assert_not_reached ("reached end of dict"); 05893 05894 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_DICT) 05895 _dbus_assert_not_reached ("not dict type"); 05896 05897 dbus_message_iter_init_dict_iterator (&dict, &dict2); 05898 05899 str = dbus_message_iter_get_dict_key (&dict2); 05900 if (str == NULL || strcmp (str, "dictkey") != 0) 05901 _dbus_assert_not_reached ("wrong dict key"); 05902 dbus_free (str); 05903 05904 if (dbus_message_iter_get_arg_type (&dict2) != DBUS_TYPE_STRING) 05905 _dbus_assert_not_reached ("wrong dict entry type"); 05906 05907 str = dbus_message_iter_get_string (&dict2); 05908 if (str == NULL || strcmp (str, "dictvalue") != 0) 05909 _dbus_assert_not_reached ("wrong dict entry value"); 05910 dbus_free (str); 05911 05912 if (dbus_message_iter_next (&dict2)) 05913 _dbus_assert_not_reached ("didn't reach end of dict"); 05914 05915 if (!dbus_message_iter_next (&dict)) 05916 _dbus_assert_not_reached ("reached end of dict"); 05917 05918 /* array of array of int32 (in dict) */ 05919 05920 str = dbus_message_iter_get_dict_key (&dict); 05921 if (str == NULL || strcmp (str, "array") != 0) 05922 _dbus_assert_not_reached ("wrong dict key"); 05923 dbus_free (str); 05924 05925 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_ARRAY) 05926 _dbus_assert_not_reached ("Argument type not an array"); 05927 05928 if (dbus_message_iter_get_array_type (&dict) != DBUS_TYPE_ARRAY) 05929 _dbus_assert_not_reached ("Array type not array"); 05930 05931 dbus_message_iter_init_array_iterator (&dict, &array, NULL); 05932 05933 if (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_ARRAY) 05934 _dbus_assert_not_reached ("Argument type isn't array"); 05935 05936 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32) 05937 _dbus_assert_not_reached ("Array type not int32"); 05938 05939 dbus_message_iter_init_array_iterator (&array, &array2, NULL); 05940 05941 if (dbus_message_iter_get_arg_type (&array2) != DBUS_TYPE_INT32) 05942 _dbus_assert_not_reached ("Argument type isn't int32"); 05943 05944 if (dbus_message_iter_get_int32 (&array2) != 0x12345678) 05945 _dbus_assert_not_reached ("Signed integers differ"); 05946 05947 if (!dbus_message_iter_next (&array2)) 05948 _dbus_assert_not_reached ("Reached end of arguments"); 05949 05950 if (dbus_message_iter_get_int32 (&array2) != 0x23456781) 05951 _dbus_assert_not_reached ("Signed integers differ"); 05952 05953 if (dbus_message_iter_next (&array2)) 05954 _dbus_assert_not_reached ("Didn't reached end of arguments"); 05955 05956 if (!dbus_message_iter_next (&array)) 05957 _dbus_assert_not_reached ("Reached end of arguments"); 05958 05959 if (dbus_message_iter_get_array_type (&array) != DBUS_TYPE_INT32) 05960 _dbus_assert_not_reached ("Array type not int32"); 05961 05962 if (!dbus_message_iter_get_int32_array (&array, 05963 &our_int_array, 05964 &len)) 05965 _dbus_assert_not_reached ("couldn't get int32 array"); 05966 05967 _dbus_assert (len == 3); 05968 _dbus_assert (our_int_array[0] == 0x34567812 && 05969 our_int_array[1] == 0x45678123 && 05970 our_int_array[2] == 0x56781234); 05971 dbus_free (our_int_array); 05972 05973 if (dbus_message_iter_next (&array)) 05974 _dbus_assert_not_reached ("Didn't reach end of array"); 05975 05976 if (dbus_message_iter_next (&dict)) 05977 _dbus_assert_not_reached ("Didn't reach end of dict"); 05978 05979 if (!dbus_message_iter_next (&iter)) 05980 _dbus_assert_not_reached ("Reached end of arguments"); 05981 05982 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BYTE) 05983 { 05984 _dbus_warn ("type was: %d\n", dbus_message_iter_get_arg_type (&iter)); 05985 _dbus_assert_not_reached ("wrong type after dict (should be byte)"); 05986 } 05987 05988 if (dbus_message_iter_get_byte (&iter) != 0xF0) 05989 _dbus_assert_not_reached ("wrong value after dict"); 05990 05991 05992 if (!dbus_message_iter_next (&iter)) 05993 _dbus_assert_not_reached ("Reached end of arguments"); 05994 05995 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_NIL) 05996 _dbus_assert_not_reached ("not a nil type"); 05997 05998 if (!dbus_message_iter_next (&iter)) 05999 _dbus_assert_not_reached ("Reached end of arguments"); 06000 06001 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_CUSTOM) 06002 _dbus_assert_not_reached ("wrong type after dict"); 06003 06004 if (!dbus_message_iter_get_custom (&iter, &str, &data, &len)) 06005 _dbus_assert_not_reached ("failed to get custom type"); 06006 06007 _dbus_assert (strcmp (str, "MyTypeName")==0); 06008 _dbus_assert (len == 5); 06009 _dbus_assert (strcmp (data, "data")==0); 06010 dbus_free (str); 06011 dbus_free (data); 06012 06013 if (!dbus_message_iter_next (&iter)) 06014 _dbus_assert_not_reached ("Reached end of arguments"); 06015 06016 if (dbus_message_iter_get_byte (&iter) != 0xF0) 06017 _dbus_assert_not_reached ("wrong value after custom"); 06018 06019 if (!dbus_message_iter_next (&iter)) 06020 _dbus_assert_not_reached ("Reached end of arguments"); 06021 06022 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 06023 _dbus_assert_not_reached ("no array"); 06024 06025 if (dbus_message_iter_get_array_type (&iter) != DBUS_TYPE_INT32) 06026 _dbus_assert_not_reached ("Array type not int32"); 06027 06028 if (dbus_message_iter_init_array_iterator (&iter, &array, NULL)) 06029 _dbus_assert_not_reached ("non empty array"); 06030 06031 if (!dbus_message_iter_next (&iter)) 06032 _dbus_assert_not_reached ("Reached end of arguments"); 06033 06034 if (dbus_message_iter_get_byte (&iter) != 0xF0) 06035 _dbus_assert_not_reached ("wrong value after empty array"); 06036 06037 if (!dbus_message_iter_next (&iter)) 06038 _dbus_assert_not_reached ("Reached end of arguments"); 06039 06040 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT) 06041 _dbus_assert_not_reached ("non dict"); 06042 06043 if (dbus_message_iter_init_dict_iterator (&iter, &dict)) 06044 _dbus_assert_not_reached ("non empty dict"); 06045 06046 if (!dbus_message_iter_next (&iter)) 06047 _dbus_assert_not_reached ("Reached end of arguments"); 06048 06049 if (dbus_message_iter_get_byte (&iter) != 0xF0) 06050 _dbus_assert_not_reached ("wrong value after empty dict"); 06051 06052 if (dbus_message_iter_next (&iter)) 06053 _dbus_assert_not_reached ("Didn't reach end of arguments"); 06054 } 06055 06056 06057 static dbus_bool_t 06058 check_message_handling_type (DBusMessageIter *iter, 06059 int type) 06060 { 06061 DBusMessageIter child_iter; 06062 06063 switch (type) 06064 { 06065 case DBUS_TYPE_NIL: 06066 break; 06067 case DBUS_TYPE_BYTE: 06068 dbus_message_iter_get_byte (iter); 06069 break; 06070 case DBUS_TYPE_BOOLEAN: 06071 dbus_message_iter_get_boolean (iter); 06072 break; 06073 case DBUS_TYPE_INT32: 06074 dbus_message_iter_get_int32 (iter); 06075 break; 06076 case DBUS_TYPE_UINT32: 06077 dbus_message_iter_get_uint32 (iter); 06078 break; 06079 case DBUS_TYPE_INT64: 06080 #ifdef DBUS_HAVE_INT64 06081 dbus_message_iter_get_int64 (iter); 06082 #endif 06083 break; 06084 case DBUS_TYPE_UINT64: 06085 #ifdef DBUS_HAVE_INT64 06086 dbus_message_iter_get_uint64 (iter); 06087 #endif 06088 break; 06089 case DBUS_TYPE_DOUBLE: 06090 dbus_message_iter_get_double (iter); 06091 break; 06092 case DBUS_TYPE_STRING: 06093 { 06094 char *str; 06095 str = dbus_message_iter_get_string (iter); 06096 if (str == NULL) 06097 { 06098 _dbus_warn ("NULL string in message\n"); 06099 return FALSE; 06100 } 06101 dbus_free (str); 06102 } 06103 break; 06104 case DBUS_TYPE_CUSTOM: 06105 { 06106 char *name; 06107 unsigned char *data; 06108 int len; 06109 06110 if (!dbus_message_iter_get_custom (iter, &name, &data, &len)) 06111 { 06112 _dbus_warn ("error reading name from custom type\n"); 06113 return FALSE; 06114 } 06115 dbus_free (data); 06116 dbus_free (name); 06117 } 06118 break; 06119 case DBUS_TYPE_ARRAY: 06120 { 06121 int array_type; 06122 06123 dbus_message_iter_init_array_iterator (iter, &child_iter, &array_type); 06124 06125 while (dbus_message_iter_has_next (&child_iter)) 06126 { 06127 if (!check_message_handling_type (&child_iter, array_type)) 06128 { 06129 _dbus_warn ("error in array element\n"); 06130 return FALSE; 06131 } 06132 06133 if (!dbus_message_iter_next (&child_iter)) 06134 break; 06135 } 06136 } 06137 break; 06138 case DBUS_TYPE_DICT: 06139 { 06140 int entry_type; 06141 char *key; 06142 06143 dbus_message_iter_init_dict_iterator (iter, &child_iter); 06144 06145 while ((entry_type = dbus_message_iter_get_arg_type (&child_iter)) != DBUS_TYPE_INVALID) 06146 { 06147 key = dbus_message_iter_get_dict_key (&child_iter); 06148 if (key == NULL) 06149 { 06150 _dbus_warn ("error reading dict key\n"); 06151 return FALSE; 06152 } 06153 dbus_free (key); 06154 06155 if (!check_message_handling_type (&child_iter, entry_type)) 06156 { 06157 _dbus_warn ("error in dict value\n"); 06158 return FALSE; 06159 } 06160 06161 if (!dbus_message_iter_next (&child_iter)) 06162 break; 06163 } 06164 } 06165 break; 06166 06167 default: 06168 _dbus_warn ("unknown type %d\n", type); 06169 return FALSE; 06170 break; 06171 } 06172 return TRUE; 06173 } 06174 06175 06176 static dbus_bool_t 06177 check_message_handling (DBusMessage *message) 06178 { 06179 DBusMessageIter iter; 06180 int type; 06181 dbus_bool_t retval; 06182 dbus_uint32_t client_serial; 06183 06184 retval = FALSE; 06185 06186 client_serial = dbus_message_get_serial (message); 06187 06188 /* can't use set_serial due to the assertions at the start of it */ 06189 _dbus_marshal_set_uint32 (&message->header, 06190 message->byte_order, 06191 CLIENT_SERIAL_OFFSET, 06192 client_serial); 06193 06194 if (client_serial != dbus_message_get_serial (message)) 06195 { 06196 _dbus_warn ("get/set cycle for client_serial did not succeed\n"); 06197 goto failed; 06198 } 06199 06200 /* If we implement message_set_arg (message, n, value) 06201 * then we would want to test it here 06202 */ 06203 06204 dbus_message_iter_init (message, &iter); 06205 while ((type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) 06206 { 06207 if (!check_message_handling_type (&iter, type)) 06208 goto failed; 06209 06210 if (!dbus_message_iter_next (&iter)) 06211 break; 06212 } 06213 06214 retval = TRUE; 06215 06216 failed: 06217 return retval; 06218 } 06219 06220 static dbus_bool_t 06221 check_have_valid_message (DBusMessageLoader *loader) 06222 { 06223 DBusMessage *message; 06224 dbus_bool_t retval; 06225 06226 message = NULL; 06227 retval = FALSE; 06228 06229 if (!_dbus_message_loader_queue_messages (loader)) 06230 _dbus_assert_not_reached ("no memory to queue messages"); 06231 06232 if (_dbus_message_loader_get_is_corrupted (loader)) 06233 { 06234 _dbus_warn ("loader corrupted on message that was expected to be valid\n"); 06235 goto failed; 06236 } 06237 06238 message = _dbus_message_loader_pop_message (loader); 06239 if (message == NULL) 06240 { 06241 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n"); 06242 goto failed; 06243 } 06244 06245 if (_dbus_string_get_length (&loader->data) > 0) 06246 { 06247 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n"); 06248 goto failed; 06249 } 06250 06251 /* Verify that we're able to properly deal with the message. 06252 * For example, this would detect improper handling of messages 06253 * in nonstandard byte order. 06254 */ 06255 if (!check_message_handling (message)) 06256 goto failed; 06257 06258 retval = TRUE; 06259 06260 failed: 06261 if (message) 06262 dbus_message_unref (message); 06263 06264 return retval; 06265 } 06266 06267 static dbus_bool_t 06268 check_invalid_message (DBusMessageLoader *loader) 06269 { 06270 dbus_bool_t retval; 06271 06272 retval = FALSE; 06273 06274 if (!_dbus_message_loader_queue_messages (loader)) 06275 _dbus_assert_not_reached ("no memory to queue messages"); 06276 06277 if (!_dbus_message_loader_get_is_corrupted (loader)) 06278 { 06279 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n"); 06280 goto failed; 06281 } 06282 06283 retval = TRUE; 06284 06285 failed: 06286 return retval; 06287 } 06288 06289 static dbus_bool_t 06290 check_incomplete_message (DBusMessageLoader *loader) 06291 { 06292 DBusMessage *message; 06293 dbus_bool_t retval; 06294 06295 message = NULL; 06296 retval = FALSE; 06297 06298 if (!_dbus_message_loader_queue_messages (loader)) 06299 _dbus_assert_not_reached ("no memory to queue messages"); 06300 06301 if (_dbus_message_loader_get_is_corrupted (loader)) 06302 { 06303 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete)\n"); 06304 goto failed; 06305 } 06306 06307 message = _dbus_message_loader_pop_message (loader); 06308 if (message != NULL) 06309 { 06310 _dbus_warn ("loaded message that was expected to be incomplete\n"); 06311 goto failed; 06312 } 06313 06314 retval = TRUE; 06315 06316 failed: 06317 if (message) 06318 dbus_message_unref (message); 06319 return retval; 06320 } 06321 06322 static dbus_bool_t 06323 check_loader_results (DBusMessageLoader *loader, 06324 DBusMessageValidity validity) 06325 { 06326 if (!_dbus_message_loader_queue_messages (loader)) 06327 _dbus_assert_not_reached ("no memory to queue messages"); 06328 06329 switch (validity) 06330 { 06331 case _DBUS_MESSAGE_VALID: 06332 return check_have_valid_message (loader); 06333 case _DBUS_MESSAGE_INVALID: 06334 return check_invalid_message (loader); 06335 case _DBUS_MESSAGE_INCOMPLETE: 06336 return check_incomplete_message (loader); 06337 case _DBUS_MESSAGE_UNKNOWN: 06338 return TRUE; 06339 } 06340 06341 _dbus_assert_not_reached ("bad DBusMessageValidity"); 06342 return FALSE; 06343 } 06344 06345 06354 dbus_bool_t 06355 dbus_internal_do_not_use_load_message_file (const DBusString *filename, 06356 dbus_bool_t is_raw, 06357 DBusString *data) 06358 { 06359 dbus_bool_t retval; 06360 06361 retval = FALSE; 06362 06363 if (is_raw) 06364 { 06365 DBusError error; 06366 06367 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename)); 06368 dbus_error_init (&error); 06369 if (!_dbus_file_get_contents (data, filename, &error)) 06370 { 06371 _dbus_warn ("Could not load message file %s: %s\n", 06372 _dbus_string_get_const_data (filename), 06373 error.message); 06374 dbus_error_free (&error); 06375 goto failed; 06376 } 06377 } 06378 else 06379 { 06380 if (!_dbus_message_data_load (data, filename)) 06381 { 06382 _dbus_warn ("Could not load message file %s\n", 06383 _dbus_string_get_const_data (filename)); 06384 goto failed; 06385 } 06386 } 06387 06388 retval = TRUE; 06389 06390 failed: 06391 06392 return retval; 06393 } 06394 06404 dbus_bool_t 06405 dbus_internal_do_not_use_try_message_file (const DBusString *filename, 06406 dbus_bool_t is_raw, 06407 DBusMessageValidity expected_validity) 06408 { 06409 DBusString data; 06410 dbus_bool_t retval; 06411 06412 retval = FALSE; 06413 06414 if (!_dbus_string_init (&data)) 06415 _dbus_assert_not_reached ("could not allocate string\n"); 06416 06417 if (!dbus_internal_do_not_use_load_message_file (filename, is_raw, 06418 &data)) 06419 goto failed; 06420 06421 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity); 06422 06423 failed: 06424 06425 if (!retval) 06426 { 06427 if (_dbus_string_get_length (&data) > 0) 06428 _dbus_verbose_bytes_of_string (&data, 0, 06429 _dbus_string_get_length (&data)); 06430 06431 _dbus_warn ("Failed message loader test on %s\n", 06432 _dbus_string_get_const_data (filename)); 06433 } 06434 06435 _dbus_string_free (&data); 06436 06437 return retval; 06438 } 06439 06448 dbus_bool_t 06449 dbus_internal_do_not_use_try_message_data (const DBusString *data, 06450 DBusMessageValidity expected_validity) 06451 { 06452 DBusMessageLoader *loader; 06453 dbus_bool_t retval; 06454 int len; 06455 int i; 06456 06457 loader = NULL; 06458 retval = FALSE; 06459 06460 /* Write the data one byte at a time */ 06461 06462 loader = _dbus_message_loader_new (); 06463 06464 /* check some trivial loader functions */ 06465 _dbus_message_loader_ref (loader); 06466 _dbus_message_loader_unref (loader); 06467 _dbus_message_loader_get_max_message_size (loader); 06468 06469 len = _dbus_string_get_length (data); 06470 for (i = 0; i < len; i++) 06471 { 06472 DBusString *buffer; 06473 06474 _dbus_message_loader_get_buffer (loader, &buffer); 06475 _dbus_string_append_byte (buffer, 06476 _dbus_string_get_byte (data, i)); 06477 _dbus_message_loader_return_buffer (loader, buffer, 1); 06478 } 06479 06480 if (!check_loader_results (loader, expected_validity)) 06481 goto failed; 06482 06483 _dbus_message_loader_unref (loader); 06484 loader = NULL; 06485 06486 /* Write the data all at once */ 06487 06488 loader = _dbus_message_loader_new (); 06489 06490 { 06491 DBusString *buffer; 06492 06493 _dbus_message_loader_get_buffer (loader, &buffer); 06494 _dbus_string_copy (data, 0, buffer, 06495 _dbus_string_get_length (buffer)); 06496 _dbus_message_loader_return_buffer (loader, buffer, 1); 06497 } 06498 06499 if (!check_loader_results (loader, expected_validity)) 06500 goto failed; 06501 06502 _dbus_message_loader_unref (loader); 06503 loader = NULL; 06504 06505 /* Write the data 2 bytes at a time */ 06506 06507 loader = _dbus_message_loader_new (); 06508 06509 len = _dbus_string_get_length (data); 06510 for (i = 0; i < len; i += 2) 06511 { 06512 DBusString *buffer; 06513 06514 _dbus_message_loader_get_buffer (loader, &buffer); 06515 _dbus_string_append_byte (buffer, 06516 _dbus_string_get_byte (data, i)); 06517 if ((i+1) < len) 06518 _dbus_string_append_byte (buffer, 06519 _dbus_string_get_byte (data, i+1)); 06520 _dbus_message_loader_return_buffer (loader, buffer, 1); 06521 } 06522 06523 if (!check_loader_results (loader, expected_validity)) 06524 goto failed; 06525 06526 _dbus_message_loader_unref (loader); 06527 loader = NULL; 06528 06529 retval = TRUE; 06530 06531 failed: 06532 06533 if (loader) 06534 _dbus_message_loader_unref (loader); 06535 06536 return retval; 06537 } 06538 06539 static dbus_bool_t 06540 process_test_subdir (const DBusString *test_base_dir, 06541 const char *subdir, 06542 DBusMessageValidity validity, 06543 DBusForeachMessageFileFunc function, 06544 void *user_data) 06545 { 06546 DBusString test_directory; 06547 DBusString filename; 06548 DBusDirIter *dir; 06549 dbus_bool_t retval; 06550 DBusError error; 06551 06552 retval = FALSE; 06553 dir = NULL; 06554 06555 if (!_dbus_string_init (&test_directory)) 06556 _dbus_assert_not_reached ("didn't allocate test_directory\n"); 06557 06558 _dbus_string_init_const (&filename, subdir); 06559 06560 if (!_dbus_string_copy (test_base_dir, 0, 06561 &test_directory, 0)) 06562 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory"); 06563 06564 if (!_dbus_concat_dir_and_file (&test_directory, &filename)) 06565 _dbus_assert_not_reached ("couldn't allocate full path"); 06566 06567 _dbus_string_free (&filename); 06568 if (!_dbus_string_init (&filename)) 06569 _dbus_assert_not_reached ("didn't allocate filename string\n"); 06570 06571 dbus_error_init (&error); 06572 dir = _dbus_directory_open (&test_directory, &error); 06573 if (dir == NULL) 06574 { 06575 _dbus_warn ("Could not open %s: %s\n", 06576 _dbus_string_get_const_data (&test_directory), 06577 error.message); 06578 dbus_error_free (&error); 06579 goto failed; 06580 } 06581 06582 printf ("Testing %s:\n", subdir); 06583 06584 next: 06585 while (_dbus_directory_get_next_file (dir, &filename, &error)) 06586 { 06587 DBusString full_path; 06588 dbus_bool_t is_raw; 06589 06590 if (!_dbus_string_init (&full_path)) 06591 _dbus_assert_not_reached ("couldn't init string"); 06592 06593 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0)) 06594 _dbus_assert_not_reached ("couldn't copy dir to full_path"); 06595 06596 if (!_dbus_concat_dir_and_file (&full_path, &filename)) 06597 _dbus_assert_not_reached ("couldn't concat file to dir"); 06598 06599 if (_dbus_string_ends_with_c_str (&filename, ".message")) 06600 is_raw = FALSE; 06601 else if (_dbus_string_ends_with_c_str (&filename, ".message-raw")) 06602 is_raw = TRUE; 06603 else 06604 { 06605 _dbus_verbose ("Skipping non-.message file %s\n", 06606 _dbus_string_get_const_data (&filename)); 06607 _dbus_string_free (&full_path); 06608 goto next; 06609 } 06610 06611 printf (" %s\n", 06612 _dbus_string_get_const_data (&filename)); 06613 06614 _dbus_verbose (" expecting %s for %s\n", 06615 validity == _DBUS_MESSAGE_VALID ? "valid" : 06616 (validity == _DBUS_MESSAGE_INVALID ? "invalid" : 06617 (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")), 06618 _dbus_string_get_const_data (&filename)); 06619 06620 if (! (*function) (&full_path, is_raw, validity, user_data)) 06621 { 06622 _dbus_string_free (&full_path); 06623 goto failed; 06624 } 06625 else 06626 _dbus_string_free (&full_path); 06627 } 06628 06629 if (dbus_error_is_set (&error)) 06630 { 06631 _dbus_warn ("Could not get next file in %s: %s\n", 06632 _dbus_string_get_const_data (&test_directory), 06633 error.message); 06634 dbus_error_free (&error); 06635 goto failed; 06636 } 06637 06638 retval = TRUE; 06639 06640 failed: 06641 06642 if (dir) 06643 _dbus_directory_close (dir); 06644 _dbus_string_free (&test_directory); 06645 _dbus_string_free (&filename); 06646 06647 return retval; 06648 } 06649 06659 dbus_bool_t 06660 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir, 06661 DBusForeachMessageFileFunc func, 06662 void *user_data) 06663 { 06664 DBusString test_directory; 06665 dbus_bool_t retval; 06666 06667 retval = FALSE; 06668 06669 _dbus_string_init_const (&test_directory, test_data_dir); 06670 06671 if (!process_test_subdir (&test_directory, "valid-messages", 06672 _DBUS_MESSAGE_VALID, func, user_data)) 06673 goto failed; 06674 06675 if (!process_test_subdir (&test_directory, "invalid-messages", 06676 _DBUS_MESSAGE_INVALID, func, user_data)) 06677 goto failed; 06678 06679 if (!process_test_subdir (&test_directory, "incomplete-messages", 06680 _DBUS_MESSAGE_INCOMPLETE, func, user_data)) 06681 goto failed; 06682 06683 retval = TRUE; 06684 06685 failed: 06686 06687 _dbus_string_free (&test_directory); 06688 06689 return retval; 06690 } 06691 06692 static void 06693 verify_test_message (DBusMessage *message) 06694 { 06695 DBusMessageIter iter, dict; 06696 DBusError error; 06697 dbus_int32_t our_int; 06698 char *our_str; 06699 double our_double; 06700 dbus_bool_t our_bool; 06701 unsigned char our_byte_1, our_byte_2; 06702 dbus_uint32_t our_uint32; 06703 dbus_int32_t *our_uint32_array; 06704 int our_uint32_array_len; 06705 dbus_int32_t *our_int32_array; 06706 int our_int32_array_len; 06707 char **our_string_array; 06708 int our_string_array_len; 06709 #ifdef DBUS_HAVE_INT64 06710 dbus_int64_t our_int64; 06711 dbus_uint64_t our_uint64; 06712 dbus_int64_t *our_uint64_array; 06713 int our_uint64_array_len; 06714 dbus_int64_t *our_int64_array; 06715 int our_int64_array_len; 06716 #endif 06717 double *our_double_array; 06718 int our_double_array_len; 06719 unsigned char *our_byte_array; 06720 int our_byte_array_len; 06721 unsigned char *our_boolean_array; 06722 int our_boolean_array_len; 06723 06724 dbus_message_iter_init (message, &iter); 06725 06726 dbus_error_init (&error); 06727 if (!dbus_message_iter_get_args (&iter, &error, 06728 DBUS_TYPE_INT32, &our_int, 06729 #ifdef DBUS_HAVE_INT64 06730 DBUS_TYPE_INT64, &our_int64, 06731 DBUS_TYPE_UINT64, &our_uint64, 06732 #endif 06733 DBUS_TYPE_STRING, &our_str, 06734 DBUS_TYPE_DOUBLE, &our_double, 06735 DBUS_TYPE_BOOLEAN, &our_bool, 06736 DBUS_TYPE_BYTE, &our_byte_1, 06737 DBUS_TYPE_BYTE, &our_byte_2, 06738 DBUS_TYPE_NIL, 06739 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 06740 &our_uint32_array, &our_uint32_array_len, 06741 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, 06742 &our_int32_array, &our_int32_array_len, 06743 #ifdef DBUS_HAVE_INT64 06744 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, 06745 &our_uint64_array, &our_uint64_array_len, 06746 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, 06747 &our_int64_array, &our_int64_array_len, 06748 #endif 06749 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 06750 &our_string_array, &our_string_array_len, 06751 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, 06752 &our_double_array, &our_double_array_len, 06753 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 06754 &our_byte_array, &our_byte_array_len, 06755 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, 06756 &our_boolean_array, &our_boolean_array_len, 06757 0)) 06758 { 06759 _dbus_warn ("error: %s - %s\n", error.name, 06760 (error.message != NULL) ? error.message : "no message"); 06761 _dbus_assert_not_reached ("Could not get arguments"); 06762 } 06763 06764 if (our_int != -0x12345678) 06765 _dbus_assert_not_reached ("integers differ!"); 06766 06767 #ifdef DBUS_HAVE_INT64 06768 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd)) 06769 _dbus_assert_not_reached ("64-bit integers differ!"); 06770 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd)) 06771 _dbus_assert_not_reached ("64-bit unsigned integers differ!"); 06772 #endif 06773 06774 if (our_double != 3.14159) 06775 _dbus_assert_not_reached ("doubles differ!"); 06776 06777 if (strcmp (our_str, "Test string") != 0) 06778 _dbus_assert_not_reached ("strings differ!"); 06779 dbus_free (our_str); 06780 06781 if (!our_bool) 06782 _dbus_assert_not_reached ("booleans differ"); 06783 06784 if (our_byte_1 != 42) 06785 _dbus_assert_not_reached ("bytes differ!"); 06786 06787 if (our_byte_2 != 24) 06788 _dbus_assert_not_reached ("bytes differ!"); 06789 06790 if (our_uint32_array_len != 4 || 06791 our_uint32_array[0] != 0x12345678 || 06792 our_uint32_array[1] != 0x23456781 || 06793 our_uint32_array[2] != 0x34567812 || 06794 our_uint32_array[3] != 0x45678123) 06795 _dbus_assert_not_reached ("uint array differs"); 06796 dbus_free (our_uint32_array); 06797 06798 if (our_int32_array_len != 4 || 06799 our_int32_array[0] != 0x12345678 || 06800 our_int32_array[1] != -0x23456781 || 06801 our_int32_array[2] != 0x34567812 || 06802 our_int32_array[3] != -0x45678123) 06803 _dbus_assert_not_reached ("int array differs"); 06804 dbus_free (our_int32_array); 06805 06806 #ifdef DBUS_HAVE_INT64 06807 if (our_uint64_array_len != 4 || 06808 our_uint64_array[0] != 0x12345678 || 06809 our_uint64_array[1] != 0x23456781 || 06810 our_uint64_array[2] != 0x34567812 || 06811 our_uint64_array[3] != 0x45678123) 06812 _dbus_assert_not_reached ("uint64 array differs"); 06813 dbus_free (our_uint64_array); 06814 06815 if (our_int64_array_len != 4 || 06816 our_int64_array[0] != 0x12345678 || 06817 our_int64_array[1] != -0x23456781 || 06818 our_int64_array[2] != 0x34567812 || 06819 our_int64_array[3] != -0x45678123) 06820 _dbus_assert_not_reached ("int64 array differs"); 06821 dbus_free (our_int64_array); 06822 #endif /* DBUS_HAVE_INT64 */ 06823 06824 if (our_string_array_len != 4) 06825 _dbus_assert_not_reached ("string array has wrong length"); 06826 06827 if (strcmp (our_string_array[0], "Foo") != 0 || 06828 strcmp (our_string_array[1], "bar") != 0 || 06829 strcmp (our_string_array[2], "") != 0 || 06830 strcmp (our_string_array[3], "woo woo woo woo") != 0) 06831 _dbus_assert_not_reached ("string array differs"); 06832 06833 dbus_free_string_array (our_string_array); 06834 06835 if (our_double_array_len != 3) 06836 _dbus_assert_not_reached ("double array had wrong length"); 06837 06838 /* On all IEEE machines (i.e. everything sane) exact equality 06839 * should be preserved over the wire 06840 */ 06841 if (our_double_array[0] != 0.1234 || 06842 our_double_array[1] != 9876.54321 || 06843 our_double_array[2] != -300.0) 06844 _dbus_assert_not_reached ("double array had wrong values"); 06845 06846 dbus_free (our_double_array); 06847 06848 if (our_byte_array_len != 4) 06849 _dbus_assert_not_reached ("byte array had wrong length"); 06850 06851 if (our_byte_array[0] != 'a' || 06852 our_byte_array[1] != 'b' || 06853 our_byte_array[2] != 'c' || 06854 our_byte_array[3] != 234) 06855 _dbus_assert_not_reached ("byte array had wrong values"); 06856 06857 dbus_free (our_byte_array); 06858 06859 if (our_boolean_array_len != 5) 06860 _dbus_assert_not_reached ("bool array had wrong length"); 06861 06862 if (our_boolean_array[0] != TRUE || 06863 our_boolean_array[1] != FALSE || 06864 our_boolean_array[2] != TRUE || 06865 our_boolean_array[3] != TRUE || 06866 our_boolean_array[4] != FALSE) 06867 _dbus_assert_not_reached ("bool array had wrong values"); 06868 06869 dbus_free (our_boolean_array); 06870 06871 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_DICT) 06872 _dbus_assert_not_reached ("not dict type"); 06873 06874 dbus_message_iter_init_dict_iterator (&iter, &dict); 06875 06876 our_str = dbus_message_iter_get_dict_key (&dict); 06877 if (our_str == NULL || strcmp (our_str, "test") != 0) 06878 _dbus_assert_not_reached ("wrong dict key"); 06879 dbus_free (our_str); 06880 06881 if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_UINT32) 06882 { 06883 _dbus_verbose ("dict entry type: %d\n", dbus_message_iter_get_arg_type (&dict)); 06884 _dbus_assert_not_reached ("wrong dict entry type"); 06885 } 06886 06887 if ((our_uint32 = dbus_message_iter_get_uint32 (&dict)) != 0xDEADBEEF) 06888 { 06889 _dbus_verbose ("dict entry val: %x\n", our_uint32); 06890 _dbus_assert_not_reached ("wrong dict entry value"); 06891 } 06892 06893 if (dbus_message_iter_next (&dict)) 06894 _dbus_assert_not_reached ("Didn't reach end of dict"); 06895 06896 if (!dbus_message_iter_next (&iter)) 06897 _dbus_assert_not_reached ("Reached end of arguments"); 06898 06899 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) 06900 _dbus_assert_not_reached ("wrong type after dict"); 06901 06902 if (dbus_message_iter_get_uint32 (&iter) != 0xCAFEBABE) 06903 _dbus_assert_not_reached ("wrong value after dict"); 06904 06905 if (dbus_message_iter_next (&iter)) 06906 _dbus_assert_not_reached ("Didn't reach end of arguments"); 06907 } 06908 06915 dbus_bool_t 06916 _dbus_message_test (const char *test_data_dir) 06917 { 06918 DBusMessage *message; 06919 DBusMessageLoader *loader; 06920 DBusMessageIter iter, child_iter, child_iter2, child_iter3; 06921 int i; 06922 const char *data; 06923 DBusMessage *copy; 06924 const char *name1; 06925 const char *name2; 06926 const dbus_uint32_t our_uint32_array[] = 06927 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 06928 const dbus_uint32_t our_int32_array[] = 06929 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 06930 #ifdef DBUS_HAVE_INT64 06931 const dbus_uint64_t our_uint64_array[] = 06932 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 06933 const dbus_uint64_t our_int64_array[] = 06934 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 06935 #endif 06936 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; 06937 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; 06938 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; 06939 const unsigned char our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; 06940 char sig[64]; 06941 const char *s; 06942 char *t; 06943 DBusError error; 06944 06945 _dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter)); 06946 06947 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 06948 "/org/freedesktop/TestPath", 06949 "Foo.TestInterface", 06950 "TestMethod"); 06951 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 06952 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", 06953 "TestMethod")); 06954 _dbus_assert (strcmp (dbus_message_get_path (message), 06955 "/org/freedesktop/TestPath") == 0); 06956 _dbus_message_set_serial (message, 1234); 06957 /* string length including nul byte not a multiple of 4 */ 06958 if (!dbus_message_set_sender (message, "org.foo.bar1")) 06959 _dbus_assert_not_reached ("out of memory"); 06960 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); 06961 dbus_message_set_reply_serial (message, 5678); 06962 if (!dbus_message_set_sender (message, NULL)) 06963 _dbus_assert_not_reached ("out of memory"); 06964 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); 06965 _dbus_assert (dbus_message_get_serial (message) == 1234); 06966 _dbus_assert (dbus_message_get_reply_serial (message) == 5678); 06967 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 06968 06969 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 06970 dbus_message_set_no_reply (message, TRUE); 06971 _dbus_assert (dbus_message_get_no_reply (message) == TRUE); 06972 dbus_message_set_no_reply (message, FALSE); 06973 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 06974 06975 /* Set/get some header fields */ 06976 06977 if (!dbus_message_set_path (message, "/foo")) 06978 _dbus_assert_not_reached ("out of memory"); 06979 _dbus_assert (strcmp (dbus_message_get_path (message), 06980 "/foo") == 0); 06981 06982 if (!dbus_message_set_interface (message, "org.Foo")) 06983 _dbus_assert_not_reached ("out of memory"); 06984 _dbus_assert (strcmp (dbus_message_get_interface (message), 06985 "org.Foo") == 0); 06986 06987 if (!dbus_message_set_member (message, "Bar")) 06988 _dbus_assert_not_reached ("out of memory"); 06989 _dbus_assert (strcmp (dbus_message_get_member (message), 06990 "Bar") == 0); 06991 06992 /* Set/get them with longer values */ 06993 if (!dbus_message_set_path (message, "/foo/bar")) 06994 _dbus_assert_not_reached ("out of memory"); 06995 _dbus_assert (strcmp (dbus_message_get_path (message), 06996 "/foo/bar") == 0); 06997 06998 if (!dbus_message_set_interface (message, "org.Foo.Bar")) 06999 _dbus_assert_not_reached ("out of memory"); 07000 _dbus_assert (strcmp (dbus_message_get_interface (message), 07001 "org.Foo.Bar") == 0); 07002 07003 if (!dbus_message_set_member (message, "BarFoo")) 07004 _dbus_assert_not_reached ("out of memory"); 07005 _dbus_assert (strcmp (dbus_message_get_member (message), 07006 "BarFoo") == 0); 07007 07008 /* Realloc shorter again */ 07009 07010 if (!dbus_message_set_path (message, "/foo")) 07011 _dbus_assert_not_reached ("out of memory"); 07012 _dbus_assert (strcmp (dbus_message_get_path (message), 07013 "/foo") == 0); 07014 07015 if (!dbus_message_set_interface (message, "org.Foo")) 07016 _dbus_assert_not_reached ("out of memory"); 07017 _dbus_assert (strcmp (dbus_message_get_interface (message), 07018 "org.Foo") == 0); 07019 07020 if (!dbus_message_set_member (message, "Bar")) 07021 _dbus_assert_not_reached ("out of memory"); 07022 _dbus_assert (strcmp (dbus_message_get_member (message), 07023 "Bar") == 0); 07024 07025 dbus_message_unref (message); 07026 07027 /* Test the vararg functions */ 07028 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 07029 "/org/freedesktop/TestPath", 07030 "Foo.TestInterface", 07031 "TestMethod"); 07032 _dbus_message_set_serial (message, 1); 07033 dbus_message_append_args (message, 07034 DBUS_TYPE_INT32, -0x12345678, 07035 #ifdef DBUS_HAVE_INT64 07036 DBUS_TYPE_INT64, DBUS_INT64_CONSTANT (-0x123456789abcd), 07037 DBUS_TYPE_UINT64, DBUS_UINT64_CONSTANT (0x123456789abcd), 07038 #endif 07039 DBUS_TYPE_STRING, "Test string", 07040 DBUS_TYPE_DOUBLE, 3.14159, 07041 DBUS_TYPE_BOOLEAN, TRUE, 07042 DBUS_TYPE_BYTE, (unsigned char) 42, 07043 DBUS_TYPE_BYTE, 24, 07044 DBUS_TYPE_NIL, 07045 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, our_uint32_array, 07046 _DBUS_N_ELEMENTS (our_uint32_array), 07047 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array, 07048 _DBUS_N_ELEMENTS (our_int32_array), 07049 #ifdef DBUS_HAVE_INT64 07050 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array, 07051 _DBUS_N_ELEMENTS (our_uint64_array), 07052 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array, 07053 _DBUS_N_ELEMENTS (our_int64_array), 07054 #endif 07055 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array, 07056 _DBUS_N_ELEMENTS (our_string_array), 07057 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array, 07058 _DBUS_N_ELEMENTS (our_double_array), 07059 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, our_byte_array, 07060 _DBUS_N_ELEMENTS (our_byte_array), 07061 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, our_boolean_array, 07062 _DBUS_N_ELEMENTS (our_boolean_array), 07063 0); 07064 07065 dbus_message_append_iter_init (message, &iter); 07066 dbus_message_iter_append_dict (&iter, &child_iter); 07067 dbus_message_iter_append_dict_key (&child_iter, "test"); 07068 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF); 07069 dbus_message_iter_append_uint32 (&iter, 0xCAFEBABE); 07070 07071 i = 0; 07072 sig[i++] = DBUS_TYPE_INT32; 07073 #ifdef DBUS_HAVE_INT64 07074 sig[i++] = DBUS_TYPE_INT64; 07075 sig[i++] = DBUS_TYPE_UINT64; 07076 #endif 07077 sig[i++] = DBUS_TYPE_STRING; 07078 sig[i++] = DBUS_TYPE_DOUBLE; 07079 sig[i++] = DBUS_TYPE_BOOLEAN; 07080 sig[i++] = DBUS_TYPE_BYTE; 07081 sig[i++] = DBUS_TYPE_BYTE; 07082 sig[i++] = DBUS_TYPE_NIL; 07083 sig[i++] = DBUS_TYPE_ARRAY; 07084 sig[i++] = DBUS_TYPE_UINT32; 07085 sig[i++] = DBUS_TYPE_ARRAY; 07086 sig[i++] = DBUS_TYPE_INT32; 07087 #ifdef DBUS_HAVE_INT64 07088 sig[i++] = DBUS_TYPE_ARRAY; 07089 sig[i++] = DBUS_TYPE_UINT64; 07090 sig[i++] = DBUS_TYPE_ARRAY; 07091 sig[i++] = DBUS_TYPE_INT64; 07092 #endif 07093 sig[i++] = DBUS_TYPE_ARRAY; 07094 sig[i++] = DBUS_TYPE_STRING; 07095 sig[i++] = DBUS_TYPE_ARRAY; 07096 sig[i++] = DBUS_TYPE_DOUBLE; 07097 sig[i++] = DBUS_TYPE_ARRAY; 07098 sig[i++] = DBUS_TYPE_BYTE; 07099 sig[i++] = DBUS_TYPE_ARRAY; 07100 sig[i++] = DBUS_TYPE_BOOLEAN; 07101 sig[i++] = DBUS_TYPE_DICT; 07102 sig[i++] = DBUS_TYPE_UINT32; 07103 sig[i++] = DBUS_TYPE_INVALID; 07104 07105 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); 07106 07107 _dbus_verbose_bytes_of_string (&message->header, 0, 07108 _dbus_string_get_length (&message->header)); 07109 _dbus_verbose_bytes_of_string (&message->body, 0, 07110 _dbus_string_get_length (&message->body)); 07111 07112 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", 07113 sig, dbus_message_get_signature (message)); 07114 07115 s = dbus_message_get_signature (message); 07116 07117 _dbus_assert (dbus_message_has_signature (message, sig)); 07118 _dbus_assert (strcmp (s, sig) == 0); 07119 07120 verify_test_message (message); 07121 07122 copy = dbus_message_copy (message); 07123 07124 _dbus_assert (message->client_serial == copy->client_serial); 07125 _dbus_assert (message->reply_serial == copy->reply_serial); 07126 _dbus_assert (message->header_padding == copy->header_padding); 07127 07128 _dbus_assert (_dbus_string_get_length (&message->header) == 07129 _dbus_string_get_length (&copy->header)); 07130 07131 _dbus_assert (_dbus_string_get_length (&message->body) == 07132 _dbus_string_get_length (&copy->body)); 07133 07134 verify_test_message (copy); 07135 07136 name1 = dbus_message_get_interface (message); 07137 name2 = dbus_message_get_interface (copy); 07138 07139 _dbus_assert (strcmp (name1, name2) == 0); 07140 07141 name1 = dbus_message_get_member (message); 07142 name2 = dbus_message_get_member (copy); 07143 07144 _dbus_assert (strcmp (name1, name2) == 0); 07145 07146 dbus_message_unref (message); 07147 dbus_message_unref (copy); 07148 07149 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 07150 "/org/freedesktop/TestPath", 07151 "Foo.TestInterface", 07152 "TestMethod"); 07153 07154 _dbus_message_set_serial (message, 1); 07155 dbus_message_set_reply_serial (message, 0x12345678); 07156 07157 dbus_message_append_iter_init (message, &iter); 07158 dbus_message_iter_append_string (&iter, "Test string"); 07159 dbus_message_iter_append_int32 (&iter, -0x12345678); 07160 dbus_message_iter_append_uint32 (&iter, 0xedd1e); 07161 dbus_message_iter_append_double (&iter, 3.14159); 07162 07163 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_DOUBLE); 07164 dbus_message_iter_append_double (&child_iter, 1.5); 07165 dbus_message_iter_append_double (&child_iter, 2.5); 07166 07167 /* dict */ 07168 dbus_message_iter_append_dict (&iter, &child_iter); 07169 dbus_message_iter_append_dict_key (&child_iter, "test"); 07170 dbus_message_iter_append_uint32 (&child_iter, 0xDEADBEEF); 07171 07172 /* dict (in dict) */ 07173 dbus_message_iter_append_dict_key (&child_iter, "testdict"); 07174 dbus_message_iter_append_dict (&child_iter, &child_iter2); 07175 07176 dbus_message_iter_append_dict_key (&child_iter2, "dictkey"); 07177 dbus_message_iter_append_string (&child_iter2, "dictvalue"); 07178 07179 /* array of array of int32 (in dict) */ 07180 dbus_message_iter_append_dict_key (&child_iter, "array"); 07181 dbus_message_iter_append_array (&child_iter, &child_iter2, DBUS_TYPE_ARRAY); 07182 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32); 07183 dbus_message_iter_append_int32 (&child_iter3, 0x12345678); 07184 dbus_message_iter_append_int32 (&child_iter3, 0x23456781); 07185 _dbus_warn ("next call expected to fail with wrong array type\n"); 07186 _dbus_assert (!dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_UINT32)); 07187 dbus_message_iter_append_array (&child_iter2, &child_iter3, DBUS_TYPE_INT32); 07188 dbus_message_iter_append_int32 (&child_iter3, 0x34567812); 07189 dbus_message_iter_append_int32 (&child_iter3, 0x45678123); 07190 dbus_message_iter_append_int32 (&child_iter3, 0x56781234); 07191 07192 dbus_message_iter_append_byte (&iter, 0xF0); 07193 07194 dbus_message_iter_append_nil (&iter); 07195 07196 dbus_message_iter_append_custom (&iter, "MyTypeName", 07197 "data", 5); 07198 07199 dbus_message_iter_append_byte (&iter, 0xF0); 07200 07201 dbus_message_iter_append_array (&iter, &child_iter, DBUS_TYPE_INT32); 07202 07203 dbus_message_iter_append_byte (&iter, 0xF0); 07204 07205 dbus_message_iter_append_dict (&iter, &child_iter); 07206 07207 dbus_message_iter_append_byte (&iter, 0xF0); 07208 07209 message_iter_test (message); 07210 07211 /* Message loader test */ 07212 _dbus_message_lock (message); 07213 loader = _dbus_message_loader_new (); 07214 07215 /* check ref/unref */ 07216 _dbus_message_loader_ref (loader); 07217 _dbus_message_loader_unref (loader); 07218 07219 /* Write the header data one byte at a time */ 07220 data = _dbus_string_get_const_data (&message->header); 07221 for (i = 0; i < _dbus_string_get_length (&message->header); i++) 07222 { 07223 DBusString *buffer; 07224 07225 _dbus_message_loader_get_buffer (loader, &buffer); 07226 _dbus_string_append_byte (buffer, data[i]); 07227 _dbus_message_loader_return_buffer (loader, buffer, 1); 07228 } 07229 07230 /* Write the body data one byte at a time */ 07231 data = _dbus_string_get_const_data (&message->body); 07232 for (i = 0; i < _dbus_string_get_length (&message->body); i++) 07233 { 07234 DBusString *buffer; 07235 07236 _dbus_message_loader_get_buffer (loader, &buffer); 07237 _dbus_string_append_byte (buffer, data[i]); 07238 _dbus_message_loader_return_buffer (loader, buffer, 1); 07239 } 07240 07241 copy = dbus_message_copy (message); /* save for tests below */ 07242 dbus_message_unref (message); 07243 07244 /* Now pop back the message */ 07245 if (!_dbus_message_loader_queue_messages (loader)) 07246 _dbus_assert_not_reached ("no memory to queue messages"); 07247 07248 if (_dbus_message_loader_get_is_corrupted (loader)) 07249 _dbus_assert_not_reached ("message loader corrupted"); 07250 07251 message = _dbus_message_loader_pop_message (loader); 07252 if (!message) 07253 _dbus_assert_not_reached ("received a NULL message"); 07254 07255 if (dbus_message_get_reply_serial (message) != 0x12345678) 07256 _dbus_assert_not_reached ("reply serial fields differ"); 07257 07258 message_iter_test (message); 07259 07260 dbus_message_unref (message); 07261 _dbus_message_loader_unref (loader); 07262 07263 message = dbus_message_new_method_return (copy); 07264 if (message == NULL) 07265 _dbus_assert_not_reached ("out of memory\n"); 07266 dbus_message_unref (copy); 07267 07268 if (!dbus_message_append_args (message, 07269 DBUS_TYPE_STRING, "hello", 07270 DBUS_TYPE_INVALID)) 07271 _dbus_assert_not_reached ("no memory"); 07272 07273 if (!dbus_message_has_signature (message, "s")) 07274 _dbus_assert_not_reached ("method return has wrong signature"); 07275 07276 dbus_error_init (&error); 07277 if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, 07278 &t, DBUS_TYPE_INVALID)) 07279 07280 { 07281 _dbus_warn ("Failed to get expected string arg: %s\n", error.message); 07282 exit (1); 07283 } 07284 dbus_free (t); 07285 07286 dbus_message_unref (message); 07287 07288 /* Now load every message in test_data_dir if we have one */ 07289 if (test_data_dir == NULL) 07290 return TRUE; 07291 07292 return dbus_internal_do_not_use_foreach_message_file (test_data_dir, 07293 (DBusForeachMessageFileFunc) 07294 dbus_internal_do_not_use_try_message_file, 07295 NULL); 07296 } 07297 07298 #endif /* DBUS_BUILD_TESTS */

Generated on Mon Aug 16 17:40:10 2004 for D-BUS by doxygen 1.3.8