1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-string.c String utility class (internal to D-Bus implementation) 3 * 4 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. 5 * Copyright (C) 2006 Ralf Habacker <ralf.habacker (at) freenet.de> 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #include <config.h> 26 #include "dbus-internals.h" 27 #include "dbus-string.h" 28 /* we allow a system header here, for speed/convenience */ 29 #include <string.h> 30 /* for vsnprintf */ 31 #include <stdio.h> 32 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1 33 #include "dbus-string-private.h" 34 #include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE 35 * into the marshaling-related files 36 */ 37 /* for DBUS_VA_COPY */ 38 #include "dbus-sysdeps.h" 39 40 /** 41 * @defgroup DBusString DBusString class 42 * @ingroup DBusInternals 43 * @brief DBusString data structure for safer string handling 44 * 45 * Types and functions related to DBusString. DBusString is intended 46 * to be a string class that makes it hard to mess up security issues 47 * (and just in general harder to write buggy code). It should be 48 * used (or extended and then used) rather than the libc stuff in 49 * string.h. The string class is a bit inconvenient at spots because 50 * it handles out-of-memory failures and tries to be extra-robust. 51 * 52 * A DBusString has a maximum length set at initialization time; this 53 * can be used to ensure that a buffer doesn't get too big. The 54 * _dbus_string_lengthen() method checks for overflow, and for max 55 * length being exceeded. 56 * 57 * Try to avoid conversion to a plain C string, i.e. add methods on 58 * the string object instead, only convert to C string when passing 59 * things out to the public API. In particular, no sprintf, strcpy, 60 * strcat, any of that should be used. The GString feature of 61 * accepting negative numbers for "length of string" is also absent, 62 * because it could keep us from detecting bogus huge lengths. i.e. if 63 * we passed in some bogus huge length it would be taken to mean 64 * "current length of string" instead of "broken crack" 65 * 66 * @todo #DBusString needs a lot of cleaning up; some of the 67 * API is no longer used, and the API is pretty inconsistent. 68 * In particular all the "append" APIs, especially those involving 69 * alignment but probably lots of them, are no longer used by the 70 * marshaling code which always does "inserts" now. 71 */ 72 73 /** 74 * @addtogroup DBusString 75 * @{ 76 */ 77 78 static void 79 fixup_alignment (DBusRealString *real) 80 { 81 unsigned char *aligned; 82 unsigned char *real_block; 83 unsigned int old_align_offset; 84 85 /* we have to have extra space in real->allocated for the align offset and nul byte */ 86 _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING); 87 88 old_align_offset = real->align_offset; 89 real_block = real->str - old_align_offset; 90 91 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8); 92 93 real->align_offset = aligned - real_block; 94 real->str = aligned; 95 96 if (old_align_offset != real->align_offset) 97 { 98 /* Here comes the suck */ 99 memmove (real_block + real->align_offset, 100 real_block + old_align_offset, 101 real->len + 1); 102 } 103 104 _dbus_assert (real->align_offset < 8); 105 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str); 106 } 107 108 static void 109 undo_alignment (DBusRealString *real) 110 { 111 if (real->align_offset != 0) 112 { 113 memmove (real->str - real->align_offset, 114 real->str, 115 real->len + 1); 116 117 real->str = real->str - real->align_offset; 118 real->align_offset = 0; 119 } 120 } 121 122 /** 123 * Initializes a string that can be up to the given allocation size 124 * before it has to realloc. The string starts life with zero length. 125 * The string must eventually be freed with _dbus_string_free(). 126 * 127 * @param str memory to hold the string 128 * @param allocate_size amount to preallocate 129 * @returns #TRUE on success, #FALSE if no memory 130 */ 131 dbus_bool_t 132 _dbus_string_init_preallocated (DBusString *str, 133 int allocate_size) 134 { 135 DBusRealString *real; 136 137 _dbus_assert (str != NULL); 138 139 _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString)); 140 141 real = (DBusRealString*) str; 142 143 /* It's very important not to touch anything 144 * other than real->str if we're going to fail, 145 * since we also use this function to reset 146 * an existing string, e.g. in _dbus_string_steal_data() 147 */ 148 149 real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size); 150 if (real->str == NULL) 151 return FALSE; 152 153 real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size; 154 real->len = 0; 155 real->str[real->len] = '\0'; 156 157 real->constant = FALSE; 158 real->locked = FALSE; 159 real->invalid = FALSE; 160 real->align_offset = 0; 161 162 fixup_alignment (real); 163 164 return TRUE; 165 } 166 167 /** 168 * Initializes a string. The string starts life with zero length. The 169 * string must eventually be freed with _dbus_string_free(). 170 * 171 * @param str memory to hold the string 172 * @returns #TRUE on success, #FALSE if no memory 173 */ 174 dbus_bool_t 175 _dbus_string_init (DBusString *str) 176 { 177 return _dbus_string_init_preallocated (str, 0); 178 } 179 180 /** 181 * Initializes a constant string. The value parameter is not copied 182 * (should be static), and the string may never be modified. 183 * It is safe but not necessary to call _dbus_string_free() 184 * on a const string. The string has a length limit of MAXINT - 8. 185 * 186 * @param str memory to use for the string 187 * @param value a string to be stored in str (not copied!!!) 188 */ 189 void 190 _dbus_string_init_const (DBusString *str, 191 const char *value) 192 { 193 _dbus_assert (value != NULL); 194 195 _dbus_string_init_const_len (str, value, 196 strlen (value)); 197 } 198 199 /** 200 * Initializes a constant string with a length. The value parameter is 201 * not copied (should be static), and the string may never be 202 * modified. It is safe but not necessary to call _dbus_string_free() 203 * on a const string. 204 * 205 * @param str memory to use for the string 206 * @param value a string to be stored in str (not copied!!!) 207 * @param len the length to use 208 */ 209 void 210 _dbus_string_init_const_len (DBusString *str, 211 const char *value, 212 int len) 213 { 214 DBusRealString *real; 215 216 _dbus_assert (str != NULL); 217 _dbus_assert (len == 0 || value != NULL); 218 _dbus_assert (len <= _DBUS_STRING_MAX_LENGTH); 219 _dbus_assert (len >= 0); 220 221 real = (DBusRealString*) str; 222 223 real->str = (unsigned char*) value; 224 real->len = len; 225 real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */ 226 real->constant = TRUE; 227 real->locked = TRUE; 228 real->invalid = FALSE; 229 real->align_offset = 0; 230 231 /* We don't require const strings to be 8-byte aligned as the 232 * memory is coming from elsewhere. 233 */ 234 } 235 236 /** 237 * Frees a string created by _dbus_string_init(). 238 * 239 * @param str memory where the string is stored. 240 */ 241 void 242 _dbus_string_free (DBusString *str) 243 { 244 DBusRealString *real = (DBusRealString*) str; 245 DBUS_GENERIC_STRING_PREAMBLE (real); 246 247 if (real->constant) 248 return; 249 dbus_free (real->str - real->align_offset); 250 251 real->invalid = TRUE; 252 } 253 254 static dbus_bool_t 255 compact (DBusRealString *real, 256 int max_waste) 257 { 258 unsigned char *new_str; 259 int new_allocated; 260 int waste; 261 262 waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING); 263 264 if (waste <= max_waste) 265 return TRUE; 266 267 new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; 268 269 new_str = dbus_realloc (real->str - real->align_offset, new_allocated); 270 if (_DBUS_UNLIKELY (new_str == NULL)) 271 return FALSE; 272 273 real->str = new_str + real->align_offset; 274 real->allocated = new_allocated; 275 fixup_alignment (real); 276 277 return TRUE; 278 } 279 280 #ifdef DBUS_BUILD_TESTS 281 /* Not using this feature at the moment, 282 * so marked DBUS_BUILD_TESTS-only 283 */ 284 /** 285 * Locks a string such that any attempts to change the string will 286 * result in aborting the program. Also, if the string is wasting a 287 * lot of memory (allocation is sufficiently larger than what the 288 * string is really using), _dbus_string_lock() will realloc the 289 * string's data to "compact" it. 290 * 291 * @param str the string to lock. 292 */ 293 void 294 _dbus_string_lock (DBusString *str) 295 { 296 DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */ 297 298 real->locked = TRUE; 299 300 /* Try to realloc to avoid excess memory usage, since 301 * we know we won't change the string further 302 */ 303 #define MAX_WASTE 48 304 compact (real, MAX_WASTE); 305 } 306 #endif /* DBUS_BUILD_TESTS */ 307 308 static dbus_bool_t 309 reallocate_for_length (DBusRealString *real, 310 int new_length) 311 { 312 int new_allocated; 313 unsigned char *new_str; 314 315 /* at least double our old allocation to avoid O(n), avoiding 316 * overflow 317 */ 318 if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2) 319 new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING; 320 else 321 new_allocated = real->allocated * 2; 322 323 /* if you change the code just above here, run the tests without 324 * the following assert-only hack before you commit 325 */ 326 /* This is keyed off asserts in addition to tests so when you 327 * disable asserts to profile, you don't get this destroyer 328 * of profiles. 329 */ 330 #ifdef DBUS_DISABLE_ASSERT 331 #else 332 #ifdef DBUS_BUILD_TESTS 333 new_allocated = 0; /* ensure a realloc every time so that we go 334 * through all malloc failure codepaths 335 */ 336 #endif /* DBUS_BUILD_TESTS */ 337 #endif /* !DBUS_DISABLE_ASSERT */ 338 339 /* But be sure we always alloc at least space for the new length */ 340 new_allocated = MAX (new_allocated, 341 new_length + _DBUS_STRING_ALLOCATION_PADDING); 342 343 _dbus_assert (new_allocated >= real->allocated); /* code relies on this */ 344 new_str = dbus_realloc (real->str - real->align_offset, new_allocated); 345 if (_DBUS_UNLIKELY (new_str == NULL)) 346 return FALSE; 347 348 real->str = new_str + real->align_offset; 349 real->allocated = new_allocated; 350 fixup_alignment (real); 351 352 return TRUE; 353 } 354 355 /** 356 * Compacts the string to avoid wasted memory. Wasted memory is 357 * memory that is allocated but not actually required to store the 358 * current length of the string. The compact is only done if more 359 * than the given amount of memory is being wasted (otherwise the 360 * waste is ignored and the call does nothing). 361 * 362 * @param str the string 363 * @param max_waste the maximum amount of waste to ignore 364 * @returns #FALSE if the compact failed due to realloc failure 365 */ 366 dbus_bool_t 367 _dbus_string_compact (DBusString *str, 368 int max_waste) 369 { 370 DBUS_STRING_PREAMBLE (str); 371 372 return compact (real, max_waste); 373 } 374 375 static dbus_bool_t 376 set_length (DBusRealString *real, 377 int new_length) 378 { 379 /* Note, we are setting the length not including nul termination */ 380 381 /* exceeding max length is the same as failure to allocate memory */ 382 if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH)) 383 return FALSE; 384 else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) && 385 _DBUS_UNLIKELY (!reallocate_for_length (real, new_length))) 386 return FALSE; 387 else 388 { 389 real->len = new_length; 390 real->str[new_length] = '\0'; 391 return TRUE; 392 } 393 } 394 395 static dbus_bool_t 396 open_gap (int len, 397 DBusRealString *dest, 398 int insert_at) 399 { 400 if (len == 0) 401 return TRUE; 402 403 if (len > _DBUS_STRING_MAX_LENGTH - dest->len) 404 return FALSE; /* detected overflow of dest->len + len below */ 405 406 if (!set_length (dest, dest->len + len)) 407 return FALSE; 408 409 memmove (dest->str + insert_at + len, 410 dest->str + insert_at, 411 dest->len - len - insert_at); 412 413 return TRUE; 414 } 415 416 #ifndef _dbus_string_get_data 417 /** 418 * Gets the raw character buffer from the string. The returned buffer 419 * will be nul-terminated, but note that strings may contain binary 420 * data so there may be extra nul characters prior to the termination. 421 * This function should be little-used, extend DBusString or add 422 * stuff to dbus-sysdeps.c instead. It's an error to use this 423 * function on a const string. 424 * 425 * @param str the string 426 * @returns the data 427 */ 428 char* 429 _dbus_string_get_data (DBusString *str) 430 { 431 DBUS_STRING_PREAMBLE (str); 432 433 return (char*) real->str; 434 } 435 #endif /* _dbus_string_get_data */ 436 437 /* only do the function if we don't have the macro */ 438 #ifndef _dbus_string_get_const_data 439 /** 440 * Gets the raw character buffer from a const string. 441 * 442 * @param str the string 443 * @returns the string data 444 */ 445 const char* 446 _dbus_string_get_const_data (const DBusString *str) 447 { 448 DBUS_CONST_STRING_PREAMBLE (str); 449 450 return (const char*) real->str; 451 } 452 #endif /* _dbus_string_get_const_data */ 453 454 /** 455 * Gets a sub-portion of the raw character buffer from the 456 * string. The "len" field is required simply for error 457 * checking, to be sure you don't try to use more 458 * string than exists. The nul termination of the 459 * returned buffer remains at the end of the entire 460 * string, not at start + len. 461 * 462 * @param str the string 463 * @param start byte offset to return 464 * @param len length of segment to return 465 * @returns the string data 466 */ 467 char* 468 _dbus_string_get_data_len (DBusString *str, 469 int start, 470 int len) 471 { 472 DBUS_STRING_PREAMBLE (str); 473 _dbus_assert (start >= 0); 474 _dbus_assert (len >= 0); 475 _dbus_assert (start <= real->len); 476 _dbus_assert (len <= real->len - start); 477 478 return (char*) real->str + start; 479 } 480 481 /* only do the function if we don't have the macro */ 482 #ifndef _dbus_string_get_const_data_len 483 /** 484 * const version of _dbus_string_get_data_len(). 485 * 486 * @param str the string 487 * @param start byte offset to return 488 * @param len length of segment to return 489 * @returns the string data 490 */ 491 const char* 492 _dbus_string_get_const_data_len (const DBusString *str, 493 int start, 494 int len) 495 { 496 DBUS_CONST_STRING_PREAMBLE (str); 497 _dbus_assert (start >= 0); 498 _dbus_assert (len >= 0); 499 _dbus_assert (start <= real->len); 500 _dbus_assert (len <= real->len - start); 501 502 return (const char*) real->str + start; 503 } 504 #endif /* _dbus_string_get_const_data_len */ 505 506 /* only do the function if we don't have the macro */ 507 #ifndef _dbus_string_set_byte 508 /** 509 * Sets the value of the byte at the given position. 510 * 511 * @param str the string 512 * @param i the position 513 * @param byte the new value 514 */ 515 void 516 _dbus_string_set_byte (DBusString *str, 517 int i, 518 unsigned char byte) 519 { 520 DBUS_STRING_PREAMBLE (str); 521 _dbus_assert (i < real->len); 522 _dbus_assert (i >= 0); 523 524 real->str[i] = byte; 525 } 526 #endif /* _dbus_string_set_byte */ 527 528 /* only have the function if we didn't create a macro */ 529 #ifndef _dbus_string_get_byte 530 /** 531 * Gets the byte at the given position. It is 532 * allowed to ask for the nul byte at the end of 533 * the string. 534 * 535 * @param str the string 536 * @param start the position 537 * @returns the byte at that position 538 */ 539 unsigned char 540 _dbus_string_get_byte (const DBusString *str, 541 int start) 542 { 543 DBUS_CONST_STRING_PREAMBLE (str); 544 _dbus_assert (start <= real->len); 545 _dbus_assert (start >= 0); 546 547 return real->str[start]; 548 } 549 #endif /* _dbus_string_get_byte */ 550 551 /** 552 * Inserts a number of bytes of a given value at the 553 * given position. 554 * 555 * @param str the string 556 * @param i the position 557 * @param n_bytes number of bytes 558 * @param byte the value to insert 559 * @returns #TRUE on success 560 */ 561 dbus_bool_t 562 _dbus_string_insert_bytes (DBusString *str, 563 int i, 564 int n_bytes, 565 unsigned char byte) 566 { 567 DBUS_STRING_PREAMBLE (str); 568 _dbus_assert (i <= real->len); 569 _dbus_assert (i >= 0); 570 _dbus_assert (n_bytes >= 0); 571 572 if (n_bytes == 0) 573 return TRUE; 574 575 if (!open_gap (n_bytes, real, i)) 576 return FALSE; 577 578 memset (real->str + i, byte, n_bytes); 579 580 return TRUE; 581 } 582 583 /** 584 * Inserts a single byte at the given position. 585 * 586 * @param str the string 587 * @param i the position 588 * @param byte the value to insert 589 * @returns #TRUE on success 590 */ 591 dbus_bool_t 592 _dbus_string_insert_byte (DBusString *str, 593 int i, 594 unsigned char byte) 595 { 596 DBUS_STRING_PREAMBLE (str); 597 _dbus_assert (i <= real->len); 598 _dbus_assert (i >= 0); 599 600 if (!open_gap (1, real, i)) 601 return FALSE; 602 603 real->str[i] = byte; 604 605 return TRUE; 606 } 607 608 /** 609 * Like _dbus_string_get_data(), but removes the 610 * gotten data from the original string. The caller 611 * must free the data returned. This function may 612 * fail due to lack of memory, and return #FALSE. 613 * 614 * @param str the string 615 * @param data_return location to return the buffer 616 * @returns #TRUE on success 617 */ 618 dbus_bool_t 619 _dbus_string_steal_data (DBusString *str, 620 char **data_return) 621 { 622 DBUS_STRING_PREAMBLE (str); 623 _dbus_assert (data_return != NULL); 624 625 undo_alignment (real); 626 627 *data_return = (char*) real->str; 628 629 /* reset the string */ 630 if (!_dbus_string_init (str)) 631 { 632 /* hrm, put it back then */ 633 real->str = (unsigned char*) *data_return; 634 *data_return = NULL; 635 fixup_alignment (real); 636 return FALSE; 637 } 638 639 return TRUE; 640 } 641 642 /** 643 * Copies the data from the string into a char* 644 * 645 * @param str the string 646 * @param data_return place to return the data 647 * @returns #TRUE on success, #FALSE on no memory 648 */ 649 dbus_bool_t 650 _dbus_string_copy_data (const DBusString *str, 651 char **data_return) 652 { 653 DBUS_CONST_STRING_PREAMBLE (str); 654 _dbus_assert (data_return != NULL); 655 656 *data_return = dbus_malloc (real->len + 1); 657 if (*data_return == NULL) 658 return FALSE; 659 660 memcpy (*data_return, real->str, real->len + 1); 661 662 return TRUE; 663 } 664 665 /** 666 * Copies the contents of a DBusString into a different buffer. It is 667 * a bug if avail_len is too short to hold the string contents. nul 668 * termination is not copied, just the supplied bytes. 669 * 670 * @param str a string 671 * @param buffer a C buffer to copy data to 672 * @param avail_len maximum length of C buffer 673 */ 674 void 675 _dbus_string_copy_to_buffer (const DBusString *str, 676 char *buffer, 677 int avail_len) 678 { 679 DBUS_CONST_STRING_PREAMBLE (str); 680 681 _dbus_assert (avail_len >= 0); 682 _dbus_assert (avail_len >= real->len); 683 684 memcpy (buffer, real->str, real->len); 685 } 686 687 /** 688 * Copies the contents of a DBusString into a different buffer. It is 689 * a bug if avail_len is too short to hold the string contents plus a 690 * nul byte. 691 * 692 * @param str a string 693 * @param buffer a C buffer to copy data to 694 * @param avail_len maximum length of C buffer 695 */ 696 void 697 _dbus_string_copy_to_buffer_with_nul (const DBusString *str, 698 char *buffer, 699 int avail_len) 700 { 701 DBUS_CONST_STRING_PREAMBLE (str); 702 703 _dbus_assert (avail_len >= 0); 704 _dbus_assert (avail_len > real->len); 705 706 memcpy (buffer, real->str, real->len+1); 707 } 708 709 /* Only have the function if we don't have the macro */ 710 #ifndef _dbus_string_get_length 711 /** 712 * Gets the length of a string (not including nul termination). 713 * 714 * @returns the length. 715 */ 716 int 717 _dbus_string_get_length (const DBusString *str) 718 { 719 DBUS_CONST_STRING_PREAMBLE (str); 720 721 return real->len; 722 } 723 #endif /* !_dbus_string_get_length */ 724 725 /** 726 * Makes a string longer by the given number of bytes. Checks whether 727 * adding additional_length to the current length would overflow an 728 * integer, and checks for exceeding a string's max length. 729 * The new bytes are not initialized, other than nul-terminating 730 * the end of the string. The uninitialized bytes may contain 731 * nul bytes or other junk. 732 * 733 * @param str a string 734 * @param additional_length length to add to the string. 735 * @returns #TRUE on success. 736 */ 737 dbus_bool_t 738 _dbus_string_lengthen (DBusString *str, 739 int additional_length) 740 { 741 DBUS_STRING_PREAMBLE (str); 742 _dbus_assert (additional_length >= 0); 743 744 if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len)) 745 return FALSE; /* would overflow */ 746 747 return set_length (real, 748 real->len + additional_length); 749 } 750 751 /** 752 * Makes a string shorter by the given number of bytes. 753 * 754 * @param str a string 755 * @param length_to_remove length to remove from the string. 756 */ 757 void 758 _dbus_string_shorten (DBusString *str, 759 int length_to_remove) 760 { 761 DBUS_STRING_PREAMBLE (str); 762 _dbus_assert (length_to_remove >= 0); 763 _dbus_assert (length_to_remove <= real->len); 764 765 set_length (real, 766 real->len - length_to_remove); 767 } 768 769 /** 770 * Sets the length of a string. Can be used to truncate or lengthen 771 * the string. If the string is lengthened, the function may fail and 772 * return #FALSE. Newly-added bytes are not initialized, as with 773 * _dbus_string_lengthen(). 774 * 775 * @param str a string 776 * @param length new length of the string. 777 * @returns #FALSE on failure. 778 */ 779 dbus_bool_t 780 _dbus_string_set_length (DBusString *str, 781 int length) 782 { 783 DBUS_STRING_PREAMBLE (str); 784 _dbus_assert (length >= 0); 785 786 return set_length (real, length); 787 } 788 789 static dbus_bool_t 790 align_insert_point_then_open_gap (DBusString *str, 791 int *insert_at_p, 792 int alignment, 793 int gap_size) 794 { 795 unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */ 796 unsigned long gap_pos; 797 int insert_at; 798 int delta; 799 DBUS_STRING_PREAMBLE (str); 800 _dbus_assert (alignment >= 1); 801 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */ 802 803 insert_at = *insert_at_p; 804 805 _dbus_assert (insert_at <= real->len); 806 807 gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment); 808 new_len = real->len + (gap_pos - insert_at) + gap_size; 809 810 if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)) 811 return FALSE; 812 813 delta = new_len - real->len; 814 _dbus_assert (delta >= 0); 815 816 if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */ 817 { 818 _dbus_assert (((unsigned long) *insert_at_p) == gap_pos); 819 return TRUE; 820 } 821 822 if (_DBUS_UNLIKELY (!open_gap (new_len - real->len, 823 real, insert_at))) 824 return FALSE; 825 826 /* nul the padding if we had to add any padding */ 827 if (gap_size < delta) 828 { 829 memset (&real->str[insert_at], '\0', 830 gap_pos - insert_at); 831 } 832 833 *insert_at_p = gap_pos; 834 835 return TRUE; 836 } 837 838 static dbus_bool_t 839 align_length_then_lengthen (DBusString *str, 840 int alignment, 841 int then_lengthen_by) 842 { 843 int insert_at; 844 845 insert_at = _dbus_string_get_length (str); 846 847 return align_insert_point_then_open_gap (str, 848 &insert_at, 849 alignment, then_lengthen_by); 850 } 851 852 /** 853 * Align the length of a string to a specific alignment (typically 4 or 8) 854 * by appending nul bytes to the string. 855 * 856 * @param str a string 857 * @param alignment the alignment 858 * @returns #FALSE if no memory 859 */ 860 dbus_bool_t 861 _dbus_string_align_length (DBusString *str, 862 int alignment) 863 { 864 return align_length_then_lengthen (str, alignment, 0); 865 } 866 867 /** 868 * Preallocate extra_bytes such that a future lengthening of the 869 * string by extra_bytes is guaranteed to succeed without an out of 870 * memory error. 871 * 872 * @param str a string 873 * @param extra_bytes bytes to alloc 874 * @returns #FALSE if no memory 875 */ 876 dbus_bool_t 877 _dbus_string_alloc_space (DBusString *str, 878 int extra_bytes) 879 { 880 if (!_dbus_string_lengthen (str, extra_bytes)) 881 return FALSE; 882 _dbus_string_shorten (str, extra_bytes); 883 884 return TRUE; 885 } 886 887 static dbus_bool_t 888 append (DBusRealString *real, 889 const char *buffer, 890 int buffer_len) 891 { 892 if (buffer_len == 0) 893 return TRUE; 894 895 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len)) 896 return FALSE; 897 898 memcpy (real->str + (real->len - buffer_len), 899 buffer, 900 buffer_len); 901 902 return TRUE; 903 } 904 905 /** 906 * Appends a nul-terminated C-style string to a DBusString. 907 * 908 * @param str the DBusString 909 * @param buffer the nul-terminated characters to append 910 * @returns #FALSE if not enough memory. 911 */ 912 dbus_bool_t 913 _dbus_string_append (DBusString *str, 914 const char *buffer) 915 { 916 unsigned long buffer_len; 917 918 DBUS_STRING_PREAMBLE (str); 919 _dbus_assert (buffer != NULL); 920 921 buffer_len = strlen (buffer); 922 if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH) 923 return FALSE; 924 925 return append (real, buffer, buffer_len); 926 } 927 928 /** assign 2 bytes from one string to another */ 929 #define ASSIGN_2_OCTETS(p, octets) \ 930 *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets)); 931 932 /** assign 4 bytes from one string to another */ 933 #define ASSIGN_4_OCTETS(p, octets) \ 934 *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets)); 935 936 #ifdef DBUS_HAVE_INT64 937 /** assign 8 bytes from one string to another */ 938 #define ASSIGN_8_OCTETS(p, octets) \ 939 *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets)); 940 #else 941 /** assign 8 bytes from one string to another */ 942 #define ASSIGN_8_OCTETS(p, octets) \ 943 do { \ 944 unsigned char *b; \ 945 \ 946 b = p; \ 947 \ 948 *b++ = octets[0]; \ 949 *b++ = octets[1]; \ 950 *b++ = octets[2]; \ 951 *b++ = octets[3]; \ 952 *b++ = octets[4]; \ 953 *b++ = octets[5]; \ 954 *b++ = octets[6]; \ 955 *b++ = octets[7]; \ 956 _dbus_assert (b == p + 8); \ 957 } while (0) 958 #endif /* DBUS_HAVE_INT64 */ 959 960 /** 961 * Inserts 2 bytes aligned on a 2 byte boundary 962 * with any alignment padding initialized to 0. 963 * 964 * @param str the DBusString 965 * @param insert_at where to insert 966 * @param octets 2 bytes to insert 967 * @returns #FALSE if not enough memory. 968 */ 969 dbus_bool_t 970 _dbus_string_insert_2_aligned (DBusString *str, 971 int insert_at, 972 const unsigned char octets[4]) 973 { 974 DBUS_STRING_PREAMBLE (str); 975 976 if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2)) 977 return FALSE; 978 979 ASSIGN_2_OCTETS (real->str + insert_at, octets); 980 981 return TRUE; 982 } 983 984 /** 985 * Inserts 4 bytes aligned on a 4 byte boundary 986 * with any alignment padding initialized to 0. 987 * 988 * @param str the DBusString 989 * @param insert_at where to insert 990 * @param octets 4 bytes to insert 991 * @returns #FALSE if not enough memory. 992 */ 993 dbus_bool_t 994 _dbus_string_insert_4_aligned (DBusString *str, 995 int insert_at, 996 const unsigned char octets[4]) 997 { 998 DBUS_STRING_PREAMBLE (str); 999 1000 if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4)) 1001 return FALSE; 1002 1003 ASSIGN_4_OCTETS (real->str + insert_at, octets); 1004 1005 return TRUE; 1006 } 1007 1008 /** 1009 * Inserts 8 bytes aligned on an 8 byte boundary 1010 * with any alignment padding initialized to 0. 1011 * 1012 * @param str the DBusString 1013 * @param insert_at where to insert 1014 * @param octets 8 bytes to insert 1015 * @returns #FALSE if not enough memory. 1016 */ 1017 dbus_bool_t 1018 _dbus_string_insert_8_aligned (DBusString *str, 1019 int insert_at, 1020 const unsigned char octets[8]) 1021 { 1022 DBUS_STRING_PREAMBLE (str); 1023 1024 if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8)) 1025 return FALSE; 1026 1027 _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at); 1028 1029 ASSIGN_8_OCTETS (real->str + insert_at, octets); 1030 1031 return TRUE; 1032 } 1033 1034 1035 /** 1036 * Inserts padding at *insert_at such to align it to the given 1037 * boundary. Initializes the padding to nul bytes. Sets *insert_at 1038 * to the aligned position. 1039 * 1040 * @param str the DBusString 1041 * @param insert_at location to be aligned 1042 * @param alignment alignment boundary (1, 2, 4, or 8) 1043 * @returns #FALSE if not enough memory. 1044 */ 1045 dbus_bool_t 1046 _dbus_string_insert_alignment (DBusString *str, 1047 int *insert_at, 1048 int alignment) 1049 { 1050 DBUS_STRING_PREAMBLE (str); 1051 1052 if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0)) 1053 return FALSE; 1054 1055 _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at); 1056 1057 return TRUE; 1058 } 1059 1060 /** 1061 * Appends a printf-style formatted string 1062 * to the #DBusString. 1063 * 1064 * @param str the string 1065 * @param format printf format 1066 * @param args variable argument list 1067 * @returns #FALSE if no memory 1068 */ 1069 dbus_bool_t 1070 _dbus_string_append_printf_valist (DBusString *str, 1071 const char *format, 1072 va_list args) 1073 { 1074 int len; 1075 va_list args_copy; 1076 1077 DBUS_STRING_PREAMBLE (str); 1078 1079 DBUS_VA_COPY (args_copy, args); 1080 1081 /* Measure the message length without terminating nul */ 1082 len = _dbus_printf_string_upper_bound (format, args); 1083 1084 if (len < 0) 1085 return FALSE; 1086 1087 if (!_dbus_string_lengthen (str, len)) 1088 { 1089 /* don't leak the copy */ 1090 va_end (args_copy); 1091 return FALSE; 1092 } 1093 1094 vsprintf ((char*) (real->str + (real->len - len)), 1095 format, args_copy); 1096 1097 va_end (args_copy); 1098 1099 return TRUE; 1100 } 1101 1102 /** 1103 * Appends a printf-style formatted string 1104 * to the #DBusString. 1105 * 1106 * @param str the string 1107 * @param format printf format 1108 * @returns #FALSE if no memory 1109 */ 1110 dbus_bool_t 1111 _dbus_string_append_printf (DBusString *str, 1112 const char *format, 1113 ...) 1114 { 1115 va_list args; 1116 dbus_bool_t retval; 1117 1118 va_start (args, format); 1119 retval = _dbus_string_append_printf_valist (str, format, args); 1120 va_end (args); 1121 1122 return retval; 1123 } 1124 1125 /** 1126 * Appends block of bytes with the given length to a DBusString. 1127 * 1128 * @param str the DBusString 1129 * @param buffer the bytes to append 1130 * @param len the number of bytes to append 1131 * @returns #FALSE if not enough memory. 1132 */ 1133 dbus_bool_t 1134 _dbus_string_append_len (DBusString *str, 1135 const char *buffer, 1136 int len) 1137 { 1138 DBUS_STRING_PREAMBLE (str); 1139 _dbus_assert (buffer != NULL); 1140 _dbus_assert (len >= 0); 1141 1142 return append (real, buffer, len); 1143 } 1144 1145 /** 1146 * Appends a single byte to the string, returning #FALSE 1147 * if not enough memory. 1148 * 1149 * @param str the string 1150 * @param byte the byte to append 1151 * @returns #TRUE on success 1152 */ 1153 dbus_bool_t 1154 _dbus_string_append_byte (DBusString *str, 1155 unsigned char byte) 1156 { 1157 DBUS_STRING_PREAMBLE (str); 1158 1159 if (!set_length (real, real->len + 1)) 1160 return FALSE; 1161 1162 real->str[real->len-1] = byte; 1163 1164 return TRUE; 1165 } 1166 1167 static void 1168 delete (DBusRealString *real, 1169 int start, 1170 int len) 1171 { 1172 if (len == 0) 1173 return; 1174 1175 memmove (real->str + start, real->str + start + len, real->len - (start + len)); 1176 real->len -= len; 1177 real->str[real->len] = '\0'; 1178 } 1179 1180 /** 1181 * Deletes a segment of a DBusString with length len starting at 1182 * start. (Hint: to clear an entire string, setting length to 0 1183 * with _dbus_string_set_length() is easier.) 1184 * 1185 * @param str the DBusString 1186 * @param start where to start deleting 1187 * @param len the number of bytes to delete 1188 */ 1189 void 1190 _dbus_string_delete (DBusString *str, 1191 int start, 1192 int len) 1193 { 1194 DBUS_STRING_PREAMBLE (str); 1195 _dbus_assert (start >= 0); 1196 _dbus_assert (len >= 0); 1197 _dbus_assert (start <= real->len); 1198 _dbus_assert (len <= real->len - start); 1199 1200 delete (real, start, len); 1201 } 1202 1203 static dbus_bool_t 1204 copy (DBusRealString *source, 1205 int start, 1206 int len, 1207 DBusRealString *dest, 1208 int insert_at) 1209 { 1210 if (len == 0) 1211 return TRUE; 1212 1213 if (!open_gap (len, dest, insert_at)) 1214 return FALSE; 1215 1216 memmove (dest->str + insert_at, 1217 source->str + start, 1218 len); 1219 1220 return TRUE; 1221 } 1222 1223 /** 1224 * Checks assertions for two strings we're copying a segment between, 1225 * and declares real_source/real_dest variables. 1226 * 1227 * @param source the source string 1228 * @param start the starting offset 1229 * @param dest the dest string 1230 * @param insert_at where the copied segment is inserted 1231 */ 1232 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \ 1233 DBusRealString *real_source = (DBusRealString*) source; \ 1234 DBusRealString *real_dest = (DBusRealString*) dest; \ 1235 _dbus_assert ((source) != (dest)); \ 1236 DBUS_GENERIC_STRING_PREAMBLE (real_source); \ 1237 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \ 1238 _dbus_assert (!real_dest->constant); \ 1239 _dbus_assert (!real_dest->locked); \ 1240 _dbus_assert ((start) >= 0); \ 1241 _dbus_assert ((start) <= real_source->len); \ 1242 _dbus_assert ((insert_at) >= 0); \ 1243 _dbus_assert ((insert_at) <= real_dest->len) 1244 1245 /** 1246 * Moves the end of one string into another string. Both strings 1247 * must be initialized, valid strings. 1248 * 1249 * @param source the source string 1250 * @param start where to chop off the source string 1251 * @param dest the destination string 1252 * @param insert_at where to move the chopped-off part of source string 1253 * @returns #FALSE if not enough memory 1254 */ 1255 dbus_bool_t 1256 _dbus_string_move (DBusString *source, 1257 int start, 1258 DBusString *dest, 1259 int insert_at) 1260 { 1261 DBusRealString *real_source = (DBusRealString*) source; 1262 _dbus_assert (start <= real_source->len); 1263 1264 return _dbus_string_move_len (source, start, 1265 real_source->len - start, 1266 dest, insert_at); 1267 } 1268 1269 /** 1270 * Like _dbus_string_move(), but does not delete the section 1271 * of the source string that's copied to the dest string. 1272 * 1273 * @param source the source string 1274 * @param start where to start copying the source string 1275 * @param dest the destination string 1276 * @param insert_at where to place the copied part of source string 1277 * @returns #FALSE if not enough memory 1278 */ 1279 dbus_bool_t 1280 _dbus_string_copy (const DBusString *source, 1281 int start, 1282 DBusString *dest, 1283 int insert_at) 1284 { 1285 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at); 1286 1287 return copy (real_source, start, 1288 real_source->len - start, 1289 real_dest, 1290 insert_at); 1291 } 1292 1293 /** 1294 * Like _dbus_string_move(), but can move a segment from 1295 * the middle of the source string. 1296 * 1297 * @param source the source string 1298 * @param start first byte of source string to move 1299 * @param len length of segment to move 1300 * @param dest the destination string 1301 * @param insert_at where to move the bytes from the source string 1302 * @returns #FALSE if not enough memory 1303 */ 1304 dbus_bool_t 1305 _dbus_string_move_len (DBusString *source, 1306 int start, 1307 int len, 1308 DBusString *dest, 1309 int insert_at) 1310 1311 { 1312 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at); 1313 _dbus_assert (len >= 0); 1314 _dbus_assert ((start + len) <= real_source->len); 1315 1316 1317 if (len == 0) 1318 { 1319 return TRUE; 1320 } 1321 else if (start == 0 && 1322 len == real_source->len && 1323 real_dest->len == 0) 1324 { 1325 /* Short-circuit moving an entire existing string to an empty string 1326 * by just swapping the buffers. 1327 */ 1328 /* we assume ->constant doesn't matter as you can't have 1329 * a constant string involved in a move. 1330 */ 1331 #define ASSIGN_DATA(a, b) do { \ 1332 (a)->str = (b)->str; \ 1333 (a)->len = (b)->len; \ 1334 (a)->allocated = (b)->allocated; \ 1335 (a)->align_offset = (b)->align_offset; \ 1336 } while (0) 1337 1338 DBusRealString tmp; 1339 1340 ASSIGN_DATA (&tmp, real_source); 1341 ASSIGN_DATA (real_source, real_dest); 1342 ASSIGN_DATA (real_dest, &tmp); 1343 1344 return TRUE; 1345 } 1346 else 1347 { 1348 if (!copy (real_source, start, len, 1349 real_dest, 1350 insert_at)) 1351 return FALSE; 1352 1353 delete (real_source, start, 1354 len); 1355 1356 return TRUE; 1357 } 1358 } 1359 1360 /** 1361 * Like _dbus_string_copy(), but can copy a segment from the middle of 1362 * the source string. 1363 * 1364 * @param source the source string 1365 * @param start where to start copying the source string 1366 * @param len length of segment to copy 1367 * @param dest the destination string 1368 * @param insert_at where to place the copied segment of source string 1369 * @returns #FALSE if not enough memory 1370 */ 1371 dbus_bool_t 1372 _dbus_string_copy_len (const DBusString *source, 1373 int start, 1374 int len, 1375 DBusString *dest, 1376 int insert_at) 1377 { 1378 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at); 1379 _dbus_assert (len >= 0); 1380 _dbus_assert (start <= real_source->len); 1381 _dbus_assert (len <= real_source->len - start); 1382 1383 return copy (real_source, start, len, 1384 real_dest, 1385 insert_at); 1386 } 1387 1388 /** 1389 * Replaces a segment of dest string with a segment of source string. 1390 * 1391 * @param source the source string 1392 * @param start where to start copying the source string 1393 * @param len length of segment to copy 1394 * @param dest the destination string 1395 * @param replace_at start of segment of dest string to replace 1396 * @param replace_len length of segment of dest string to replace 1397 * @returns #FALSE if not enough memory 1398 * 1399 */ 1400 dbus_bool_t 1401 _dbus_string_replace_len (const DBusString *source, 1402 int start, 1403 int len, 1404 DBusString *dest, 1405 int replace_at, 1406 int replace_len) 1407 { 1408 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at); 1409 _dbus_assert (len >= 0); 1410 _dbus_assert (start <= real_source->len); 1411 _dbus_assert (len <= real_source->len - start); 1412 _dbus_assert (replace_at >= 0); 1413 _dbus_assert (replace_at <= real_dest->len); 1414 _dbus_assert (replace_len <= real_dest->len - replace_at); 1415 1416 if (len == replace_len) 1417 { 1418 memmove (real_dest->str + replace_at, 1419 real_source->str + start, len); 1420 } 1421 else if (len < replace_len) 1422 { 1423 memmove (real_dest->str + replace_at, 1424 real_source->str + start, len); 1425 delete (real_dest, replace_at + len, 1426 replace_len - len); 1427 } 1428 else 1429 { 1430 int diff; 1431 1432 _dbus_assert (len > replace_len); 1433 1434 diff = len - replace_len; 1435 1436 /* First of all we check if destination string can be enlarged as 1437 * required, then we overwrite previous bytes 1438 */ 1439 1440 if (!copy (real_source, start + replace_len, diff, 1441 real_dest, replace_at + replace_len)) 1442 return FALSE; 1443 1444 memmove (real_dest->str + replace_at, 1445 real_source->str + start, replace_len); 1446 } 1447 1448 return TRUE; 1449 } 1450 1451 /** 1452 * Looks for the first occurance of a byte, deletes that byte, 1453 * and moves everything after the byte to the beginning of a 1454 * separate string. Both strings must be initialized, valid 1455 * strings. 1456 * 1457 * @param source the source string 1458 * @param byte the byte to remove and split the string at 1459 * @param tail the split off string 1460 * @returns #FALSE if not enough memory or if byte could not be found 1461 * 1462 */ 1463 dbus_bool_t 1464 _dbus_string_split_on_byte (DBusString *source, 1465 unsigned char byte, 1466 DBusString *tail) 1467 { 1468 int byte_position; 1469 char byte_string[2] = ""; 1470 int head_length; 1471 int tail_length; 1472 1473 byte_string[0] = (char) byte; 1474 1475 if (!_dbus_string_find (source, 0, byte_string, &byte_position)) 1476 return FALSE; 1477 1478 head_length = byte_position; 1479 tail_length = _dbus_string_get_length (source) - head_length - 1; 1480 1481 if (!_dbus_string_move_len (source, byte_position + 1, tail_length, 1482 tail, 0)) 1483 return FALSE; 1484 1485 /* remove the trailing delimiter byte from the head now. 1486 */ 1487 if (!_dbus_string_set_length (source, head_length)) 1488 return FALSE; 1489 1490 return TRUE; 1491 } 1492 1493 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc 1494 * Pennington, and Tom Tromey are the authors and authorized relicense. 1495 */ 1496 1497 /** computes length and mask of a unicode character 1498 * @param Char the char 1499 * @param Mask the mask variable to assign to 1500 * @param Len the length variable to assign to 1501 */ 1502 #define UTF8_COMPUTE(Char, Mask, Len) \ 1503 if (Char < 128) \ 1504 { \ 1505 Len = 1; \ 1506 Mask = 0x7f; \ 1507 } \ 1508 else if ((Char & 0xe0) == 0xc0) \ 1509 { \ 1510 Len = 2; \ 1511 Mask = 0x1f; \ 1512 } \ 1513 else if ((Char & 0xf0) == 0xe0) \ 1514 { \ 1515 Len = 3; \ 1516 Mask = 0x0f; \ 1517 } \ 1518 else if ((Char & 0xf8) == 0xf0) \ 1519 { \ 1520 Len = 4; \ 1521 Mask = 0x07; \ 1522 } \ 1523 else if ((Char & 0xfc) == 0xf8) \ 1524 { \ 1525 Len = 5; \ 1526 Mask = 0x03; \ 1527 } \ 1528 else if ((Char & 0xfe) == 0xfc) \ 1529 { \ 1530 Len = 6; \ 1531 Mask = 0x01; \ 1532 } \ 1533 else \ 1534 { \ 1535 Len = 0; \ 1536 Mask = 0; \ 1537 } 1538 1539 /** 1540 * computes length of a unicode character in UTF-8 1541 * @param Char the char 1542 */ 1543 #define UTF8_LENGTH(Char) \ 1544 ((Char) < 0x80 ? 1 : \ 1545 ((Char) < 0x800 ? 2 : \ 1546 ((Char) < 0x10000 ? 3 : \ 1547 ((Char) < 0x200000 ? 4 : \ 1548 ((Char) < 0x4000000 ? 5 : 6))))) 1549 1550 /** 1551 * Gets a UTF-8 value. 1552 * 1553 * @param Result variable for extracted unicode char. 1554 * @param Chars the bytes to decode 1555 * @param Count counter variable 1556 * @param Mask mask for this char 1557 * @param Len length for this char in bytes 1558 */ 1559 #define UTF8_GET(Result, Chars, Count, Mask, Len) \ 1560 (Result) = (Chars)[0] & (Mask); \ 1561 for ((Count) = 1; (Count) < (Len); ++(Count)) \ 1562 { \ 1563 if (((Chars)[(Count)] & 0xc0) != 0x80) \ 1564 { \ 1565 (Result) = -1; \ 1566 break; \ 1567 } \ 1568 (Result) <<= 6; \ 1569 (Result) |= ((Chars)[(Count)] & 0x3f); \ 1570 } 1571 1572 /** 1573 * Check whether a Unicode (5.2) char is in a valid range. 1574 * 1575 * The first check comes from the Unicode guarantee to never encode 1576 * a point above 0x0010ffff, since UTF-16 couldn't represent it. 1577 * 1578 * The second check covers surrogate pairs (category Cs). 1579 * 1580 * The last two checks cover "Noncharacter": defined as: 1581 * "A code point that is permanently reserved for 1582 * internal use, and that should never be interchanged. In 1583 * Unicode 3.1, these consist of the values U+nFFFE and U+nFFFF 1584 * (where n is from 0 to 10_16) and the values U+FDD0..U+FDEF." 1585 * 1586 * @param Char the character 1587 */ 1588 #define UNICODE_VALID(Char) \ 1589 ((Char) < 0x110000 && \ 1590 (((Char) & 0xFFFFF800) != 0xD800) && \ 1591 ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \ 1592 ((Char) & 0xFFFE) != 0xFFFE) 1593 1594 /** 1595 * Finds the given substring in the string, 1596 * returning #TRUE and filling in the byte index 1597 * where the substring was found, if it was found. 1598 * Returns #FALSE if the substring wasn't found. 1599 * Sets *start to the length of the string if the substring 1600 * is not found. 1601 * 1602 * @param str the string 1603 * @param start where to start looking 1604 * @param substr the substring 1605 * @param found return location for where it was found, or #NULL 1606 * @returns #TRUE if found 1607 */ 1608 dbus_bool_t 1609 _dbus_string_find (const DBusString *str, 1610 int start, 1611 const char *substr, 1612 int *found) 1613 { 1614 return _dbus_string_find_to (str, start, 1615 ((const DBusRealString*)str)->len, 1616 substr, found); 1617 } 1618 1619 /** 1620 * Finds end of line ("\r\n" or "\n") in the string, 1621 * returning #TRUE and filling in the byte index 1622 * where the eol string was found, if it was found. 1623 * Returns #FALSE if eol wasn't found. 1624 * 1625 * @param str the string 1626 * @param start where to start looking 1627 * @param found return location for where eol was found or string length otherwise 1628 * @param found_len return length of found eol string or zero otherwise 1629 * @returns #TRUE if found 1630 */ 1631 dbus_bool_t 1632 _dbus_string_find_eol (const DBusString *str, 1633 int start, 1634 int *found, 1635 int *found_len) 1636 { 1637 int i; 1638 1639 DBUS_CONST_STRING_PREAMBLE (str); 1640 _dbus_assert (start <= real->len); 1641 _dbus_assert (start >= 0); 1642 1643 i = start; 1644 while (i < real->len) 1645 { 1646 if (real->str[i] == '\r') 1647 { 1648 if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */ 1649 { 1650 if (found) 1651 *found = i; 1652 if (found_len) 1653 *found_len = 2; 1654 return TRUE; 1655 } 1656 else /* only "\r" */ 1657 { 1658 if (found) 1659 *found = i; 1660 if (found_len) 1661 *found_len = 1; 1662 return TRUE; 1663 } 1664 } 1665 else if (real->str[i] == '\n') /* only "\n" */ 1666 { 1667 if (found) 1668 *found = i; 1669 if (found_len) 1670 *found_len = 1; 1671 return TRUE; 1672 } 1673 ++i; 1674 } 1675 1676 if (found) 1677 *found = real->len; 1678 1679 if (found_len) 1680 *found_len = 0; 1681 1682 return FALSE; 1683 } 1684 1685 /** 1686 * Finds the given substring in the string, 1687 * up to a certain position, 1688 * returning #TRUE and filling in the byte index 1689 * where the substring was found, if it was found. 1690 * Returns #FALSE if the substring wasn't found. 1691 * Sets *start to the length of the string if the substring 1692 * is not found. 1693 * 1694 * @param str the string 1695 * @param start where to start looking 1696 * @param end where to stop looking 1697 * @param substr the substring 1698 * @param found return location for where it was found, or #NULL 1699 * @returns #TRUE if found 1700 */ 1701 dbus_bool_t 1702 _dbus_string_find_to (const DBusString *str, 1703 int start, 1704 int end, 1705 const char *substr, 1706 int *found) 1707 { 1708 int i; 1709 DBUS_CONST_STRING_PREAMBLE (str); 1710 _dbus_assert (substr != NULL); 1711 _dbus_assert (start <= real->len); 1712 _dbus_assert (start >= 0); 1713 _dbus_assert (substr != NULL); 1714 _dbus_assert (end <= real->len); 1715 _dbus_assert (start <= end); 1716 1717 /* we always "find" an empty string */ 1718 if (*substr == '\0') 1719 { 1720 if (found) 1721 *found = start; 1722 return TRUE; 1723 } 1724 1725 i = start; 1726 while (i < end) 1727 { 1728 if (real->str[i] == substr[0]) 1729 { 1730 int j = i + 1; 1731 1732 while (j < end) 1733 { 1734 if (substr[j - i] == '\0') 1735 break; 1736 else if (real->str[j] != substr[j - i]) 1737 break; 1738 1739 ++j; 1740 } 1741 1742 if (substr[j - i] == '\0') 1743 { 1744 if (found) 1745 *found = i; 1746 return TRUE; 1747 } 1748 } 1749 1750 ++i; 1751 } 1752 1753 if (found) 1754 *found = end; 1755 1756 return FALSE; 1757 } 1758 1759 /** 1760 * Finds a blank (space or tab) in the string. Returns #TRUE 1761 * if found, #FALSE otherwise. If a blank is not found sets 1762 * *found to the length of the string. 1763 * 1764 * @param str the string 1765 * @param start byte index to start looking 1766 * @param found place to store the location of the first blank 1767 * @returns #TRUE if a blank was found 1768 */ 1769 dbus_bool_t 1770 _dbus_string_find_blank (const DBusString *str, 1771 int start, 1772 int *found) 1773 { 1774 int i; 1775 DBUS_CONST_STRING_PREAMBLE (str); 1776 _dbus_assert (start <= real->len); 1777 _dbus_assert (start >= 0); 1778 1779 i = start; 1780 while (i < real->len) 1781 { 1782 if (real->str[i] == ' ' || 1783 real->str[i] == '\t') 1784 { 1785 if (found) 1786 *found = i; 1787 return TRUE; 1788 } 1789 1790 ++i; 1791 } 1792 1793 if (found) 1794 *found = real->len; 1795 1796 return FALSE; 1797 } 1798 1799 /** 1800 * Skips blanks from start, storing the first non-blank in *end 1801 * (blank is space or tab). 1802 * 1803 * @param str the string 1804 * @param start where to start 1805 * @param end where to store the first non-blank byte index 1806 */ 1807 void 1808 _dbus_string_skip_blank (const DBusString *str, 1809 int start, 1810 int *end) 1811 { 1812 int i; 1813 DBUS_CONST_STRING_PREAMBLE (str); 1814 _dbus_assert (start <= real->len); 1815 _dbus_assert (start >= 0); 1816 1817 i = start; 1818 while (i < real->len) 1819 { 1820 if (!DBUS_IS_ASCII_BLANK (real->str[i])) 1821 break; 1822 1823 ++i; 1824 } 1825 1826 _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i])); 1827 1828 if (end) 1829 *end = i; 1830 } 1831 1832 1833 /** 1834 * Skips whitespace from start, storing the first non-whitespace in *end. 1835 * (whitespace is space, tab, newline, CR). 1836 * 1837 * @param str the string 1838 * @param start where to start 1839 * @param end where to store the first non-whitespace byte index 1840 */ 1841 void 1842 _dbus_string_skip_white (const DBusString *str, 1843 int start, 1844 int *end) 1845 { 1846 int i; 1847 DBUS_CONST_STRING_PREAMBLE (str); 1848 _dbus_assert (start <= real->len); 1849 _dbus_assert (start >= 0); 1850 1851 i = start; 1852 while (i < real->len) 1853 { 1854 if (!DBUS_IS_ASCII_WHITE (real->str[i])) 1855 break; 1856 1857 ++i; 1858 } 1859 1860 _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i]))); 1861 1862 if (end) 1863 *end = i; 1864 } 1865 1866 /** 1867 * Skips whitespace from end, storing the start index of the trailing 1868 * whitespace in *start. (whitespace is space, tab, newline, CR). 1869 * 1870 * @param str the string 1871 * @param end where to start scanning backward 1872 * @param start where to store the start of whitespace chars 1873 */ 1874 void 1875 _dbus_string_skip_white_reverse (const DBusString *str, 1876 int end, 1877 int *start) 1878 { 1879 int i; 1880 DBUS_CONST_STRING_PREAMBLE (str); 1881 _dbus_assert (end <= real->len); 1882 _dbus_assert (end >= 0); 1883 1884 i = end; 1885 while (i > 0) 1886 { 1887 if (!DBUS_IS_ASCII_WHITE (real->str[i-1])) 1888 break; 1889 --i; 1890 } 1891 1892 _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1])))); 1893 1894 if (start) 1895 *start = i; 1896 } 1897 1898 /** 1899 * Assigns a newline-terminated or \\r\\n-terminated line from the front 1900 * of the string to the given dest string. The dest string's previous 1901 * contents are deleted. If the source string contains no newline, 1902 * moves the entire source string to the dest string. 1903 * 1904 * @todo owen correctly notes that this is a stupid function (it was 1905 * written purely for test code, 1906 * e.g. dbus-message-builder.c). Probably should be enforced as test 1907 * code only with ifdef DBUS_BUILD_TESTS 1908 * 1909 * @param source the source string 1910 * @param dest the destination string (contents are replaced) 1911 * @returns #FALSE if no memory, or source has length 0 1912 */ 1913 dbus_bool_t 1914 _dbus_string_pop_line (DBusString *source, 1915 DBusString *dest) 1916 { 1917 int eol, eol_len; 1918 1919 _dbus_string_set_length (dest, 0); 1920 1921 eol = 0; 1922 eol_len = 0; 1923 if (!_dbus_string_find_eol (source, 0, &eol, &eol_len)) 1924 { 1925 _dbus_assert (eol == _dbus_string_get_length (source)); 1926 if (eol == 0) 1927 { 1928 /* If there's no newline and source has zero length, we're done */ 1929 return FALSE; 1930 } 1931 /* otherwise, the last line of the file has no eol characters */ 1932 } 1933 1934 /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also 1935 * since find_eol returned TRUE 1936 */ 1937 1938 if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0)) 1939 return FALSE; 1940 1941 /* remove line ending */ 1942 if (!_dbus_string_set_length (dest, eol)) 1943 { 1944 _dbus_assert_not_reached ("out of memory when shortening a string"); 1945 return FALSE; 1946 } 1947 1948 return TRUE; 1949 } 1950 1951 #ifdef DBUS_BUILD_TESTS 1952 /** 1953 * Deletes up to and including the first blank space 1954 * in the string. 1955 * 1956 * @param str the string 1957 */ 1958 void 1959 _dbus_string_delete_first_word (DBusString *str) 1960 { 1961 int i; 1962 1963 if (_dbus_string_find_blank (str, 0, &i)) 1964 _dbus_string_skip_blank (str, i, &i); 1965 1966 _dbus_string_delete (str, 0, i); 1967 } 1968 #endif 1969 1970 #ifdef DBUS_BUILD_TESTS 1971 /** 1972 * Deletes any leading blanks in the string 1973 * 1974 * @param str the string 1975 */ 1976 void 1977 _dbus_string_delete_leading_blanks (DBusString *str) 1978 { 1979 int i; 1980 1981 _dbus_string_skip_blank (str, 0, &i); 1982 1983 if (i > 0) 1984 _dbus_string_delete (str, 0, i); 1985 } 1986 #endif 1987 1988 /** 1989 * Deletes leading and trailing whitespace 1990 * 1991 * @param str the string 1992 */ 1993 void 1994 _dbus_string_chop_white(DBusString *str) 1995 { 1996 int i; 1997 1998 _dbus_string_skip_white (str, 0, &i); 1999 2000 if (i > 0) 2001 _dbus_string_delete (str, 0, i); 2002 2003 _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i); 2004 2005 _dbus_string_set_length (str, i); 2006 } 2007 2008 /** 2009 * Tests two DBusString for equality. 2010 * 2011 * @todo memcmp is probably faster 2012 * 2013 * @param a first string 2014 * @param b second string 2015 * @returns #TRUE if equal 2016 */ 2017 dbus_bool_t 2018 _dbus_string_equal (const DBusString *a, 2019 const DBusString *b) 2020 { 2021 const unsigned char *ap; 2022 const unsigned char *bp; 2023 const unsigned char *a_end; 2024 const DBusRealString *real_a = (const DBusRealString*) a; 2025 const DBusRealString *real_b = (const DBusRealString*) b; 2026 DBUS_GENERIC_STRING_PREAMBLE (real_a); 2027 DBUS_GENERIC_STRING_PREAMBLE (real_b); 2028 2029 if (real_a->len != real_b->len) 2030 return FALSE; 2031 2032 ap = real_a->str; 2033 bp = real_b->str; 2034 a_end = real_a->str + real_a->len; 2035 while (ap != a_end) 2036 { 2037 if (*ap != *bp) 2038 return FALSE; 2039 2040 ++ap; 2041 ++bp; 2042 } 2043 2044 return TRUE; 2045 } 2046 2047 /** 2048 * Tests two DBusString for equality up to the given length. 2049 * The strings may be shorter than the given length. 2050 * 2051 * @todo write a unit test 2052 * 2053 * @todo memcmp is probably faster 2054 * 2055 * @param a first string 2056 * @param b second string 2057 * @param len the maximum length to look at 2058 * @returns #TRUE if equal for the given number of bytes 2059 */ 2060 dbus_bool_t 2061 _dbus_string_equal_len (const DBusString *a, 2062 const DBusString *b, 2063 int len) 2064 { 2065 const unsigned char *ap; 2066 const unsigned char *bp; 2067 const unsigned char *a_end; 2068 const DBusRealString *real_a = (const DBusRealString*) a; 2069 const DBusRealString *real_b = (const DBusRealString*) b; 2070 DBUS_GENERIC_STRING_PREAMBLE (real_a); 2071 DBUS_GENERIC_STRING_PREAMBLE (real_b); 2072 2073 if (real_a->len != real_b->len && 2074 (real_a->len < len || real_b->len < len)) 2075 return FALSE; 2076 2077 ap = real_a->str; 2078 bp = real_b->str; 2079 a_end = real_a->str + MIN (real_a->len, len); 2080 while (ap != a_end) 2081 { 2082 if (*ap != *bp) 2083 return FALSE; 2084 2085 ++ap; 2086 ++bp; 2087 } 2088 2089 return TRUE; 2090 } 2091 2092 /** 2093 * Tests two sub-parts of two DBusString for equality. The specified 2094 * range of the first string must exist; the specified start position 2095 * of the second string must exist. 2096 * 2097 * @todo write a unit test 2098 * 2099 * @todo memcmp is probably faster 2100 * 2101 * @param a first string 2102 * @param a_start where to start substring in first string 2103 * @param a_len length of substring in first string 2104 * @param b second string 2105 * @param b_start where to start substring in second string 2106 * @returns #TRUE if the two substrings are equal 2107 */ 2108 dbus_bool_t 2109 _dbus_string_equal_substring (const DBusString *a, 2110 int a_start, 2111 int a_len, 2112 const DBusString *b, 2113 int b_start) 2114 { 2115 const unsigned char *ap; 2116 const unsigned char *bp; 2117 const unsigned char *a_end; 2118 const DBusRealString *real_a = (const DBusRealString*) a; 2119 const DBusRealString *real_b = (const DBusRealString*) b; 2120 DBUS_GENERIC_STRING_PREAMBLE (real_a); 2121 DBUS_GENERIC_STRING_PREAMBLE (real_b); 2122 _dbus_assert (a_start >= 0); 2123 _dbus_assert (a_len >= 0); 2124 _dbus_assert (a_start <= real_a->len); 2125 _dbus_assert (a_len <= real_a->len - a_start); 2126 _dbus_assert (b_start >= 0); 2127 _dbus_assert (b_start <= real_b->len); 2128 2129 if (a_len > real_b->len - b_start) 2130 return FALSE; 2131 2132 ap = real_a->str + a_start; 2133 bp = real_b->str + b_start; 2134 a_end = ap + a_len; 2135 while (ap != a_end) 2136 { 2137 if (*ap != *bp) 2138 return FALSE; 2139 2140 ++ap; 2141 ++bp; 2142 } 2143 2144 _dbus_assert (bp <= (real_b->str + real_b->len)); 2145 2146 return TRUE; 2147 } 2148 2149 /** 2150 * Checks whether a string is equal to a C string. 2151 * 2152 * @param a the string 2153 * @param c_str the C string 2154 * @returns #TRUE if equal 2155 */ 2156 dbus_bool_t 2157 _dbus_string_equal_c_str (const DBusString *a, 2158 const char *c_str) 2159 { 2160 const unsigned char *ap; 2161 const unsigned char *bp; 2162 const unsigned char *a_end; 2163 const DBusRealString *real_a = (const DBusRealString*) a; 2164 DBUS_GENERIC_STRING_PREAMBLE (real_a); 2165 _dbus_assert (c_str != NULL); 2166 2167 ap = real_a->str; 2168 bp = (const unsigned char*) c_str; 2169 a_end = real_a->str + real_a->len; 2170 while (ap != a_end && *bp) 2171 { 2172 if (*ap != *bp) 2173 return FALSE; 2174 2175 ++ap; 2176 ++bp; 2177 } 2178 2179 if (ap != a_end || *bp) 2180 return FALSE; 2181 2182 return TRUE; 2183 } 2184 2185 /** 2186 * Checks whether a string starts with the given C string. 2187 * 2188 * @param a the string 2189 * @param c_str the C string 2190 * @returns #TRUE if string starts with it 2191 */ 2192 dbus_bool_t 2193 _dbus_string_starts_with_c_str (const DBusString *a, 2194 const char *c_str) 2195 { 2196 const unsigned char *ap; 2197 const unsigned char *bp; 2198 const unsigned char *a_end; 2199 const DBusRealString *real_a = (const DBusRealString*) a; 2200 DBUS_GENERIC_STRING_PREAMBLE (real_a); 2201 _dbus_assert (c_str != NULL); 2202 2203 ap = real_a->str; 2204 bp = (const unsigned char*) c_str; 2205 a_end = real_a->str + real_a->len; 2206 while (ap != a_end && *bp) 2207 { 2208 if (*ap != *bp) 2209 return FALSE; 2210 2211 ++ap; 2212 ++bp; 2213 } 2214 2215 if (*bp == '\0') 2216 return TRUE; 2217 else 2218 return FALSE; 2219 } 2220 2221 /** 2222 * Appends a two-character hex digit to a string, where the hex digit 2223 * has the value of the given byte. 2224 * 2225 * @param str the string 2226 * @param byte the byte 2227 * @returns #FALSE if no memory 2228 */ 2229 dbus_bool_t 2230 _dbus_string_append_byte_as_hex (DBusString *str, 2231 int byte) 2232 { 2233 const char hexdigits[16] = { 2234 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 2235 'a', 'b', 'c', 'd', 'e', 'f' 2236 }; 2237 2238 if (!_dbus_string_append_byte (str, 2239 hexdigits[(byte >> 4)])) 2240 return FALSE; 2241 2242 if (!_dbus_string_append_byte (str, 2243 hexdigits[(byte & 0x0f)])) 2244 { 2245 _dbus_string_set_length (str, 2246 _dbus_string_get_length (str) - 1); 2247 return FALSE; 2248 } 2249 2250 return TRUE; 2251 } 2252 2253 /** 2254 * Encodes a string in hex, the way MD5 and SHA-1 are usually 2255 * encoded. (Each byte is two hex digits.) 2256 * 2257 * @param source the string to encode 2258 * @param start byte index to start encoding 2259 * @param dest string where encoded data should be placed 2260 * @param insert_at where to place encoded data 2261 * @returns #TRUE if encoding was successful, #FALSE if no memory etc. 2262 */ 2263 dbus_bool_t 2264 _dbus_string_hex_encode (const DBusString *source, 2265 int start, 2266 DBusString *dest, 2267 int insert_at) 2268 { 2269 DBusString result; 2270 const unsigned char *p; 2271 const unsigned char *end; 2272 dbus_bool_t retval; 2273 2274 _dbus_assert (start <= _dbus_string_get_length (source)); 2275 2276 if (!_dbus_string_init (&result)) 2277 return FALSE; 2278 2279 retval = FALSE; 2280 2281 p = (const unsigned char*) _dbus_string_get_const_data (source); 2282 end = p + _dbus_string_get_length (source); 2283 p += start; 2284 2285 while (p != end) 2286 { 2287 if (!_dbus_string_append_byte_as_hex (&result, *p)) 2288 goto out; 2289 2290 ++p; 2291 } 2292 2293 if (!_dbus_string_move (&result, 0, dest, insert_at)) 2294 goto out; 2295 2296 retval = TRUE; 2297 2298 out: 2299 _dbus_string_free (&result); 2300 return retval; 2301 } 2302 2303 /** 2304 * Decodes a string from hex encoding. 2305 * 2306 * @param source the string to decode 2307 * @param start byte index to start decode 2308 * @param end_return return location of the end of the hex data, or #NULL 2309 * @param dest string where decoded data should be placed 2310 * @param insert_at where to place decoded data 2311 * @returns #TRUE if decoding was successful, #FALSE if no memory. 2312 */ 2313 dbus_bool_t 2314 _dbus_string_hex_decode (const DBusString *source, 2315 int start, 2316 int *end_return, 2317 DBusString *dest, 2318 int insert_at) 2319 { 2320 DBusString result; 2321 const unsigned char *p; 2322 const unsigned char *end; 2323 dbus_bool_t retval; 2324 dbus_bool_t high_bits; 2325 2326 _dbus_assert (start <= _dbus_string_get_length (source)); 2327 2328 if (!_dbus_string_init (&result)) 2329 return FALSE; 2330 2331 retval = FALSE; 2332 2333 high_bits = TRUE; 2334 p = (const unsigned char*) _dbus_string_get_const_data (source); 2335 end = p + _dbus_string_get_length (source); 2336 p += start; 2337 2338 while (p != end) 2339 { 2340 unsigned int val; 2341 2342 switch (*p) 2343 { 2344 case '0': 2345 val = 0; 2346 break; 2347 case '1': 2348 val = 1; 2349 break; 2350 case '2': 2351 val = 2; 2352 break; 2353 case '3': 2354 val = 3; 2355 break; 2356 case '4': 2357 val = 4; 2358 break; 2359 case '5': 2360 val = 5; 2361 break; 2362 case '6': 2363 val = 6; 2364 break; 2365 case '7': 2366 val = 7; 2367 break; 2368 case '8': 2369 val = 8; 2370 break; 2371 case '9': 2372 val = 9; 2373 break; 2374 case 'a': 2375 case 'A': 2376 val = 10; 2377 break; 2378 case 'b': 2379 case 'B': 2380 val = 11; 2381 break; 2382 case 'c': 2383 case 'C': 2384 val = 12; 2385 break; 2386 case 'd': 2387 case 'D': 2388 val = 13; 2389 break; 2390 case 'e': 2391 case 'E': 2392 val = 14; 2393 break; 2394 case 'f': 2395 case 'F': 2396 val = 15; 2397 break; 2398 default: 2399 goto done; 2400 } 2401 2402 if (high_bits) 2403 { 2404 if (!_dbus_string_append_byte (&result, 2405 val << 4)) 2406 goto out; 2407 } 2408 else 2409 { 2410 int len; 2411 unsigned char b; 2412 2413 len = _dbus_string_get_length (&result); 2414 2415 b = _dbus_string_get_byte (&result, len - 1); 2416 2417 b |= val; 2418 2419 _dbus_string_set_byte (&result, len - 1, b); 2420 } 2421 2422 high_bits = !high_bits; 2423 2424 ++p; 2425 } 2426 2427 done: 2428 if (!_dbus_string_move (&result, 0, dest, insert_at)) 2429 goto out; 2430 2431 if (end_return) 2432 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source); 2433 2434 retval = TRUE; 2435 2436 out: 2437 _dbus_string_free (&result); 2438 return retval; 2439 } 2440 2441 /** 2442 * Checks that the given range of the string is valid ASCII with no 2443 * nul bytes. If the given range is not entirely contained in the 2444 * string, returns #FALSE. 2445 * 2446 * @todo this is inconsistent with most of DBusString in that 2447 * it allows a start,len range that extends past the string end. 2448 * 2449 * @param str the string 2450 * @param start first byte index to check 2451 * @param len number of bytes to check 2452 * @returns #TRUE if the byte range exists and is all valid ASCII 2453 */ 2454 dbus_bool_t 2455 _dbus_string_validate_ascii (const DBusString *str, 2456 int start, 2457 int len) 2458 { 2459 const unsigned char *s; 2460 const unsigned char *end; 2461 DBUS_CONST_STRING_PREAMBLE (str); 2462 _dbus_assert (start >= 0); 2463 _dbus_assert (start <= real->len); 2464 _dbus_assert (len >= 0); 2465 2466 if (len > real->len - start) 2467 return FALSE; 2468 2469 s = real->str + start; 2470 end = s + len; 2471 while (s != end) 2472 { 2473 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s))) 2474 return FALSE; 2475 2476 ++s; 2477 } 2478 2479 return TRUE; 2480 } 2481 2482 /** 2483 * Converts the given range of the string to lower case. 2484 * 2485 * @param str the string 2486 * @param start first byte index to convert 2487 * @param len number of bytes to convert 2488 */ 2489 void 2490 _dbus_string_tolower_ascii (const DBusString *str, 2491 int start, 2492 int len) 2493 { 2494 unsigned char *s; 2495 unsigned char *end; 2496 DBUS_STRING_PREAMBLE (str); 2497 _dbus_assert (start >= 0); 2498 _dbus_assert (start <= real->len); 2499 _dbus_assert (len >= 0); 2500 _dbus_assert (len <= real->len - start); 2501 2502 s = real->str + start; 2503 end = s + len; 2504 2505 while (s != end) 2506 { 2507 if (*s >= 'A' && *s <= 'Z') 2508 *s += 'a' - 'A'; 2509 ++s; 2510 } 2511 } 2512 2513 /** 2514 * Converts the given range of the string to upper case. 2515 * 2516 * @param str the string 2517 * @param start first byte index to convert 2518 * @param len number of bytes to convert 2519 */ 2520 void 2521 _dbus_string_toupper_ascii (const DBusString *str, 2522 int start, 2523 int len) 2524 { 2525 unsigned char *s; 2526 unsigned char *end; 2527 DBUS_STRING_PREAMBLE (str); 2528 _dbus_assert (start >= 0); 2529 _dbus_assert (start <= real->len); 2530 _dbus_assert (len >= 0); 2531 _dbus_assert (len <= real->len - start); 2532 2533 s = real->str + start; 2534 end = s + len; 2535 2536 while (s != end) 2537 { 2538 if (*s >= 'a' && *s <= 'z') 2539 *s += 'A' - 'a'; 2540 ++s; 2541 } 2542 } 2543 2544 /** 2545 * Checks that the given range of the string is valid UTF-8. If the 2546 * given range is not entirely contained in the string, returns 2547 * #FALSE. If the string contains any nul bytes in the given range, 2548 * returns #FALSE. If the start and start+len are not on character 2549 * boundaries, returns #FALSE. 2550 * 2551 * @todo this is inconsistent with most of DBusString in that 2552 * it allows a start,len range that extends past the string end. 2553 * 2554 * @param str the string 2555 * @param start first byte index to check 2556 * @param len number of bytes to check 2557 * @returns #TRUE if the byte range exists and is all valid UTF-8 2558 */ 2559 dbus_bool_t 2560 _dbus_string_validate_utf8 (const DBusString *str, 2561 int start, 2562 int len) 2563 { 2564 const unsigned char *p; 2565 const unsigned char *end; 2566 DBUS_CONST_STRING_PREAMBLE (str); 2567 _dbus_assert (start >= 0); 2568 _dbus_assert (start <= real->len); 2569 _dbus_assert (len >= 0); 2570 2571 /* we are doing _DBUS_UNLIKELY() here which might be 2572 * dubious in a generic library like GLib, but in D-Bus 2573 * we know we're validating messages and that it would 2574 * only be evil/broken apps that would have invalid 2575 * UTF-8. Also, this function seems to be a performance 2576 * bottleneck in profiles. 2577 */ 2578 2579 if (_DBUS_UNLIKELY (len > real->len - start)) 2580 return FALSE; 2581 2582 p = real->str + start; 2583 end = p + len; 2584 2585 while (p < end) 2586 { 2587 int i, mask, char_len; 2588 dbus_unichar_t result; 2589 2590 /* nul bytes considered invalid */ 2591 if (*p == '\0') 2592 break; 2593 2594 /* Special-case ASCII; this makes us go a lot faster in 2595 * D-Bus profiles where we are typically validating 2596 * function names and such. We have to know that 2597 * all following checks will pass for ASCII though, 2598 * comments follow ... 2599 */ 2600 if (*p < 128) 2601 { 2602 ++p; 2603 continue; 2604 } 2605 2606 UTF8_COMPUTE (*p, mask, char_len); 2607 2608 if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */ 2609 break; 2610 2611 /* check that the expected number of bytes exists in the remaining length */ 2612 if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */ 2613 break; 2614 2615 UTF8_GET (result, p, i, mask, char_len); 2616 2617 /* Check for overlong UTF-8 */ 2618 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */ 2619 break; 2620 #if 0 2621 /* The UNICODE_VALID check below will catch this */ 2622 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */ 2623 break; 2624 #endif 2625 2626 if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */ 2627 break; 2628 2629 /* UNICODE_VALID should have caught it */ 2630 _dbus_assert (result != (dbus_unichar_t)-1); 2631 2632 p += char_len; 2633 } 2634 2635 /* See that we covered the entire length if a length was 2636 * passed in 2637 */ 2638 if (_DBUS_UNLIKELY (p != end)) 2639 return FALSE; 2640 else 2641 return TRUE; 2642 } 2643 2644 /** 2645 * Checks that the given range of the string is all nul bytes. If the 2646 * given range is not entirely contained in the string, returns 2647 * #FALSE. 2648 * 2649 * @todo this is inconsistent with most of DBusString in that 2650 * it allows a start,len range that extends past the string end. 2651 * 2652 * @param str the string 2653 * @param start first byte index to check 2654 * @param len number of bytes to check 2655 * @returns #TRUE if the byte range exists and is all nul bytes 2656 */ 2657 dbus_bool_t 2658 _dbus_string_validate_nul (const DBusString *str, 2659 int start, 2660 int len) 2661 { 2662 const unsigned char *s; 2663 const unsigned char *end; 2664 DBUS_CONST_STRING_PREAMBLE (str); 2665 _dbus_assert (start >= 0); 2666 _dbus_assert (len >= 0); 2667 _dbus_assert (start <= real->len); 2668 2669 if (len > real->len - start) 2670 return FALSE; 2671 2672 s = real->str + start; 2673 end = s + len; 2674 while (s != end) 2675 { 2676 if (_DBUS_UNLIKELY (*s != '\0')) 2677 return FALSE; 2678 ++s; 2679 } 2680 2681 return TRUE; 2682 } 2683 2684 /** 2685 * Clears all allocated bytes in the string to zero. 2686 * 2687 * @param str the string 2688 */ 2689 void 2690 _dbus_string_zero (DBusString *str) 2691 { 2692 DBUS_STRING_PREAMBLE (str); 2693 2694 memset (real->str - real->align_offset, '\0', real->allocated); 2695 } 2696 /** @} */ 2697 2698 /* tests are in dbus-string-util.c */ 2699