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