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