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