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