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
00085 #define ALLOCATION_PADDING 8
00086
00091 #define MAX_MAX_LENGTH (_DBUS_INT_MAX - ALLOCATION_PADDING)
00092
00098 #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)
00099
00106 #define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00107 DBUS_GENERIC_STRING_PREAMBLE (real); \
00108 _dbus_assert (!(real)->constant); \
00109 _dbus_assert (!(real)->locked)
00110
00118 #define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00119 DBUS_GENERIC_STRING_PREAMBLE (real); \
00120 _dbus_assert (!(real)->constant)
00121
00127 #define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
00128 DBUS_GENERIC_STRING_PREAMBLE (real)
00129
00137 static void
00138 fixup_alignment (DBusRealString *real)
00139 {
00140 char *aligned;
00141 char *real_block;
00142 unsigned int old_align_offset;
00143
00144
00145 _dbus_assert (real->len <= real->allocated - ALLOCATION_PADDING);
00146
00147 old_align_offset = real->align_offset;
00148 real_block = real->str - old_align_offset;
00149
00150 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
00151
00152 real->align_offset = aligned - real_block;
00153 real->str = aligned;
00154
00155 if (old_align_offset != real->align_offset)
00156 {
00157
00158 memmove (real_block + real->align_offset,
00159 real_block + old_align_offset,
00160 real->len + 1);
00161 }
00162
00163 _dbus_assert (real->align_offset < 8);
00164 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
00165 }
00166
00167 static void
00168 undo_alignment (DBusRealString *real)
00169 {
00170 if (real->align_offset != 0)
00171 {
00172 memmove (real->str - real->align_offset,
00173 real->str,
00174 real->len + 1);
00175
00176 real->str = real->str - real->align_offset;
00177 real->align_offset = 0;
00178 }
00179 }
00180
00190 dbus_bool_t
00191 _dbus_string_init_preallocated (DBusString *str,
00192 int allocate_size)
00193 {
00194 DBusRealString *real;
00195
00196 _dbus_assert (str != NULL);
00197
00198 _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
00199
00200 real = (DBusRealString*) str;
00201
00202
00203
00204
00205
00206
00207
00208 real->str = dbus_malloc (ALLOCATION_PADDING + allocate_size);
00209 if (real->str == NULL)
00210 return FALSE;
00211
00212 real->allocated = ALLOCATION_PADDING + allocate_size;
00213 real->len = 0;
00214 real->str[real->len] = '\0';
00215
00216 real->max_length = MAX_MAX_LENGTH;
00217 real->constant = FALSE;
00218 real->locked = FALSE;
00219 real->invalid = FALSE;
00220 real->align_offset = 0;
00221
00222 fixup_alignment (real);
00223
00224 return TRUE;
00225 }
00226
00234 dbus_bool_t
00235 _dbus_string_init (DBusString *str)
00236 {
00237 return _dbus_string_init_preallocated (str, 0);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246 static void
00247 set_max_length (DBusString *str,
00248 int max_length)
00249 {
00250 DBusRealString *real;
00251
00252 real = (DBusRealString*) str;
00253
00254 real->max_length = max_length;
00255 }
00256
00266 void
00267 _dbus_string_init_const (DBusString *str,
00268 const char *value)
00269 {
00270 _dbus_assert (value != NULL);
00271
00272 _dbus_string_init_const_len (str, value,
00273 strlen (value));
00274 }
00275
00286 void
00287 _dbus_string_init_const_len (DBusString *str,
00288 const char *value,
00289 int len)
00290 {
00291 DBusRealString *real;
00292
00293 _dbus_assert (str != NULL);
00294 _dbus_assert (value != NULL);
00295 _dbus_assert (len <= MAX_MAX_LENGTH);
00296 _dbus_assert (len >= 0);
00297
00298 real = (DBusRealString*) str;
00299
00300 real->str = (char*) value;
00301 real->len = len;
00302 real->allocated = real->len + ALLOCATION_PADDING;
00303 real->max_length = real->len + 1;
00304 real->constant = TRUE;
00305 real->invalid = FALSE;
00306
00307
00308
00309
00310 }
00311
00317 void
00318 _dbus_string_free (DBusString *str)
00319 {
00320 DBusRealString *real = (DBusRealString*) str;
00321 DBUS_GENERIC_STRING_PREAMBLE (real);
00322
00323 if (real->constant)
00324 return;
00325 dbus_free (real->str - real->align_offset);
00326
00327 real->invalid = TRUE;
00328 }
00329
00330 #ifdef DBUS_BUILD_TESTS
00331
00332
00333
00343 void
00344 _dbus_string_lock (DBusString *str)
00345 {
00346 DBUS_LOCKED_STRING_PREAMBLE (str);
00347
00348 real->locked = TRUE;
00349
00350
00351
00352
00353 #define MAX_WASTE 48
00354 if (real->allocated - MAX_WASTE > real->len)
00355 {
00356 char *new_str;
00357 int new_allocated;
00358
00359 new_allocated = real->len + ALLOCATION_PADDING;
00360
00361 new_str = dbus_realloc (real->str - real->align_offset,
00362 new_allocated);
00363 if (new_str != NULL)
00364 {
00365 real->str = new_str + real->align_offset;
00366 real->allocated = new_allocated;
00367 fixup_alignment (real);
00368 }
00369 }
00370 }
00371 #endif
00372
00373 static dbus_bool_t
00374 reallocate_for_length (DBusRealString *real,
00375 int new_length)
00376 {
00377 int new_allocated;
00378 char *new_str;
00379
00380
00381
00382
00383 if (real->allocated > (MAX_MAX_LENGTH + ALLOCATION_PADDING) / 2)
00384 new_allocated = MAX_MAX_LENGTH + ALLOCATION_PADDING;
00385 else
00386 new_allocated = real->allocated * 2;
00387
00388
00389
00390
00391
00392
00393
00394
00395 #ifdef DBUS_DISABLE_ASSERT
00396 #else
00397 #ifdef DBUS_BUILD_TESTS
00398 new_allocated = 0;
00399
00400
00401 #endif
00402 #endif
00403
00404
00405 new_allocated = MAX (new_allocated,
00406 new_length + ALLOCATION_PADDING);
00407
00408 _dbus_assert (new_allocated >= real->allocated);
00409 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00410 if (_DBUS_UNLIKELY (new_str == NULL))
00411 return FALSE;
00412
00413 real->str = new_str + real->align_offset;
00414 real->allocated = new_allocated;
00415 fixup_alignment (real);
00416
00417 return TRUE;
00418 }
00419
00420 static dbus_bool_t
00421 set_length (DBusRealString *real,
00422 int new_length)
00423 {
00424
00425
00426
00427 if (_DBUS_UNLIKELY (new_length > real->max_length))
00428 return FALSE;
00429 else if (new_length > (real->allocated - ALLOCATION_PADDING) &&
00430 _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
00431 return FALSE;
00432 else
00433 {
00434 real->len = new_length;
00435 real->str[new_length] = '\0';
00436 return TRUE;
00437 }
00438 }
00439
00440 static dbus_bool_t
00441 open_gap (int len,
00442 DBusRealString *dest,
00443 int insert_at)
00444 {
00445 if (len == 0)
00446 return TRUE;
00447
00448 if (len > dest->max_length - dest->len)
00449 return FALSE;
00450
00451 if (!set_length (dest, dest->len + len))
00452 return FALSE;
00453
00454 memmove (dest->str + insert_at + len,
00455 dest->str + insert_at,
00456 dest->len - len - insert_at);
00457
00458 return TRUE;
00459 }
00460
00472 char*
00473 _dbus_string_get_data (DBusString *str)
00474 {
00475 DBUS_STRING_PREAMBLE (str);
00476
00477 return real->str;
00478 }
00479
00480
00481 #ifndef _dbus_string_get_const_data
00482
00488 const char*
00489 _dbus_string_get_const_data (const DBusString *str)
00490 {
00491 DBUS_CONST_STRING_PREAMBLE (str);
00492
00493 return real->str;
00494 }
00495 #endif
00496
00510 char*
00511 _dbus_string_get_data_len (DBusString *str,
00512 int start,
00513 int len)
00514 {
00515 DBUS_STRING_PREAMBLE (str);
00516 _dbus_assert (start >= 0);
00517 _dbus_assert (len >= 0);
00518 _dbus_assert (start <= real->len);
00519 _dbus_assert (len <= real->len - start);
00520
00521 return real->str + start;
00522 }
00523
00532 const char*
00533 _dbus_string_get_const_data_len (const DBusString *str,
00534 int start,
00535 int len)
00536 {
00537 DBUS_CONST_STRING_PREAMBLE (str);
00538 _dbus_assert (start >= 0);
00539 _dbus_assert (len >= 0);
00540 _dbus_assert (start <= real->len);
00541 _dbus_assert (len <= real->len - start);
00542
00543 return real->str + start;
00544 }
00545
00553 void
00554 _dbus_string_set_byte (DBusString *str,
00555 int i,
00556 unsigned char byte)
00557 {
00558 DBUS_STRING_PREAMBLE (str);
00559 _dbus_assert (i < real->len);
00560 _dbus_assert (i >= 0);
00561
00562 real->str[i] = byte;
00563 }
00564
00565
00566 #ifndef _dbus_string_get_byte
00567
00576 unsigned char
00577 _dbus_string_get_byte (const DBusString *str,
00578 int start)
00579 {
00580 DBUS_CONST_STRING_PREAMBLE (str);
00581 _dbus_assert (start <= real->len);
00582 _dbus_assert (start >= 0);
00583
00584 return real->str[start];
00585 }
00586 #endif
00587
00598 dbus_bool_t
00599 _dbus_string_insert_bytes (DBusString *str,
00600 int i,
00601 int n_bytes,
00602 unsigned char byte)
00603 {
00604 DBUS_STRING_PREAMBLE (str);
00605 _dbus_assert (i <= real->len);
00606 _dbus_assert (i >= 0);
00607 _dbus_assert (n_bytes >= 0);
00608
00609 if (n_bytes == 0)
00610 return TRUE;
00611
00612 if (!open_gap (n_bytes, real, i))
00613 return FALSE;
00614
00615 memset (real->str + i, byte, n_bytes);
00616
00617 return TRUE;
00618 }
00619
00628 dbus_bool_t
00629 _dbus_string_insert_byte (DBusString *str,
00630 int i,
00631 unsigned char byte)
00632 {
00633 DBUS_STRING_PREAMBLE (str);
00634 _dbus_assert (i <= real->len);
00635 _dbus_assert (i >= 0);
00636
00637 if (!open_gap (1, real, i))
00638 return FALSE;
00639
00640 real->str[i] = byte;
00641
00642 return TRUE;
00643 }
00644
00655 dbus_bool_t
00656 _dbus_string_steal_data (DBusString *str,
00657 char **data_return)
00658 {
00659 int old_max_length;
00660 DBUS_STRING_PREAMBLE (str);
00661 _dbus_assert (data_return != NULL);
00662
00663 undo_alignment (real);
00664
00665 *data_return = real->str;
00666
00667 old_max_length = real->max_length;
00668
00669
00670 if (!_dbus_string_init (str))
00671 {
00672
00673 real->str = *data_return;
00674 *data_return = NULL;
00675 fixup_alignment (real);
00676 return FALSE;
00677 }
00678
00679 real->max_length = old_max_length;
00680
00681 return TRUE;
00682 }
00683
00699 dbus_bool_t
00700 _dbus_string_steal_data_len (DBusString *str,
00701 char **data_return,
00702 int start,
00703 int len)
00704 {
00705 DBusString dest;
00706 DBUS_STRING_PREAMBLE (str);
00707 _dbus_assert (data_return != NULL);
00708 _dbus_assert (start >= 0);
00709 _dbus_assert (len >= 0);
00710 _dbus_assert (start <= real->len);
00711 _dbus_assert (len <= real->len - start);
00712
00713 if (!_dbus_string_init (&dest))
00714 return FALSE;
00715
00716 set_max_length (&dest, real->max_length);
00717
00718 if (!_dbus_string_move_len (str, start, len, &dest, 0))
00719 {
00720 _dbus_string_free (&dest);
00721 return FALSE;
00722 }
00723
00724 _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
00725 if (!_dbus_string_steal_data (&dest, data_return))
00726 {
00727 _dbus_string_free (&dest);
00728 return FALSE;
00729 }
00730
00731 _dbus_string_free (&dest);
00732 return TRUE;
00733 }
00734
00735
00743 dbus_bool_t
00744 _dbus_string_copy_data (const DBusString *str,
00745 char **data_return)
00746 {
00747 DBUS_CONST_STRING_PREAMBLE (str);
00748 _dbus_assert (data_return != NULL);
00749
00750 *data_return = dbus_malloc (real->len + 1);
00751 if (*data_return == NULL)
00752 return FALSE;
00753
00754 memcpy (*data_return, real->str, real->len + 1);
00755
00756 return TRUE;
00757 }
00758
00768 dbus_bool_t
00769 _dbus_string_copy_data_len (const DBusString *str,
00770 char **data_return,
00771 int start,
00772 int len)
00773 {
00774 DBusString dest;
00775
00776 DBUS_CONST_STRING_PREAMBLE (str);
00777 _dbus_assert (data_return != NULL);
00778 _dbus_assert (start >= 0);
00779 _dbus_assert (len >= 0);
00780 _dbus_assert (start <= real->len);
00781 _dbus_assert (len <= real->len - start);
00782
00783 if (!_dbus_string_init (&dest))
00784 return FALSE;
00785
00786 set_max_length (&dest, real->max_length);
00787
00788 if (!_dbus_string_copy_len (str, start, len, &dest, 0))
00789 {
00790 _dbus_string_free (&dest);
00791 return FALSE;
00792 }
00793
00794 if (!_dbus_string_steal_data (&dest, data_return))
00795 {
00796 _dbus_string_free (&dest);
00797 return FALSE;
00798 }
00799
00800 _dbus_string_free (&dest);
00801 return TRUE;
00802 }
00803
00812 void
00813 _dbus_string_copy_to_buffer (const DBusString *str,
00814 char *buffer,
00815 int avail_len)
00816 {
00817 int copy_len;
00818 DBUS_CONST_STRING_PREAMBLE (str);
00819
00820 _dbus_assert (avail_len >= 0);
00821
00822 copy_len = MIN (avail_len, real->len+1);
00823 memcpy (buffer, real->str, copy_len);
00824 if (avail_len > 0 && avail_len == copy_len)
00825 buffer[avail_len-1] = '\0';
00826 }
00827
00828
00829 #ifndef _dbus_string_get_length
00830
00835 int
00836 _dbus_string_get_length (const DBusString *str)
00837 {
00838 DBUS_CONST_STRING_PREAMBLE (str);
00839
00840 return real->len;
00841 }
00842 #endif
00843
00856 dbus_bool_t
00857 _dbus_string_lengthen (DBusString *str,
00858 int additional_length)
00859 {
00860 DBUS_STRING_PREAMBLE (str);
00861 _dbus_assert (additional_length >= 0);
00862
00863 if (_DBUS_UNLIKELY (additional_length > real->max_length - real->len))
00864 return FALSE;
00865
00866 return set_length (real,
00867 real->len + additional_length);
00868 }
00869
00876 void
00877 _dbus_string_shorten (DBusString *str,
00878 int length_to_remove)
00879 {
00880 DBUS_STRING_PREAMBLE (str);
00881 _dbus_assert (length_to_remove >= 0);
00882 _dbus_assert (length_to_remove <= real->len);
00883
00884 set_length (real,
00885 real->len - length_to_remove);
00886 }
00887
00898 dbus_bool_t
00899 _dbus_string_set_length (DBusString *str,
00900 int length)
00901 {
00902 DBUS_STRING_PREAMBLE (str);
00903 _dbus_assert (length >= 0);
00904
00905 return set_length (real, length);
00906 }
00907
00908 static dbus_bool_t
00909 align_insert_point_then_open_gap (DBusString *str,
00910 int *insert_at_p,
00911 int alignment,
00912 int gap_size)
00913 {
00914 unsigned long new_len;
00915 unsigned long gap_pos;
00916 int insert_at;
00917 int delta;
00918 DBUS_STRING_PREAMBLE (str);
00919 _dbus_assert (alignment >= 1);
00920 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
00921
00922 insert_at = *insert_at_p;
00923
00924 _dbus_assert (insert_at <= real->len);
00925
00926 gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
00927 new_len = real->len + (gap_pos - insert_at) + gap_size;
00928
00929 if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length))
00930 return FALSE;
00931
00932 delta = new_len - real->len;
00933 _dbus_assert (delta >= 0);
00934
00935 if (delta == 0)
00936 {
00937 _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
00938 return TRUE;
00939 }
00940
00941 if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
00942 real, insert_at)))
00943 return FALSE;
00944
00945
00946 if (gap_size < delta)
00947 {
00948 memset (&real->str[insert_at], '\0',
00949 gap_pos - insert_at);
00950 }
00951
00952 *insert_at_p = gap_pos;
00953
00954 return TRUE;
00955 }
00956
00957 static dbus_bool_t
00958 align_length_then_lengthen (DBusString *str,
00959 int alignment,
00960 int then_lengthen_by)
00961 {
00962 int insert_at;
00963
00964 insert_at = _dbus_string_get_length (str);
00965
00966 return align_insert_point_then_open_gap (str,
00967 &insert_at,
00968 alignment, then_lengthen_by);
00969 }
00970
00979 dbus_bool_t
00980 _dbus_string_align_length (DBusString *str,
00981 int alignment)
00982 {
00983 return align_length_then_lengthen (str, alignment, 0);
00984 }
00985
00995 dbus_bool_t
00996 _dbus_string_alloc_space (DBusString *str,
00997 int extra_bytes)
00998 {
00999 if (!_dbus_string_lengthen (str, extra_bytes))
01000 return FALSE;
01001 _dbus_string_shorten (str, extra_bytes);
01002
01003 return TRUE;
01004 }
01005
01006 static dbus_bool_t
01007 append (DBusRealString *real,
01008 const char *buffer,
01009 int buffer_len)
01010 {
01011 if (buffer_len == 0)
01012 return TRUE;
01013
01014 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
01015 return FALSE;
01016
01017 memcpy (real->str + (real->len - buffer_len),
01018 buffer,
01019 buffer_len);
01020
01021 return TRUE;
01022 }
01023
01031 dbus_bool_t
01032 _dbus_string_append (DBusString *str,
01033 const char *buffer)
01034 {
01035 unsigned long buffer_len;
01036
01037 DBUS_STRING_PREAMBLE (str);
01038 _dbus_assert (buffer != NULL);
01039
01040 buffer_len = strlen (buffer);
01041 if (buffer_len > (unsigned long) real->max_length)
01042 return FALSE;
01043
01044 return append (real, buffer, buffer_len);
01045 }
01046
01047 #define ASSIGN_4_OCTETS(p, octets) \
01048 *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
01049
01050 #ifdef DBUS_HAVE_INT64
01051 #define ASSIGN_8_OCTETS(p, octets) \
01052 *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
01053 #else
01054 #define ASSIGN_8_OCTETS(p, octets) \
01055 do { \
01056 unsigned char *b; \
01057 \
01058 b = p; \
01059 \
01060 *b++ = octets[0]; \
01061 *b++ = octets[1]; \
01062 *b++ = octets[2]; \
01063 *b++ = octets[3]; \
01064 *b++ = octets[4]; \
01065 *b++ = octets[5]; \
01066 *b++ = octets[6]; \
01067 *b++ = octets[7]; \
01068 _dbus_assert (b == p + 8); \
01069 } while (0)
01070 #endif
01071
01080 dbus_bool_t
01081 _dbus_string_append_4_aligned (DBusString *str,
01082 const unsigned char octets[4])
01083 {
01084 DBUS_STRING_PREAMBLE (str);
01085
01086 if (!align_length_then_lengthen (str, 4, 4))
01087 return FALSE;
01088
01089 ASSIGN_4_OCTETS (real->str + (real->len - 4), octets);
01090
01091 return TRUE;
01092 }
01093
01102 dbus_bool_t
01103 _dbus_string_append_8_aligned (DBusString *str,
01104 const unsigned char octets[8])
01105 {
01106 DBUS_STRING_PREAMBLE (str);
01107
01108 if (!align_length_then_lengthen (str, 8, 8))
01109 return FALSE;
01110
01111 ASSIGN_8_OCTETS (real->str + (real->len - 8), octets);
01112
01113 return TRUE;
01114 }
01115
01124 dbus_bool_t
01125 _dbus_string_insert_4_aligned (DBusString *str,
01126 int insert_at,
01127 const unsigned char octets[4])
01128 {
01129 DBUS_STRING_PREAMBLE (str);
01130
01131 if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
01132 return FALSE;
01133
01134 ASSIGN_4_OCTETS (real->str + insert_at, octets);
01135
01136 return TRUE;
01137 }
01138
01147 dbus_bool_t
01148 _dbus_string_insert_8_aligned (DBusString *str,
01149 int insert_at,
01150 const unsigned char octets[8])
01151 {
01152 DBUS_STRING_PREAMBLE (str);
01153
01154 if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
01155 return FALSE;
01156
01157 _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
01158
01159 ASSIGN_8_OCTETS (real->str + insert_at, octets);
01160
01161 return TRUE;
01162 }
01163
01164
01175 dbus_bool_t
01176 _dbus_string_insert_alignment (DBusString *str,
01177 int *insert_at,
01178 int alignment)
01179 {
01180 DBUS_STRING_PREAMBLE (str);
01181
01182 if (!align_insert_point_then_open_gap (str, insert_at, 8, 0))
01183 return FALSE;
01184
01185 _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, 8) == (unsigned) *insert_at);
01186
01187 return TRUE;
01188 }
01189
01199 dbus_bool_t
01200 _dbus_string_append_printf_valist (DBusString *str,
01201 const char *format,
01202 va_list args)
01203 {
01204 int len;
01205 char c;
01206 va_list args_copy;
01207
01208 DBUS_STRING_PREAMBLE (str);
01209
01210 DBUS_VA_COPY (args_copy, args);
01211
01212
01213 len = vsnprintf (&c, 1, format, args);
01214
01215 if (!_dbus_string_lengthen (str, len))
01216 {
01217
01218 va_end (args_copy);
01219 return FALSE;
01220 }
01221
01222 vsprintf (real->str + (real->len - len),
01223 format, args_copy);
01224
01225 va_end (args_copy);
01226
01227 return TRUE;
01228 }
01229
01238 dbus_bool_t
01239 _dbus_string_append_printf (DBusString *str,
01240 const char *format,
01241 ...)
01242 {
01243 va_list args;
01244 dbus_bool_t retval;
01245
01246 va_start (args, format);
01247 retval = _dbus_string_append_printf_valist (str, format, args);
01248 va_end (args);
01249
01250 return retval;
01251 }
01252
01261 dbus_bool_t
01262 _dbus_string_append_len (DBusString *str,
01263 const char *buffer,
01264 int len)
01265 {
01266 DBUS_STRING_PREAMBLE (str);
01267 _dbus_assert (buffer != NULL);
01268 _dbus_assert (len >= 0);
01269
01270 return append (real, buffer, len);
01271 }
01272
01281 dbus_bool_t
01282 _dbus_string_append_byte (DBusString *str,
01283 unsigned char byte)
01284 {
01285 DBUS_STRING_PREAMBLE (str);
01286
01287 if (!set_length (real, real->len + 1))
01288 return FALSE;
01289
01290 real->str[real->len-1] = byte;
01291
01292 return TRUE;
01293 }
01294
01302 dbus_bool_t
01303 _dbus_string_append_unichar (DBusString *str,
01304 dbus_unichar_t ch)
01305 {
01306 int len;
01307 int first;
01308 int i;
01309 char *out;
01310
01311 DBUS_STRING_PREAMBLE (str);
01312
01313
01314
01315 len = 0;
01316
01317 if (ch < 0x80)
01318 {
01319 first = 0;
01320 len = 1;
01321 }
01322 else if (ch < 0x800)
01323 {
01324 first = 0xc0;
01325 len = 2;
01326 }
01327 else if (ch < 0x10000)
01328 {
01329 first = 0xe0;
01330 len = 3;
01331 }
01332 else if (ch < 0x200000)
01333 {
01334 first = 0xf0;
01335 len = 4;
01336 }
01337 else if (ch < 0x4000000)
01338 {
01339 first = 0xf8;
01340 len = 5;
01341 }
01342 else
01343 {
01344 first = 0xfc;
01345 len = 6;
01346 }
01347
01348 if (len > (real->max_length - real->len))
01349 return FALSE;
01350
01351 if (!set_length (real, real->len + len))
01352 return FALSE;
01353
01354 out = real->str + (real->len - len);
01355
01356 for (i = len - 1; i > 0; --i)
01357 {
01358 out[i] = (ch & 0x3f) | 0x80;
01359 ch >>= 6;
01360 }
01361 out[0] = ch | first;
01362
01363 return TRUE;
01364 }
01365
01366 static void
01367 delete (DBusRealString *real,
01368 int start,
01369 int len)
01370 {
01371 if (len == 0)
01372 return;
01373
01374 memmove (real->str + start, real->str + start + len, real->len - (start + len));
01375 real->len -= len;
01376 real->str[real->len] = '\0';
01377 }
01378
01388 void
01389 _dbus_string_delete (DBusString *str,
01390 int start,
01391 int len)
01392 {
01393 DBUS_STRING_PREAMBLE (str);
01394 _dbus_assert (start >= 0);
01395 _dbus_assert (len >= 0);
01396 _dbus_assert (start <= real->len);
01397 _dbus_assert (len <= real->len - start);
01398
01399 delete (real, start, len);
01400 }
01401
01402 static dbus_bool_t
01403 copy (DBusRealString *source,
01404 int start,
01405 int len,
01406 DBusRealString *dest,
01407 int insert_at)
01408 {
01409 if (len == 0)
01410 return TRUE;
01411
01412 if (!open_gap (len, dest, insert_at))
01413 return FALSE;
01414
01415 memcpy (dest->str + insert_at,
01416 source->str + start,
01417 len);
01418
01419 return TRUE;
01420 }
01421
01431 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
01432 DBusRealString *real_source = (DBusRealString*) source; \
01433 DBusRealString *real_dest = (DBusRealString*) dest; \
01434 _dbus_assert ((source) != (dest)); \
01435 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
01436 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
01437 _dbus_assert (!real_dest->constant); \
01438 _dbus_assert (!real_dest->locked); \
01439 _dbus_assert ((start) >= 0); \
01440 _dbus_assert ((start) <= real_source->len); \
01441 _dbus_assert ((insert_at) >= 0); \
01442 _dbus_assert ((insert_at) <= real_dest->len)
01443
01454 dbus_bool_t
01455 _dbus_string_move (DBusString *source,
01456 int start,
01457 DBusString *dest,
01458 int insert_at)
01459 {
01460 DBusRealString *real_source = (DBusRealString*) source;
01461 _dbus_assert (start <= real_source->len);
01462
01463 return _dbus_string_move_len (source, start,
01464 real_source->len - start,
01465 dest, insert_at);
01466 }
01467
01478 dbus_bool_t
01479 _dbus_string_copy (const DBusString *source,
01480 int start,
01481 DBusString *dest,
01482 int insert_at)
01483 {
01484 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01485
01486 return copy (real_source, start,
01487 real_source->len - start,
01488 real_dest,
01489 insert_at);
01490 }
01491
01506 dbus_bool_t
01507 _dbus_string_move_len (DBusString *source,
01508 int start,
01509 int len,
01510 DBusString *dest,
01511 int insert_at)
01512
01513 {
01514 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01515 _dbus_assert (len >= 0);
01516 _dbus_assert ((start + len) <= real_source->len);
01517
01518
01519 if (len == 0)
01520 {
01521 return TRUE;
01522 }
01523 else if (start == 0 &&
01524 len == real_source->len &&
01525 real_dest->len == 0)
01526 {
01527
01528
01529
01530
01531
01532
01533 #define ASSIGN_DATA(a, b) do { \
01534 (a)->str = (b)->str; \
01535 (a)->len = (b)->len; \
01536 (a)->allocated = (b)->allocated; \
01537 (a)->align_offset = (b)->align_offset; \
01538 } while (0)
01539
01540 DBusRealString tmp;
01541
01542 ASSIGN_DATA (&tmp, real_source);
01543 ASSIGN_DATA (real_source, real_dest);
01544 ASSIGN_DATA (real_dest, &tmp);
01545
01546 return TRUE;
01547 }
01548 else
01549 {
01550 if (!copy (real_source, start, len,
01551 real_dest,
01552 insert_at))
01553 return FALSE;
01554
01555 delete (real_source, start,
01556 len);
01557
01558 return TRUE;
01559 }
01560 }
01561
01573 dbus_bool_t
01574 _dbus_string_copy_len (const DBusString *source,
01575 int start,
01576 int len,
01577 DBusString *dest,
01578 int insert_at)
01579 {
01580 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01581 _dbus_assert (len >= 0);
01582 _dbus_assert (start <= real_source->len);
01583 _dbus_assert (len <= real_source->len - start);
01584
01585 return copy (real_source, start, len,
01586 real_dest,
01587 insert_at);
01588 }
01589
01611 dbus_bool_t
01612 _dbus_string_replace_len (const DBusString *source,
01613 int start,
01614 int len,
01615 DBusString *dest,
01616 int replace_at,
01617 int replace_len)
01618 {
01619 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
01620 _dbus_assert (len >= 0);
01621 _dbus_assert (start <= real_source->len);
01622 _dbus_assert (len <= real_source->len - start);
01623 _dbus_assert (replace_at >= 0);
01624 _dbus_assert (replace_at <= real_dest->len);
01625 _dbus_assert (replace_len <= real_dest->len - replace_at);
01626
01627 if (!copy (real_source, start, len,
01628 real_dest, replace_at))
01629 return FALSE;
01630
01631 delete (real_dest, replace_at + len, replace_len);
01632
01633 return TRUE;
01634 }
01635
01636
01637
01638
01639
01645 #define UTF8_COMPUTE(Char, Mask, Len) \
01646 if (Char < 128) \
01647 { \
01648 Len = 1; \
01649 Mask = 0x7f; \
01650 } \
01651 else if ((Char & 0xe0) == 0xc0) \
01652 { \
01653 Len = 2; \
01654 Mask = 0x1f; \
01655 } \
01656 else if ((Char & 0xf0) == 0xe0) \
01657 { \
01658 Len = 3; \
01659 Mask = 0x0f; \
01660 } \
01661 else if ((Char & 0xf8) == 0xf0) \
01662 { \
01663 Len = 4; \
01664 Mask = 0x07; \
01665 } \
01666 else if ((Char & 0xfc) == 0xf8) \
01667 { \
01668 Len = 5; \
01669 Mask = 0x03; \
01670 } \
01671 else if ((Char & 0xfe) == 0xfc) \
01672 { \
01673 Len = 6; \
01674 Mask = 0x01; \
01675 } \
01676 else \
01677 { \
01678 Len = 0; \
01679 Mask = 0; \
01680 }
01681
01686 #define UTF8_LENGTH(Char) \
01687 ((Char) < 0x80 ? 1 : \
01688 ((Char) < 0x800 ? 2 : \
01689 ((Char) < 0x10000 ? 3 : \
01690 ((Char) < 0x200000 ? 4 : \
01691 ((Char) < 0x4000000 ? 5 : 6)))))
01692
01702 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
01703 (Result) = (Chars)[0] & (Mask); \
01704 for ((Count) = 1; (Count) < (Len); ++(Count)) \
01705 { \
01706 if (((Chars)[(Count)] & 0xc0) != 0x80) \
01707 { \
01708 (Result) = -1; \
01709 break; \
01710 } \
01711 (Result) <<= 6; \
01712 (Result) |= ((Chars)[(Count)] & 0x3f); \
01713 }
01714
01720 #define UNICODE_VALID(Char) \
01721 ((Char) < 0x110000 && \
01722 (((Char) & 0xFFFFF800) != 0xD800) && \
01723 ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
01724 ((Char) & 0xFFFF) != 0xFFFF)
01725
01736 void
01737 _dbus_string_get_unichar (const DBusString *str,
01738 int start,
01739 dbus_unichar_t *ch_return,
01740 int *end_return)
01741 {
01742 int i, mask, len;
01743 dbus_unichar_t result;
01744 unsigned char c;
01745 unsigned char *p;
01746 DBUS_CONST_STRING_PREAMBLE (str);
01747 _dbus_assert (start >= 0);
01748 _dbus_assert (start <= real->len);
01749
01750 if (ch_return)
01751 *ch_return = 0;
01752 if (end_return)
01753 *end_return = real->len;
01754
01755 mask = 0;
01756 p = real->str + start;
01757 c = *p;
01758
01759 UTF8_COMPUTE (c, mask, len);
01760 if (len == 0)
01761 return;
01762 UTF8_GET (result, p, i, mask, len);
01763
01764 if (result == (dbus_unichar_t)-1)
01765 return;
01766
01767 if (ch_return)
01768 *ch_return = result;
01769 if (end_return)
01770 *end_return = start + len;
01771 }
01772
01787 dbus_bool_t
01788 _dbus_string_find (const DBusString *str,
01789 int start,
01790 const char *substr,
01791 int *found)
01792 {
01793 return _dbus_string_find_to (str, start,
01794 ((const DBusRealString*)str)->len,
01795 substr, found);
01796 }
01797
01814 dbus_bool_t
01815 _dbus_string_find_to (const DBusString *str,
01816 int start,
01817 int end,
01818 const char *substr,
01819 int *found)
01820 {
01821 int i;
01822 DBUS_CONST_STRING_PREAMBLE (str);
01823 _dbus_assert (substr != NULL);
01824 _dbus_assert (start <= real->len);
01825 _dbus_assert (start >= 0);
01826 _dbus_assert (substr != NULL);
01827 _dbus_assert (end <= real->len);
01828 _dbus_assert (start <= end);
01829
01830
01831 if (*substr == '\0')
01832 {
01833 if (found)
01834 *found = start;
01835 return TRUE;
01836 }
01837
01838 i = start;
01839 while (i < end)
01840 {
01841 if (real->str[i] == substr[0])
01842 {
01843 int j = i + 1;
01844
01845 while (j < end)
01846 {
01847 if (substr[j - i] == '\0')
01848 break;
01849 else if (real->str[j] != substr[j - i])
01850 break;
01851
01852 ++j;
01853 }
01854
01855 if (substr[j - i] == '\0')
01856 {
01857 if (found)
01858 *found = i;
01859 return TRUE;
01860 }
01861 }
01862
01863 ++i;
01864 }
01865
01866 if (found)
01867 *found = end;
01868
01869 return FALSE;
01870 }
01871
01882 dbus_bool_t
01883 _dbus_string_find_byte_backward (const DBusString *str,
01884 int start,
01885 unsigned char byte,
01886 int *found)
01887 {
01888 int i;
01889 DBUS_CONST_STRING_PREAMBLE (str);
01890 _dbus_assert (start <= real->len);
01891 _dbus_assert (start >= 0);
01892 _dbus_assert (found != NULL);
01893
01894 i = start - 1;
01895 while (i >= 0)
01896 {
01897 if (real->str[i] == byte)
01898 break;
01899
01900 --i;
01901 }
01902
01903 if (found)
01904 *found = i;
01905
01906 return i >= 0;
01907 }
01908
01919 dbus_bool_t
01920 _dbus_string_find_blank (const DBusString *str,
01921 int start,
01922 int *found)
01923 {
01924 int i;
01925 DBUS_CONST_STRING_PREAMBLE (str);
01926 _dbus_assert (start <= real->len);
01927 _dbus_assert (start >= 0);
01928
01929 i = start;
01930 while (i < real->len)
01931 {
01932 if (real->str[i] == ' ' ||
01933 real->str[i] == '\t')
01934 {
01935 if (found)
01936 *found = i;
01937 return TRUE;
01938 }
01939
01940 ++i;
01941 }
01942
01943 if (found)
01944 *found = real->len;
01945
01946 return FALSE;
01947 }
01948
01957 void
01958 _dbus_string_skip_blank (const DBusString *str,
01959 int start,
01960 int *end)
01961 {
01962 int i;
01963 DBUS_CONST_STRING_PREAMBLE (str);
01964 _dbus_assert (start <= real->len);
01965 _dbus_assert (start >= 0);
01966
01967 i = start;
01968 while (i < real->len)
01969 {
01970 if (!(real->str[i] == ' ' ||
01971 real->str[i] == '\t'))
01972 break;
01973
01974 ++i;
01975 }
01976
01977 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
01978 real->str[i] == '\t'));
01979
01980 if (end)
01981 *end = i;
01982 }
01983
01992 void
01993 _dbus_string_skip_white (const DBusString *str,
01994 int start,
01995 int *end)
01996 {
01997 int i;
01998 DBUS_CONST_STRING_PREAMBLE (str);
01999 _dbus_assert (start <= real->len);
02000 _dbus_assert (start >= 0);
02001
02002 i = start;
02003 while (i < real->len)
02004 {
02005 if (!(real->str[i] == ' ' ||
02006 real->str[i] == '\n' ||
02007 real->str[i] == '\r' ||
02008 real->str[i] == '\t'))
02009 break;
02010
02011 ++i;
02012 }
02013
02014 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
02015 real->str[i] == '\t'));
02016
02017 if (end)
02018 *end = i;
02019 }
02020
02036 dbus_bool_t
02037 _dbus_string_pop_line (DBusString *source,
02038 DBusString *dest)
02039 {
02040 int eol;
02041 dbus_bool_t have_newline;
02042
02043 _dbus_string_set_length (dest, 0);
02044
02045 eol = 0;
02046 if (_dbus_string_find (source, 0, "\n", &eol))
02047 {
02048 have_newline = TRUE;
02049 eol += 1;
02050 }
02051 else
02052 {
02053 eol = _dbus_string_get_length (source);
02054 have_newline = FALSE;
02055 }
02056
02057 if (eol == 0)
02058 return FALSE;
02059
02060 if (!_dbus_string_move_len (source, 0, eol,
02061 dest, 0))
02062 {
02063 return FALSE;
02064 }
02065
02066
02067 if (have_newline)
02068 {
02069 dbus_bool_t have_cr;
02070
02071 _dbus_assert (_dbus_string_get_length (dest) > 0);
02072
02073 if (_dbus_string_get_length (dest) > 1 &&
02074 _dbus_string_get_byte (dest,
02075 _dbus_string_get_length (dest) - 2) == '\r')
02076 have_cr = TRUE;
02077 else
02078 have_cr = FALSE;
02079
02080 _dbus_string_set_length (dest,
02081 _dbus_string_get_length (dest) -
02082 (have_cr ? 2 : 1));
02083 }
02084
02085 return TRUE;
02086 }
02087
02094 void
02095 _dbus_string_delete_first_word (DBusString *str)
02096 {
02097 int i;
02098
02099 if (_dbus_string_find_blank (str, 0, &i))
02100 _dbus_string_skip_blank (str, i, &i);
02101
02102 _dbus_string_delete (str, 0, i);
02103 }
02104
02110 void
02111 _dbus_string_delete_leading_blanks (DBusString *str)
02112 {
02113 int i;
02114
02115 _dbus_string_skip_blank (str, 0, &i);
02116
02117 if (i > 0)
02118 _dbus_string_delete (str, 0, i);
02119 }
02120
02130 dbus_bool_t
02131 _dbus_string_equal (const DBusString *a,
02132 const DBusString *b)
02133 {
02134 const unsigned char *ap;
02135 const unsigned char *bp;
02136 const unsigned char *a_end;
02137 const DBusRealString *real_a = (const DBusRealString*) a;
02138 const DBusRealString *real_b = (const DBusRealString*) b;
02139 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02140 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02141
02142 if (real_a->len != real_b->len)
02143 return FALSE;
02144
02145 ap = real_a->str;
02146 bp = real_b->str;
02147 a_end = real_a->str + real_a->len;
02148 while (ap != a_end)
02149 {
02150 if (*ap != *bp)
02151 return FALSE;
02152
02153 ++ap;
02154 ++bp;
02155 }
02156
02157 return TRUE;
02158 }
02159
02173 dbus_bool_t
02174 _dbus_string_equal_len (const DBusString *a,
02175 const DBusString *b,
02176 int len)
02177 {
02178 const unsigned char *ap;
02179 const unsigned char *bp;
02180 const unsigned char *a_end;
02181 const DBusRealString *real_a = (const DBusRealString*) a;
02182 const DBusRealString *real_b = (const DBusRealString*) b;
02183 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02184 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02185
02186 if (real_a->len != real_b->len &&
02187 (real_a->len < len || real_b->len < len))
02188 return FALSE;
02189
02190 ap = real_a->str;
02191 bp = real_b->str;
02192 a_end = real_a->str + MIN (real_a->len, len);
02193 while (ap != a_end)
02194 {
02195 if (*ap != *bp)
02196 return FALSE;
02197
02198 ++ap;
02199 ++bp;
02200 }
02201
02202 return TRUE;
02203 }
02204
02221 dbus_bool_t
02222 _dbus_string_equal_substring (const DBusString *a,
02223 int a_start,
02224 int a_len,
02225 const DBusString *b,
02226 int b_start)
02227 {
02228 const unsigned char *ap;
02229 const unsigned char *bp;
02230 const unsigned char *a_end;
02231 const DBusRealString *real_a = (const DBusRealString*) a;
02232 const DBusRealString *real_b = (const DBusRealString*) b;
02233 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02234 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02235 _dbus_assert (a_start >= 0);
02236 _dbus_assert (a_len >= 0);
02237 _dbus_assert (a_start <= real_a->len);
02238 _dbus_assert (a_len <= real_a->len - a_start);
02239 _dbus_assert (b_start >= 0);
02240 _dbus_assert (b_start <= real_b->len);
02241
02242 if (a_len > real_b->len - b_start)
02243 return FALSE;
02244
02245 ap = real_a->str + a_start;
02246 bp = real_b->str + b_start;
02247 a_end = ap + a_len;
02248 while (ap != a_end)
02249 {
02250 if (*ap != *bp)
02251 return FALSE;
02252
02253 ++ap;
02254 ++bp;
02255 }
02256
02257 _dbus_assert (bp <= (real_b->str + real_b->len));
02258
02259 return TRUE;
02260 }
02261
02269 dbus_bool_t
02270 _dbus_string_equal_c_str (const DBusString *a,
02271 const char *c_str)
02272 {
02273 const unsigned char *ap;
02274 const unsigned char *bp;
02275 const unsigned char *a_end;
02276 const DBusRealString *real_a = (const DBusRealString*) a;
02277 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02278 _dbus_assert (c_str != NULL);
02279
02280 ap = real_a->str;
02281 bp = (const unsigned char*) c_str;
02282 a_end = real_a->str + real_a->len;
02283 while (ap != a_end && *bp)
02284 {
02285 if (*ap != *bp)
02286 return FALSE;
02287
02288 ++ap;
02289 ++bp;
02290 }
02291
02292 if (ap != a_end || *bp)
02293 return FALSE;
02294
02295 return TRUE;
02296 }
02297
02305 dbus_bool_t
02306 _dbus_string_starts_with_c_str (const DBusString *a,
02307 const char *c_str)
02308 {
02309 const unsigned char *ap;
02310 const unsigned char *bp;
02311 const unsigned char *a_end;
02312 const DBusRealString *real_a = (const DBusRealString*) a;
02313 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02314 _dbus_assert (c_str != NULL);
02315
02316 ap = real_a->str;
02317 bp = (const unsigned char*) c_str;
02318 a_end = real_a->str + real_a->len;
02319 while (ap != a_end && *bp)
02320 {
02321 if (*ap != *bp)
02322 return FALSE;
02323
02324 ++ap;
02325 ++bp;
02326 }
02327
02328 if (*bp == '\0')
02329 return TRUE;
02330 else
02331 return FALSE;
02332 }
02333
02343 dbus_bool_t
02344 _dbus_string_ends_with_c_str (const DBusString *a,
02345 const char *c_str)
02346 {
02347 const unsigned char *ap;
02348 const unsigned char *bp;
02349 const unsigned char *a_end;
02350 unsigned long c_str_len;
02351 const DBusRealString *real_a = (const DBusRealString*) a;
02352 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02353 _dbus_assert (c_str != NULL);
02354
02355 c_str_len = strlen (c_str);
02356 if (((unsigned long)real_a->len) < c_str_len)
02357 return FALSE;
02358
02359 ap = real_a->str + (real_a->len - c_str_len);
02360 bp = (const unsigned char*) c_str;
02361 a_end = real_a->str + real_a->len;
02362 while (ap != a_end)
02363 {
02364 if (*ap != *bp)
02365 return FALSE;
02366
02367 ++ap;
02368 ++bp;
02369 }
02370
02371 _dbus_assert (*ap == '\0');
02372 _dbus_assert (*bp == '\0');
02373
02374 return TRUE;
02375 }
02376
02387 dbus_bool_t
02388 _dbus_string_hex_encode (const DBusString *source,
02389 int start,
02390 DBusString *dest,
02391 int insert_at)
02392 {
02393 DBusString result;
02394 const char hexdigits[16] = {
02395 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
02396 'a', 'b', 'c', 'd', 'e', 'f'
02397 };
02398 const unsigned char *p;
02399 const unsigned char *end;
02400 dbus_bool_t retval;
02401
02402 _dbus_assert (start <= _dbus_string_get_length (source));
02403
02404 if (!_dbus_string_init (&result))
02405 return FALSE;
02406
02407 retval = FALSE;
02408
02409 p = (const unsigned char*) _dbus_string_get_const_data (source);
02410 end = p + _dbus_string_get_length (source);
02411 p += start;
02412
02413 while (p != end)
02414 {
02415 if (!_dbus_string_append_byte (&result,
02416 hexdigits[(*p >> 4)]))
02417 goto out;
02418
02419 if (!_dbus_string_append_byte (&result,
02420 hexdigits[(*p & 0x0f)]))
02421 goto out;
02422
02423 ++p;
02424 }
02425
02426 if (!_dbus_string_move (&result, 0, dest, insert_at))
02427 goto out;
02428
02429 retval = TRUE;
02430
02431 out:
02432 _dbus_string_free (&result);
02433 return retval;
02434 }
02435
02446 dbus_bool_t
02447 _dbus_string_hex_decode (const DBusString *source,
02448 int start,
02449 int *end_return,
02450 DBusString *dest,
02451 int insert_at)
02452 {
02453 DBusString result;
02454 const unsigned char *p;
02455 const unsigned char *end;
02456 dbus_bool_t retval;
02457 dbus_bool_t high_bits;
02458
02459 _dbus_assert (start <= _dbus_string_get_length (source));
02460
02461 if (!_dbus_string_init (&result))
02462 return FALSE;
02463
02464 retval = FALSE;
02465
02466 high_bits = TRUE;
02467 p = (const unsigned char*) _dbus_string_get_const_data (source);
02468 end = p + _dbus_string_get_length (source);
02469 p += start;
02470
02471 while (p != end)
02472 {
02473 unsigned int val;
02474
02475 switch (*p)
02476 {
02477 case '0':
02478 val = 0;
02479 break;
02480 case '1':
02481 val = 1;
02482 break;
02483 case '2':
02484 val = 2;
02485 break;
02486 case '3':
02487 val = 3;
02488 break;
02489 case '4':
02490 val = 4;
02491 break;
02492 case '5':
02493 val = 5;
02494 break;
02495 case '6':
02496 val = 6;
02497 break;
02498 case '7':
02499 val = 7;
02500 break;
02501 case '8':
02502 val = 8;
02503 break;
02504 case '9':
02505 val = 9;
02506 break;
02507 case 'a':
02508 case 'A':
02509 val = 10;
02510 break;
02511 case 'b':
02512 case 'B':
02513 val = 11;
02514 break;
02515 case 'c':
02516 case 'C':
02517 val = 12;
02518 break;
02519 case 'd':
02520 case 'D':
02521 val = 13;
02522 break;
02523 case 'e':
02524 case 'E':
02525 val = 14;
02526 break;
02527 case 'f':
02528 case 'F':
02529 val = 15;
02530 break;
02531 default:
02532 goto done;
02533 }
02534
02535 if (high_bits)
02536 {
02537 if (!_dbus_string_append_byte (&result,
02538 val << 4))
02539 goto out;
02540 }
02541 else
02542 {
02543 int len;
02544 unsigned char b;
02545
02546 len = _dbus_string_get_length (&result);
02547
02548 b = _dbus_string_get_byte (&result, len - 1);
02549
02550 b |= val;
02551
02552 _dbus_string_set_byte (&result, len - 1, b);
02553 }
02554
02555 high_bits = !high_bits;
02556
02557 ++p;
02558 }
02559
02560 done:
02561 if (!_dbus_string_move (&result, 0, dest, insert_at))
02562 goto out;
02563
02564 if (end_return)
02565 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
02566
02567 retval = TRUE;
02568
02569 out:
02570 _dbus_string_free (&result);
02571 return retval;
02572 }
02573
02587 dbus_bool_t
02588 _dbus_string_validate_ascii (const DBusString *str,
02589 int start,
02590 int len)
02591 {
02592 const unsigned char *s;
02593 const unsigned char *end;
02594 DBUS_CONST_STRING_PREAMBLE (str);
02595 _dbus_assert (start >= 0);
02596 _dbus_assert (start <= real->len);
02597 _dbus_assert (len >= 0);
02598
02599 if (len > real->len - start)
02600 return FALSE;
02601
02602 s = real->str + start;
02603 end = s + len;
02604 while (s != end)
02605 {
02606 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
02607 return FALSE;
02608
02609 ++s;
02610 }
02611
02612 return TRUE;
02613 }
02614
02630 dbus_bool_t
02631 _dbus_string_validate_utf8 (const DBusString *str,
02632 int start,
02633 int len)
02634 {
02635 const unsigned char *p;
02636 const unsigned char *end;
02637 DBUS_CONST_STRING_PREAMBLE (str);
02638 _dbus_assert (start >= 0);
02639 _dbus_assert (start <= real->len);
02640 _dbus_assert (len >= 0);
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650 if (_DBUS_UNLIKELY (len > real->len - start))
02651 return FALSE;
02652
02653 p = real->str + start;
02654 end = p + len;
02655
02656 while (p < end)
02657 {
02658 int i, mask, char_len;
02659 dbus_unichar_t result;
02660
02661
02662 if (*p == '\0')
02663 break;
02664
02665
02666
02667
02668
02669
02670
02671 if (*p < 128)
02672 {
02673 ++p;
02674 continue;
02675 }
02676
02677 UTF8_COMPUTE (*p, mask, char_len);
02678
02679 if (_DBUS_UNLIKELY (char_len == 0))
02680 break;
02681
02682
02683 if (_DBUS_UNLIKELY ((end - p) < char_len))
02684 break;
02685
02686 UTF8_GET (result, p, i, mask, char_len);
02687
02688
02689 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len))
02690 break;
02691 #if 0
02692
02693 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1))
02694 break;
02695 #endif
02696
02697 if (_DBUS_UNLIKELY (!UNICODE_VALID (result)))
02698 break;
02699
02700
02701 _dbus_assert (result != (dbus_unichar_t)-1);
02702
02703 p += char_len;
02704 }
02705
02706
02707
02708
02709 if (_DBUS_UNLIKELY (p != end))
02710 return FALSE;
02711 else
02712 return TRUE;
02713 }
02714
02728 dbus_bool_t
02729 _dbus_string_validate_nul (const DBusString *str,
02730 int start,
02731 int len)
02732 {
02733 const unsigned char *s;
02734 const unsigned char *end;
02735 DBUS_CONST_STRING_PREAMBLE (str);
02736 _dbus_assert (start >= 0);
02737 _dbus_assert (len >= 0);
02738 _dbus_assert (start <= real->len);
02739
02740 if (len > real->len - start)
02741 return FALSE;
02742
02743 s = real->str + start;
02744 end = s + len;
02745 while (s != end)
02746 {
02747 if (_DBUS_UNLIKELY (*s != '\0'))
02748 return FALSE;
02749 ++s;
02750 }
02751
02752 return TRUE;
02753 }
02754
02772 dbus_bool_t
02773 _dbus_string_validate_path (const DBusString *str,
02774 int start,
02775 int len)
02776 {
02777 const unsigned char *s;
02778 const unsigned char *end;
02779 const unsigned char *last_slash;
02780
02781 DBUS_CONST_STRING_PREAMBLE (str);
02782 _dbus_assert (start >= 0);
02783 _dbus_assert (len >= 0);
02784 _dbus_assert (start <= real->len);
02785
02786 if (len > real->len - start)
02787 return FALSE;
02788
02789 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02790 return FALSE;
02791
02792 if (len == 0)
02793 return FALSE;
02794
02795 s = real->str + start;
02796 end = s + len;
02797
02798 if (*s != '/')
02799 return FALSE;
02800 last_slash = s;
02801 ++s;
02802
02803 while (s != end)
02804 {
02805 if (*s == '/')
02806 {
02807 if ((s - last_slash) < 2)
02808 return FALSE;
02809
02810 last_slash = s;
02811 }
02812
02813 ++s;
02814 }
02815
02816 if ((end - last_slash) < 2 &&
02817 len > 1)
02818 return FALSE;
02819
02820 return TRUE;
02821 }
02822
02827 #define VALID_INITIAL_NAME_CHARACTER(c) \
02828 ( ((c) >= 'A' && (c) <= 'Z') || \
02829 ((c) >= 'a' && (c) <= 'z') || \
02830 ((c) == '_') )
02831
02836 #define VALID_NAME_CHARACTER(c) \
02837 ( ((c) >= '0' && (c) <= '9') || \
02838 ((c) >= 'A' && (c) <= 'Z') || \
02839 ((c) >= 'a' && (c) <= 'z') || \
02840 ((c) == '_') )
02841
02855 dbus_bool_t
02856 _dbus_string_validate_interface (const DBusString *str,
02857 int start,
02858 int len)
02859 {
02860 const unsigned char *s;
02861 const unsigned char *end;
02862 const unsigned char *iface;
02863 const unsigned char *last_dot;
02864
02865 DBUS_CONST_STRING_PREAMBLE (str);
02866 _dbus_assert (start >= 0);
02867 _dbus_assert (len >= 0);
02868 _dbus_assert (start <= real->len);
02869
02870 if (len > real->len - start)
02871 return FALSE;
02872
02873 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02874 return FALSE;
02875
02876 if (len == 0)
02877 return FALSE;
02878
02879 last_dot = NULL;
02880 iface = real->str + start;
02881 end = iface + len;
02882 s = iface;
02883
02884
02885
02886
02887 if (_DBUS_UNLIKELY (*s == '.'))
02888 return FALSE;
02889 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
02890 return FALSE;
02891 else
02892 ++s;
02893
02894 while (s != end)
02895 {
02896 if (*s == '.')
02897 {
02898 if (_DBUS_UNLIKELY ((s + 1) == end))
02899 return FALSE;
02900 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
02901 return FALSE;
02902 last_dot = s;
02903 ++s;
02904 }
02905 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
02906 {
02907 return FALSE;
02908 }
02909
02910 ++s;
02911 }
02912
02913 if (_DBUS_UNLIKELY (last_dot == NULL))
02914 return FALSE;
02915
02916 return TRUE;
02917 }
02918
02932 dbus_bool_t
02933 _dbus_string_validate_member (const DBusString *str,
02934 int start,
02935 int len)
02936 {
02937 const unsigned char *s;
02938 const unsigned char *end;
02939 const unsigned char *member;
02940
02941 DBUS_CONST_STRING_PREAMBLE (str);
02942 _dbus_assert (start >= 0);
02943 _dbus_assert (len >= 0);
02944 _dbus_assert (start <= real->len);
02945
02946 if (len > real->len - start)
02947 return FALSE;
02948
02949 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02950 return FALSE;
02951
02952 if (len == 0)
02953 return FALSE;
02954
02955 member = real->str + start;
02956 end = member + len;
02957 s = member;
02958
02959
02960
02961
02962
02963 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
02964 return FALSE;
02965 else
02966 ++s;
02967
02968 while (s != end)
02969 {
02970 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
02971 {
02972 return FALSE;
02973 }
02974
02975 ++s;
02976 }
02977
02978 return TRUE;
02979 }
02980
02994 dbus_bool_t
02995 _dbus_string_validate_error_name (const DBusString *str,
02996 int start,
02997 int len)
02998 {
02999
03000 return _dbus_string_validate_interface (str, start, len);
03001 }
03002
03003
03004 static dbus_bool_t
03005 _dbus_string_validate_base_service (const DBusString *str,
03006 int start,
03007 int len)
03008 {
03009 const unsigned char *s;
03010 const unsigned char *end;
03011 const unsigned char *service;
03012
03013 DBUS_CONST_STRING_PREAMBLE (str);
03014 _dbus_assert (start >= 0);
03015 _dbus_assert (len >= 0);
03016 _dbus_assert (start <= real->len);
03017
03018 if (len > real->len - start)
03019 return FALSE;
03020
03021 if (len > DBUS_MAXIMUM_NAME_LENGTH)
03022 return FALSE;
03023
03024 _dbus_assert (len > 0);
03025
03026 service = real->str + start;
03027 end = service + len;
03028 _dbus_assert (*service == ':');
03029 s = service + 1;
03030
03031 while (s != end)
03032 {
03033 if (*s == '.')
03034 {
03035 if (_DBUS_UNLIKELY ((s + 1) == end))
03036 return FALSE;
03037 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*(s + 1))))
03038 return FALSE;
03039 ++s;
03040 }
03041 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
03042 {
03043 return FALSE;
03044 }
03045
03046 ++s;
03047 }
03048
03049 return TRUE;
03050 }
03051
03065 dbus_bool_t
03066 _dbus_string_validate_service (const DBusString *str,
03067 int start,
03068 int len)
03069 {
03070 if (_DBUS_UNLIKELY (len == 0))
03071 return FALSE;
03072 if (_dbus_string_get_byte (str, start) == ':')
03073 return _dbus_string_validate_base_service (str, start, len);
03074 else
03075 return _dbus_string_validate_interface (str, start, len);
03076 }
03077
03090 dbus_bool_t
03091 _dbus_string_validate_signature (const DBusString *str,
03092 int start,
03093 int len)
03094 {
03095 const unsigned char *s;
03096 const unsigned char *end;
03097 DBUS_CONST_STRING_PREAMBLE (str);
03098 _dbus_assert (start >= 0);
03099 _dbus_assert (start <= real->len);
03100 _dbus_assert (len >= 0);
03101
03102 if (len > real->len - start)
03103 return FALSE;
03104
03105 s = real->str + start;
03106 end = s + len;
03107 while (s != end)
03108 {
03109 switch (*s)
03110 {
03111 case DBUS_TYPE_NIL:
03112 case DBUS_TYPE_BYTE:
03113 case DBUS_TYPE_BOOLEAN:
03114 case DBUS_TYPE_INT32:
03115 case DBUS_TYPE_UINT32:
03116 case DBUS_TYPE_INT64:
03117 case DBUS_TYPE_UINT64:
03118 case DBUS_TYPE_DOUBLE:
03119 case DBUS_TYPE_STRING:
03120 case DBUS_TYPE_CUSTOM:
03121 case DBUS_TYPE_ARRAY:
03122 case DBUS_TYPE_DICT:
03123 case DBUS_TYPE_OBJECT_PATH:
03124 break;
03125
03126 default:
03127 return FALSE;
03128 }
03129
03130 ++s;
03131 }
03132
03133 return TRUE;
03134 }
03135
03141 void
03142 _dbus_string_zero (DBusString *str)
03143 {
03144 DBUS_STRING_PREAMBLE (str);
03145
03146 memset (real->str - real->align_offset, '\0', real->allocated);
03147 }
03150 #ifdef DBUS_BUILD_TESTS
03151 #include "dbus-test.h"
03152 #include <stdio.h>
03153
03167 dbus_bool_t
03168 _dbus_string_parse_basic_type (const DBusString *str,
03169 char type,
03170 int start,
03171 void *value,
03172 int *end_return)
03173 {
03174 int end = start;
03175
03176 switch (type)
03177 {
03178 case DBUS_TYPE_BOOLEAN:
03179 {
03180 int len = _dbus_string_get_length (str) - start;
03181 if (len >= 5 && _dbus_string_find_to (str, start, start + 5, "false", NULL))
03182 {
03183 end += 5;
03184 *(unsigned char *) value = TRUE;
03185 }
03186 else if (len >= 4 && _dbus_string_find_to (str, start, start + 4, "true", NULL))
03187 {
03188 end += 4;
03189 *(unsigned char *) value = FALSE;
03190 }
03191 else
03192 _dbus_warn ("could not parse BOOLEAN\n");
03193 break;
03194 }
03195 case DBUS_TYPE_BYTE:
03196 {
03197 long val = 0;
03198
03199 if (_dbus_string_get_byte (str, start) == '\'' &&
03200 _dbus_string_get_length (str) >= start + 4 &&
03201 _dbus_string_get_byte (str, start + 1) == '\\' &&
03202 _dbus_string_get_byte (str, start + 2) == '\'' &&
03203 _dbus_string_get_byte (str, start + 3) == '\'')
03204 {
03205 val = '\'';
03206 end += 4;
03207 }
03208 else if (_dbus_string_get_byte (str, start) == '\'' &&
03209 _dbus_string_get_length (str) >= start + 3 &&
03210 _dbus_string_get_byte (str, start + 2) == '\'')
03211 {
03212 val = _dbus_string_get_byte (str, start + 1);
03213 end += 3;
03214 }
03215 else
03216 {
03217 if (!_dbus_string_parse_int (str, start, &val, &end))
03218 _dbus_warn ("Failed to parse integer for BYTE\n");
03219 }
03220
03221 if (val > 255)
03222 _dbus_warn ("A byte must be in range 0-255 not %ld\n", val);
03223
03224 *(unsigned char *) value = val;
03225 break;
03226 }
03227 case DBUS_TYPE_INT32:
03228 {
03229 long val;
03230 if (_dbus_string_parse_int (str, start, &val, &end))
03231 *(dbus_int32_t *)value = val;
03232 break;
03233 }
03234 case DBUS_TYPE_UINT32:
03235 {
03236 unsigned long val;
03237 if (_dbus_string_parse_uint (str, start, &val, &end))
03238 *(dbus_uint32_t *)value = val;
03239 break;
03240 }
03241 #ifdef DBUS_HAVE_INT64
03242 case DBUS_TYPE_INT64:
03243 case DBUS_TYPE_UINT64:
03244
03245 _dbus_assert_not_reached ("string -> [u]int64 not supported yet");
03246 break;
03247 #endif
03248 case DBUS_TYPE_DOUBLE:
03249 _dbus_string_parse_double (str, start, value, &end);
03250 break;
03251 default:
03252 _dbus_assert_not_reached ("not a basic type");
03253 break;
03254 }
03255 if (end_return)
03256 *end_return = end;
03257
03258 return end != start;
03259 }
03260
03261 static void
03262 test_max_len (DBusString *str,
03263 int max_len)
03264 {
03265 if (max_len > 0)
03266 {
03267 if (!_dbus_string_set_length (str, max_len - 1))
03268 _dbus_assert_not_reached ("setting len to one less than max should have worked");
03269 }
03270
03271 if (!_dbus_string_set_length (str, max_len))
03272 _dbus_assert_not_reached ("setting len to max len should have worked");
03273
03274 if (_dbus_string_set_length (str, max_len + 1))
03275 _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
03276
03277 if (!_dbus_string_set_length (str, 0))
03278 _dbus_assert_not_reached ("setting len to zero should have worked");
03279 }
03280
03281 static void
03282 test_hex_roundtrip (const unsigned char *data,
03283 int len)
03284 {
03285 DBusString orig;
03286 DBusString encoded;
03287 DBusString decoded;
03288 int end;
03289
03290 if (len < 0)
03291 len = strlen (data);
03292
03293 if (!_dbus_string_init (&orig))
03294 _dbus_assert_not_reached ("could not init string");
03295
03296 if (!_dbus_string_init (&encoded))
03297 _dbus_assert_not_reached ("could not init string");
03298
03299 if (!_dbus_string_init (&decoded))
03300 _dbus_assert_not_reached ("could not init string");
03301
03302 if (!_dbus_string_append_len (&orig, data, len))
03303 _dbus_assert_not_reached ("couldn't append orig data");
03304
03305 if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
03306 _dbus_assert_not_reached ("could not encode");
03307
03308 if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
03309 _dbus_assert_not_reached ("could not decode");
03310
03311 _dbus_assert (_dbus_string_get_length (&encoded) == end);
03312
03313 if (!_dbus_string_equal (&orig, &decoded))
03314 {
03315 const char *s;
03316
03317 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
03318 _dbus_string_get_length (&orig),
03319 _dbus_string_get_length (&encoded),
03320 _dbus_string_get_length (&decoded));
03321 printf ("Original: %s\n", data);
03322 s = _dbus_string_get_const_data (&decoded);
03323 printf ("Decoded: %s\n", s);
03324 _dbus_assert_not_reached ("original string not the same as string decoded from hex");
03325 }
03326
03327 _dbus_string_free (&orig);
03328 _dbus_string_free (&encoded);
03329 _dbus_string_free (&decoded);
03330 }
03331
03332 typedef void (* TestRoundtripFunc) (const unsigned char *data,
03333 int len);
03334 static void
03335 test_roundtrips (TestRoundtripFunc func)
03336 {
03337 (* func) ("Hello this is a string\n", -1);
03338 (* func) ("Hello this is a string\n1", -1);
03339 (* func) ("Hello this is a string\n12", -1);
03340 (* func) ("Hello this is a string\n123", -1);
03341 (* func) ("Hello this is a string\n1234", -1);
03342 (* func) ("Hello this is a string\n12345", -1);
03343 (* func) ("", 0);
03344 (* func) ("1", 1);
03345 (* func) ("12", 2);
03346 (* func) ("123", 3);
03347 (* func) ("1234", 4);
03348 (* func) ("12345", 5);
03349 (* func) ("", 1);
03350 (* func) ("1", 2);
03351 (* func) ("12", 3);
03352 (* func) ("123", 4);
03353 (* func) ("1234", 5);
03354 (* func) ("12345", 6);
03355 {
03356 unsigned char buf[512];
03357 int i;
03358
03359 i = 0;
03360 while (i < _DBUS_N_ELEMENTS (buf))
03361 {
03362 buf[i] = i;
03363 ++i;
03364 }
03365 i = 0;
03366 while (i < _DBUS_N_ELEMENTS (buf))
03367 {
03368 (* func) (buf, i);
03369 ++i;
03370 }
03371 }
03372 }
03373
03374
03385 dbus_bool_t
03386 _dbus_string_test (void)
03387 {
03388 DBusString str;
03389 DBusString other;
03390 int i, end;
03391 long v;
03392 double d;
03393 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 };
03394 char *s;
03395 dbus_unichar_t ch;
03396 const char *valid_paths[] = {
03397 "/",
03398 "/foo/bar",
03399 "/foo",
03400 "/foo/bar/baz"
03401 };
03402 const char *invalid_paths[] = {
03403 "bar",
03404 "bar/baz",
03405 "/foo/bar/",
03406 "/foo/"
03407 "foo/",
03408 "boo//blah",
03409 "//",
03410 "
03411 "foo
03412 "Hello World",
03413 "",
03414 " ",
03415 "foo bar"
03416 };
03417
03418 const char *valid_interfaces[] = {
03419 "org.freedesktop.Foo",
03420 "Bar.Baz",
03421 "Blah.Blah.Blah.Blah.Blah",
03422 "a.b",
03423 "a.b.c.d.e.f.g",
03424 "a0.b1.c2.d3.e4.f5.g6",
03425 "abc123.foo27"
03426 };
03427 const char *invalid_interfaces[] = {
03428 ".",
03429 "",
03430 "..",
03431 ".Foo.Bar",
03432 "..Foo.Bar",
03433 "Foo.Bar.",
03434 "Foo.Bar..",
03435 "Foo",
03436 "9foo.bar.baz",
03437 "foo.bar..baz",
03438 "foo.bar...baz",
03439 "foo.bar.b..blah",
03440 ":",
03441 ":0-1",
03442 "10",
03443 ":11.34324",
03444 "0.0.0",
03445 "0..0",
03446 "foo.Bar.%",
03447 "foo.Bar!!",
03448 "!Foo.bar.bz",
03449 "foo.$.blah",
03450 "",
03451 " ",
03452 "foo bar"
03453 };
03454
03455 const char *valid_base_services[] = {
03456 ":0",
03457 ":a",
03458 ":",
03459 ":.a",
03460 ":.1",
03461 ":0.1",
03462 ":000.2222",
03463 ":.blah",
03464 ":abce.freedesktop.blah"
03465 };
03466 const char *invalid_base_services[] = {
03467 ":-",
03468 ":!",
03469 ":0-10",
03470 ":blah.",
03471 ":blah.",
03472 ":blah..org",
03473 ":blah.org..",
03474 ":..blah.org",
03475 "",
03476 " ",
03477 "foo bar"
03478 };
03479
03480 const char *valid_members[] = {
03481 "Hello",
03482 "Bar",
03483 "foobar",
03484 "_foobar",
03485 "foo89"
03486 };
03487
03488 const char *invalid_members[] = {
03489 "9Hello",
03490 "10",
03491 "1",
03492 "foo-bar",
03493 "blah.org",
03494 ".blah",
03495 "blah.",
03496 "Hello.",
03497 "!foo",
03498 "",
03499 " ",
03500 "foo bar"
03501 };
03502
03503 const char *valid_signatures[] = {
03504 "",
03505 "sss",
03506 "i",
03507 "b"
03508 };
03509
03510 const char *invalid_signatures[] = {
03511 " ",
03512 "not a valid signature",
03513 "123",
03514 ".",
03515 "("
03516 };
03517
03518 i = 0;
03519 while (i < _DBUS_N_ELEMENTS (lens))
03520 {
03521 if (!_dbus_string_init (&str))
03522 _dbus_assert_not_reached ("failed to init string");
03523
03524 set_max_length (&str, lens[i]);
03525
03526 test_max_len (&str, lens[i]);
03527 _dbus_string_free (&str);
03528
03529 ++i;
03530 }
03531
03532
03533 i = 0;
03534 while (i < _DBUS_N_ELEMENTS (lens))
03535 {
03536 int j;
03537
03538 if (!_dbus_string_init (&str))
03539 _dbus_assert_not_reached ("failed to init string");
03540
03541 set_max_length (&str, lens[i]);
03542
03543 if (!_dbus_string_set_length (&str, lens[i]))
03544 _dbus_assert_not_reached ("failed to set string length");
03545
03546 j = lens[i];
03547 while (j > 0)
03548 {
03549 _dbus_assert (_dbus_string_get_length (&str) == j);
03550 if (j > 0)
03551 {
03552 _dbus_string_shorten (&str, 1);
03553 _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
03554 }
03555 --j;
03556 }
03557
03558 _dbus_string_free (&str);
03559
03560 ++i;
03561 }
03562
03563
03564 if (!_dbus_string_init (&str))
03565 _dbus_assert_not_reached ("failed to init string");
03566
03567 i = 0;
03568 while (i < 10)
03569 {
03570 if (!_dbus_string_append (&str, "a"))
03571 _dbus_assert_not_reached ("failed to append string to string\n");
03572
03573 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
03574
03575 if (!_dbus_string_append_byte (&str, 'b'))
03576 _dbus_assert_not_reached ("failed to append byte to string\n");
03577
03578 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
03579
03580 ++i;
03581 }
03582
03583 _dbus_string_free (&str);
03584
03585
03586
03587 if (!_dbus_string_init (&str))
03588 _dbus_assert_not_reached ("failed to init string");
03589
03590 if (!_dbus_string_append (&str, "Hello World"))
03591 _dbus_assert_not_reached ("could not append to string");
03592
03593 i = _dbus_string_get_length (&str);
03594
03595 if (!_dbus_string_steal_data (&str, &s))
03596 _dbus_assert_not_reached ("failed to steal data");
03597
03598 _dbus_assert (_dbus_string_get_length (&str) == 0);
03599 _dbus_assert (((int)strlen (s)) == i);
03600
03601 dbus_free (s);
03602
03603
03604
03605 if (!_dbus_string_append (&str, "Hello World"))
03606 _dbus_assert_not_reached ("could not append to string");
03607
03608 i = _dbus_string_get_length (&str);
03609
03610 if (!_dbus_string_init (&other))
03611 _dbus_assert_not_reached ("could not init string");
03612
03613 if (!_dbus_string_move (&str, 0, &other, 0))
03614 _dbus_assert_not_reached ("could not move");
03615
03616 _dbus_assert (_dbus_string_get_length (&str) == 0);
03617 _dbus_assert (_dbus_string_get_length (&other) == i);
03618
03619 if (!_dbus_string_append (&str, "Hello World"))
03620 _dbus_assert_not_reached ("could not append to string");
03621
03622 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
03623 _dbus_assert_not_reached ("could not move");
03624
03625 _dbus_assert (_dbus_string_get_length (&str) == 0);
03626 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03627
03628 if (!_dbus_string_append (&str, "Hello World"))
03629 _dbus_assert_not_reached ("could not append to string");
03630
03631 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03632 _dbus_assert_not_reached ("could not move");
03633
03634 _dbus_assert (_dbus_string_get_length (&str) == 0);
03635 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03636
03637 _dbus_string_free (&other);
03638
03639
03640
03641 if (!_dbus_string_append (&str, "Hello World"))
03642 _dbus_assert_not_reached ("could not append to string");
03643
03644 i = _dbus_string_get_length (&str);
03645
03646 if (!_dbus_string_init (&other))
03647 _dbus_assert_not_reached ("could not init string");
03648
03649 if (!_dbus_string_copy (&str, 0, &other, 0))
03650 _dbus_assert_not_reached ("could not copy");
03651
03652 _dbus_assert (_dbus_string_get_length (&str) == i);
03653 _dbus_assert (_dbus_string_get_length (&other) == i);
03654
03655 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
03656 _dbus_assert_not_reached ("could not copy");
03657
03658 _dbus_assert (_dbus_string_get_length (&str) == i);
03659 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03660 _dbus_assert (_dbus_string_equal_c_str (&other,
03661 "Hello WorldHello World"));
03662
03663 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03664 _dbus_assert_not_reached ("could not copy");
03665
03666 _dbus_assert (_dbus_string_get_length (&str) == i);
03667 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03668 _dbus_assert (_dbus_string_equal_c_str (&other,
03669 "Hello WorldHello WorldHello World"));
03670
03671 _dbus_string_free (&str);
03672 _dbus_string_free (&other);
03673
03674
03675
03676 if (!_dbus_string_init (&str))
03677 _dbus_assert_not_reached ("failed to init string");
03678
03679 if (!_dbus_string_append (&str, "Hello World"))
03680 _dbus_assert_not_reached ("could not append to string");
03681
03682 i = _dbus_string_get_length (&str);
03683
03684 if (!_dbus_string_init (&other))
03685 _dbus_assert_not_reached ("could not init string");
03686
03687 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03688 &other, 0, _dbus_string_get_length (&other)))
03689 _dbus_assert_not_reached ("could not replace");
03690
03691 _dbus_assert (_dbus_string_get_length (&str) == i);
03692 _dbus_assert (_dbus_string_get_length (&other) == i);
03693 _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
03694
03695 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03696 &other, 5, 1))
03697 _dbus_assert_not_reached ("could not replace center space");
03698
03699 _dbus_assert (_dbus_string_get_length (&str) == i);
03700 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03701 _dbus_assert (_dbus_string_equal_c_str (&other,
03702 "HelloHello WorldWorld"));
03703
03704
03705 if (!_dbus_string_replace_len (&str, 1, 1,
03706 &other,
03707 _dbus_string_get_length (&other) - 1,
03708 1))
03709 _dbus_assert_not_reached ("could not replace end character");
03710
03711 _dbus_assert (_dbus_string_get_length (&str) == i);
03712 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03713 _dbus_assert (_dbus_string_equal_c_str (&other,
03714 "HelloHello WorldWorle"));
03715
03716 _dbus_string_free (&str);
03717 _dbus_string_free (&other);
03718
03719
03720
03721 if (!_dbus_string_init (&str))
03722 _dbus_assert_not_reached ("failed to init string");
03723
03724 ch = 0;
03725 if (!_dbus_string_append_unichar (&str, 0xfffc))
03726 _dbus_assert_not_reached ("failed to append unichar");
03727
03728 _dbus_string_get_unichar (&str, 0, &ch, &i);
03729
03730 _dbus_assert (ch == 0xfffc);
03731 _dbus_assert (i == _dbus_string_get_length (&str));
03732
03733 _dbus_string_free (&str);
03734
03735
03736
03737 if (!_dbus_string_init (&str))
03738 _dbus_assert_not_reached ("failed to init string");
03739
03740 if (!_dbus_string_append (&str, "Hello"))
03741 _dbus_assert_not_reached ("failed to append Hello");
03742
03743 _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
03744 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
03745 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
03746 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
03747 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
03748
03749 _dbus_string_set_byte (&str, 1, 'q');
03750 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
03751
03752 if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
03753 _dbus_assert_not_reached ("can't insert byte");
03754
03755 if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
03756 _dbus_assert_not_reached ("can't insert byte");
03757
03758 if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
03759 _dbus_assert_not_reached ("can't insert byte");
03760
03761 _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
03762 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
03763 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
03764 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
03765 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
03766 _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
03767 _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
03768 _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
03769 _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
03770 _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
03771 _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
03772
03773 _dbus_string_free (&str);
03774
03775
03776
03777 if (!_dbus_string_init (&str))
03778 _dbus_assert_not_reached ("failed to init string");
03779
03780 if (!_dbus_string_append_int (&str, 27))
03781 _dbus_assert_not_reached ("failed to append int");
03782
03783 i = _dbus_string_get_length (&str);
03784
03785 if (!_dbus_string_parse_int (&str, 0, &v, &end))
03786 _dbus_assert_not_reached ("failed to parse int");
03787
03788 _dbus_assert (v == 27);
03789 _dbus_assert (end == i);
03790
03791 _dbus_string_free (&str);
03792
03793 if (!_dbus_string_init (&str))
03794 _dbus_assert_not_reached ("failed to init string");
03795
03796 if (!_dbus_string_append_double (&str, 50.3))
03797 _dbus_assert_not_reached ("failed to append float");
03798
03799 i = _dbus_string_get_length (&str);
03800
03801 if (!_dbus_string_parse_double (&str, 0, &d, &end))
03802 _dbus_assert_not_reached ("failed to parse float");
03803
03804 _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
03805 _dbus_assert (end == i);
03806
03807 _dbus_string_free (&str);
03808
03809
03810 if (!_dbus_string_init (&str))
03811 _dbus_assert_not_reached ("failed to init string");
03812
03813 if (!_dbus_string_append (&str, "Hello"))
03814 _dbus_assert_not_reached ("couldn't append to string");
03815
03816 if (!_dbus_string_find (&str, 0, "He", &i))
03817 _dbus_assert_not_reached ("didn't find 'He'");
03818 _dbus_assert (i == 0);
03819
03820 if (!_dbus_string_find (&str, 0, "Hello", &i))
03821 _dbus_assert_not_reached ("didn't find 'Hello'");
03822 _dbus_assert (i == 0);
03823
03824 if (!_dbus_string_find (&str, 0, "ello", &i))
03825 _dbus_assert_not_reached ("didn't find 'ello'");
03826 _dbus_assert (i == 1);
03827
03828 if (!_dbus_string_find (&str, 0, "lo", &i))
03829 _dbus_assert_not_reached ("didn't find 'lo'");
03830 _dbus_assert (i == 3);
03831
03832 if (!_dbus_string_find (&str, 2, "lo", &i))
03833 _dbus_assert_not_reached ("didn't find 'lo'");
03834 _dbus_assert (i == 3);
03835
03836 if (_dbus_string_find (&str, 4, "lo", &i))
03837 _dbus_assert_not_reached ("did find 'lo'");
03838
03839 if (!_dbus_string_find (&str, 0, "l", &i))
03840 _dbus_assert_not_reached ("didn't find 'l'");
03841 _dbus_assert (i == 2);
03842
03843 if (!_dbus_string_find (&str, 0, "H", &i))
03844 _dbus_assert_not_reached ("didn't find 'H'");
03845 _dbus_assert (i == 0);
03846
03847 if (!_dbus_string_find (&str, 0, "", &i))
03848 _dbus_assert_not_reached ("didn't find ''");
03849 _dbus_assert (i == 0);
03850
03851 if (_dbus_string_find (&str, 0, "Hello!", NULL))
03852 _dbus_assert_not_reached ("Did find 'Hello!'");
03853
03854 if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
03855 _dbus_assert_not_reached ("Did find 'Oh, Hello'");
03856
03857 if (_dbus_string_find (&str, 0, "ill", NULL))
03858 _dbus_assert_not_reached ("Did find 'ill'");
03859
03860 if (_dbus_string_find (&str, 0, "q", NULL))
03861 _dbus_assert_not_reached ("Did find 'q'");
03862
03863 if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
03864 _dbus_assert_not_reached ("Didn't find 'He'");
03865
03866 if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
03867 _dbus_assert_not_reached ("Did find 'Hello'");
03868
03869 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
03870 _dbus_assert_not_reached ("Did not find 'H'");
03871 _dbus_assert (i == 0);
03872
03873 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
03874 _dbus_assert_not_reached ("Did not find 'o'");
03875 _dbus_assert (i == _dbus_string_get_length (&str) - 1);
03876
03877 if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
03878 _dbus_assert_not_reached ("Did find 'o'");
03879 _dbus_assert (i == -1);
03880
03881 if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
03882 _dbus_assert_not_reached ("Did find 'e'");
03883 _dbus_assert (i == -1);
03884
03885 if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
03886 _dbus_assert_not_reached ("Didn't find 'e'");
03887 _dbus_assert (i == 1);
03888
03889 _dbus_string_free (&str);
03890
03891
03892 _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
03893 if (!_dbus_string_init (&other))
03894 _dbus_assert_not_reached ("could not init string");
03895
03896 if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
03897 _dbus_assert_not_reached ("deccoded bogus hex string with no error");
03898
03899 _dbus_assert (end == 8);
03900
03901 _dbus_string_free (&other);
03902
03903 test_roundtrips (test_hex_roundtrip);
03904
03905
03906 i = 0;
03907 while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
03908 {
03909 _dbus_string_init_const (&str, valid_paths[i]);
03910
03911 if (!_dbus_string_validate_path (&str, 0,
03912 _dbus_string_get_length (&str)))
03913 {
03914 _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
03915 _dbus_assert_not_reached ("invalid path");
03916 }
03917
03918 ++i;
03919 }
03920
03921 i = 0;
03922 while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
03923 {
03924 _dbus_string_init_const (&str, invalid_paths[i]);
03925
03926 if (_dbus_string_validate_path (&str, 0,
03927 _dbus_string_get_length (&str)))
03928 {
03929 _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
03930 _dbus_assert_not_reached ("valid path");
03931 }
03932
03933 ++i;
03934 }
03935
03936
03937 i = 0;
03938 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
03939 {
03940 _dbus_string_init_const (&str, valid_interfaces[i]);
03941
03942 if (!_dbus_string_validate_interface (&str, 0,
03943 _dbus_string_get_length (&str)))
03944 {
03945 _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]);
03946 _dbus_assert_not_reached ("invalid interface");
03947 }
03948
03949 ++i;
03950 }
03951
03952 i = 0;
03953 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
03954 {
03955 _dbus_string_init_const (&str, invalid_interfaces[i]);
03956
03957 if (_dbus_string_validate_interface (&str, 0,
03958 _dbus_string_get_length (&str)))
03959 {
03960 _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]);
03961 _dbus_assert_not_reached ("valid interface");
03962 }
03963
03964 ++i;
03965 }
03966
03967
03968
03969
03970 i = 0;
03971 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
03972 {
03973 _dbus_string_init_const (&str, valid_interfaces[i]);
03974
03975 if (!_dbus_string_validate_service (&str, 0,
03976 _dbus_string_get_length (&str)))
03977 {
03978 _dbus_warn ("Service \"%s\" should have been valid\n", valid_interfaces[i]);
03979 _dbus_assert_not_reached ("invalid service");
03980 }
03981
03982 ++i;
03983 }
03984
03985 i = 0;
03986 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
03987 {
03988 if (invalid_interfaces[i][0] != ':')
03989 {
03990 _dbus_string_init_const (&str, invalid_interfaces[i]);
03991
03992 if (_dbus_string_validate_service (&str, 0,
03993 _dbus_string_get_length (&str)))
03994 {
03995 _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_interfaces[i]);
03996 _dbus_assert_not_reached ("valid service");
03997 }
03998 }
03999
04000 ++i;
04001 }
04002
04003
04004 i = 0;
04005 while (i < (int) _DBUS_N_ELEMENTS (valid_base_services))
04006 {
04007 _dbus_string_init_const (&str, valid_base_services[i]);
04008
04009 if (!_dbus_string_validate_service (&str, 0,
04010 _dbus_string_get_length (&str)))
04011 {
04012 _dbus_warn ("Service \"%s\" should have been valid\n", valid_base_services[i]);
04013 _dbus_assert_not_reached ("invalid base service");
04014 }
04015
04016 ++i;
04017 }
04018
04019 i = 0;
04020 while (i < (int) _DBUS_N_ELEMENTS (invalid_base_services))
04021 {
04022 _dbus_string_init_const (&str, invalid_base_services[i]);
04023
04024 if (_dbus_string_validate_service (&str, 0,
04025 _dbus_string_get_length (&str)))
04026 {
04027 _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_base_services[i]);
04028 _dbus_assert_not_reached ("valid base service");
04029 }
04030
04031 ++i;
04032 }
04033
04034
04035
04036
04037 i = 0;
04038 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
04039 {
04040 _dbus_string_init_const (&str, valid_interfaces[i]);
04041
04042 if (!_dbus_string_validate_error_name (&str, 0,
04043 _dbus_string_get_length (&str)))
04044 {
04045 _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]);
04046 _dbus_assert_not_reached ("invalid error name");
04047 }
04048
04049 ++i;
04050 }
04051
04052 i = 0;
04053 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
04054 {
04055 if (invalid_interfaces[i][0] != ':')
04056 {
04057 _dbus_string_init_const (&str, invalid_interfaces[i]);
04058
04059 if (_dbus_string_validate_error_name (&str, 0,
04060 _dbus_string_get_length (&str)))
04061 {
04062 _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]);
04063 _dbus_assert_not_reached ("valid error name");
04064 }
04065 }
04066
04067 ++i;
04068 }
04069
04070
04071 i = 0;
04072 while (i < (int) _DBUS_N_ELEMENTS (valid_members))
04073 {
04074 _dbus_string_init_const (&str, valid_members[i]);
04075
04076 if (!_dbus_string_validate_member (&str, 0,
04077 _dbus_string_get_length (&str)))
04078 {
04079 _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]);
04080 _dbus_assert_not_reached ("invalid member");
04081 }
04082
04083 ++i;
04084 }
04085
04086 i = 0;
04087 while (i < (int) _DBUS_N_ELEMENTS (invalid_members))
04088 {
04089 _dbus_string_init_const (&str, invalid_members[i]);
04090
04091 if (_dbus_string_validate_member (&str, 0,
04092 _dbus_string_get_length (&str)))
04093 {
04094 _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]);
04095 _dbus_assert_not_reached ("valid member");
04096 }
04097
04098 ++i;
04099 }
04100
04101
04102 i = 0;
04103 while (i < (int) _DBUS_N_ELEMENTS (valid_signatures))
04104 {
04105 _dbus_string_init_const (&str, valid_signatures[i]);
04106
04107 if (!_dbus_string_validate_signature (&str, 0,
04108 _dbus_string_get_length (&str)))
04109 {
04110 _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]);
04111 _dbus_assert_not_reached ("invalid signature");
04112 }
04113
04114 ++i;
04115 }
04116
04117 i = 0;
04118 while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures))
04119 {
04120 _dbus_string_init_const (&str, invalid_signatures[i]);
04121
04122 if (_dbus_string_validate_signature (&str, 0,
04123 _dbus_string_get_length (&str)))
04124 {
04125 _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]);
04126 _dbus_assert_not_reached ("valid signature");
04127 }
04128
04129 ++i;
04130 }
04131
04132
04133 _dbus_string_init_const (&str, "abc.efg");
04134 if (_dbus_string_validate_service (&str, 0, 8))
04135 _dbus_assert_not_reached ("validated too-long string");
04136 if (_dbus_string_validate_interface (&str, 0, 8))
04137 _dbus_assert_not_reached ("validated too-long string");
04138 if (_dbus_string_validate_error_name (&str, 0, 8))
04139 _dbus_assert_not_reached ("validated too-long string");
04140
04141 _dbus_string_init_const (&str, "abc");
04142 if (_dbus_string_validate_member (&str, 0, 4))
04143 _dbus_assert_not_reached ("validated too-long string");
04144
04145 _dbus_string_init_const (&str, "sss");
04146 if (_dbus_string_validate_signature (&str, 0, 4))
04147 _dbus_assert_not_reached ("validated too-long signature");
04148
04149
04150 if (!_dbus_string_init (&str))
04151 _dbus_assert_not_reached ("no memory");
04152
04153 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
04154 if (!_dbus_string_append (&str, "abc.def"))
04155 _dbus_assert_not_reached ("no memory");
04156
04157 if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
04158 _dbus_assert_not_reached ("validated overmax string");
04159 if (_dbus_string_validate_interface (&str, 0, _dbus_string_get_length (&str)))
04160 _dbus_assert_not_reached ("validated overmax string");
04161 if (_dbus_string_validate_error_name (&str, 0, _dbus_string_get_length (&str)))
04162 _dbus_assert_not_reached ("validated overmax string");
04163
04164
04165 _dbus_string_set_length (&str, 0);
04166 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
04167 if (!_dbus_string_append (&str, "abc"))
04168 _dbus_assert_not_reached ("no memory");
04169
04170 if (_dbus_string_validate_member (&str, 0, _dbus_string_get_length (&str)))
04171 _dbus_assert_not_reached ("validated overmax string");
04172
04173
04174 _dbus_string_set_length (&str, 0);
04175 _dbus_string_append (&str, ":");
04176 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
04177 if (!_dbus_string_append (&str, "abc"))
04178 _dbus_assert_not_reached ("no memory");
04179
04180 if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
04181 _dbus_assert_not_reached ("validated overmax string");
04182
04183 _dbus_string_free (&str);
04184
04185 return TRUE;
04186 }
04187
04188 #endif