1/* -*- mode: C; c-file-style: "gnu" -*- */ 2/* dbus-marshal-header.c Managing marshaling/demarshaling of message headers 3 * 4 * Copyright (C) 2005 Red Hat, Inc. 5 * 6 * Licensed under the Academic Free License version 2.1 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24#include "dbus/dbus-shared.h" 25#include "dbus-marshal-header.h" 26#include "dbus-marshal-recursive.h" 27#include "dbus-marshal-byteswap.h" 28 29/** 30 * @addtogroup DBusMarshal 31 * 32 * @{ 33 */ 34 35 36/* Not thread locked, but strictly const/read-only so should be OK 37 */ 38/** Static #DBusString containing the signature of a message header */ 39_DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE); 40/** Static #DBusString containing the local interface */ 41_DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_LOCAL); 42/** Static #DBusString containing the local path */ 43_DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_LOCAL); 44 45/** Offset from start of _dbus_header_signature_str to the signature of the fields array */ 46#define FIELDS_ARRAY_SIGNATURE_OFFSET 6 47/** Offset from start of _dbus_header_signature_str to the signature of an element of the fields array */ 48#define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7 49 50 51/** Offset to byte order from start of header */ 52#define BYTE_ORDER_OFFSET 0 53/** Offset to type from start of header */ 54#define TYPE_OFFSET 1 55/** Offset to flags from start of header */ 56#define FLAGS_OFFSET 2 57/** Offset to version from start of header */ 58#define VERSION_OFFSET 3 59/** Offset to body length from start of header */ 60#define BODY_LENGTH_OFFSET 4 61/** Offset to client serial from start of header */ 62#define SERIAL_OFFSET 8 63/** Offset to fields array length from start of header */ 64#define FIELDS_ARRAY_LENGTH_OFFSET 12 65/** Offset to first field in header */ 66#define FIRST_FIELD_OFFSET 16 67 68typedef struct 69{ 70 unsigned char code; /**< the field code */ 71 unsigned char type; /**< the value type */ 72} HeaderFieldType; 73 74static const HeaderFieldType 75_dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = { 76 { DBUS_HEADER_FIELD_INVALID, DBUS_TYPE_INVALID }, 77 { DBUS_HEADER_FIELD_PATH, DBUS_TYPE_OBJECT_PATH }, 78 { DBUS_HEADER_FIELD_INTERFACE, DBUS_TYPE_STRING }, 79 { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING }, 80 { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING }, 81 { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 }, 82 { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING }, 83 { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING }, 84 { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE } 85}; 86 87/** Macro to look up the correct type for a field */ 88#define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type) 89 90/** The most padding we could ever need for a header */ 91#define MAX_POSSIBLE_HEADER_PADDING 7 92static dbus_bool_t 93reserve_header_padding (DBusHeader *header) 94{ 95 _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING); 96 97 if (!_dbus_string_lengthen (&header->data, 98 MAX_POSSIBLE_HEADER_PADDING - header->padding)) 99 return FALSE; 100 header->padding = MAX_POSSIBLE_HEADER_PADDING; 101 return TRUE; 102} 103 104static void 105correct_header_padding (DBusHeader *header) 106{ 107 int unpadded_len; 108 109 _dbus_assert (header->padding == 7); 110 111 _dbus_string_shorten (&header->data, header->padding); 112 unpadded_len = _dbus_string_get_length (&header->data); 113 114 if (!_dbus_string_align_length (&header->data, 8)) 115 _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated"); 116 117 header->padding = _dbus_string_get_length (&header->data) - unpadded_len; 118} 119 120/** Compute the end of the header, ignoring padding */ 121#define HEADER_END_BEFORE_PADDING(header) \ 122 (_dbus_string_get_length (&(header)->data) - (header)->padding) 123 124/** 125 * Invalidates all fields in the cache. This may be used when the 126 * cache is totally uninitialized (contains junk) so should not 127 * look at what's in there now. 128 * 129 * @param header the header 130 */ 131static void 132_dbus_header_cache_invalidate_all (DBusHeader *header) 133{ 134 int i; 135 136 i = 0; 137 while (i <= DBUS_HEADER_FIELD_LAST) 138 { 139 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN; 140 ++i; 141 } 142} 143 144/** 145 * Caches one field 146 * 147 * @param header the header 148 * @param field_code the field 149 * @param variant_reader the reader for the variant in the field 150 */ 151static void 152_dbus_header_cache_one (DBusHeader *header, 153 int field_code, 154 DBusTypeReader *variant_reader) 155{ 156 header->fields[field_code].value_pos = 157 _dbus_type_reader_get_value_pos (variant_reader); 158 159#if 0 160 _dbus_verbose ("cached value_pos %d for field %d\n", 161 header->fields[field_code].value_pos, field_code) 162#endif 163} 164 165/** 166 * Revalidates the fields cache 167 * 168 * @param header the header 169 */ 170static void 171_dbus_header_cache_revalidate (DBusHeader *header) 172{ 173 DBusTypeReader array; 174 DBusTypeReader reader; 175 int i; 176 177 i = 0; 178 while (i <= DBUS_HEADER_FIELD_LAST) 179 { 180 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT; 181 ++i; 182 } 183 184 _dbus_type_reader_init (&reader, 185 header->byte_order, 186 &_dbus_header_signature_str, 187 FIELDS_ARRAY_SIGNATURE_OFFSET, 188 &header->data, 189 FIELDS_ARRAY_LENGTH_OFFSET); 190 191 _dbus_type_reader_recurse (&reader, &array); 192 193 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID) 194 { 195 DBusTypeReader sub; 196 DBusTypeReader variant; 197 unsigned char field_code; 198 199 _dbus_type_reader_recurse (&array, &sub); 200 201 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE); 202 _dbus_type_reader_read_basic (&sub, &field_code); 203 204 /* Unknown fields should be ignored */ 205 if (field_code > DBUS_HEADER_FIELD_LAST) 206 goto next_field; 207 208 _dbus_type_reader_next (&sub); 209 210 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT); 211 _dbus_type_reader_recurse (&sub, &variant); 212 213 _dbus_header_cache_one (header, field_code, &variant); 214 215 next_field: 216 _dbus_type_reader_next (&array); 217 } 218} 219 220/** 221 * Checks for a field, updating the cache if required. 222 * 223 * @param header the header 224 * @param field the field to check 225 * @returns #FALSE if the field doesn't exist 226 */ 227static dbus_bool_t 228_dbus_header_cache_check (DBusHeader *header, 229 int field) 230{ 231 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 232 233 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN) 234 _dbus_header_cache_revalidate (header); 235 236 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT) 237 return FALSE; 238 239 return TRUE; 240} 241 242/** 243 * Checks whether a field is known not to exist. It may exist 244 * even if it's not known to exist. 245 * 246 * @param header the header 247 * @param field the field to check 248 * @returns #FALSE if the field definitely doesn't exist 249 */ 250static dbus_bool_t 251_dbus_header_cache_known_nonexistent (DBusHeader *header, 252 int field) 253{ 254 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 255 256 return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT); 257} 258 259/** 260 * Writes a struct of { byte, variant } with the given basic type. 261 * 262 * @param writer the writer (should be ready to write a struct) 263 * @param type the type of the value 264 * @param value the value as for _dbus_marshal_set_basic() 265 * @returns #FALSE if no memory 266 */ 267static dbus_bool_t 268write_basic_field (DBusTypeWriter *writer, 269 int field, 270 int type, 271 const void *value) 272{ 273 DBusTypeWriter sub; 274 DBusTypeWriter variant; 275 int start; 276 int padding; 277 unsigned char field_byte; 278 DBusString contained_type; 279 char buf[2]; 280 281 start = writer->value_pos; 282 padding = _dbus_string_get_length (writer->value_str) - start; 283 284 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT, 285 NULL, 0, &sub)) 286 goto append_failed; 287 288 field_byte = field; 289 if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE, 290 &field_byte)) 291 goto append_failed; 292 293 buf[0] = type; 294 buf[1] = '\0'; 295 _dbus_string_init_const_len (&contained_type, buf, 1); 296 297 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT, 298 &contained_type, 0, &variant)) 299 goto append_failed; 300 301 if (!_dbus_type_writer_write_basic (&variant, type, value)) 302 goto append_failed; 303 304 if (!_dbus_type_writer_unrecurse (&sub, &variant)) 305 goto append_failed; 306 307 if (!_dbus_type_writer_unrecurse (writer, &sub)) 308 goto append_failed; 309 310 return TRUE; 311 312 append_failed: 313 _dbus_string_delete (writer->value_str, 314 start, 315 _dbus_string_get_length (writer->value_str) - start - padding); 316 return FALSE; 317} 318 319/** 320 * Sets a struct of { byte, variant } with the given basic type. 321 * 322 * @param reader the reader (should be iterating over the array pointing at the field to set) 323 * @param type the type of the value 324 * @param value the value as for _dbus_marshal_set_basic() 325 * @param realign_root where to realign from 326 * @returns #FALSE if no memory 327 */ 328static dbus_bool_t 329set_basic_field (DBusTypeReader *reader, 330 int field, 331 int type, 332 const void *value, 333 const DBusTypeReader *realign_root) 334{ 335 DBusTypeReader sub; 336 DBusTypeReader variant; 337 338 _dbus_type_reader_recurse (reader, &sub); 339 340 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE); 341#ifndef DBUS_DISABLE_ASSERT 342 { 343 unsigned char v_BYTE; 344 _dbus_type_reader_read_basic (&sub, &v_BYTE); 345 _dbus_assert (((int) v_BYTE) == field); 346 } 347#endif 348 349 if (!_dbus_type_reader_next (&sub)) 350 _dbus_assert_not_reached ("no variant field?"); 351 352 _dbus_type_reader_recurse (&sub, &variant); 353 _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type); 354 355 if (!_dbus_type_reader_set_basic (&variant, value, realign_root)) 356 return FALSE; 357 358 return TRUE; 359} 360 361/** 362 * Gets the type of the message. 363 * 364 * @param header the header 365 * @returns the type 366 */ 367int 368_dbus_header_get_message_type (DBusHeader *header) 369{ 370 int type; 371 372 type = _dbus_string_get_byte (&header->data, TYPE_OFFSET); 373 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID); 374 375 return type; 376} 377 378/** 379 * Sets the serial number of a header. This can only be done once on 380 * a header. 381 * 382 * @param header the header 383 * @param serial the serial 384 */ 385void 386_dbus_header_set_serial (DBusHeader *header, 387 dbus_uint32_t serial) 388{ 389 /* we use this function to set the serial on outgoing 390 * messages, and to reset the serial in dbus_message_copy; 391 * this assertion should catch a double-set on outgoing. 392 */ 393 _dbus_assert (_dbus_header_get_serial (header) == 0 || 394 serial == 0); 395 396 _dbus_marshal_set_uint32 (&header->data, 397 SERIAL_OFFSET, 398 serial, 399 header->byte_order); 400} 401 402/** 403 * See dbus_message_get_serial() 404 * 405 * @param header the header 406 * @returns the client serial 407 */ 408dbus_uint32_t 409_dbus_header_get_serial (DBusHeader *header) 410{ 411 return _dbus_marshal_read_uint32 (&header->data, 412 SERIAL_OFFSET, 413 header->byte_order, 414 NULL); 415} 416 417/** 418 * Re-initializes a header that was previously initialized and never 419 * freed. After this, to make the header valid you have to call 420 * _dbus_header_create(). 421 * 422 * @param header header to re-initialize 423 * @param byte_order byte order of the header 424 */ 425void 426_dbus_header_reinit (DBusHeader *header, 427 int byte_order) 428{ 429 _dbus_string_set_length (&header->data, 0); 430 431 header->byte_order = byte_order; 432 header->padding = 0; 433 434 _dbus_header_cache_invalidate_all (header); 435} 436 437/** 438 * Initializes a header, but doesn't prepare it for use; 439 * to make the header valid, you have to call _dbus_header_create(). 440 * 441 * @param header header to initialize 442 * @param byte_order byte order of the header 443 * @returns #FALSE if not enough memory 444 */ 445dbus_bool_t 446_dbus_header_init (DBusHeader *header, 447 int byte_order) 448{ 449 if (!_dbus_string_init_preallocated (&header->data, 32)) 450 return FALSE; 451 452 _dbus_header_reinit (header, byte_order); 453 454 return TRUE; 455} 456 457/** 458 * Frees a header. 459 * 460 * @param header the header 461 */ 462void 463_dbus_header_free (DBusHeader *header) 464{ 465 _dbus_string_free (&header->data); 466} 467 468/** 469 * Initializes dest with a copy of the given header. 470 * Resets the message serial to 0 on the copy. 471 * 472 * @param header header to copy 473 * @param dest destination for copy 474 * @returns #FALSE if not enough memory 475 */ 476dbus_bool_t 477_dbus_header_copy (const DBusHeader *header, 478 DBusHeader *dest) 479{ 480 *dest = *header; 481 482 if (!_dbus_string_init_preallocated (&dest->data, 483 _dbus_string_get_length (&header->data))) 484 return FALSE; 485 486 if (!_dbus_string_copy (&header->data, 0, &dest->data, 0)) 487 { 488 _dbus_string_free (&dest->data); 489 return FALSE; 490 } 491 492 /* Reset the serial */ 493 _dbus_header_set_serial (dest, 0); 494 495 return TRUE; 496} 497 498/** 499 * Fills in the primary fields of the header, so the header is ready 500 * for use. #NULL may be specified for some or all of the fields to 501 * avoid adding those fields. Some combinations of fields don't make 502 * sense, and passing them in will trigger an assertion failure. 503 * 504 * @param header the header 505 * @param message_type the message type 506 * @param destination destination field or #NULL 507 * @param path path field or #NULL 508 * @param interface interface field or #NULL 509 * @param member member field or #NULL 510 * @param error_name error name or #NULL 511 * @returns #FALSE if not enough memory 512 */ 513dbus_bool_t 514_dbus_header_create (DBusHeader *header, 515 int message_type, 516 const char *destination, 517 const char *path, 518 const char *interface, 519 const char *member, 520 const char *error_name) 521{ 522 unsigned char v_BYTE; 523 dbus_uint32_t v_UINT32; 524 DBusTypeWriter writer; 525 DBusTypeWriter array; 526 527 _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) || 528 (error_name) || 529 !(interface || member || error_name)); 530 _dbus_assert (_dbus_string_get_length (&header->data) == 0); 531 532 if (!reserve_header_padding (header)) 533 return FALSE; 534 535 _dbus_type_writer_init_values_only (&writer, header->byte_order, 536 &_dbus_header_signature_str, 0, 537 &header->data, 538 HEADER_END_BEFORE_PADDING (header)); 539 540 v_BYTE = header->byte_order; 541 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 542 &v_BYTE)) 543 goto oom; 544 545 v_BYTE = message_type; 546 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 547 &v_BYTE)) 548 goto oom; 549 550 v_BYTE = 0; /* flags */ 551 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 552 &v_BYTE)) 553 goto oom; 554 555 v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION; 556 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, 557 &v_BYTE)) 558 goto oom; 559 560 v_UINT32 = 0; /* body length */ 561 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32, 562 &v_UINT32)) 563 goto oom; 564 565 v_UINT32 = 0; /* serial */ 566 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32, 567 &v_UINT32)) 568 goto oom; 569 570 if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY, 571 &_dbus_header_signature_str, 572 FIELDS_ARRAY_SIGNATURE_OFFSET, 573 &array)) 574 goto oom; 575 576 /* Marshal all the fields (Marshall Fields?) */ 577 578 if (path != NULL) 579 { 580 if (!write_basic_field (&array, 581 DBUS_HEADER_FIELD_PATH, 582 DBUS_TYPE_OBJECT_PATH, 583 &path)) 584 goto oom; 585 } 586 587 if (destination != NULL) 588 { 589 if (!write_basic_field (&array, 590 DBUS_HEADER_FIELD_DESTINATION, 591 DBUS_TYPE_STRING, 592 &destination)) 593 goto oom; 594 } 595 596 if (interface != NULL) 597 { 598 if (!write_basic_field (&array, 599 DBUS_HEADER_FIELD_INTERFACE, 600 DBUS_TYPE_STRING, 601 &interface)) 602 goto oom; 603 } 604 605 if (member != NULL) 606 { 607 if (!write_basic_field (&array, 608 DBUS_HEADER_FIELD_MEMBER, 609 DBUS_TYPE_STRING, 610 &member)) 611 goto oom; 612 } 613 614 if (error_name != NULL) 615 { 616 if (!write_basic_field (&array, 617 DBUS_HEADER_FIELD_ERROR_NAME, 618 DBUS_TYPE_STRING, 619 &error_name)) 620 goto oom; 621 } 622 623 if (!_dbus_type_writer_unrecurse (&writer, &array)) 624 goto oom; 625 626 correct_header_padding (header); 627 628 return TRUE; 629 630 oom: 631 _dbus_string_delete (&header->data, 0, 632 _dbus_string_get_length (&header->data) - header->padding); 633 correct_header_padding (header); 634 635 return FALSE; 636} 637 638/** 639 * Given data long enough to contain the length of the message body 640 * and the fields array, check whether the data is long enough to 641 * contain the entire message (assuming the claimed lengths are 642 * accurate). Also checks that the lengths are in sanity parameters. 643 * 644 * @param max_message_length maximum length of a valid message 645 * @param validity return location for why the data is invalid if it is 646 * @param byte_order return location for byte order 647 * @param fields_array_len return location for claimed fields array length 648 * @param header_len return location for claimed header length 649 * @param body_len return location for claimed body length 650 * @param str the data 651 * @param start start of data, 8-aligned 652 * @param len length of data 653 * @returns #TRUE if the data is long enough for the claimed length, and the lengths were valid 654 */ 655dbus_bool_t 656_dbus_header_have_message_untrusted (int max_message_length, 657 DBusValidity *validity, 658 int *byte_order, 659 int *fields_array_len, 660 int *header_len, 661 int *body_len, 662 const DBusString *str, 663 int start, 664 int len) 665 666{ 667 dbus_uint32_t header_len_unsigned; 668 dbus_uint32_t fields_array_len_unsigned; 669 dbus_uint32_t body_len_unsigned; 670 671 _dbus_assert (start >= 0); 672 _dbus_assert (start < _DBUS_INT32_MAX / 2); 673 _dbus_assert (len >= 0); 674 675 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8)); 676 677 *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET); 678 679 if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN) 680 { 681 *validity = DBUS_INVALID_BAD_BYTE_ORDER; 682 return FALSE; 683 } 684 685 _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len); 686 fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET, 687 *byte_order, NULL); 688 689 if (fields_array_len_unsigned > (unsigned) max_message_length) 690 { 691 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH; 692 return FALSE; 693 } 694 695 _dbus_assert (BODY_LENGTH_OFFSET + 4 < len); 696 body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET, 697 *byte_order, NULL); 698 699 if (body_len_unsigned > (unsigned) max_message_length) 700 { 701 *validity = DBUS_INVALID_INSANE_BODY_LENGTH; 702 return FALSE; 703 } 704 705 header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned; 706 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8); 707 708 /* overflow should be impossible since the lengths aren't allowed to 709 * be huge. 710 */ 711 _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2); 712 if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length) 713 { 714 *validity = DBUS_INVALID_MESSAGE_TOO_LONG; 715 return FALSE; 716 } 717 718 _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX); 719 _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX); 720 _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX); 721 722 *body_len = body_len_unsigned; 723 *fields_array_len = fields_array_len_unsigned; 724 *header_len = header_len_unsigned; 725 726 *validity = DBUS_VALID; 727 728 _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n", 729 len, body_len_unsigned, header_len_unsigned, 730 body_len_unsigned + header_len_unsigned); 731 732 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len; 733} 734 735static DBusValidity 736check_mandatory_fields (DBusHeader *header) 737{ 738#define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0) 739 740 switch (_dbus_header_get_message_type (header)) 741 { 742 case DBUS_MESSAGE_TYPE_SIGNAL: 743 REQUIRE_FIELD (INTERFACE); 744 /* FALL THRU - signals also require the path and member */ 745 case DBUS_MESSAGE_TYPE_METHOD_CALL: 746 REQUIRE_FIELD (PATH); 747 REQUIRE_FIELD (MEMBER); 748 break; 749 case DBUS_MESSAGE_TYPE_ERROR: 750 REQUIRE_FIELD (ERROR_NAME); 751 REQUIRE_FIELD (REPLY_SERIAL); 752 break; 753 case DBUS_MESSAGE_TYPE_METHOD_RETURN: 754 REQUIRE_FIELD (REPLY_SERIAL); 755 break; 756 default: 757 /* other message types allowed but ignored */ 758 break; 759 } 760 761 return DBUS_VALID; 762} 763 764static DBusValidity 765load_and_validate_field (DBusHeader *header, 766 int field, 767 DBusTypeReader *variant_reader) 768{ 769 int type; 770 int expected_type; 771 const DBusString *value_str; 772 int value_pos; 773 int str_data_pos; 774 dbus_uint32_t v_UINT32; 775 int bad_string_code; 776 dbus_bool_t (* string_validation_func) (const DBusString *str, 777 int start, int len); 778 779 /* Supposed to have been checked already */ 780 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 781 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID); 782 783 /* Before we can cache a field, we need to know it has the right type */ 784 type = _dbus_type_reader_get_current_type (variant_reader); 785 786 _dbus_assert (_dbus_header_field_types[field].code == field); 787 788 expected_type = EXPECTED_TYPE_OF_FIELD (field); 789 if (type != expected_type) 790 { 791 _dbus_verbose ("Field %d should have type %d but has %d\n", 792 field, expected_type, type); 793 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE; 794 } 795 796 /* If the field was provided twice, we aren't happy */ 797 if (header->fields[field].value_pos >= 0) 798 { 799 _dbus_verbose ("Header field %d seen a second time\n", field); 800 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE; 801 } 802 803 /* Now we can cache and look at the field content */ 804 _dbus_verbose ("initially caching field %d\n", field); 805 _dbus_header_cache_one (header, field, variant_reader); 806 807 string_validation_func = NULL; 808 809 /* make compiler happy that all this is initialized */ 810 v_UINT32 = 0; 811 value_str = NULL; 812 value_pos = -1; 813 str_data_pos = -1; 814 bad_string_code = DBUS_VALID; 815 816 if (expected_type == DBUS_TYPE_UINT32) 817 { 818 _dbus_header_get_field_basic (header, field, expected_type, 819 &v_UINT32); 820 } 821 else if (expected_type == DBUS_TYPE_STRING || 822 expected_type == DBUS_TYPE_OBJECT_PATH || 823 expected_type == DBUS_TYPE_SIGNATURE) 824 { 825 _dbus_header_get_field_raw (header, field, 826 &value_str, &value_pos); 827 str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4; 828 } 829 else 830 { 831 _dbus_assert_not_reached ("none of the known fields should have this type"); 832 } 833 834 switch (field) 835 { 836 case DBUS_HEADER_FIELD_DESTINATION: 837 string_validation_func = _dbus_validate_bus_name; 838 bad_string_code = DBUS_INVALID_BAD_DESTINATION; 839 break; 840 case DBUS_HEADER_FIELD_INTERFACE: 841 string_validation_func = _dbus_validate_interface; 842 bad_string_code = DBUS_INVALID_BAD_INTERFACE; 843 844 if (_dbus_string_equal_substring (&_dbus_local_interface_str, 845 0, 846 _dbus_string_get_length (&_dbus_local_interface_str), 847 value_str, str_data_pos)) 848 { 849 _dbus_verbose ("Message is on the local interface\n"); 850 return DBUS_INVALID_USES_LOCAL_INTERFACE; 851 } 852 break; 853 854 case DBUS_HEADER_FIELD_MEMBER: 855 string_validation_func = _dbus_validate_member; 856 bad_string_code = DBUS_INVALID_BAD_MEMBER; 857 break; 858 859 case DBUS_HEADER_FIELD_ERROR_NAME: 860 string_validation_func = _dbus_validate_error_name; 861 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME; 862 break; 863 864 case DBUS_HEADER_FIELD_SENDER: 865 string_validation_func = _dbus_validate_bus_name; 866 bad_string_code = DBUS_INVALID_BAD_SENDER; 867 break; 868 869 case DBUS_HEADER_FIELD_PATH: 870 /* OBJECT_PATH was validated generically due to its type */ 871 string_validation_func = NULL; 872 873 if (_dbus_string_equal_substring (&_dbus_local_path_str, 874 0, 875 _dbus_string_get_length (&_dbus_local_path_str), 876 value_str, str_data_pos)) 877 { 878 _dbus_verbose ("Message is from the local path\n"); 879 return DBUS_INVALID_USES_LOCAL_PATH; 880 } 881 break; 882 883 case DBUS_HEADER_FIELD_REPLY_SERIAL: 884 /* Can't be 0 */ 885 if (v_UINT32 == 0) 886 { 887 return DBUS_INVALID_BAD_SERIAL; 888 } 889 break; 890 891 case DBUS_HEADER_FIELD_SIGNATURE: 892 /* SIGNATURE validated generically due to its type */ 893 string_validation_func = NULL; 894 break; 895 896 default: 897 _dbus_assert_not_reached ("unknown field shouldn't be seen here"); 898 break; 899 } 900 901 if (string_validation_func) 902 { 903 dbus_uint32_t len; 904 905 _dbus_assert (bad_string_code != DBUS_VALID); 906 907 len = _dbus_marshal_read_uint32 (value_str, value_pos, 908 header->byte_order, NULL); 909 910#if 0 911 _dbus_verbose ("Validating string header field; code %d if fails\n", 912 bad_string_code); 913#endif 914 if (!(*string_validation_func) (value_str, str_data_pos, len)) 915 return bad_string_code; 916 } 917 918 return DBUS_VALID; 919} 920 921/** 922 * Creates a message header from potentially-untrusted data. The 923 * return value is #TRUE if there was enough memory and the data was 924 * valid. If it returns #TRUE, the header will be created. If it 925 * returns #FALSE and *validity == #DBUS_VALIDITY_UNKNOWN_OOM_ERROR, 926 * then there wasn't enough memory. If it returns #FALSE 927 * and *validity != #DBUS_VALIDITY_UNKNOWN_OOM_ERROR then the data was 928 * invalid. 929 * 930 * The byte_order, fields_array_len, and body_len args should be from 931 * _dbus_header_have_message_untrusted(). Validation performed in 932 * _dbus_header_have_message_untrusted() is assumed to have been 933 * already done. 934 * 935 * @param header the header (must be initialized) 936 * @param mode whether to do validation 937 * @param validity return location for invalidity reason 938 * @param byte_order byte order from header 939 * @param fields_array_len claimed length of fields array 940 * @param body_len claimed length of body 941 * @param header_len claimed length of header 942 * @param str a string 943 * @param start start of header, 8-aligned 944 * @param len length of string to look at 945 * @returns #FALSE if no memory or data was invalid, #TRUE otherwise 946 */ 947dbus_bool_t 948_dbus_header_load (DBusHeader *header, 949 DBusValidationMode mode, 950 DBusValidity *validity, 951 int byte_order, 952 int fields_array_len, 953 int header_len, 954 int body_len, 955 const DBusString *str, 956 int start, 957 int len) 958{ 959 int leftover; 960 DBusValidity v; 961 DBusTypeReader reader; 962 DBusTypeReader array_reader; 963 unsigned char v_byte; 964 dbus_uint32_t v_uint32; 965 dbus_uint32_t serial; 966 int padding_start; 967 int padding_len; 968 int i; 969 970 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8)); 971 _dbus_assert (header_len <= len); 972 _dbus_assert (_dbus_string_get_length (&header->data) == 0); 973 974 if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0)) 975 { 976 _dbus_verbose ("Failed to copy buffer into new header\n"); 977 *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; 978 return FALSE; 979 } 980 981 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) 982 { 983 leftover = len - header_len - body_len - start; 984 } 985 else 986 { 987 v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0, 988 byte_order, 989 &leftover, 990 str, start, len); 991 992 if (v != DBUS_VALID) 993 { 994 *validity = v; 995 goto invalid; 996 } 997 } 998 999 _dbus_assert (leftover < len); 1000 1001 padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len); 1002 padding_start = start + FIRST_FIELD_OFFSET + fields_array_len; 1003 _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8)); 1004 _dbus_assert (start + header_len == padding_start + padding_len); 1005 1006 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) 1007 { 1008 if (!_dbus_string_validate_nul (str, padding_start, padding_len)) 1009 { 1010 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL; 1011 goto invalid; 1012 } 1013 } 1014 1015 header->padding = padding_len; 1016 1017 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) 1018 { 1019 *validity = DBUS_VALID; 1020 return TRUE; 1021 } 1022 1023 /* We now know the data is well-formed, but we have to check that 1024 * it's valid. 1025 */ 1026 1027 _dbus_type_reader_init (&reader, 1028 byte_order, 1029 &_dbus_header_signature_str, 0, 1030 str, start); 1031 1032 /* BYTE ORDER */ 1033 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 1034 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET); 1035 _dbus_type_reader_read_basic (&reader, &v_byte); 1036 _dbus_type_reader_next (&reader); 1037 1038 _dbus_assert (v_byte == byte_order); 1039 header->byte_order = byte_order; 1040 1041 /* MESSAGE TYPE */ 1042 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 1043 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET); 1044 _dbus_type_reader_read_basic (&reader, &v_byte); 1045 _dbus_type_reader_next (&reader); 1046 1047 /* unknown message types are supposed to be ignored, so only validation here is 1048 * that it isn't invalid 1049 */ 1050 if (v_byte == DBUS_MESSAGE_TYPE_INVALID) 1051 { 1052 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE; 1053 goto invalid; 1054 } 1055 1056 /* FLAGS */ 1057 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 1058 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET); 1059 _dbus_type_reader_read_basic (&reader, &v_byte); 1060 _dbus_type_reader_next (&reader); 1061 1062 /* unknown flags should be ignored */ 1063 1064 /* PROTOCOL VERSION */ 1065 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); 1066 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET); 1067 _dbus_type_reader_read_basic (&reader, &v_byte); 1068 _dbus_type_reader_next (&reader); 1069 1070 if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION) 1071 { 1072 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION; 1073 goto invalid; 1074 } 1075 1076 /* BODY LENGTH */ 1077 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32); 1078 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET); 1079 _dbus_type_reader_read_basic (&reader, &v_uint32); 1080 _dbus_type_reader_next (&reader); 1081 1082 _dbus_assert (body_len == (signed) v_uint32); 1083 1084 /* SERIAL */ 1085 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32); 1086 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET); 1087 _dbus_type_reader_read_basic (&reader, &serial); 1088 _dbus_type_reader_next (&reader); 1089 1090 if (serial == 0) 1091 { 1092 *validity = DBUS_INVALID_BAD_SERIAL; 1093 goto invalid; 1094 } 1095 1096 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY); 1097 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET); 1098 1099 _dbus_type_reader_recurse (&reader, &array_reader); 1100 while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID) 1101 { 1102 DBusTypeReader struct_reader; 1103 DBusTypeReader variant_reader; 1104 unsigned char field_code; 1105 1106 _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT); 1107 1108 _dbus_type_reader_recurse (&array_reader, &struct_reader); 1109 1110 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE); 1111 _dbus_type_reader_read_basic (&struct_reader, &field_code); 1112 _dbus_type_reader_next (&struct_reader); 1113 1114 if (field_code == DBUS_HEADER_FIELD_INVALID) 1115 { 1116 _dbus_verbose ("invalid header field code\n"); 1117 *validity = DBUS_INVALID_HEADER_FIELD_CODE; 1118 goto invalid; 1119 } 1120 1121 if (field_code > DBUS_HEADER_FIELD_LAST) 1122 { 1123 _dbus_verbose ("unknown header field code %d, skipping\n", 1124 field_code); 1125 goto next_field; 1126 } 1127 1128 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT); 1129 _dbus_type_reader_recurse (&struct_reader, &variant_reader); 1130 1131 v = load_and_validate_field (header, field_code, &variant_reader); 1132 if (v != DBUS_VALID) 1133 { 1134 _dbus_verbose ("Field %d was invalid\n", field_code); 1135 *validity = v; 1136 goto invalid; 1137 } 1138 1139 next_field: 1140 _dbus_type_reader_next (&array_reader); 1141 } 1142 1143 /* Anything we didn't fill in is now known not to exist */ 1144 i = 0; 1145 while (i <= DBUS_HEADER_FIELD_LAST) 1146 { 1147 if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN) 1148 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT; 1149 ++i; 1150 } 1151 1152 v = check_mandatory_fields (header); 1153 if (v != DBUS_VALID) 1154 { 1155 _dbus_verbose ("Mandatory fields were missing, code %d\n", v); 1156 *validity = v; 1157 goto invalid; 1158 } 1159 1160 *validity = DBUS_VALID; 1161 return TRUE; 1162 1163 invalid: 1164 _dbus_string_set_length (&header->data, 0); 1165 return FALSE; 1166} 1167 1168/** 1169 * Fills in the correct body length. 1170 * 1171 * @param header the header 1172 * @param body_len the length of the body 1173 */ 1174void 1175_dbus_header_update_lengths (DBusHeader *header, 1176 int body_len) 1177{ 1178 _dbus_marshal_set_uint32 (&header->data, 1179 BODY_LENGTH_OFFSET, 1180 body_len, 1181 header->byte_order); 1182} 1183 1184static dbus_bool_t 1185find_field_for_modification (DBusHeader *header, 1186 int field, 1187 DBusTypeReader *reader, 1188 DBusTypeReader *realign_root) 1189{ 1190 dbus_bool_t retval; 1191 1192 retval = FALSE; 1193 1194 _dbus_type_reader_init (realign_root, 1195 header->byte_order, 1196 &_dbus_header_signature_str, 1197 FIELDS_ARRAY_SIGNATURE_OFFSET, 1198 &header->data, 1199 FIELDS_ARRAY_LENGTH_OFFSET); 1200 1201 _dbus_type_reader_recurse (realign_root, reader); 1202 1203 while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID) 1204 { 1205 DBusTypeReader sub; 1206 unsigned char field_code; 1207 1208 _dbus_type_reader_recurse (reader, &sub); 1209 1210 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE); 1211 _dbus_type_reader_read_basic (&sub, &field_code); 1212 1213 if (field_code == (unsigned) field) 1214 { 1215 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT); 1216 retval = TRUE; 1217 goto done; 1218 } 1219 1220 _dbus_type_reader_next (reader); 1221 } 1222 1223 done: 1224 return retval; 1225} 1226 1227/** 1228 * Sets the value of a field with basic type. If the value is a string 1229 * value, it isn't allowed to be #NULL. If the field doesn't exist, 1230 * it will be created. 1231 * 1232 * @param header the header 1233 * @param field the field to set 1234 * @param type the type of the value 1235 * @param value the value as for _dbus_marshal_set_basic() 1236 * @returns #FALSE if no memory 1237 */ 1238dbus_bool_t 1239_dbus_header_set_field_basic (DBusHeader *header, 1240 int field, 1241 int type, 1242 const void *value) 1243{ 1244 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 1245 1246 if (!reserve_header_padding (header)) 1247 return FALSE; 1248 1249 /* If the field exists we set, otherwise we append */ 1250 if (_dbus_header_cache_check (header, field)) 1251 { 1252 DBusTypeReader reader; 1253 DBusTypeReader realign_root; 1254 1255 if (!find_field_for_modification (header, field, 1256 &reader, &realign_root)) 1257 _dbus_assert_not_reached ("field was marked present in cache but wasn't found"); 1258 1259 if (!set_basic_field (&reader, field, type, value, &realign_root)) 1260 return FALSE; 1261 } 1262 else 1263 { 1264 DBusTypeWriter writer; 1265 DBusTypeWriter array; 1266 1267 _dbus_type_writer_init_values_only (&writer, 1268 header->byte_order, 1269 &_dbus_header_signature_str, 1270 FIELDS_ARRAY_SIGNATURE_OFFSET, 1271 &header->data, 1272 FIELDS_ARRAY_LENGTH_OFFSET); 1273 1274 /* recurse into array without creating a new length, and jump to 1275 * end of array. 1276 */ 1277 if (!_dbus_type_writer_append_array (&writer, 1278 &_dbus_header_signature_str, 1279 FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET, 1280 &array)) 1281 _dbus_assert_not_reached ("recurse into ARRAY should not have used memory"); 1282 1283 _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET); 1284 _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET); 1285 _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header)); 1286 1287 if (!write_basic_field (&array, 1288 field, type, value)) 1289 return FALSE; 1290 1291 if (!_dbus_type_writer_unrecurse (&writer, &array)) 1292 _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory"); 1293 } 1294 1295 correct_header_padding (header); 1296 1297 /* We could be smarter about this (only invalidate fields after the 1298 * one we modified, or even only if the one we modified changed 1299 * length). But this hack is a start. 1300 */ 1301 _dbus_header_cache_invalidate_all (header); 1302 1303 return TRUE; 1304} 1305 1306/** 1307 * Gets the value of a field with basic type. If the field 1308 * doesn't exist, returns #FALSE, otherwise returns #TRUE. 1309 * 1310 * @param header the header 1311 * @param field the field to get 1312 * @param type the type of the value 1313 * @param value the value as for _dbus_marshal_read_basic() 1314 * @returns #FALSE if the field doesn't exist 1315 */ 1316dbus_bool_t 1317_dbus_header_get_field_basic (DBusHeader *header, 1318 int field, 1319 int type, 1320 void *value) 1321{ 1322 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID); 1323 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST); 1324 _dbus_assert (_dbus_header_field_types[field].code == field); 1325 /* in light of this you might ask why the type is passed in; 1326 * the only rationale I can think of is so the caller has 1327 * to specify its expectation and breaks if we change it 1328 */ 1329 _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field)); 1330 1331 if (!_dbus_header_cache_check (header, field)) 1332 return FALSE; 1333 1334 _dbus_assert (header->fields[field].value_pos >= 0); 1335 1336 _dbus_marshal_read_basic (&header->data, 1337 header->fields[field].value_pos, 1338 type, value, header->byte_order, 1339 NULL); 1340 1341 return TRUE; 1342} 1343 1344/** 1345 * Gets the raw marshaled data for a field. If the field doesn't 1346 * exist, returns #FALSE, otherwise returns #TRUE. Returns the start 1347 * of the marshaled data, i.e. usually the byte where the length 1348 * starts (for strings and arrays) or for basic types just the value 1349 * itself. 1350 * 1351 * @param header the header 1352 * @param field the field to get 1353 * @param str return location for the data string 1354 * @param pos return location for start of field value 1355 * @returns #FALSE if the field doesn't exist 1356 */ 1357dbus_bool_t 1358_dbus_header_get_field_raw (DBusHeader *header, 1359 int field, 1360 const DBusString **str, 1361 int *pos) 1362{ 1363 if (!_dbus_header_cache_check (header, field)) 1364 return FALSE; 1365 1366 if (str) 1367 *str = &header->data; 1368 if (pos) 1369 *pos = header->fields[field].value_pos; 1370 1371 return TRUE; 1372} 1373 1374/** 1375 * Deletes a field, if it exists. 1376 * 1377 * @param header the header 1378 * @param field the field to delete 1379 * @returns #FALSE if no memory 1380 */ 1381dbus_bool_t 1382_dbus_header_delete_field (DBusHeader *header, 1383 int field) 1384{ 1385 DBusTypeReader reader; 1386 DBusTypeReader realign_root; 1387 1388 if (_dbus_header_cache_known_nonexistent (header, field)) 1389 return TRUE; /* nothing to do */ 1390 1391 /* Scan to the field we want, delete and realign, reappend 1392 * padding. Field may turn out not to exist. 1393 */ 1394 if (!find_field_for_modification (header, field, 1395 &reader, &realign_root)) 1396 return TRUE; /* nothing to do */ 1397 1398 if (!reserve_header_padding (header)) 1399 return FALSE; 1400 1401 if (!_dbus_type_reader_delete (&reader, 1402 &realign_root)) 1403 return FALSE; 1404 1405 correct_header_padding (header); 1406 1407 _dbus_header_cache_invalidate_all (header); 1408 1409 _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */ 1410 1411 return TRUE; 1412} 1413 1414/** 1415 * Toggles a message flag bit, turning on the bit if value = TRUE and 1416 * flipping it off if value = FALSE. 1417 * 1418 * @param header the header 1419 * @param flag the message flag to toggle 1420 * @param value toggle on or off 1421 */ 1422void 1423_dbus_header_toggle_flag (DBusHeader *header, 1424 dbus_uint32_t flag, 1425 dbus_bool_t value) 1426{ 1427 unsigned char *flags_p; 1428 1429 flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1); 1430 1431 if (value) 1432 *flags_p |= flag; 1433 else 1434 *flags_p &= ~flag; 1435} 1436 1437/** 1438 * Gets a message flag bit, returning TRUE if the bit is set. 1439 * 1440 * @param header the header 1441 * @param flag the message flag to get 1442 * @returns #TRUE if the flag is set 1443 */ 1444dbus_bool_t 1445_dbus_header_get_flag (DBusHeader *header, 1446 dbus_uint32_t flag) 1447{ 1448 const unsigned char *flags_p; 1449 1450 flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1); 1451 1452 return (*flags_p & flag) != 0; 1453} 1454 1455/** 1456 * Swaps the header into the given order if required. 1457 * 1458 * @param header the header 1459 * @param new_order the new byte order 1460 */ 1461void 1462_dbus_header_byteswap (DBusHeader *header, 1463 int new_order) 1464{ 1465 if (header->byte_order == new_order) 1466 return; 1467 1468 _dbus_marshal_byteswap (&_dbus_header_signature_str, 1469 0, header->byte_order, 1470 new_order, 1471 &header->data, 0); 1472 1473 header->byte_order = new_order; 1474} 1475 1476/** @} */ 1477 1478#ifdef DBUS_BUILD_TESTS 1479#include "dbus-test.h" 1480#include <stdio.h> 1481 1482dbus_bool_t 1483_dbus_marshal_header_test (void) 1484{ 1485 1486 return TRUE; 1487} 1488 1489#endif /* DBUS_BUILD_TESTS */ 1490