00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-internals.h"
00025 #include "dbus-string.h"
00026
00027 #include <string.h>
00028
00029 #include <stdio.h>
00030 #include "dbus-marshal.h"
00031 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
00032 #include "dbus-string-private.h"
00033 #include "dbus-protocol.h"
00034
00035 #include "dbus-sysdeps.h"
00036
00079 #define ALLOCATION_PADDING 8
00080
00085 #define MAX_MAX_LENGTH (_DBUS_INT_MAX - ALLOCATION_PADDING)
00086
00092 #define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= ((real)->allocated - ALLOCATION_PADDING)); _dbus_assert ((real)->len <= (real)->max_length)
00093
00100 #define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00101 DBUS_GENERIC_STRING_PREAMBLE (real); \
00102 _dbus_assert (!(real)->constant); \
00103 _dbus_assert (!(real)->locked)
00104
00112 #define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00113 DBUS_GENERIC_STRING_PREAMBLE (real); \
00114 _dbus_assert (!(real)->constant)
00115
00121 #define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
00122 DBUS_GENERIC_STRING_PREAMBLE (real)
00123
00131 static void
00132 fixup_alignment (DBusRealString *real)
00133 {
00134 char *aligned;
00135 char *real_block;
00136 unsigned int old_align_offset;
00137
00138
00139 _dbus_assert (real->len <= real->allocated - ALLOCATION_PADDING);
00140
00141 old_align_offset = real->align_offset;
00142 real_block = real->str - old_align_offset;
00143
00144 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
00145
00146 real->align_offset = aligned - real_block;
00147 real->str = aligned;
00148
00149 if (old_align_offset != real->align_offset)
00150 {
00151
00152 memmove (real_block + real->align_offset,
00153 real_block + old_align_offset,
00154 real->len + 1);
00155 }
00156
00157 _dbus_assert (real->align_offset < 8);
00158 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
00159 }
00160
00161 static void
00162 undo_alignment (DBusRealString *real)
00163 {
00164 if (real->align_offset != 0)
00165 {
00166 memmove (real->str - real->align_offset,
00167 real->str,
00168 real->len + 1);
00169
00170 real->str = real->str - real->align_offset;
00171 real->align_offset = 0;
00172 }
00173 }
00174
00184 dbus_bool_t
00185 _dbus_string_init_preallocated (DBusString *str,
00186 int allocate_size)
00187 {
00188 DBusRealString *real;
00189
00190 _dbus_assert (str != NULL);
00191
00192 _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
00193
00194 real = (DBusRealString*) str;
00195
00196
00197
00198
00199
00200
00201
00202 real->str = dbus_malloc (ALLOCATION_PADDING + allocate_size);
00203 if (real->str == NULL)
00204 return FALSE;
00205
00206 real->allocated = ALLOCATION_PADDING + allocate_size;
00207 real->len = 0;
00208 real->str[real->len] = '\0';
00209
00210 real->max_length = MAX_MAX_LENGTH;
00211 real->constant = FALSE;
00212 real->locked = FALSE;
00213 real->invalid = FALSE;
00214 real->align_offset = 0;
00215
00216 fixup_alignment (real);
00217
00218 return TRUE;
00219 }
00220
00228 dbus_bool_t
00229 _dbus_string_init (DBusString *str)
00230 {
00231 return _dbus_string_init_preallocated (str, 0);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240 static void
00241 set_max_length (DBusString *str,
00242 int max_length)
00243 {
00244 DBusRealString *real;
00245
00246 real = (DBusRealString*) str;
00247
00248 real->max_length = max_length;
00249 }
00250
00260 void
00261 _dbus_string_init_const (DBusString *str,
00262 const char *value)
00263 {
00264 _dbus_assert (value != NULL);
00265
00266 _dbus_string_init_const_len (str, value,
00267 strlen (value));
00268 }
00269
00280 void
00281 _dbus_string_init_const_len (DBusString *str,
00282 const char *value,
00283 int len)
00284 {
00285 DBusRealString *real;
00286
00287 _dbus_assert (str != NULL);
00288 _dbus_assert (value != NULL);
00289 _dbus_assert (len <= MAX_MAX_LENGTH);
00290 _dbus_assert (len >= 0);
00291
00292 real = (DBusRealString*) str;
00293
00294 real->str = (char*) value;
00295 real->len = len;
00296 real->allocated = real->len + ALLOCATION_PADDING;
00297 real->max_length = real->len + 1;
00298 real->constant = TRUE;
00299 real->invalid = FALSE;
00300
00301
00302
00303
00304 }
00305
00311 void
00312 _dbus_string_free (DBusString *str)
00313 {
00314 DBusRealString *real = (DBusRealString*) str;
00315 DBUS_GENERIC_STRING_PREAMBLE (real);
00316
00317 if (real->constant)
00318 return;
00319 dbus_free (real->str - real->align_offset);
00320
00321 real->invalid = TRUE;
00322 }
00323
00324 #ifdef DBUS_BUILD_TESTS
00325
00326
00327
00337 void
00338 _dbus_string_lock (DBusString *str)
00339 {
00340 DBUS_LOCKED_STRING_PREAMBLE (str);
00341
00342 real->locked = TRUE;
00343
00344
00345
00346
00347 #define MAX_WASTE 48
00348 if (real->allocated - MAX_WASTE > real->len)
00349 {
00350 char *new_str;
00351 int new_allocated;
00352
00353 new_allocated = real->len + ALLOCATION_PADDING;
00354
00355 new_str = dbus_realloc (real->str - real->align_offset,
00356 new_allocated);
00357 if (new_str != NULL)
00358 {
00359 real->str = new_str + real->align_offset;
00360 real->allocated = new_allocated;
00361 fixup_alignment (real);
00362 }
00363 }
00364 }
00365 #endif
00366
00367 static dbus_bool_t
00368 reallocate_for_length (DBusRealString *real,
00369 int new_length)
00370 {
00371 int new_allocated;
00372 char *new_str;
00373
00374
00375
00376
00377 if (real->allocated > (MAX_MAX_LENGTH + ALLOCATION_PADDING) / 2)
00378 new_allocated = MAX_MAX_LENGTH + ALLOCATION_PADDING;
00379 else
00380 new_allocated = real->allocated * 2;
00381
00382
00383
00384
00385 #ifdef DBUS_BUILD_TESTS
00386 new_allocated = 0;
00387
00388
00389 #endif
00390
00391
00392 new_allocated = MAX (new_allocated, new_length + ALLOCATION_PADDING);
00393
00394 _dbus_assert (new_allocated >= real->allocated);
00395 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00396 if (new_str == NULL)
00397 return FALSE;
00398
00399 real->str = new_str + real->align_offset;
00400 real->allocated = new_allocated;
00401 fixup_alignment (real);
00402
00403 return TRUE;
00404 }
00405
00406 static dbus_bool_t
00407 set_length (DBusRealString *real,
00408 int new_length)
00409 {
00410
00411
00412
00413 if (new_length > real->max_length)
00414 return FALSE;
00415 else if (new_length > (real->allocated - ALLOCATION_PADDING) &&
00416 !reallocate_for_length (real, new_length))
00417 return FALSE;
00418 else
00419 {
00420 real->len = new_length;
00421 real->str[real->len] = '\0';
00422 return TRUE;
00423 }
00424 }
00425
00426 static dbus_bool_t
00427 open_gap (int len,
00428 DBusRealString *dest,
00429 int insert_at)
00430 {
00431 if (len == 0)
00432 return TRUE;
00433
00434 if (len > dest->max_length - dest->len)
00435 return FALSE;
00436
00437 if (!set_length (dest, dest->len + len))
00438 return FALSE;
00439
00440 memmove (dest->str + insert_at + len,
00441 dest->str + insert_at,
00442 dest->len - len - insert_at);
00443
00444 return TRUE;
00445 }
00446
00458 char*
00459 _dbus_string_get_data (DBusString *str)
00460 {
00461 DBUS_STRING_PREAMBLE (str);
00462
00463 return real->str;
00464 }
00465
00472 const char*
00473 _dbus_string_get_const_data (const DBusString *str)
00474 {
00475 DBUS_CONST_STRING_PREAMBLE (str);
00476
00477 return real->str;
00478 }
00479
00493 char*
00494 _dbus_string_get_data_len (DBusString *str,
00495 int start,
00496 int len)
00497 {
00498 DBUS_STRING_PREAMBLE (str);
00499 _dbus_assert (start >= 0);
00500 _dbus_assert (len >= 0);
00501 _dbus_assert (start <= real->len);
00502 _dbus_assert (len <= real->len - start);
00503
00504 return real->str + start;
00505 }
00506
00515 const char*
00516 _dbus_string_get_const_data_len (const DBusString *str,
00517 int start,
00518 int len)
00519 {
00520 DBUS_CONST_STRING_PREAMBLE (str);
00521 _dbus_assert (start >= 0);
00522 _dbus_assert (len >= 0);
00523 _dbus_assert (start <= real->len);
00524 _dbus_assert (len <= real->len - start);
00525
00526 return real->str + start;
00527 }
00528
00536 void
00537 _dbus_string_set_byte (DBusString *str,
00538 int i,
00539 unsigned char byte)
00540 {
00541 DBUS_STRING_PREAMBLE (str);
00542 _dbus_assert (i < real->len);
00543 _dbus_assert (i >= 0);
00544
00545 real->str[i] = byte;
00546 }
00547
00557 unsigned char
00558 _dbus_string_get_byte (const DBusString *str,
00559 int start)
00560 {
00561 DBUS_CONST_STRING_PREAMBLE (str);
00562 _dbus_assert (start <= real->len);
00563 _dbus_assert (start >= 0);
00564
00565 return real->str[start];
00566 }
00567
00578 dbus_bool_t
00579 _dbus_string_insert_bytes (DBusString *str,
00580 int i,
00581 int n_bytes,
00582 unsigned char byte)
00583 {
00584 DBUS_STRING_PREAMBLE (str);
00585 _dbus_assert (i <= real->len);
00586 _dbus_assert (i >= 0);
00587 _dbus_assert (n_bytes >= 0);
00588
00589 if (n_bytes == 0)
00590 return TRUE;
00591
00592 if (!open_gap (n_bytes, real, i))
00593 return FALSE;
00594
00595 memset (real->str + i, byte, n_bytes);
00596
00597 return TRUE;
00598 }
00599
00610 dbus_bool_t
00611 _dbus_string_steal_data (DBusString *str,
00612 char **data_return)
00613 {
00614 int old_max_length;
00615 DBUS_STRING_PREAMBLE (str);
00616 _dbus_assert (data_return != NULL);
00617
00618 undo_alignment (real);
00619
00620 *data_return = real->str;
00621
00622 old_max_length = real->max_length;
00623
00624
00625 if (!_dbus_string_init (str))
00626 {
00627
00628 real->str = *data_return;
00629 *data_return = NULL;
00630 fixup_alignment (real);
00631 return FALSE;
00632 }
00633
00634 real->max_length = old_max_length;
00635
00636 return TRUE;
00637 }
00638
00654 dbus_bool_t
00655 _dbus_string_steal_data_len (DBusString *str,
00656 char **data_return,
00657 int start,
00658 int len)
00659 {
00660 DBusString dest;
00661 DBUS_STRING_PREAMBLE (str);
00662 _dbus_assert (data_return != NULL);
00663 _dbus_assert (start >= 0);
00664 _dbus_assert (len >= 0);
00665 _dbus_assert (start <= real->len);
00666 _dbus_assert (len <= real->len - start);
00667
00668 if (!_dbus_string_init (&dest))
00669 return FALSE;
00670
00671 set_max_length (&dest, real->max_length);
00672
00673 if (!_dbus_string_move_len (str, start, len, &dest, 0))
00674 {
00675 _dbus_string_free (&dest);
00676 return FALSE;
00677 }
00678
00679 _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
00680 if (!_dbus_string_steal_data (&dest, data_return))
00681 {
00682 _dbus_string_free (&dest);
00683 return FALSE;
00684 }
00685
00686 _dbus_string_free (&dest);
00687 return TRUE;
00688 }
00689
00690
00698 dbus_bool_t
00699 _dbus_string_copy_data (const DBusString *str,
00700 char **data_return)
00701 {
00702 DBUS_CONST_STRING_PREAMBLE (str);
00703 _dbus_assert (data_return != NULL);
00704
00705 *data_return = dbus_malloc (real->len + 1);
00706 if (*data_return == NULL)
00707 return FALSE;
00708
00709 memcpy (*data_return, real->str, real->len + 1);
00710
00711 return TRUE;
00712 }
00713
00723 dbus_bool_t
00724 _dbus_string_copy_data_len (const DBusString *str,
00725 char **data_return,
00726 int start,
00727 int len)
00728 {
00729 DBusString dest;
00730
00731 DBUS_CONST_STRING_PREAMBLE (str);
00732 _dbus_assert (data_return != NULL);
00733 _dbus_assert (start >= 0);
00734 _dbus_assert (len >= 0);
00735 _dbus_assert (start <= real->len);
00736 _dbus_assert (len <= real->len - start);
00737
00738 if (!_dbus_string_init (&dest))
00739 return FALSE;
00740
00741 set_max_length (&dest, real->max_length);
00742
00743 if (!_dbus_string_copy_len (str, start, len, &dest, 0))
00744 {
00745 _dbus_string_free (&dest);
00746 return FALSE;
00747 }
00748
00749 if (!_dbus_string_steal_data (&dest, data_return))
00750 {
00751 _dbus_string_free (&dest);
00752 return FALSE;
00753 }
00754
00755 _dbus_string_free (&dest);
00756 return TRUE;
00757 }
00758
00764 int
00765 _dbus_string_get_length (const DBusString *str)
00766 {
00767 DBUS_CONST_STRING_PREAMBLE (str);
00768
00769 return real->len;
00770 }
00771
00784 dbus_bool_t
00785 _dbus_string_lengthen (DBusString *str,
00786 int additional_length)
00787 {
00788 DBUS_STRING_PREAMBLE (str);
00789 _dbus_assert (additional_length >= 0);
00790
00791 if (additional_length > real->max_length - real->len)
00792 return FALSE;
00793
00794 return set_length (real,
00795 real->len + additional_length);
00796 }
00797
00804 void
00805 _dbus_string_shorten (DBusString *str,
00806 int length_to_remove)
00807 {
00808 DBUS_STRING_PREAMBLE (str);
00809 _dbus_assert (length_to_remove >= 0);
00810 _dbus_assert (length_to_remove <= real->len);
00811
00812 set_length (real,
00813 real->len - length_to_remove);
00814 }
00815
00826 dbus_bool_t
00827 _dbus_string_set_length (DBusString *str,
00828 int length)
00829 {
00830 DBUS_STRING_PREAMBLE (str);
00831 _dbus_assert (length >= 0);
00832
00833 return set_length (real, length);
00834 }
00835
00836 static dbus_bool_t
00837 align_length_then_lengthen (DBusString *str,
00838 int alignment,
00839 int then_lengthen_by)
00840 {
00841 unsigned long new_len;
00842 int delta;
00843 DBUS_STRING_PREAMBLE (str);
00844 _dbus_assert (alignment >= 1);
00845 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
00846
00847 new_len = _DBUS_ALIGN_VALUE (real->len, alignment);
00848 if (new_len > (unsigned long) real->max_length - then_lengthen_by)
00849 return FALSE;
00850 new_len += then_lengthen_by;
00851
00852 delta = new_len - real->len;
00853 _dbus_assert (delta >= 0);
00854
00855 if (delta == 0)
00856 return TRUE;
00857
00858 if (!set_length (real, new_len))
00859 return FALSE;
00860
00861
00862
00863
00864 if (then_lengthen_by < delta)
00865 {
00866 unsigned int i;
00867 i = new_len - delta;
00868 while (i < (new_len - then_lengthen_by))
00869 {
00870 real->str[i] = '\0';
00871 ++i;
00872 }
00873 }
00874
00875 return TRUE;
00876 }
00877
00886 dbus_bool_t
00887 _dbus_string_align_length (DBusString *str,
00888 int alignment)
00889 {
00890 return align_length_then_lengthen (str, alignment, 0);
00891 }
00892
00893 static dbus_bool_t
00894 append (DBusRealString *real,
00895 const char *buffer,
00896 int buffer_len)
00897 {
00898 if (buffer_len == 0)
00899 return TRUE;
00900
00901 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
00902 return FALSE;
00903
00904 memcpy (real->str + (real->len - buffer_len),
00905 buffer,
00906 buffer_len);
00907
00908 return TRUE;
00909 }
00910
00918 dbus_bool_t
00919 _dbus_string_append (DBusString *str,
00920 const char *buffer)
00921 {
00922 unsigned long buffer_len;
00923
00924 DBUS_STRING_PREAMBLE (str);
00925 _dbus_assert (buffer != NULL);
00926
00927 buffer_len = strlen (buffer);
00928 if (buffer_len > (unsigned long) real->max_length)
00929 return FALSE;
00930
00931 return append (real, buffer, buffer_len);
00932 }
00933
00942 dbus_bool_t
00943 _dbus_string_append_4_aligned (DBusString *str,
00944 const unsigned char octets[4])
00945 {
00946 dbus_uint32_t *p;
00947 DBUS_STRING_PREAMBLE (str);
00948
00949 if (!align_length_then_lengthen (str, 4, 4))
00950 return FALSE;
00951
00952 p = (dbus_uint32_t*) (real->str + (real->len - 4));
00953 *p = *((dbus_uint32_t*)octets);
00954
00955 return TRUE;
00956 }
00957
00966 dbus_bool_t
00967 _dbus_string_append_8_aligned (DBusString *str,
00968 const unsigned char octets[8])
00969 {
00970 #ifdef DBUS_HAVE_INT64
00971 dbus_uint64_t *p;
00972 DBUS_STRING_PREAMBLE (str);
00973
00974 if (!align_length_then_lengthen (str, 8, 8))
00975 return FALSE;
00976
00977 p = (dbus_uint64_t*) (real->str + (real->len - 8));
00978 *p = *((dbus_uint64_t*)octets);
00979 #else
00980 unsigned char *p;
00981 DBUS_STRING_PREAMBLE (str);
00982
00983 if (!align_length_then_lengthen (str, 8, 8))
00984 return FALSE;
00985
00986 p = real->str + (real->len - 8);
00987
00988 *p++ = octets[0];
00989 *p++ = octets[1];
00990 *p++ = octets[2];
00991 *p++ = octets[3];
00992 *p++ = octets[4];
00993 *p++ = octets[5];
00994 *p++ = octets[6];
00995 *p++ = octets[7];
00996 _dbus_assert (p == (real->str + real->len));
00997 #endif
00998
00999 return TRUE;
01000 }
01001
01011 dbus_bool_t
01012 _dbus_string_append_printf_valist (DBusString *str,
01013 const char *format,
01014 va_list args)
01015 {
01016 int len;
01017 char c;
01018 va_list args_copy;
01019
01020 DBUS_STRING_PREAMBLE (str);
01021
01022 DBUS_VA_COPY (args_copy, args);
01023
01024
01025 len = vsnprintf (&c, 1, format, args);
01026
01027 if (!_dbus_string_lengthen (str, len))
01028 {
01029
01030 va_end (args_copy);
01031 return FALSE;
01032 }
01033
01034 vsprintf (real->str + (real->len - len),
01035 format, args_copy);
01036
01037 va_end (args_copy);
01038
01039 return TRUE;
01040 }
01041
01050 dbus_bool_t
01051 _dbus_string_append_printf (DBusString *str,
01052 const char *format,
01053 ...)
01054 {
01055 va_list args;
01056 dbus_bool_t retval;
01057
01058 va_start (args, format);
01059 retval = _dbus_string_append_printf_valist (str, format, args);
01060 va_end (args);
01061
01062 return retval;
01063 }
01064
01073 dbus_bool_t
01074 _dbus_string_append_len (DBusString *str,
01075 const char *buffer,
01076 int len)
01077 {
01078 DBUS_STRING_PREAMBLE (str);
01079 _dbus_assert (buffer != NULL);
01080 _dbus_assert (len >= 0);
01081
01082 return append (real, buffer, len);
01083 }
01084
01093 dbus_bool_t
01094 _dbus_string_append_byte (DBusString *str,
01095 unsigned char byte)
01096 {
01097 DBUS_STRING_PREAMBLE (str);
01098
01099 if (!set_length (real, real->len + 1))
01100 return FALSE;
01101
01102 real->str[real->len-1] = byte;
01103
01104 return TRUE;
01105 }
01106
01114 dbus_bool_t
01115 _dbus_string_append_unichar (DBusString *str,
01116 dbus_unichar_t ch)
01117 {
01118 int len;
01119 int first;
01120 int i;
01121 char *out;
01122
01123 DBUS_STRING_PREAMBLE (str);
01124
01125
01126
01127 len = 0;
01128
01129 if (ch < 0x80)
01130 {
01131 first = 0;
01132 len = 1;
01133 }
01134 else if (ch < 0x800)
01135 {
01136 first = 0xc0;
01137 len = 2;
01138 }
01139 else if (ch < 0x10000)
01140 {
01141 first = 0xe0;
01142 len = 3;
01143 }
01144 else if (ch < 0x200000)
01145 {
01146 first = 0xf0;
01147 len = 4;
01148 }
01149 else if (ch < 0x4000000)
01150 {
01151 first = 0xf8;
01152 len = 5;
01153 }
01154 else
01155 {
01156 first = 0xfc;
01157 len = 6;
01158 }
01159
01160 if (len > (real->max_length - real->len))
01161 return FALSE;
01162
01163 if (!set_length (real, real->len + len))
01164 return FALSE;
01165
01166 out = real->str + (real->len - len);
01167
01168 for (i = len - 1; i > 0; --i)
01169 {
01170 out[i] = (ch & 0x3f) | 0x80;
01171 ch >>= 6;
01172 }
01173 out[0] = ch | first;
01174
01175 return TRUE;
01176 }
01177
01178 static void
01179 delete (DBusRealString *real,
01180 int start,
01181 int len)
01182 {
01183 if (len == 0)
01184 return;
01185
01186 memmove (real->str + start, real->str + start + len, real->len - (start + len));
01187 real->len -= len;
01188 real->str[real->len] = '\0';
01189 }
01190
01200 void
01201 _dbus_string_delete (DBusString *str,
01202 int start,
01203 int len)
01204 {
01205 DBUS_STRING_PREAMBLE (str);
01206 _dbus_assert (start >= 0);
01207 _dbus_assert (len >= 0);
01208 _dbus_assert (start <= real->len);
01209 _dbus_assert (len <= real->len - start);
01210
01211 delete (real, start, len);
01212 }
01213
01214 static dbus_bool_t
01215 copy (DBusRealString *source,
01216 int start,
01217 int len,
01218 DBusRealString *dest,
01219 int insert_at)
01220 {
01221 if (len == 0)
01222 return TRUE;
01223
01224 if (!open_gap (len, dest, insert_at))
01225 return FALSE;
01226
01227 memcpy (dest->str + insert_at,
01228 source->str + start,
01229 len);
01230
01231 return TRUE;
01232 }
01233
01243 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
01244 DBusRealString *real_source = (DBusRealString*) source; \
01245 DBusRealString *real_dest = (DBusRealString*) dest; \
01246 _dbus_assert ((source) != (dest)); \
01247 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
01248 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
01249 _dbus_assert (!real_dest->constant); \
01250 _dbus_assert (!real_dest->locked); \
01251 _dbus_assert ((start) >= 0); \
01252 _dbus_assert ((start) <= real_source->len); \
01253 _dbus_assert ((insert_at) >= 0); \
01254 _dbus_assert ((insert_at) <= real_dest->len)
01255
01266 dbus_bool_t
01267 _dbus_string_move (DBusString *source,
01268 int start,
01269 DBusString *dest,
01270 int insert_at)
01271 {
01272 DBusRealString *real_source = (DBusRealString*) source;
01273 _dbus_assert (start <= real_source->len);
01274
01275 return _dbus_string_move_len (source, start,
01276 real_source->len - start,
01277 dest, insert_at);
01278 }
01279
01290 dbus_bool_t
01291 _dbus_string_copy (const DBusString *source,
01292 int start,
01293 DBusString *dest,
01294 int insert_at)
01295 {
01296 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01297
01298 return copy (real_source, start,
01299 real_source->len - start,
01300 real_dest,
01301 insert_at);
01302 }
01303
01318 dbus_bool_t
01319 _dbus_string_move_len (DBusString *source,
01320 int start,
01321 int len,
01322 DBusString *dest,
01323 int insert_at)
01324
01325 {
01326 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01327 _dbus_assert (len >= 0);
01328 _dbus_assert ((start + len) <= real_source->len);
01329
01330
01331 if (len == 0)
01332 {
01333 return TRUE;
01334 }
01335 else if (start == 0 &&
01336 len == real_source->len &&
01337 real_dest->len == 0)
01338 {
01339
01340
01341
01342
01343
01344
01345 #define ASSIGN_DATA(a, b) do { \
01346 (a)->str = (b)->str; \
01347 (a)->len = (b)->len; \
01348 (a)->allocated = (b)->allocated; \
01349 (a)->align_offset = (b)->align_offset; \
01350 } while (0)
01351
01352 DBusRealString tmp;
01353
01354 ASSIGN_DATA (&tmp, real_source);
01355 ASSIGN_DATA (real_source, real_dest);
01356 ASSIGN_DATA (real_dest, &tmp);
01357
01358 return TRUE;
01359 }
01360 else
01361 {
01362 if (!copy (real_source, start, len,
01363 real_dest,
01364 insert_at))
01365 return FALSE;
01366
01367 delete (real_source, start,
01368 len);
01369
01370 return TRUE;
01371 }
01372 }
01373
01385 dbus_bool_t
01386 _dbus_string_copy_len (const DBusString *source,
01387 int start,
01388 int len,
01389 DBusString *dest,
01390 int insert_at)
01391 {
01392 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01393 _dbus_assert (len >= 0);
01394 _dbus_assert (start <= real_source->len);
01395 _dbus_assert (len <= real_source->len - start);
01396
01397 return copy (real_source, start, len,
01398 real_dest,
01399 insert_at);
01400 }
01401
01423 dbus_bool_t
01424 _dbus_string_replace_len (const DBusString *source,
01425 int start,
01426 int len,
01427 DBusString *dest,
01428 int replace_at,
01429 int replace_len)
01430 {
01431 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
01432 _dbus_assert (len >= 0);
01433 _dbus_assert (start <= real_source->len);
01434 _dbus_assert (len <= real_source->len - start);
01435 _dbus_assert (replace_at >= 0);
01436 _dbus_assert (replace_at <= real_dest->len);
01437 _dbus_assert (replace_len <= real_dest->len - replace_at);
01438
01439 if (!copy (real_source, start, len,
01440 real_dest, replace_at))
01441 return FALSE;
01442
01443 delete (real_dest, replace_at + len, replace_len);
01444
01445 return TRUE;
01446 }
01447
01448
01449
01450
01451
01457 #define UTF8_COMPUTE(Char, Mask, Len) \
01458 if (Char < 128) \
01459 { \
01460 Len = 1; \
01461 Mask = 0x7f; \
01462 } \
01463 else if ((Char & 0xe0) == 0xc0) \
01464 { \
01465 Len = 2; \
01466 Mask = 0x1f; \
01467 } \
01468 else if ((Char & 0xf0) == 0xe0) \
01469 { \
01470 Len = 3; \
01471 Mask = 0x0f; \
01472 } \
01473 else if ((Char & 0xf8) == 0xf0) \
01474 { \
01475 Len = 4; \
01476 Mask = 0x07; \
01477 } \
01478 else if ((Char & 0xfc) == 0xf8) \
01479 { \
01480 Len = 5; \
01481 Mask = 0x03; \
01482 } \
01483 else if ((Char & 0xfe) == 0xfc) \
01484 { \
01485 Len = 6; \
01486 Mask = 0x01; \
01487 } \
01488 else \
01489 Len = -1;
01490
01495 #define UTF8_LENGTH(Char) \
01496 ((Char) < 0x80 ? 1 : \
01497 ((Char) < 0x800 ? 2 : \
01498 ((Char) < 0x10000 ? 3 : \
01499 ((Char) < 0x200000 ? 4 : \
01500 ((Char) < 0x4000000 ? 5 : 6)))))
01501
01511 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
01512 (Result) = (Chars)[0] & (Mask); \
01513 for ((Count) = 1; (Count) < (Len); ++(Count)) \
01514 { \
01515 if (((Chars)[(Count)] & 0xc0) != 0x80) \
01516 { \
01517 (Result) = -1; \
01518 break; \
01519 } \
01520 (Result) <<= 6; \
01521 (Result) |= ((Chars)[(Count)] & 0x3f); \
01522 }
01523
01529 #define UNICODE_VALID(Char) \
01530 ((Char) < 0x110000 && \
01531 (((Char) & 0xFFFFF800) != 0xD800) && \
01532 ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
01533 ((Char) & 0xFFFF) != 0xFFFF)
01534
01545 void
01546 _dbus_string_get_unichar (const DBusString *str,
01547 int start,
01548 dbus_unichar_t *ch_return,
01549 int *end_return)
01550 {
01551 int i, mask, len;
01552 dbus_unichar_t result;
01553 unsigned char c;
01554 unsigned char *p;
01555 DBUS_CONST_STRING_PREAMBLE (str);
01556 _dbus_assert (start >= 0);
01557 _dbus_assert (start <= real->len);
01558
01559 if (ch_return)
01560 *ch_return = 0;
01561 if (end_return)
01562 *end_return = real->len;
01563
01564 mask = 0;
01565 p = real->str + start;
01566 c = *p;
01567
01568 UTF8_COMPUTE (c, mask, len);
01569 if (len == -1)
01570 return;
01571 UTF8_GET (result, p, i, mask, len);
01572
01573 if (result == (dbus_unichar_t)-1)
01574 return;
01575
01576 if (ch_return)
01577 *ch_return = result;
01578 if (end_return)
01579 *end_return = start + len;
01580 }
01581
01596 dbus_bool_t
01597 _dbus_string_find (const DBusString *str,
01598 int start,
01599 const char *substr,
01600 int *found)
01601 {
01602 return _dbus_string_find_to (str, start,
01603 ((const DBusRealString*)str)->len,
01604 substr, found);
01605 }
01606
01623 dbus_bool_t
01624 _dbus_string_find_to (const DBusString *str,
01625 int start,
01626 int end,
01627 const char *substr,
01628 int *found)
01629 {
01630 int i;
01631 DBUS_CONST_STRING_PREAMBLE (str);
01632 _dbus_assert (substr != NULL);
01633 _dbus_assert (start <= real->len);
01634 _dbus_assert (start >= 0);
01635 _dbus_assert (substr != NULL);
01636 _dbus_assert (end <= real->len);
01637 _dbus_assert (start <= end);
01638
01639
01640 if (*substr == '\0')
01641 {
01642 if (found)
01643 *found = start;
01644 return TRUE;
01645 }
01646
01647 i = start;
01648 while (i < end)
01649 {
01650 if (real->str[i] == substr[0])
01651 {
01652 int j = i + 1;
01653
01654 while (j < end)
01655 {
01656 if (substr[j - i] == '\0')
01657 break;
01658 else if (real->str[j] != substr[j - i])
01659 break;
01660
01661 ++j;
01662 }
01663
01664 if (substr[j - i] == '\0')
01665 {
01666 if (found)
01667 *found = i;
01668 return TRUE;
01669 }
01670 }
01671
01672 ++i;
01673 }
01674
01675 if (found)
01676 *found = end;
01677
01678 return FALSE;
01679 }
01680
01691 dbus_bool_t
01692 _dbus_string_find_byte_backward (const DBusString *str,
01693 int start,
01694 unsigned char byte,
01695 int *found)
01696 {
01697 int i;
01698 DBUS_CONST_STRING_PREAMBLE (str);
01699 _dbus_assert (start <= real->len);
01700 _dbus_assert (start >= 0);
01701 _dbus_assert (found != NULL);
01702
01703 i = start - 1;
01704 while (i >= 0)
01705 {
01706 if (real->str[i] == byte)
01707 break;
01708
01709 --i;
01710 }
01711
01712 if (found)
01713 *found = i;
01714
01715 return i >= 0;
01716 }
01717
01728 dbus_bool_t
01729 _dbus_string_find_blank (const DBusString *str,
01730 int start,
01731 int *found)
01732 {
01733 int i;
01734 DBUS_CONST_STRING_PREAMBLE (str);
01735 _dbus_assert (start <= real->len);
01736 _dbus_assert (start >= 0);
01737
01738 i = start;
01739 while (i < real->len)
01740 {
01741 if (real->str[i] == ' ' ||
01742 real->str[i] == '\t')
01743 {
01744 if (found)
01745 *found = i;
01746 return TRUE;
01747 }
01748
01749 ++i;
01750 }
01751
01752 if (found)
01753 *found = real->len;
01754
01755 return FALSE;
01756 }
01757
01766 void
01767 _dbus_string_skip_blank (const DBusString *str,
01768 int start,
01769 int *end)
01770 {
01771 int i;
01772 DBUS_CONST_STRING_PREAMBLE (str);
01773 _dbus_assert (start <= real->len);
01774 _dbus_assert (start >= 0);
01775
01776 i = start;
01777 while (i < real->len)
01778 {
01779 if (!(real->str[i] == ' ' ||
01780 real->str[i] == '\t'))
01781 break;
01782
01783 ++i;
01784 }
01785
01786 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
01787 real->str[i] == '\t'));
01788
01789 if (end)
01790 *end = i;
01791 }
01792
01801 void
01802 _dbus_string_skip_white (const DBusString *str,
01803 int start,
01804 int *end)
01805 {
01806 int i;
01807 DBUS_CONST_STRING_PREAMBLE (str);
01808 _dbus_assert (start <= real->len);
01809 _dbus_assert (start >= 0);
01810
01811 i = start;
01812 while (i < real->len)
01813 {
01814 if (!(real->str[i] == ' ' ||
01815 real->str[i] == '\n' ||
01816 real->str[i] == '\r' ||
01817 real->str[i] == '\t'))
01818 break;
01819
01820 ++i;
01821 }
01822
01823 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
01824 real->str[i] == '\t'));
01825
01826 if (end)
01827 *end = i;
01828 }
01829
01845 dbus_bool_t
01846 _dbus_string_pop_line (DBusString *source,
01847 DBusString *dest)
01848 {
01849 int eol;
01850 dbus_bool_t have_newline;
01851
01852 _dbus_string_set_length (dest, 0);
01853
01854 eol = 0;
01855 if (_dbus_string_find (source, 0, "\n", &eol))
01856 {
01857 have_newline = TRUE;
01858 eol += 1;
01859 }
01860 else
01861 {
01862 eol = _dbus_string_get_length (source);
01863 have_newline = FALSE;
01864 }
01865
01866 if (eol == 0)
01867 return FALSE;
01868
01869 if (!_dbus_string_move_len (source, 0, eol,
01870 dest, 0))
01871 {
01872 return FALSE;
01873 }
01874
01875
01876 if (have_newline)
01877 {
01878 dbus_bool_t have_cr;
01879
01880 _dbus_assert (_dbus_string_get_length (dest) > 0);
01881
01882 if (_dbus_string_get_length (dest) > 1 &&
01883 _dbus_string_get_byte (dest,
01884 _dbus_string_get_length (dest) - 2) == '\r')
01885 have_cr = TRUE;
01886 else
01887 have_cr = FALSE;
01888
01889 _dbus_string_set_length (dest,
01890 _dbus_string_get_length (dest) -
01891 (have_cr ? 2 : 1));
01892 }
01893
01894 return TRUE;
01895 }
01896
01903 void
01904 _dbus_string_delete_first_word (DBusString *str)
01905 {
01906 int i;
01907
01908 if (_dbus_string_find_blank (str, 0, &i))
01909 _dbus_string_skip_blank (str, i, &i);
01910
01911 _dbus_string_delete (str, 0, i);
01912 }
01913
01919 void
01920 _dbus_string_delete_leading_blanks (DBusString *str)
01921 {
01922 int i;
01923
01924 _dbus_string_skip_blank (str, 0, &i);
01925
01926 if (i > 0)
01927 _dbus_string_delete (str, 0, i);
01928 }
01929
01939 dbus_bool_t
01940 _dbus_string_equal (const DBusString *a,
01941 const DBusString *b)
01942 {
01943 const unsigned char *ap;
01944 const unsigned char *bp;
01945 const unsigned char *a_end;
01946 const DBusRealString *real_a = (const DBusRealString*) a;
01947 const DBusRealString *real_b = (const DBusRealString*) b;
01948 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01949 DBUS_GENERIC_STRING_PREAMBLE (real_b);
01950
01951 if (real_a->len != real_b->len)
01952 return FALSE;
01953
01954 ap = real_a->str;
01955 bp = real_b->str;
01956 a_end = real_a->str + real_a->len;
01957 while (ap != a_end)
01958 {
01959 if (*ap != *bp)
01960 return FALSE;
01961
01962 ++ap;
01963 ++bp;
01964 }
01965
01966 return TRUE;
01967 }
01968
01981 dbus_bool_t
01982 _dbus_string_equal_len (const DBusString *a,
01983 const DBusString *b,
01984 int len)
01985 {
01986 const unsigned char *ap;
01987 const unsigned char *bp;
01988 const unsigned char *a_end;
01989 const DBusRealString *real_a = (const DBusRealString*) a;
01990 const DBusRealString *real_b = (const DBusRealString*) b;
01991 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01992 DBUS_GENERIC_STRING_PREAMBLE (real_b);
01993
01994 if (real_a->len != real_b->len &&
01995 (real_a->len < len || real_b->len < len))
01996 return FALSE;
01997
01998 ap = real_a->str;
01999 bp = real_b->str;
02000 a_end = real_a->str + MIN (real_a->len, len);
02001 while (ap != a_end)
02002 {
02003 if (*ap != *bp)
02004 return FALSE;
02005
02006 ++ap;
02007 ++bp;
02008 }
02009
02010 return TRUE;
02011 }
02012
02020 dbus_bool_t
02021 _dbus_string_equal_c_str (const DBusString *a,
02022 const char *c_str)
02023 {
02024 const unsigned char *ap;
02025 const unsigned char *bp;
02026 const unsigned char *a_end;
02027 const DBusRealString *real_a = (const DBusRealString*) a;
02028 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02029 _dbus_assert (c_str != NULL);
02030
02031 ap = real_a->str;
02032 bp = (const unsigned char*) c_str;
02033 a_end = real_a->str + real_a->len;
02034 while (ap != a_end && *bp)
02035 {
02036 if (*ap != *bp)
02037 return FALSE;
02038
02039 ++ap;
02040 ++bp;
02041 }
02042
02043 if (ap != a_end || *bp)
02044 return FALSE;
02045
02046 return TRUE;
02047 }
02048
02056 dbus_bool_t
02057 _dbus_string_starts_with_c_str (const DBusString *a,
02058 const char *c_str)
02059 {
02060 const unsigned char *ap;
02061 const unsigned char *bp;
02062 const unsigned char *a_end;
02063 const DBusRealString *real_a = (const DBusRealString*) a;
02064 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02065 _dbus_assert (c_str != NULL);
02066
02067 ap = real_a->str;
02068 bp = (const unsigned char*) c_str;
02069 a_end = real_a->str + real_a->len;
02070 while (ap != a_end && *bp)
02071 {
02072 if (*ap != *bp)
02073 return FALSE;
02074
02075 ++ap;
02076 ++bp;
02077 }
02078
02079 if (*bp == '\0')
02080 return TRUE;
02081 else
02082 return FALSE;
02083 }
02084
02094 dbus_bool_t
02095 _dbus_string_ends_with_c_str (const DBusString *a,
02096 const char *c_str)
02097 {
02098 const unsigned char *ap;
02099 const unsigned char *bp;
02100 const unsigned char *a_end;
02101 unsigned long c_str_len;
02102 const DBusRealString *real_a = (const DBusRealString*) a;
02103 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02104 _dbus_assert (c_str != NULL);
02105
02106 c_str_len = strlen (c_str);
02107 if (((unsigned long)real_a->len) < c_str_len)
02108 return FALSE;
02109
02110 ap = real_a->str + (real_a->len - c_str_len);
02111 bp = (const unsigned char*) c_str;
02112 a_end = real_a->str + real_a->len;
02113 while (ap != a_end)
02114 {
02115 if (*ap != *bp)
02116 return FALSE;
02117
02118 ++ap;
02119 ++bp;
02120 }
02121
02122 _dbus_assert (*ap == '\0');
02123 _dbus_assert (*bp == '\0');
02124
02125 return TRUE;
02126 }
02127
02128 static const signed char base64_table[] = {
02129 'A',
02130 'B',
02131 'C',
02132 'D',
02133 'E',
02134 'F',
02135 'G',
02136 'H',
02137 'I',
02138 'J',
02139 'K',
02140 'L',
02141 'M',
02142 'N',
02143 'O',
02144 'P',
02145 'Q',
02146 'R',
02147 'S',
02148 'T',
02149 'U',
02150 'V',
02151 'W',
02152 'X',
02153 'Y',
02154 'Z',
02155 'a',
02156 'b',
02157 'c',
02158 'd',
02159 'e',
02160 'f',
02161 'g',
02162 'h',
02163 'i',
02164 'j',
02165 'k',
02166 'l',
02167 'm',
02168 'n',
02169 'o',
02170 'p',
02171 'q',
02172 'r',
02173 's',
02174 't',
02175 'u',
02176 'v',
02177 'w',
02178 'x',
02179 'y',
02180 'z',
02181 '0',
02182 '1',
02183 '2',
02184 '3',
02185 '4',
02186 '5',
02187 '6',
02188 '7',
02189 '8',
02190 '9',
02191 '+',
02192 '/'
02193 };
02194
02196 #define UNBASE64_MIN_CHAR (43)
02197
02198 #define UNBASE64_MAX_CHAR (122)
02199
02202 #define UNBASE64_TABLE_OFFSET UNBASE64_MIN_CHAR
02203 static const signed char unbase64_table[] = {
02204 62,
02205 -1,
02206 -1,
02207 -1,
02208 63,
02209 52,
02210 53,
02211 54,
02212 55,
02213 56,
02214 57,
02215 58,
02216 59,
02217 60,
02218 61,
02219 -1,
02220 -1,
02221 -1,
02222 -1,
02223 -1,
02224 -1,
02225 -1,
02226 0,
02227 1,
02228 2,
02229 3,
02230 4,
02231 5,
02232 6,
02233 7,
02234 8,
02235 9,
02236 10,
02237 11,
02238 12,
02239 13,
02240 14,
02241 15,
02242 16,
02243 17,
02244 18,
02245 19,
02246 20,
02247 21,
02248 22,
02249 23,
02250 24,
02251 25,
02252 -1,
02253 -1,
02254 -1,
02255 -1,
02256 -1,
02257 -1,
02258 26,
02259 27,
02260 28,
02261 29,
02262 30,
02263 31,
02264 32,
02265 33,
02266 34,
02267 35,
02268 36,
02269 37,
02270 38,
02271 39,
02272 40,
02273 41,
02274 42,
02275 43,
02276 44,
02277 45,
02278 46,
02279 47,
02280 48,
02281 49,
02282 50,
02283 51
02284 };
02285
02295 dbus_bool_t
02296 _dbus_string_base64_encode (const DBusString *source,
02297 int start,
02298 DBusString *dest,
02299 int insert_at)
02300 {
02301 int source_len;
02302 unsigned int dest_len;
02303 const unsigned char *s;
02304 unsigned char *d;
02305 const unsigned char *triplet_end;
02306 const unsigned char *final_end;
02307 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
02308 _dbus_assert (source != dest);
02309
02310
02311
02312
02313 source_len = real_source->len - start;
02314 dest_len = (source_len / 3) * 4;
02315 if (source_len % 3 != 0)
02316 dest_len += 4;
02317
02318 if (dest_len > (unsigned int) real_dest->max_length)
02319 return FALSE;
02320
02321 if (source_len == 0)
02322 return TRUE;
02323
02324 if (!open_gap (dest_len, real_dest, insert_at))
02325 return FALSE;
02326
02327 d = real_dest->str + insert_at;
02328 s = real_source->str + start;
02329 final_end = real_source->str + (start + source_len);
02330 triplet_end = final_end - (source_len % 3);
02331 _dbus_assert (triplet_end <= final_end);
02332 _dbus_assert ((final_end - triplet_end) < 3);
02333
02334 #define ENCODE_64(v) (base64_table[ (unsigned char) (v) ])
02335 #define SIX_BITS_MASK (0x3f)
02336 _dbus_assert (SIX_BITS_MASK < _DBUS_N_ELEMENTS (base64_table));
02337
02338 while (s != triplet_end)
02339 {
02340 unsigned int triplet;
02341
02342 triplet = s[2] | (s[1] << 8) | (s[0] << 16);
02343
02344
02345
02346 *d++ = ENCODE_64 (triplet >> 18);
02347 *d++ = ENCODE_64 ((triplet >> 12) & SIX_BITS_MASK);
02348 *d++ = ENCODE_64 ((triplet >> 6) & SIX_BITS_MASK);
02349 *d++ = ENCODE_64 (triplet & SIX_BITS_MASK);
02350
02351 s += 3;
02352 }
02353
02354 switch (final_end - triplet_end)
02355 {
02356 case 2:
02357 {
02358 unsigned int doublet;
02359
02360 doublet = s[1] | (s[0] << 8);
02361
02362 *d++ = ENCODE_64 (doublet >> 12);
02363 *d++ = ENCODE_64 ((doublet >> 6) & SIX_BITS_MASK);
02364 *d++ = ENCODE_64 (doublet & SIX_BITS_MASK);
02365 *d++ = '=';
02366 }
02367 break;
02368 case 1:
02369 {
02370 unsigned int singlet;
02371
02372 singlet = s[0];
02373
02374 *d++ = ENCODE_64 ((singlet >> 6) & SIX_BITS_MASK);
02375 *d++ = ENCODE_64 (singlet & SIX_BITS_MASK);
02376 *d++ = '=';
02377 *d++ = '=';
02378 }
02379 break;
02380 case 0:
02381 break;
02382 }
02383
02384 _dbus_assert (d == (real_dest->str + (insert_at + dest_len)));
02385
02386 return TRUE;
02387 }
02388
02403 dbus_bool_t
02404 _dbus_string_base64_decode (const DBusString *source,
02405 int start,
02406 DBusString *dest,
02407 int insert_at)
02408 {
02409 int source_len;
02410 const char *s;
02411 const char *end;
02412 DBusString result;
02413 unsigned int triplet = 0;
02414 int sextet_count;
02415 int pad_count;
02416 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
02417 _dbus_assert (source != dest);
02418
02419 source_len = real_source->len - start;
02420 s = real_source->str + start;
02421 end = real_source->str + source_len;
02422
02423 if (source_len == 0)
02424 return TRUE;
02425
02426 if (!_dbus_string_init (&result))
02427 return FALSE;
02428
02429 pad_count = 0;
02430 sextet_count = 0;
02431 while (s != end)
02432 {
02433
02434
02435
02436
02437
02438
02439 if (*s >= UNBASE64_MIN_CHAR &&
02440 *s <= UNBASE64_MAX_CHAR)
02441 {
02442 if (*s == '=')
02443 {
02444
02445
02446
02447 pad_count += 1;
02448 sextet_count += 1;
02449 }
02450 else
02451 {
02452 int val;
02453
02454 val = unbase64_table[(*s) - UNBASE64_TABLE_OFFSET];
02455
02456 if (val >= 0)
02457 {
02458 triplet <<= 6;
02459 triplet |= (unsigned int) val;
02460 sextet_count += 1;
02461 }
02462 }
02463
02464 if (sextet_count == 4)
02465 {
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479 if (pad_count < 1)
02480 {
02481 if (!_dbus_string_append_byte (&result,
02482 triplet >> 16))
02483 goto failed;
02484 }
02485
02486 if (pad_count < 2)
02487 {
02488 if (!_dbus_string_append_byte (&result,
02489 (triplet >> 8) & 0xff))
02490 goto failed;
02491 }
02492
02493 if (!_dbus_string_append_byte (&result,
02494 triplet & 0xff))
02495 goto failed;
02496
02497 sextet_count = 0;
02498 pad_count = 0;
02499 triplet = 0;
02500 }
02501 }
02502
02503 ++s;
02504 }
02505
02506 if (!_dbus_string_move (&result, 0, dest, insert_at))
02507 {
02508 _dbus_string_free (&result);
02509 return FALSE;
02510 }
02511
02512 _dbus_string_free (&result);
02513
02514 return TRUE;
02515
02516 failed:
02517 _dbus_string_free (&result);
02518
02519 return FALSE;
02520 }
02521
02532 dbus_bool_t
02533 _dbus_string_hex_encode (const DBusString *source,
02534 int start,
02535 DBusString *dest,
02536 int insert_at)
02537 {
02538 DBusString result;
02539 const char hexdigits[16] = {
02540 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
02541 'a', 'b', 'c', 'd', 'e', 'f'
02542 };
02543 const unsigned char *p;
02544 const unsigned char *end;
02545 dbus_bool_t retval;
02546
02547 _dbus_assert (start <= _dbus_string_get_length (source));
02548
02549 if (!_dbus_string_init (&result))
02550 return FALSE;
02551
02552 retval = FALSE;
02553
02554 p = (const unsigned char*) _dbus_string_get_const_data (source);
02555 end = p + _dbus_string_get_length (source);
02556 p += start;
02557
02558 while (p != end)
02559 {
02560 if (!_dbus_string_append_byte (&result,
02561 hexdigits[(*p >> 4)]))
02562 goto out;
02563
02564 if (!_dbus_string_append_byte (&result,
02565 hexdigits[(*p & 0x0f)]))
02566 goto out;
02567
02568 ++p;
02569 }
02570
02571 if (!_dbus_string_move (&result, 0, dest, insert_at))
02572 goto out;
02573
02574 retval = TRUE;
02575
02576 out:
02577 _dbus_string_free (&result);
02578 return retval;
02579 }
02580
02590 dbus_bool_t
02591 _dbus_string_hex_decode (const DBusString *source,
02592 int start,
02593 DBusString *dest,
02594 int insert_at)
02595 {
02596 DBusString result;
02597 const unsigned char *p;
02598 const unsigned char *end;
02599 dbus_bool_t retval;
02600 dbus_bool_t high_bits;
02601
02602 _dbus_assert (start <= _dbus_string_get_length (source));
02603
02604 if (!_dbus_string_init (&result))
02605 return FALSE;
02606
02607 retval = FALSE;
02608
02609 high_bits = TRUE;
02610 p = (const unsigned char*) _dbus_string_get_const_data (source);
02611 end = p + _dbus_string_get_length (source);
02612 p += start;
02613
02614 while (p != end)
02615 {
02616 unsigned int val;
02617
02618 switch (*p)
02619 {
02620 case '0':
02621 val = 0;
02622 break;
02623 case '1':
02624 val = 1;
02625 break;
02626 case '2':
02627 val = 2;
02628 break;
02629 case '3':
02630 val = 3;
02631 break;
02632 case '4':
02633 val = 4;
02634 break;
02635 case '5':
02636 val = 5;
02637 break;
02638 case '6':
02639 val = 6;
02640 break;
02641 case '7':
02642 val = 7;
02643 break;
02644 case '8':
02645 val = 8;
02646 break;
02647 case '9':
02648 val = 9;
02649 break;
02650 case 'a':
02651 case 'A':
02652 val = 10;
02653 break;
02654 case 'b':
02655 case 'B':
02656 val = 11;
02657 break;
02658 case 'c':
02659 case 'C':
02660 val = 12;
02661 break;
02662 case 'd':
02663 case 'D':
02664 val = 13;
02665 break;
02666 case 'e':
02667 case 'E':
02668 val = 14;
02669 break;
02670 case 'f':
02671 case 'F':
02672 val = 15;
02673 break;
02674 default:
02675 val = 0;
02676 _dbus_verbose ("invalid character '%c' in hex encoded text\n",
02677 *p);
02678 goto out;
02679 }
02680
02681 if (high_bits)
02682 {
02683 if (!_dbus_string_append_byte (&result,
02684 val << 4))
02685 goto out;
02686 }
02687 else
02688 {
02689 int len;
02690 unsigned char b;
02691
02692 len = _dbus_string_get_length (&result);
02693
02694 b = _dbus_string_get_byte (&result, len - 1);
02695
02696 b |= val;
02697
02698 _dbus_string_set_byte (&result, len - 1, b);
02699 }
02700
02701 high_bits = !high_bits;
02702
02703 ++p;
02704 }
02705
02706 if (!_dbus_string_move (&result, 0, dest, insert_at))
02707 goto out;
02708
02709 retval = TRUE;
02710
02711 out:
02712 _dbus_string_free (&result);
02713 return retval;
02714 }
02715
02729 dbus_bool_t
02730 _dbus_string_validate_ascii (const DBusString *str,
02731 int start,
02732 int len)
02733 {
02734 const unsigned char *s;
02735 const unsigned char *end;
02736 DBUS_CONST_STRING_PREAMBLE (str);
02737 _dbus_assert (start >= 0);
02738 _dbus_assert (start <= real->len);
02739 _dbus_assert (len >= 0);
02740
02741 if (len > real->len - start)
02742 return FALSE;
02743
02744 s = real->str + start;
02745 end = s + len;
02746 while (s != end)
02747 {
02748 if (_DBUS_UNLIKELY (*s == '\0' ||
02749 ((*s & ~0x7f) != 0)))
02750 return FALSE;
02751
02752 ++s;
02753 }
02754
02755 return TRUE;
02756 }
02757
02773 dbus_bool_t
02774 _dbus_string_validate_utf8 (const DBusString *str,
02775 int start,
02776 int len)
02777 {
02778 const unsigned char *p;
02779 const unsigned char *end;
02780 DBUS_CONST_STRING_PREAMBLE (str);
02781 _dbus_assert (start >= 0);
02782 _dbus_assert (start <= real->len);
02783 _dbus_assert (len >= 0);
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793 if (_DBUS_UNLIKELY (len > real->len - start))
02794 return FALSE;
02795
02796 p = real->str + start;
02797 end = p + len;
02798
02799 while (p < end)
02800 {
02801 int i, mask = 0, char_len;
02802 dbus_unichar_t result;
02803 unsigned char c = (unsigned char) *p;
02804
02805 UTF8_COMPUTE (c, mask, char_len);
02806
02807 if (_DBUS_UNLIKELY (char_len == -1))
02808 break;
02809
02810
02811 if (_DBUS_UNLIKELY ((end - p) < char_len))
02812 break;
02813
02814 UTF8_GET (result, p, i, mask, char_len);
02815
02816 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len))
02817 break;
02818
02819 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1))
02820 break;
02821
02822 if (_DBUS_UNLIKELY (!UNICODE_VALID (result)))
02823 break;
02824
02825 p += char_len;
02826 }
02827
02828
02829
02830
02831 if (_DBUS_UNLIKELY (p != end))
02832 return FALSE;
02833 else
02834 return TRUE;
02835 }
02836
02850 dbus_bool_t
02851 _dbus_string_validate_nul (const DBusString *str,
02852 int start,
02853 int len)
02854 {
02855 const unsigned char *s;
02856 const unsigned char *end;
02857 DBUS_CONST_STRING_PREAMBLE (str);
02858 _dbus_assert (start >= 0);
02859 _dbus_assert (len >= 0);
02860 _dbus_assert (start <= real->len);
02861
02862 if (len > real->len - start)
02863 return FALSE;
02864
02865 s = real->str + start;
02866 end = s + len;
02867 while (s != end)
02868 {
02869 if (_DBUS_UNLIKELY (*s != '\0'))
02870 return FALSE;
02871 ++s;
02872 }
02873
02874 return TRUE;
02875 }
02876
02894 dbus_bool_t
02895 _dbus_string_validate_path (const DBusString *str,
02896 int start,
02897 int len)
02898 {
02899 const unsigned char *s;
02900 const unsigned char *end;
02901 const unsigned char *last_slash;
02902
02903 DBUS_CONST_STRING_PREAMBLE (str);
02904 _dbus_assert (start >= 0);
02905 _dbus_assert (len >= 0);
02906 _dbus_assert (start <= real->len);
02907
02908 if (len > real->len - start)
02909 return FALSE;
02910
02911 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02912 return FALSE;
02913
02914 if (len == 0)
02915 return FALSE;
02916
02917 s = real->str + start;
02918 end = s + len;
02919
02920 if (*s != '/')
02921 return FALSE;
02922 last_slash = s;
02923 ++s;
02924
02925 while (s != end)
02926 {
02927 if (*s == '/')
02928 {
02929 if ((s - last_slash) < 2)
02930 return FALSE;
02931
02932 last_slash = s;
02933 }
02934
02935 ++s;
02936 }
02937
02938 if ((end - last_slash) < 2 &&
02939 len > 1)
02940 return FALSE;
02941
02942 return TRUE;
02943 }
02944
02945 #define VALID_INITIAL_NAME_CHARACTER(c) \
02946 ( ((c) >= 'A' && (c) <= 'Z') || \
02947 ((c) >= 'a' && (c) <= 'z') || \
02948 ((c) == '_') )
02949
02950 #define VALID_NAME_CHARACTER(c) \
02951 ( ((c) >= '0' && (c) <= '9') || \
02952 ((c) >= 'A' && (c) <= 'Z') || \
02953 ((c) >= 'a' && (c) <= 'z') || \
02954 ((c) == '_') )
02955
02969 dbus_bool_t
02970 _dbus_string_validate_interface (const DBusString *str,
02971 int start,
02972 int len)
02973 {
02974 const unsigned char *s;
02975 const unsigned char *end;
02976 const unsigned char *iface;
02977 const unsigned char *last_dot;
02978
02979 DBUS_CONST_STRING_PREAMBLE (str);
02980 _dbus_assert (start >= 0);
02981 _dbus_assert (len >= 0);
02982 _dbus_assert (start <= real->len);
02983
02984 if (len > real->len - start)
02985 return FALSE;
02986
02987 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02988 return FALSE;
02989
02990 if (len == 0)
02991 return FALSE;
02992
02993 last_dot = NULL;
02994 iface = real->str + start;
02995 end = iface + len;
02996 s = iface;
02997
02998
02999
03000
03001 if (_DBUS_UNLIKELY (*s == '.'))
03002 return FALSE;
03003 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
03004 return FALSE;
03005 else
03006 ++s;
03007
03008 while (s != end)
03009 {
03010 if (*s == '.')
03011 {
03012 if (_DBUS_UNLIKELY ((s + 1) == end))
03013 return FALSE;
03014 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
03015 return FALSE;
03016 last_dot = s;
03017 ++s;
03018 }
03019 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
03020 {
03021 return FALSE;
03022 }
03023
03024 ++s;
03025 }
03026
03027 if (_DBUS_UNLIKELY (last_dot == NULL))
03028 return FALSE;
03029
03030 return TRUE;
03031 }
03032
03046 dbus_bool_t
03047 _dbus_string_validate_member (const DBusString *str,
03048 int start,
03049 int len)
03050 {
03051 const unsigned char *s;
03052 const unsigned char *end;
03053 const unsigned char *member;
03054
03055 DBUS_CONST_STRING_PREAMBLE (str);
03056 _dbus_assert (start >= 0);
03057 _dbus_assert (len >= 0);
03058 _dbus_assert (start <= real->len);
03059
03060 if (len > real->len - start)
03061 return FALSE;
03062
03063 if (len > DBUS_MAXIMUM_NAME_LENGTH)
03064 return FALSE;
03065
03066 if (len == 0)
03067 return FALSE;
03068
03069 member = real->str + start;
03070 end = member + len;
03071 s = member;
03072
03073
03074
03075
03076
03077 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
03078 return FALSE;
03079 else
03080 ++s;
03081
03082 while (s != end)
03083 {
03084 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
03085 {
03086 return FALSE;
03087 }
03088
03089 ++s;
03090 }
03091
03092 return TRUE;
03093 }
03094
03108 dbus_bool_t
03109 _dbus_string_validate_error_name (const DBusString *str,
03110 int start,
03111 int len)
03112 {
03113
03114 return _dbus_string_validate_interface (str, start, len);
03115 }
03116
03117
03118 static dbus_bool_t
03119 _dbus_string_validate_base_service (const DBusString *str,
03120 int start,
03121 int len)
03122 {
03123 const unsigned char *s;
03124 const unsigned char *end;
03125 const unsigned char *service;
03126
03127 DBUS_CONST_STRING_PREAMBLE (str);
03128 _dbus_assert (start >= 0);
03129 _dbus_assert (len >= 0);
03130 _dbus_assert (start <= real->len);
03131
03132 if (len > real->len - start)
03133 return FALSE;
03134
03135 if (len > DBUS_MAXIMUM_NAME_LENGTH)
03136 return FALSE;
03137
03138 _dbus_assert (len > 0);
03139
03140 service = real->str + start;
03141 end = service + len;
03142 _dbus_assert (*service == ':');
03143 s = service + 1;
03144
03145 while (s != end)
03146 {
03147 if (*s == '.')
03148 {
03149 if (_DBUS_UNLIKELY ((s + 1) == end))
03150 return FALSE;
03151 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*(s + 1))))
03152 return FALSE;
03153 ++s;
03154 }
03155 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
03156 {
03157 return FALSE;
03158 }
03159
03160 ++s;
03161 }
03162
03163 return TRUE;
03164 }
03165
03179 dbus_bool_t
03180 _dbus_string_validate_service (const DBusString *str,
03181 int start,
03182 int len)
03183 {
03184 if (_DBUS_UNLIKELY (len == 0))
03185 return FALSE;
03186 if (_dbus_string_get_byte (str, start) == ':')
03187 return _dbus_string_validate_base_service (str, start, len);
03188 else
03189 return _dbus_string_validate_interface (str, start, len);
03190 }
03191
03197 void
03198 _dbus_string_zero (DBusString *str)
03199 {
03200 DBUS_STRING_PREAMBLE (str);
03201
03202 memset (real->str - real->align_offset, '\0', real->allocated);
03203 }
03206 #ifdef DBUS_BUILD_TESTS
03207 #include "dbus-test.h"
03208 #include <stdio.h>
03209
03210 static void
03211 test_max_len (DBusString *str,
03212 int max_len)
03213 {
03214 if (max_len > 0)
03215 {
03216 if (!_dbus_string_set_length (str, max_len - 1))
03217 _dbus_assert_not_reached ("setting len to one less than max should have worked");
03218 }
03219
03220 if (!_dbus_string_set_length (str, max_len))
03221 _dbus_assert_not_reached ("setting len to max len should have worked");
03222
03223 if (_dbus_string_set_length (str, max_len + 1))
03224 _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
03225
03226 if (!_dbus_string_set_length (str, 0))
03227 _dbus_assert_not_reached ("setting len to zero should have worked");
03228 }
03229
03230 static void
03231 test_base64_roundtrip (const unsigned char *data,
03232 int len)
03233 {
03234 DBusString orig;
03235 DBusString encoded;
03236 DBusString decoded;
03237
03238 if (len < 0)
03239 len = strlen (data);
03240
03241 if (!_dbus_string_init (&orig))
03242 _dbus_assert_not_reached ("could not init string");
03243
03244 if (!_dbus_string_init (&encoded))
03245 _dbus_assert_not_reached ("could not init string");
03246
03247 if (!_dbus_string_init (&decoded))
03248 _dbus_assert_not_reached ("could not init string");
03249
03250 if (!_dbus_string_append_len (&orig, data, len))
03251 _dbus_assert_not_reached ("couldn't append orig data");
03252
03253 if (!_dbus_string_base64_encode (&orig, 0, &encoded, 0))
03254 _dbus_assert_not_reached ("could not encode");
03255
03256 if (!_dbus_string_base64_decode (&encoded, 0, &decoded, 0))
03257 _dbus_assert_not_reached ("could not decode");
03258
03259 if (!_dbus_string_equal (&orig, &decoded))
03260 {
03261 const char *s;
03262
03263 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
03264 _dbus_string_get_length (&orig),
03265 _dbus_string_get_length (&encoded),
03266 _dbus_string_get_length (&decoded));
03267 printf ("Original: %s\n", data);
03268 s = _dbus_string_get_const_data (&decoded);
03269 printf ("Decoded: %s\n", s);
03270 _dbus_assert_not_reached ("original string not the same as string decoded from base64");
03271 }
03272
03273 _dbus_string_free (&orig);
03274 _dbus_string_free (&encoded);
03275 _dbus_string_free (&decoded);
03276 }
03277
03278 static void
03279 test_hex_roundtrip (const unsigned char *data,
03280 int len)
03281 {
03282 DBusString orig;
03283 DBusString encoded;
03284 DBusString decoded;
03285
03286 if (len < 0)
03287 len = strlen (data);
03288
03289 if (!_dbus_string_init (&orig))
03290 _dbus_assert_not_reached ("could not init string");
03291
03292 if (!_dbus_string_init (&encoded))
03293 _dbus_assert_not_reached ("could not init string");
03294
03295 if (!_dbus_string_init (&decoded))
03296 _dbus_assert_not_reached ("could not init string");
03297
03298 if (!_dbus_string_append_len (&orig, data, len))
03299 _dbus_assert_not_reached ("couldn't append orig data");
03300
03301 if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
03302 _dbus_assert_not_reached ("could not encode");
03303
03304 if (!_dbus_string_hex_decode (&encoded, 0, &decoded, 0))
03305 _dbus_assert_not_reached ("could not decode");
03306
03307 if (!_dbus_string_equal (&orig, &decoded))
03308 {
03309 const char *s;
03310
03311 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
03312 _dbus_string_get_length (&orig),
03313 _dbus_string_get_length (&encoded),
03314 _dbus_string_get_length (&decoded));
03315 printf ("Original: %s\n", data);
03316 s = _dbus_string_get_const_data (&decoded);
03317 printf ("Decoded: %s\n", s);
03318 _dbus_assert_not_reached ("original string not the same as string decoded from base64");
03319 }
03320
03321 _dbus_string_free (&orig);
03322 _dbus_string_free (&encoded);
03323 _dbus_string_free (&decoded);
03324 }
03325
03326 typedef void (* TestRoundtripFunc) (const unsigned char *data,
03327 int len);
03328 static void
03329 test_roundtrips (TestRoundtripFunc func)
03330 {
03331 (* func) ("Hello this is a string\n", -1);
03332 (* func) ("Hello this is a string\n1", -1);
03333 (* func) ("Hello this is a string\n12", -1);
03334 (* func) ("Hello this is a string\n123", -1);
03335 (* func) ("Hello this is a string\n1234", -1);
03336 (* func) ("Hello this is a string\n12345", -1);
03337 (* func) ("", 0);
03338 (* func) ("1", 1);
03339 (* func) ("12", 2);
03340 (* func) ("123", 3);
03341 (* func) ("1234", 4);
03342 (* func) ("12345", 5);
03343 (* func) ("", 1);
03344 (* func) ("1", 2);
03345 (* func) ("12", 3);
03346 (* func) ("123", 4);
03347 (* func) ("1234", 5);
03348 (* func) ("12345", 6);
03349 {
03350 unsigned char buf[512];
03351 int i;
03352
03353 i = 0;
03354 while (i < _DBUS_N_ELEMENTS (buf))
03355 {
03356 buf[i] = i;
03357 ++i;
03358 }
03359 i = 0;
03360 while (i < _DBUS_N_ELEMENTS (buf))
03361 {
03362 (* func) (buf, i);
03363 ++i;
03364 }
03365 }
03366 }
03367
03368
03379 dbus_bool_t
03380 _dbus_string_test (void)
03381 {
03382 DBusString str;
03383 DBusString other;
03384 int i, end;
03385 long v;
03386 double d;
03387 int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 };
03388 char *s;
03389 dbus_unichar_t ch;
03390 const char *valid_paths[] = {
03391 "/",
03392 "/foo/bar",
03393 "/foo",
03394 "/foo/bar/baz"
03395 };
03396 const char *invalid_paths[] = {
03397 "bar",
03398 "bar/baz",
03399 "/foo/bar/",
03400 "/foo/"
03401 "foo/",
03402 "boo//blah",
03403 "//",
03404 "
03405 "foo
03406 "Hello World",
03407 "",
03408 " ",
03409 "foo bar"
03410 };
03411
03412 const char *valid_interfaces[] = {
03413 "org.freedesktop.Foo",
03414 "Bar.Baz",
03415 "Blah.Blah.Blah.Blah.Blah",
03416 "a.b",
03417 "a.b.c.d.e.f.g",
03418 "a0.b1.c2.d3.e4.f5.g6",
03419 "abc123.foo27"
03420 };
03421 const char *invalid_interfaces[] = {
03422 ".",
03423 "",
03424 "..",
03425 ".Foo.Bar",
03426 "..Foo.Bar",
03427 "Foo.Bar.",
03428 "Foo.Bar..",
03429 "Foo",
03430 "9foo.bar.baz",
03431 "foo.bar..baz",
03432 "foo.bar...baz",
03433 "foo.bar.b..blah",
03434 ":",
03435 ":0-1",
03436 "10",
03437 ":11.34324",
03438 "0.0.0",
03439 "0..0",
03440 "foo.Bar.%",
03441 "foo.Bar!!",
03442 "!Foo.bar.bz",
03443 "foo.$.blah",
03444 "",
03445 " ",
03446 "foo bar"
03447 };
03448
03449 const char *valid_base_services[] = {
03450 ":0",
03451 ":a",
03452 ":",
03453 ":.a",
03454 ":.1",
03455 ":0.1",
03456 ":000.2222",
03457 ":.blah",
03458 ":abce.freedesktop.blah"
03459 };
03460 const char *invalid_base_services[] = {
03461 ":-",
03462 ":!",
03463 ":0-10",
03464 ":blah.",
03465 ":blah.",
03466 ":blah..org",
03467 ":blah.org..",
03468 ":..blah.org",
03469 "",
03470 " ",
03471 "foo bar"
03472 };
03473
03474 const char *valid_members[] = {
03475 "Hello",
03476 "Bar",
03477 "foobar",
03478 "_foobar",
03479 "foo89"
03480 };
03481
03482 const char *invalid_members[] = {
03483 "9Hello",
03484 "10",
03485 "1",
03486 "foo-bar",
03487 "blah.org",
03488 ".blah",
03489 "blah.",
03490 "Hello.",
03491 "!foo",
03492 "",
03493 " ",
03494 "foo bar"
03495 };
03496
03497 i = 0;
03498 while (i < _DBUS_N_ELEMENTS (lens))
03499 {
03500 if (!_dbus_string_init (&str))
03501 _dbus_assert_not_reached ("failed to init string");
03502
03503 set_max_length (&str, lens[i]);
03504
03505 test_max_len (&str, lens[i]);
03506 _dbus_string_free (&str);
03507
03508 ++i;
03509 }
03510
03511
03512 i = 0;
03513 while (i < _DBUS_N_ELEMENTS (lens))
03514 {
03515 int j;
03516
03517 if (!_dbus_string_init (&str))
03518 _dbus_assert_not_reached ("failed to init string");
03519
03520 set_max_length (&str, lens[i]);
03521
03522 if (!_dbus_string_set_length (&str, lens[i]))
03523 _dbus_assert_not_reached ("failed to set string length");
03524
03525 j = lens[i];
03526 while (j > 0)
03527 {
03528 _dbus_assert (_dbus_string_get_length (&str) == j);
03529 if (j > 0)
03530 {
03531 _dbus_string_shorten (&str, 1);
03532 _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
03533 }
03534 --j;
03535 }
03536
03537 _dbus_string_free (&str);
03538
03539 ++i;
03540 }
03541
03542
03543 if (!_dbus_string_init (&str))
03544 _dbus_assert_not_reached ("failed to init string");
03545
03546 i = 0;
03547 while (i < 10)
03548 {
03549 if (!_dbus_string_append (&str, "a"))
03550 _dbus_assert_not_reached ("failed to append string to string\n");
03551
03552 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
03553
03554 if (!_dbus_string_append_byte (&str, 'b'))
03555 _dbus_assert_not_reached ("failed to append byte to string\n");
03556
03557 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
03558
03559 ++i;
03560 }
03561
03562 _dbus_string_free (&str);
03563
03564
03565
03566 if (!_dbus_string_init (&str))
03567 _dbus_assert_not_reached ("failed to init string");
03568
03569 if (!_dbus_string_append (&str, "Hello World"))
03570 _dbus_assert_not_reached ("could not append to string");
03571
03572 i = _dbus_string_get_length (&str);
03573
03574 if (!_dbus_string_steal_data (&str, &s))
03575 _dbus_assert_not_reached ("failed to steal data");
03576
03577 _dbus_assert (_dbus_string_get_length (&str) == 0);
03578 _dbus_assert (((int)strlen (s)) == i);
03579
03580 dbus_free (s);
03581
03582
03583
03584 if (!_dbus_string_append (&str, "Hello World"))
03585 _dbus_assert_not_reached ("could not append to string");
03586
03587 i = _dbus_string_get_length (&str);
03588
03589 if (!_dbus_string_init (&other))
03590 _dbus_assert_not_reached ("could not init string");
03591
03592 if (!_dbus_string_move (&str, 0, &other, 0))
03593 _dbus_assert_not_reached ("could not move");
03594
03595 _dbus_assert (_dbus_string_get_length (&str) == 0);
03596 _dbus_assert (_dbus_string_get_length (&other) == i);
03597
03598 if (!_dbus_string_append (&str, "Hello World"))
03599 _dbus_assert_not_reached ("could not append to string");
03600
03601 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
03602 _dbus_assert_not_reached ("could not move");
03603
03604 _dbus_assert (_dbus_string_get_length (&str) == 0);
03605 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03606
03607 if (!_dbus_string_append (&str, "Hello World"))
03608 _dbus_assert_not_reached ("could not append to string");
03609
03610 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03611 _dbus_assert_not_reached ("could not move");
03612
03613 _dbus_assert (_dbus_string_get_length (&str) == 0);
03614 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03615
03616 _dbus_string_free (&other);
03617
03618
03619
03620 if (!_dbus_string_append (&str, "Hello World"))
03621 _dbus_assert_not_reached ("could not append to string");
03622
03623 i = _dbus_string_get_length (&str);
03624
03625 if (!_dbus_string_init (&other))
03626 _dbus_assert_not_reached ("could not init string");
03627
03628 if (!_dbus_string_copy (&str, 0, &other, 0))
03629 _dbus_assert_not_reached ("could not copy");
03630
03631 _dbus_assert (_dbus_string_get_length (&str) == i);
03632 _dbus_assert (_dbus_string_get_length (&other) == i);
03633
03634 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
03635 _dbus_assert_not_reached ("could not copy");
03636
03637 _dbus_assert (_dbus_string_get_length (&str) == i);
03638 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03639 _dbus_assert (_dbus_string_equal_c_str (&other,
03640 "Hello WorldHello World"));
03641
03642 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03643 _dbus_assert_not_reached ("could not copy");
03644
03645 _dbus_assert (_dbus_string_get_length (&str) == i);
03646 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03647 _dbus_assert (_dbus_string_equal_c_str (&other,
03648 "Hello WorldHello WorldHello World"));
03649
03650 _dbus_string_free (&str);
03651 _dbus_string_free (&other);
03652
03653
03654
03655 if (!_dbus_string_init (&str))
03656 _dbus_assert_not_reached ("failed to init string");
03657
03658 if (!_dbus_string_append (&str, "Hello World"))
03659 _dbus_assert_not_reached ("could not append to string");
03660
03661 i = _dbus_string_get_length (&str);
03662
03663 if (!_dbus_string_init (&other))
03664 _dbus_assert_not_reached ("could not init string");
03665
03666 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03667 &other, 0, _dbus_string_get_length (&other)))
03668 _dbus_assert_not_reached ("could not replace");
03669
03670 _dbus_assert (_dbus_string_get_length (&str) == i);
03671 _dbus_assert (_dbus_string_get_length (&other) == i);
03672 _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
03673
03674 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03675 &other, 5, 1))
03676 _dbus_assert_not_reached ("could not replace center space");
03677
03678 _dbus_assert (_dbus_string_get_length (&str) == i);
03679 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03680 _dbus_assert (_dbus_string_equal_c_str (&other,
03681 "HelloHello WorldWorld"));
03682
03683
03684 if (!_dbus_string_replace_len (&str, 1, 1,
03685 &other,
03686 _dbus_string_get_length (&other) - 1,
03687 1))
03688 _dbus_assert_not_reached ("could not replace end character");
03689
03690 _dbus_assert (_dbus_string_get_length (&str) == i);
03691 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03692 _dbus_assert (_dbus_string_equal_c_str (&other,
03693 "HelloHello WorldWorle"));
03694
03695 _dbus_string_free (&str);
03696 _dbus_string_free (&other);
03697
03698
03699
03700 if (!_dbus_string_init (&str))
03701 _dbus_assert_not_reached ("failed to init string");
03702
03703 ch = 0;
03704 if (!_dbus_string_append_unichar (&str, 0xfffc))
03705 _dbus_assert_not_reached ("failed to append unichar");
03706
03707 _dbus_string_get_unichar (&str, 0, &ch, &i);
03708
03709 _dbus_assert (ch == 0xfffc);
03710 _dbus_assert (i == _dbus_string_get_length (&str));
03711
03712 _dbus_string_free (&str);
03713
03714
03715
03716 if (!_dbus_string_init (&str))
03717 _dbus_assert_not_reached ("failed to init string");
03718
03719 if (!_dbus_string_append (&str, "Hello"))
03720 _dbus_assert_not_reached ("failed to append Hello");
03721
03722 _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
03723 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
03724 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
03725 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
03726 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
03727
03728 _dbus_string_set_byte (&str, 1, 'q');
03729 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
03730
03731 if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
03732 _dbus_assert_not_reached ("can't insert byte");
03733
03734 if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
03735 _dbus_assert_not_reached ("can't insert byte");
03736
03737 if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
03738 _dbus_assert_not_reached ("can't insert byte");
03739
03740 _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
03741 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
03742 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
03743 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
03744 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
03745 _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
03746 _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
03747 _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
03748 _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
03749 _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
03750 _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
03751
03752 _dbus_string_free (&str);
03753
03754
03755
03756 if (!_dbus_string_init (&str))
03757 _dbus_assert_not_reached ("failed to init string");
03758
03759 if (!_dbus_string_append_int (&str, 27))
03760 _dbus_assert_not_reached ("failed to append int");
03761
03762 i = _dbus_string_get_length (&str);
03763
03764 if (!_dbus_string_parse_int (&str, 0, &v, &end))
03765 _dbus_assert_not_reached ("failed to parse int");
03766
03767 _dbus_assert (v == 27);
03768 _dbus_assert (end == i);
03769
03770 _dbus_string_free (&str);
03771
03772 if (!_dbus_string_init (&str))
03773 _dbus_assert_not_reached ("failed to init string");
03774
03775 if (!_dbus_string_append_double (&str, 50.3))
03776 _dbus_assert_not_reached ("failed to append float");
03777
03778 i = _dbus_string_get_length (&str);
03779
03780 if (!_dbus_string_parse_double (&str, 0, &d, &end))
03781 _dbus_assert_not_reached ("failed to parse float");
03782
03783 _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
03784 _dbus_assert (end == i);
03785
03786 _dbus_string_free (&str);
03787
03788
03789 if (!_dbus_string_init (&str))
03790 _dbus_assert_not_reached ("failed to init string");
03791
03792 if (!_dbus_string_append (&str, "Hello"))
03793 _dbus_assert_not_reached ("couldn't append to string");
03794
03795 if (!_dbus_string_find (&str, 0, "He", &i))
03796 _dbus_assert_not_reached ("didn't find 'He'");
03797 _dbus_assert (i == 0);
03798
03799 if (!_dbus_string_find (&str, 0, "Hello", &i))
03800 _dbus_assert_not_reached ("didn't find 'Hello'");
03801 _dbus_assert (i == 0);
03802
03803 if (!_dbus_string_find (&str, 0, "ello", &i))
03804 _dbus_assert_not_reached ("didn't find 'ello'");
03805 _dbus_assert (i == 1);
03806
03807 if (!_dbus_string_find (&str, 0, "lo", &i))
03808 _dbus_assert_not_reached ("didn't find 'lo'");
03809 _dbus_assert (i == 3);
03810
03811 if (!_dbus_string_find (&str, 2, "lo", &i))
03812 _dbus_assert_not_reached ("didn't find 'lo'");
03813 _dbus_assert (i == 3);
03814
03815 if (_dbus_string_find (&str, 4, "lo", &i))
03816 _dbus_assert_not_reached ("did find 'lo'");
03817
03818 if (!_dbus_string_find (&str, 0, "l", &i))
03819 _dbus_assert_not_reached ("didn't find 'l'");
03820 _dbus_assert (i == 2);
03821
03822 if (!_dbus_string_find (&str, 0, "H", &i))
03823 _dbus_assert_not_reached ("didn't find 'H'");
03824 _dbus_assert (i == 0);
03825
03826 if (!_dbus_string_find (&str, 0, "", &i))
03827 _dbus_assert_not_reached ("didn't find ''");
03828 _dbus_assert (i == 0);
03829
03830 if (_dbus_string_find (&str, 0, "Hello!", NULL))
03831 _dbus_assert_not_reached ("Did find 'Hello!'");
03832
03833 if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
03834 _dbus_assert_not_reached ("Did find 'Oh, Hello'");
03835
03836 if (_dbus_string_find (&str, 0, "ill", NULL))
03837 _dbus_assert_not_reached ("Did find 'ill'");
03838
03839 if (_dbus_string_find (&str, 0, "q", NULL))
03840 _dbus_assert_not_reached ("Did find 'q'");
03841
03842 if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
03843 _dbus_assert_not_reached ("Didn't find 'He'");
03844
03845 if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
03846 _dbus_assert_not_reached ("Did find 'Hello'");
03847
03848 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
03849 _dbus_assert_not_reached ("Did not find 'H'");
03850 _dbus_assert (i == 0);
03851
03852 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
03853 _dbus_assert_not_reached ("Did not find 'o'");
03854 _dbus_assert (i == _dbus_string_get_length (&str) - 1);
03855
03856 if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
03857 _dbus_assert_not_reached ("Did find 'o'");
03858 _dbus_assert (i == -1);
03859
03860 if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
03861 _dbus_assert_not_reached ("Did find 'e'");
03862 _dbus_assert (i == -1);
03863
03864 if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
03865 _dbus_assert_not_reached ("Didn't find 'e'");
03866 _dbus_assert (i == 1);
03867
03868 _dbus_string_free (&str);
03869
03870
03871 test_roundtrips (test_base64_roundtrip);
03872 test_roundtrips (test_hex_roundtrip);
03873
03874
03875 i = 0;
03876 while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
03877 {
03878 _dbus_string_init_const (&str, valid_paths[i]);
03879
03880 if (!_dbus_string_validate_path (&str, 0,
03881 _dbus_string_get_length (&str)))
03882 {
03883 _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
03884 _dbus_assert_not_reached ("invalid path");
03885 }
03886
03887 ++i;
03888 }
03889
03890 i = 0;
03891 while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
03892 {
03893 _dbus_string_init_const (&str, invalid_paths[i]);
03894
03895 if (_dbus_string_validate_path (&str, 0,
03896 _dbus_string_get_length (&str)))
03897 {
03898 _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
03899 _dbus_assert_not_reached ("valid path");
03900 }
03901
03902 ++i;
03903 }
03904
03905
03906 i = 0;
03907 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
03908 {
03909 _dbus_string_init_const (&str, valid_interfaces[i]);
03910
03911 if (!_dbus_string_validate_interface (&str, 0,
03912 _dbus_string_get_length (&str)))
03913 {
03914 _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]);
03915 _dbus_assert_not_reached ("invalid interface");
03916 }
03917
03918 ++i;
03919 }
03920
03921 i = 0;
03922 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
03923 {
03924 _dbus_string_init_const (&str, invalid_interfaces[i]);
03925
03926 if (_dbus_string_validate_interface (&str, 0,
03927 _dbus_string_get_length (&str)))
03928 {
03929 _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]);
03930 _dbus_assert_not_reached ("valid interface");
03931 }
03932
03933 ++i;
03934 }
03935
03936
03937
03938
03939 i = 0;
03940 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
03941 {
03942 _dbus_string_init_const (&str, valid_interfaces[i]);
03943
03944 if (!_dbus_string_validate_service (&str, 0,
03945 _dbus_string_get_length (&str)))
03946 {
03947 _dbus_warn ("Service \"%s\" should have been valid\n", valid_interfaces[i]);
03948 _dbus_assert_not_reached ("invalid service");
03949 }
03950
03951 ++i;
03952 }
03953
03954 i = 0;
03955 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
03956 {
03957 if (invalid_interfaces[i][0] != ':')
03958 {
03959 _dbus_string_init_const (&str, invalid_interfaces[i]);
03960
03961 if (_dbus_string_validate_service (&str, 0,
03962 _dbus_string_get_length (&str)))
03963 {
03964 _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_interfaces[i]);
03965 _dbus_assert_not_reached ("valid service");
03966 }
03967 }
03968
03969 ++i;
03970 }
03971
03972
03973 i = 0;
03974 while (i < (int) _DBUS_N_ELEMENTS (valid_base_services))
03975 {
03976 _dbus_string_init_const (&str, valid_base_services[i]);
03977
03978 if (!_dbus_string_validate_service (&str, 0,
03979 _dbus_string_get_length (&str)))
03980 {
03981 _dbus_warn ("Service \"%s\" should have been valid\n", valid_base_services[i]);
03982 _dbus_assert_not_reached ("invalid base service");
03983 }
03984
03985 ++i;
03986 }
03987
03988 i = 0;
03989 while (i < (int) _DBUS_N_ELEMENTS (invalid_base_services))
03990 {
03991 _dbus_string_init_const (&str, invalid_base_services[i]);
03992
03993 if (_dbus_string_validate_service (&str, 0,
03994 _dbus_string_get_length (&str)))
03995 {
03996 _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_base_services[i]);
03997 _dbus_assert_not_reached ("valid base service");
03998 }
03999
04000 ++i;
04001 }
04002
04003
04004
04005
04006 i = 0;
04007 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
04008 {
04009 _dbus_string_init_const (&str, valid_interfaces[i]);
04010
04011 if (!_dbus_string_validate_error_name (&str, 0,
04012 _dbus_string_get_length (&str)))
04013 {
04014 _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]);
04015 _dbus_assert_not_reached ("invalid error name");
04016 }
04017
04018 ++i;
04019 }
04020
04021 i = 0;
04022 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
04023 {
04024 if (invalid_interfaces[i][0] != ':')
04025 {
04026 _dbus_string_init_const (&str, invalid_interfaces[i]);
04027
04028 if (_dbus_string_validate_error_name (&str, 0,
04029 _dbus_string_get_length (&str)))
04030 {
04031 _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]);
04032 _dbus_assert_not_reached ("valid error name");
04033 }
04034 }
04035
04036 ++i;
04037 }
04038
04039
04040 i = 0;
04041 while (i < (int) _DBUS_N_ELEMENTS (valid_members))
04042 {
04043 _dbus_string_init_const (&str, valid_members[i]);
04044
04045 if (!_dbus_string_validate_member (&str, 0,
04046 _dbus_string_get_length (&str)))
04047 {
04048 _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]);
04049 _dbus_assert_not_reached ("invalid member");
04050 }
04051
04052 ++i;
04053 }
04054
04055 i = 0;
04056 while (i < (int) _DBUS_N_ELEMENTS (invalid_members))
04057 {
04058 _dbus_string_init_const (&str, invalid_members[i]);
04059
04060 if (_dbus_string_validate_member (&str, 0,
04061 _dbus_string_get_length (&str)))
04062 {
04063 _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]);
04064 _dbus_assert_not_reached ("valid member");
04065 }
04066
04067 ++i;
04068 }
04069
04070
04071 _dbus_string_init_const (&str, "abc.efg");
04072 if (_dbus_string_validate_service (&str, 0, 8))
04073 _dbus_assert_not_reached ("validated too-long string");
04074 if (_dbus_string_validate_interface (&str, 0, 8))
04075 _dbus_assert_not_reached ("validated too-long string");
04076 if (_dbus_string_validate_error_name (&str, 0, 8))
04077 _dbus_assert_not_reached ("validated too-long string");
04078
04079 _dbus_string_init_const (&str, "abc");
04080 if (_dbus_string_validate_member (&str, 0, 4))
04081 _dbus_assert_not_reached ("validated too-long string");
04082
04083
04084 if (!_dbus_string_init (&str))
04085 _dbus_assert_not_reached ("no memory");
04086
04087 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
04088 if (!_dbus_string_append (&str, "abc.def"))
04089 _dbus_assert_not_reached ("no memory");
04090
04091 if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
04092 _dbus_assert_not_reached ("validated overmax string");
04093 if (_dbus_string_validate_interface (&str, 0, _dbus_string_get_length (&str)))
04094 _dbus_assert_not_reached ("validated overmax string");
04095 if (_dbus_string_validate_error_name (&str, 0, _dbus_string_get_length (&str)))
04096 _dbus_assert_not_reached ("validated overmax string");
04097
04098
04099 _dbus_string_set_length (&str, 0);
04100 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
04101 if (!_dbus_string_append (&str, "abc"))
04102 _dbus_assert_not_reached ("no memory");
04103
04104 if (_dbus_string_validate_member (&str, 0, _dbus_string_get_length (&str)))
04105 _dbus_assert_not_reached ("validated overmax string");
04106
04107
04108 _dbus_string_set_length (&str, 0);
04109 _dbus_string_append (&str, ":");
04110 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
04111 if (!_dbus_string_append (&str, "abc"))
04112 _dbus_assert_not_reached ("no memory");
04113
04114 if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
04115 _dbus_assert_not_reached ("validated overmax string");
04116
04117 _dbus_string_free (&str);
04118
04119 return TRUE;
04120 }
04121
04122 #endif