D-Bus  1.4.10
dbus-string.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-string.c String utility class (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
5  * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-string.h"
28 /* we allow a system header here, for speed/convenience */
29 #include <string.h>
30 /* for vsnprintf */
31 #include <stdio.h>
32 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
33 #include "dbus-string-private.h"
34 #include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
35  * into the marshaling-related files
36  */
37 /* for DBUS_VA_COPY */
38 #include "dbus-sysdeps.h"
39 
78 static void
79 fixup_alignment (DBusRealString *real)
80 {
81  unsigned char *aligned;
82  unsigned char *real_block;
83  unsigned int old_align_offset;
84 
85  /* we have to have extra space in real->allocated for the align offset and nul byte */
86  _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
87 
88  old_align_offset = real->align_offset;
89  real_block = real->str - old_align_offset;
90 
91  aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
92 
93  real->align_offset = aligned - real_block;
94  real->str = aligned;
95 
96  if (old_align_offset != real->align_offset)
97  {
98  /* Here comes the suck */
99  memmove (real_block + real->align_offset,
100  real_block + old_align_offset,
101  real->len + 1);
102  }
103 
104  _dbus_assert (real->align_offset < 8);
105  _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
106 }
107 
108 static void
109 undo_alignment (DBusRealString *real)
110 {
111  if (real->align_offset != 0)
112  {
113  memmove (real->str - real->align_offset,
114  real->str,
115  real->len + 1);
116 
117  real->str = real->str - real->align_offset;
118  real->align_offset = 0;
119  }
120 }
121 
133  int allocate_size)
134 {
135  DBusRealString *real;
136 
137  _dbus_assert (str != NULL);
138 
139  _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
140 
141  real = (DBusRealString*) str;
142 
143  /* It's very important not to touch anything
144  * other than real->str if we're going to fail,
145  * since we also use this function to reset
146  * an existing string, e.g. in _dbus_string_steal_data()
147  */
148 
149  real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
150  if (real->str == NULL)
151  return FALSE;
152 
153  real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
154  real->len = 0;
155  real->str[real->len] = '\0';
156 
158  real->constant = FALSE;
159  real->locked = FALSE;
160  real->invalid = FALSE;
161  real->align_offset = 0;
162 
163  fixup_alignment (real);
164 
165  return TRUE;
166 }
167 
177 {
178  return _dbus_string_init_preallocated (str, 0);
179 }
180 
181 #ifdef DBUS_BUILD_TESTS
182 /* The max length thing is sort of a historical artifact
183  * from a feature that turned out to be dumb; perhaps
184  * we should purge it entirely. The problem with
185  * the feature is that it looks like memory allocation
186  * failure, but is not a transient or resolvable failure.
187  */
188 static void
189 set_max_length (DBusString *str,
190  int max_length)
191 {
192  DBusRealString *real;
193 
194  real = (DBusRealString*) str;
195 
196  real->max_length = max_length;
197 }
198 #endif /* DBUS_BUILD_TESTS */
199 
209 void
211  const char *value)
212 {
213  _dbus_assert (value != NULL);
214 
215  _dbus_string_init_const_len (str, value,
216  strlen (value));
217 }
218 
229 void
231  const char *value,
232  int len)
233 {
234  DBusRealString *real;
235 
236  _dbus_assert (str != NULL);
237  _dbus_assert (len == 0 || value != NULL);
239  _dbus_assert (len >= 0);
240 
241  real = (DBusRealString*) str;
242 
243  real->str = (unsigned char*) value;
244  real->len = len;
245  real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
246  real->max_length = real->len + 1;
247  real->constant = TRUE;
248  real->locked = TRUE;
249  real->invalid = FALSE;
250  real->align_offset = 0;
251 
252  /* We don't require const strings to be 8-byte aligned as the
253  * memory is coming from elsewhere.
254  */
255 }
256 
262 void
264 {
265  DBusRealString *real = (DBusRealString*) str;
267 
268  if (real->constant)
269  return;
270  dbus_free (real->str - real->align_offset);
271 
272  real->invalid = TRUE;
273 }
274 
275 static dbus_bool_t
276 compact (DBusRealString *real,
277  int max_waste)
278 {
279  unsigned char *new_str;
280  int new_allocated;
281  int waste;
282 
283  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
284 
285  if (waste <= max_waste)
286  return TRUE;
287 
288  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
289 
290  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
291  if (_DBUS_UNLIKELY (new_str == NULL))
292  return FALSE;
293 
294  real->str = new_str + real->align_offset;
295  real->allocated = new_allocated;
296  fixup_alignment (real);
297 
298  return TRUE;
299 }
300 
301 #ifdef DBUS_BUILD_TESTS
302 /* Not using this feature at the moment,
303  * so marked DBUS_BUILD_TESTS-only
304  */
314 void
315 _dbus_string_lock (DBusString *str)
316 {
317  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
318 
319  real->locked = TRUE;
320 
321  /* Try to realloc to avoid excess memory usage, since
322  * we know we won't change the string further
323  */
324 #define MAX_WASTE 48
325  compact (real, MAX_WASTE);
326 }
327 #endif /* DBUS_BUILD_TESTS */
328 
329 static dbus_bool_t
330 reallocate_for_length (DBusRealString *real,
331  int new_length)
332 {
333  int new_allocated;
334  unsigned char *new_str;
335 
336  /* at least double our old allocation to avoid O(n), avoiding
337  * overflow
338  */
339  if (real->allocated > (_DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
340  new_allocated = _DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
341  else
342  new_allocated = real->allocated * 2;
343 
344  /* if you change the code just above here, run the tests without
345  * the following assert-only hack before you commit
346  */
347  /* This is keyed off asserts in addition to tests so when you
348  * disable asserts to profile, you don't get this destroyer
349  * of profiles.
350  */
351 #ifdef DBUS_DISABLE_ASSERT
352 #else
353 #ifdef DBUS_BUILD_TESTS
354  new_allocated = 0; /* ensure a realloc every time so that we go
355  * through all malloc failure codepaths
356  */
357 #endif /* DBUS_BUILD_TESTS */
358 #endif /* !DBUS_DISABLE_ASSERT */
359 
360  /* But be sure we always alloc at least space for the new length */
361  new_allocated = MAX (new_allocated,
362  new_length + _DBUS_STRING_ALLOCATION_PADDING);
363 
364  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
365  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
366  if (_DBUS_UNLIKELY (new_str == NULL))
367  return FALSE;
368 
369  real->str = new_str + real->align_offset;
370  real->allocated = new_allocated;
371  fixup_alignment (real);
372 
373  return TRUE;
374 }
375 
389  int max_waste)
390 {
391  DBUS_STRING_PREAMBLE (str);
392 
393  return compact (real, max_waste);
394 }
395 
396 static dbus_bool_t
397 set_length (DBusRealString *real,
398  int new_length)
399 {
400  /* Note, we are setting the length not including nul termination */
401 
402  /* exceeding max length is the same as failure to allocate memory */
403  if (_DBUS_UNLIKELY (new_length > real->max_length))
404  return FALSE;
405  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
406  _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
407  return FALSE;
408  else
409  {
410  real->len = new_length;
411  real->str[new_length] = '\0';
412  return TRUE;
413  }
414 }
415 
416 static dbus_bool_t
417 open_gap (int len,
418  DBusRealString *dest,
419  int insert_at)
420 {
421  if (len == 0)
422  return TRUE;
423 
424  if (len > dest->max_length - dest->len)
425  return FALSE; /* detected overflow of dest->len + len below */
426 
427  if (!set_length (dest, dest->len + len))
428  return FALSE;
429 
430  memmove (dest->str + insert_at + len,
431  dest->str + insert_at,
432  dest->len - len - insert_at);
433 
434  return TRUE;
435 }
436 
437 #ifndef _dbus_string_get_data
438 
449 char*
451 {
452  DBUS_STRING_PREAMBLE (str);
453 
454  return (char*) real->str;
455 }
456 #endif /* _dbus_string_get_data */
457 
458 /* only do the function if we don't have the macro */
459 #ifndef _dbus_string_get_const_data
460 
466 const char*
468 {
470 
471  return (const char*) real->str;
472 }
473 #endif /* _dbus_string_get_const_data */
474 
488 char*
490  int start,
491  int len)
492 {
493  DBUS_STRING_PREAMBLE (str);
494  _dbus_assert (start >= 0);
495  _dbus_assert (len >= 0);
496  _dbus_assert (start <= real->len);
497  _dbus_assert (len <= real->len - start);
498 
499  return (char*) real->str + start;
500 }
501 
502 /* only do the function if we don't have the macro */
503 #ifndef _dbus_string_get_const_data_len
504 
512 const char*
514  int start,
515  int len)
516 {
518  _dbus_assert (start >= 0);
519  _dbus_assert (len >= 0);
520  _dbus_assert (start <= real->len);
521  _dbus_assert (len <= real->len - start);
522 
523  return (const char*) real->str + start;
524 }
525 #endif /* _dbus_string_get_const_data_len */
526 
527 /* only do the function if we don't have the macro */
528 #ifndef _dbus_string_set_byte
529 
536 void
538  int i,
539  unsigned char byte)
540 {
541  DBUS_STRING_PREAMBLE (str);
542  _dbus_assert (i < real->len);
543  _dbus_assert (i >= 0);
544 
545  real->str[i] = byte;
546 }
547 #endif /* _dbus_string_set_byte */
548 
549 /* only have the function if we didn't create a macro */
550 #ifndef _dbus_string_get_byte
551 
560 unsigned char
562  int start)
563 {
565  _dbus_assert (start <= real->len);
566  _dbus_assert (start >= 0);
567 
568  return real->str[start];
569 }
570 #endif /* _dbus_string_get_byte */
571 
584  int i,
585  int n_bytes,
586  unsigned char byte)
587 {
588  DBUS_STRING_PREAMBLE (str);
589  _dbus_assert (i <= real->len);
590  _dbus_assert (i >= 0);
591  _dbus_assert (n_bytes >= 0);
592 
593  if (n_bytes == 0)
594  return TRUE;
595 
596  if (!open_gap (n_bytes, real, i))
597  return FALSE;
598 
599  memset (real->str + i, byte, n_bytes);
600 
601  return TRUE;
602 }
603 
614  int i,
615  unsigned char byte)
616 {
617  DBUS_STRING_PREAMBLE (str);
618  _dbus_assert (i <= real->len);
619  _dbus_assert (i >= 0);
620 
621  if (!open_gap (1, real, i))
622  return FALSE;
623 
624  real->str[i] = byte;
625 
626  return TRUE;
627 }
628 
641  char **data_return)
642 {
643  int old_max_length;
644  DBUS_STRING_PREAMBLE (str);
645  _dbus_assert (data_return != NULL);
646 
647  undo_alignment (real);
648 
649  *data_return = (char*) real->str;
650 
651  old_max_length = real->max_length;
652 
653  /* reset the string */
654  if (!_dbus_string_init (str))
655  {
656  /* hrm, put it back then */
657  real->str = (unsigned char*) *data_return;
658  *data_return = NULL;
659  fixup_alignment (real);
660  return FALSE;
661  }
662 
663  real->max_length = old_max_length;
664 
665  return TRUE;
666 }
667 
668 #ifdef DBUS_BUILD_TESTS
669 
685 _dbus_string_steal_data_len (DBusString *str,
686  char **data_return,
687  int start,
688  int len)
689 {
690  DBusString dest;
691  DBUS_STRING_PREAMBLE (str);
692  _dbus_assert (data_return != NULL);
693  _dbus_assert (start >= 0);
694  _dbus_assert (len >= 0);
695  _dbus_assert (start <= real->len);
696  _dbus_assert (len <= real->len - start);
697 
698  if (!_dbus_string_init (&dest))
699  return FALSE;
700 
701  set_max_length (&dest, real->max_length);
702 
703  if (!_dbus_string_move_len (str, start, len, &dest, 0))
704  {
705  _dbus_string_free (&dest);
706  return FALSE;
707  }
708 
709  _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
710  if (!_dbus_string_steal_data (&dest, data_return))
711  {
712  _dbus_string_free (&dest);
713  return FALSE;
714  }
715 
716  _dbus_string_free (&dest);
717  return TRUE;
718 }
719 #endif /* DBUS_BUILD_TESTS */
720 
730  char **data_return)
731 {
733  _dbus_assert (data_return != NULL);
734 
735  *data_return = dbus_malloc (real->len + 1);
736  if (*data_return == NULL)
737  return FALSE;
738 
739  memcpy (*data_return, real->str, real->len + 1);
740 
741  return TRUE;
742 }
743 
753 void
755  char *buffer,
756  int avail_len)
757 {
759 
760  _dbus_assert (avail_len >= 0);
761  _dbus_assert (avail_len >= real->len);
762 
763  memcpy (buffer, real->str, real->len);
764 }
765 
775 void
777  char *buffer,
778  int avail_len)
779 {
781 
782  _dbus_assert (avail_len >= 0);
783  _dbus_assert (avail_len > real->len);
784 
785  memcpy (buffer, real->str, real->len+1);
786 }
787 
788 #ifdef DBUS_BUILD_TESTS
789 
799 _dbus_string_copy_data_len (const DBusString *str,
800  char **data_return,
801  int start,
802  int len)
803 {
804  DBusString dest;
805 
807  _dbus_assert (data_return != NULL);
808  _dbus_assert (start >= 0);
809  _dbus_assert (len >= 0);
810  _dbus_assert (start <= real->len);
811  _dbus_assert (len <= real->len - start);
812 
813  if (!_dbus_string_init (&dest))
814  return FALSE;
815 
816  set_max_length (&dest, real->max_length);
817 
818  if (!_dbus_string_copy_len (str, start, len, &dest, 0))
819  {
820  _dbus_string_free (&dest);
821  return FALSE;
822  }
823 
824  if (!_dbus_string_steal_data (&dest, data_return))
825  {
826  _dbus_string_free (&dest);
827  return FALSE;
828  }
829 
830  _dbus_string_free (&dest);
831  return TRUE;
832 }
833 #endif /* DBUS_BUILD_TESTS */
834 
835 /* Only have the function if we don't have the macro */
836 #ifndef _dbus_string_get_length
837 
842 int
844 {
846 
847  return real->len;
848 }
849 #endif /* !_dbus_string_get_length */
850 
865  int additional_length)
866 {
867  DBUS_STRING_PREAMBLE (str);
868  _dbus_assert (additional_length >= 0);
869 
870  if (_DBUS_UNLIKELY (additional_length > real->max_length - real->len))
871  return FALSE; /* would overflow */
872 
873  return set_length (real,
874  real->len + additional_length);
875 }
876 
883 void
885  int length_to_remove)
886 {
887  DBUS_STRING_PREAMBLE (str);
888  _dbus_assert (length_to_remove >= 0);
889  _dbus_assert (length_to_remove <= real->len);
890 
891  set_length (real,
892  real->len - length_to_remove);
893 }
894 
907  int length)
908 {
909  DBUS_STRING_PREAMBLE (str);
910  _dbus_assert (length >= 0);
911 
912  return set_length (real, length);
913 }
914 
915 static dbus_bool_t
916 align_insert_point_then_open_gap (DBusString *str,
917  int *insert_at_p,
918  int alignment,
919  int gap_size)
920 {
921  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
922  unsigned long gap_pos;
923  int insert_at;
924  int delta;
925  DBUS_STRING_PREAMBLE (str);
926  _dbus_assert (alignment >= 1);
927  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
928 
929  insert_at = *insert_at_p;
930 
931  _dbus_assert (insert_at <= real->len);
932 
933  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
934  new_len = real->len + (gap_pos - insert_at) + gap_size;
935 
936  if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length))
937  return FALSE;
938 
939  delta = new_len - real->len;
940  _dbus_assert (delta >= 0);
941 
942  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
943  {
944  _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
945  return TRUE;
946  }
947 
948  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
949  real, insert_at)))
950  return FALSE;
951 
952  /* nul the padding if we had to add any padding */
953  if (gap_size < delta)
954  {
955  memset (&real->str[insert_at], '\0',
956  gap_pos - insert_at);
957  }
958 
959  *insert_at_p = gap_pos;
960 
961  return TRUE;
962 }
963 
964 static dbus_bool_t
965 align_length_then_lengthen (DBusString *str,
966  int alignment,
967  int then_lengthen_by)
968 {
969  int insert_at;
970 
971  insert_at = _dbus_string_get_length (str);
972 
973  return align_insert_point_then_open_gap (str,
974  &insert_at,
975  alignment, then_lengthen_by);
976 }
977 
988  int alignment)
989 {
990  return align_length_then_lengthen (str, alignment, 0);
991 }
992 
1004  int extra_bytes)
1005 {
1006  if (!_dbus_string_lengthen (str, extra_bytes))
1007  return FALSE;
1008  _dbus_string_shorten (str, extra_bytes);
1009 
1010  return TRUE;
1011 }
1012 
1013 static dbus_bool_t
1014 append (DBusRealString *real,
1015  const char *buffer,
1016  int buffer_len)
1017 {
1018  if (buffer_len == 0)
1019  return TRUE;
1020 
1021  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
1022  return FALSE;
1023 
1024  memcpy (real->str + (real->len - buffer_len),
1025  buffer,
1026  buffer_len);
1027 
1028  return TRUE;
1029 }
1030 
1040  const char *buffer)
1041 {
1042  unsigned long buffer_len;
1043 
1044  DBUS_STRING_PREAMBLE (str);
1045  _dbus_assert (buffer != NULL);
1046 
1047  buffer_len = strlen (buffer);
1048  if (buffer_len > (unsigned long) real->max_length)
1049  return FALSE;
1050 
1051  return append (real, buffer, buffer_len);
1052 }
1053 
1055 #define ASSIGN_2_OCTETS(p, octets) \
1056  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
1057 
1059 #define ASSIGN_4_OCTETS(p, octets) \
1060  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
1061 
1062 #ifdef DBUS_HAVE_INT64
1063 
1064 #define ASSIGN_8_OCTETS(p, octets) \
1065  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
1066 #else
1067 
1068 #define ASSIGN_8_OCTETS(p, octets) \
1069 do { \
1070  unsigned char *b; \
1071  \
1072  b = p; \
1073  \
1074  *b++ = octets[0]; \
1075  *b++ = octets[1]; \
1076  *b++ = octets[2]; \
1077  *b++ = octets[3]; \
1078  *b++ = octets[4]; \
1079  *b++ = octets[5]; \
1080  *b++ = octets[6]; \
1081  *b++ = octets[7]; \
1082  _dbus_assert (b == p + 8); \
1083 } while (0)
1084 #endif /* DBUS_HAVE_INT64 */
1085 
1086 #ifdef DBUS_BUILD_TESTS
1087 
1096 _dbus_string_append_4_aligned (DBusString *str,
1097  const unsigned char octets[4])
1098 {
1099  DBUS_STRING_PREAMBLE (str);
1100 
1101  if (!align_length_then_lengthen (str, 4, 4))
1102  return FALSE;
1103 
1104  ASSIGN_4_OCTETS (real->str + (real->len - 4), octets);
1105 
1106  return TRUE;
1107 }
1108 #endif /* DBUS_BUILD_TESTS */
1109 
1110 #ifdef DBUS_BUILD_TESTS
1111 
1120 _dbus_string_append_8_aligned (DBusString *str,
1121  const unsigned char octets[8])
1122 {
1123  DBUS_STRING_PREAMBLE (str);
1124 
1125  if (!align_length_then_lengthen (str, 8, 8))
1126  return FALSE;
1127 
1128  ASSIGN_8_OCTETS (real->str + (real->len - 8), octets);
1129 
1130  return TRUE;
1131 }
1132 #endif /* DBUS_BUILD_TESTS */
1133 
1145  int insert_at,
1146  const unsigned char octets[4])
1147 {
1148  DBUS_STRING_PREAMBLE (str);
1149 
1150  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
1151  return FALSE;
1152 
1153  ASSIGN_2_OCTETS (real->str + insert_at, octets);
1154 
1155  return TRUE;
1156 }
1157 
1169  int insert_at,
1170  const unsigned char octets[4])
1171 {
1172  DBUS_STRING_PREAMBLE (str);
1173 
1174  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1175  return FALSE;
1176 
1177  ASSIGN_4_OCTETS (real->str + insert_at, octets);
1178 
1179  return TRUE;
1180 }
1181 
1193  int insert_at,
1194  const unsigned char octets[8])
1195 {
1196  DBUS_STRING_PREAMBLE (str);
1197 
1198  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1199  return FALSE;
1200 
1201  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1202 
1203  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1204 
1205  return TRUE;
1206 }
1207 
1208 
1221  int *insert_at,
1222  int alignment)
1223 {
1224  DBUS_STRING_PREAMBLE (str);
1225 
1226  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1227  return FALSE;
1228 
1229  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1230 
1231  return TRUE;
1232 }
1233 
1245  const char *format,
1246  va_list args)
1247 {
1248  int len;
1249  va_list args_copy;
1250 
1251  DBUS_STRING_PREAMBLE (str);
1252 
1253  DBUS_VA_COPY (args_copy, args);
1254 
1255  /* Measure the message length without terminating nul */
1256  len = _dbus_printf_string_upper_bound (format, args);
1257 
1258  if (!_dbus_string_lengthen (str, len))
1259  {
1260  /* don't leak the copy */
1261  va_end (args_copy);
1262  return FALSE;
1263  }
1264 
1265  vsprintf ((char*) (real->str + (real->len - len)),
1266  format, args_copy);
1267 
1268  va_end (args_copy);
1269 
1270  return TRUE;
1271 }
1272 
1283  const char *format,
1284  ...)
1285 {
1286  va_list args;
1287  dbus_bool_t retval;
1288 
1289  va_start (args, format);
1290  retval = _dbus_string_append_printf_valist (str, format, args);
1291  va_end (args);
1292 
1293  return retval;
1294 }
1295 
1306  const char *buffer,
1307  int len)
1308 {
1309  DBUS_STRING_PREAMBLE (str);
1310  _dbus_assert (buffer != NULL);
1311  _dbus_assert (len >= 0);
1312 
1313  return append (real, buffer, len);
1314 }
1315 
1326  unsigned char byte)
1327 {
1328  DBUS_STRING_PREAMBLE (str);
1329 
1330  if (!set_length (real, real->len + 1))
1331  return FALSE;
1332 
1333  real->str[real->len-1] = byte;
1334 
1335  return TRUE;
1336 }
1337 
1338 #ifdef DBUS_BUILD_TESTS
1339 
1347 _dbus_string_append_unichar (DBusString *str,
1348  dbus_unichar_t ch)
1349 {
1350  int len;
1351  int first;
1352  int i;
1353  unsigned char *out;
1354 
1355  DBUS_STRING_PREAMBLE (str);
1356 
1357  /* this code is from GLib but is pretty standard I think */
1358 
1359  len = 0;
1360 
1361  if (ch < 0x80)
1362  {
1363  first = 0;
1364  len = 1;
1365  }
1366  else if (ch < 0x800)
1367  {
1368  first = 0xc0;
1369  len = 2;
1370  }
1371  else if (ch < 0x10000)
1372  {
1373  first = 0xe0;
1374  len = 3;
1375  }
1376  else if (ch < 0x200000)
1377  {
1378  first = 0xf0;
1379  len = 4;
1380  }
1381  else if (ch < 0x4000000)
1382  {
1383  first = 0xf8;
1384  len = 5;
1385  }
1386  else
1387  {
1388  first = 0xfc;
1389  len = 6;
1390  }
1391 
1392  if (len > (real->max_length - real->len))
1393  return FALSE; /* real->len + len would overflow */
1394 
1395  if (!set_length (real, real->len + len))
1396  return FALSE;
1397 
1398  out = real->str + (real->len - len);
1399 
1400  for (i = len - 1; i > 0; --i)
1401  {
1402  out[i] = (ch & 0x3f) | 0x80;
1403  ch >>= 6;
1404  }
1405  out[0] = ch | first;
1406 
1407  return TRUE;
1408 }
1409 #endif /* DBUS_BUILD_TESTS */
1410 
1411 static void
1412 delete (DBusRealString *real,
1413  int start,
1414  int len)
1415 {
1416  if (len == 0)
1417  return;
1418 
1419  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1420  real->len -= len;
1421  real->str[real->len] = '\0';
1422 }
1423 
1433 void
1435  int start,
1436  int len)
1437 {
1438  DBUS_STRING_PREAMBLE (str);
1439  _dbus_assert (start >= 0);
1440  _dbus_assert (len >= 0);
1441  _dbus_assert (start <= real->len);
1442  _dbus_assert (len <= real->len - start);
1443 
1444  delete (real, start, len);
1445 }
1446 
1447 static dbus_bool_t
1448 copy (DBusRealString *source,
1449  int start,
1450  int len,
1451  DBusRealString *dest,
1452  int insert_at)
1453 {
1454  if (len == 0)
1455  return TRUE;
1456 
1457  if (!open_gap (len, dest, insert_at))
1458  return FALSE;
1459 
1460  memmove (dest->str + insert_at,
1461  source->str + start,
1462  len);
1463 
1464  return TRUE;
1465 }
1466 
1476 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1477  DBusRealString *real_source = (DBusRealString*) source; \
1478  DBusRealString *real_dest = (DBusRealString*) dest; \
1479  _dbus_assert ((source) != (dest)); \
1480  DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1481  DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1482  _dbus_assert (!real_dest->constant); \
1483  _dbus_assert (!real_dest->locked); \
1484  _dbus_assert ((start) >= 0); \
1485  _dbus_assert ((start) <= real_source->len); \
1486  _dbus_assert ((insert_at) >= 0); \
1487  _dbus_assert ((insert_at) <= real_dest->len)
1488 
1501  int start,
1502  DBusString *dest,
1503  int insert_at)
1504 {
1505  DBusRealString *real_source = (DBusRealString*) source;
1506  _dbus_assert (start <= real_source->len);
1507 
1508  return _dbus_string_move_len (source, start,
1509  real_source->len - start,
1510  dest, insert_at);
1511 }
1512 
1525  int start,
1526  DBusString *dest,
1527  int insert_at)
1528 {
1529  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1530 
1531  return copy (real_source, start,
1532  real_source->len - start,
1533  real_dest,
1534  insert_at);
1535 }
1536 
1553  int start,
1554  int len,
1555  DBusString *dest,
1556  int insert_at)
1557 
1558 {
1559  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1560  _dbus_assert (len >= 0);
1561  _dbus_assert ((start + len) <= real_source->len);
1562 
1563 
1564  if (len == 0)
1565  {
1566  return TRUE;
1567  }
1568  else if (start == 0 &&
1569  len == real_source->len &&
1570  real_dest->len == 0)
1571  {
1572  /* Short-circuit moving an entire existing string to an empty string
1573  * by just swapping the buffers.
1574  */
1575  /* we assume ->constant doesn't matter as you can't have
1576  * a constant string involved in a move.
1577  */
1578 #define ASSIGN_DATA(a, b) do { \
1579  (a)->str = (b)->str; \
1580  (a)->len = (b)->len; \
1581  (a)->allocated = (b)->allocated; \
1582  (a)->align_offset = (b)->align_offset; \
1583  } while (0)
1584 
1585  DBusRealString tmp;
1586 
1587  ASSIGN_DATA (&tmp, real_source);
1588  ASSIGN_DATA (real_source, real_dest);
1589  ASSIGN_DATA (real_dest, &tmp);
1590 
1591  return TRUE;
1592  }
1593  else
1594  {
1595  if (!copy (real_source, start, len,
1596  real_dest,
1597  insert_at))
1598  return FALSE;
1599 
1600  delete (real_source, start,
1601  len);
1602 
1603  return TRUE;
1604  }
1605 }
1606 
1620  int start,
1621  int len,
1622  DBusString *dest,
1623  int insert_at)
1624 {
1625  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1626  _dbus_assert (len >= 0);
1627  _dbus_assert (start <= real_source->len);
1628  _dbus_assert (len <= real_source->len - start);
1629 
1630  return copy (real_source, start, len,
1631  real_dest,
1632  insert_at);
1633 }
1634 
1658  int start,
1659  int len,
1660  DBusString *dest,
1661  int replace_at,
1662  int replace_len)
1663 {
1664  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1665  _dbus_assert (len >= 0);
1666  _dbus_assert (start <= real_source->len);
1667  _dbus_assert (len <= real_source->len - start);
1668  _dbus_assert (replace_at >= 0);
1669  _dbus_assert (replace_at <= real_dest->len);
1670  _dbus_assert (replace_len <= real_dest->len - replace_at);
1671 
1672  if (!copy (real_source, start, len,
1673  real_dest, replace_at))
1674  return FALSE;
1675 
1676  delete (real_dest, replace_at + len, replace_len);
1677 
1678  return TRUE;
1679 }
1680 
1695  unsigned char byte,
1696  DBusString *tail)
1697 {
1698  int byte_position;
1699  char byte_string[2] = "";
1700  int head_length;
1701  int tail_length;
1702 
1703  byte_string[0] = (char) byte;
1704 
1705  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1706  return FALSE;
1707 
1708  head_length = byte_position;
1709  tail_length = _dbus_string_get_length (source) - head_length - 1;
1710 
1711  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1712  tail, 0))
1713  return FALSE;
1714 
1715  /* remove the trailing delimiter byte from the head now.
1716  */
1717  if (!_dbus_string_set_length (source, head_length))
1718  return FALSE;
1719 
1720  return TRUE;
1721 }
1722 
1723 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1724  * Pennington, and Tom Tromey are the authors and authorized relicense.
1725  */
1726 
1732 #define UTF8_COMPUTE(Char, Mask, Len) \
1733  if (Char < 128) \
1734  { \
1735  Len = 1; \
1736  Mask = 0x7f; \
1737  } \
1738  else if ((Char & 0xe0) == 0xc0) \
1739  { \
1740  Len = 2; \
1741  Mask = 0x1f; \
1742  } \
1743  else if ((Char & 0xf0) == 0xe0) \
1744  { \
1745  Len = 3; \
1746  Mask = 0x0f; \
1747  } \
1748  else if ((Char & 0xf8) == 0xf0) \
1749  { \
1750  Len = 4; \
1751  Mask = 0x07; \
1752  } \
1753  else if ((Char & 0xfc) == 0xf8) \
1754  { \
1755  Len = 5; \
1756  Mask = 0x03; \
1757  } \
1758  else if ((Char & 0xfe) == 0xfc) \
1759  { \
1760  Len = 6; \
1761  Mask = 0x01; \
1762  } \
1763  else \
1764  { \
1765  Len = 0; \
1766  Mask = 0; \
1767  }
1768 
1773 #define UTF8_LENGTH(Char) \
1774  ((Char) < 0x80 ? 1 : \
1775  ((Char) < 0x800 ? 2 : \
1776  ((Char) < 0x10000 ? 3 : \
1777  ((Char) < 0x200000 ? 4 : \
1778  ((Char) < 0x4000000 ? 5 : 6)))))
1779 
1789 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
1790  (Result) = (Chars)[0] & (Mask); \
1791  for ((Count) = 1; (Count) < (Len); ++(Count)) \
1792  { \
1793  if (((Chars)[(Count)] & 0xc0) != 0x80) \
1794  { \
1795  (Result) = -1; \
1796  break; \
1797  } \
1798  (Result) <<= 6; \
1799  (Result) |= ((Chars)[(Count)] & 0x3f); \
1800  }
1801 
1818 #define UNICODE_VALID(Char) \
1819  ((Char) < 0x110000 && \
1820  (((Char) & 0xFFFFF800) != 0xD800) && \
1821  ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
1822  ((Char) & 0xFFFE) != 0xFFFE)
1823 
1824 #ifdef DBUS_BUILD_TESTS
1825 
1835 void
1836 _dbus_string_get_unichar (const DBusString *str,
1837  int start,
1838  dbus_unichar_t *ch_return,
1839  int *end_return)
1840 {
1841  int i, mask, len;
1842  dbus_unichar_t result;
1843  unsigned char c;
1844  unsigned char *p;
1846  _dbus_assert (start >= 0);
1847  _dbus_assert (start <= real->len);
1848 
1849  if (ch_return)
1850  *ch_return = 0;
1851  if (end_return)
1852  *end_return = real->len;
1853 
1854  mask = 0;
1855  p = real->str + start;
1856  c = *p;
1857 
1858  UTF8_COMPUTE (c, mask, len);
1859  if (len == 0)
1860  return;
1861  UTF8_GET (result, p, i, mask, len);
1862 
1863  if (result == (dbus_unichar_t)-1)
1864  return;
1865 
1866  if (ch_return)
1867  *ch_return = result;
1868  if (end_return)
1869  *end_return = start + len;
1870 }
1871 #endif /* DBUS_BUILD_TESTS */
1872 
1889  int start,
1890  const char *substr,
1891  int *found)
1892 {
1893  return _dbus_string_find_to (str, start,
1894  ((const DBusRealString*)str)->len,
1895  substr, found);
1896 }
1897 
1912  int start,
1913  int *found,
1914  int *found_len)
1915 {
1916  int i;
1917 
1919  _dbus_assert (start <= real->len);
1920  _dbus_assert (start >= 0);
1921 
1922  i = start;
1923  while (i < real->len)
1924  {
1925  if (real->str[i] == '\r')
1926  {
1927  if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1928  {
1929  if (found)
1930  *found = i;
1931  if (found_len)
1932  *found_len = 2;
1933  return TRUE;
1934  }
1935  else /* only "\r" */
1936  {
1937  if (found)
1938  *found = i;
1939  if (found_len)
1940  *found_len = 1;
1941  return TRUE;
1942  }
1943  }
1944  else if (real->str[i] == '\n') /* only "\n" */
1945  {
1946  if (found)
1947  *found = i;
1948  if (found_len)
1949  *found_len = 1;
1950  return TRUE;
1951  }
1952  ++i;
1953  }
1954 
1955  if (found)
1956  *found = real->len;
1957 
1958  if (found_len)
1959  *found_len = 0;
1960 
1961  return FALSE;
1962 }
1963 
1982  int start,
1983  int end,
1984  const char *substr,
1985  int *found)
1986 {
1987  int i;
1989  _dbus_assert (substr != NULL);
1990  _dbus_assert (start <= real->len);
1991  _dbus_assert (start >= 0);
1992  _dbus_assert (substr != NULL);
1993  _dbus_assert (end <= real->len);
1994  _dbus_assert (start <= end);
1995 
1996  /* we always "find" an empty string */
1997  if (*substr == '\0')
1998  {
1999  if (found)
2000  *found = start;
2001  return TRUE;
2002  }
2003 
2004  i = start;
2005  while (i < end)
2006  {
2007  if (real->str[i] == substr[0])
2008  {
2009  int j = i + 1;
2010 
2011  while (j < end)
2012  {
2013  if (substr[j - i] == '\0')
2014  break;
2015  else if (real->str[j] != substr[j - i])
2016  break;
2017 
2018  ++j;
2019  }
2020 
2021  if (substr[j - i] == '\0')
2022  {
2023  if (found)
2024  *found = i;
2025  return TRUE;
2026  }
2027  }
2028 
2029  ++i;
2030  }
2031 
2032  if (found)
2033  *found = end;
2034 
2035  return FALSE;
2036 }
2037 
2050  int start,
2051  int *found)
2052 {
2053  int i;
2055  _dbus_assert (start <= real->len);
2056  _dbus_assert (start >= 0);
2057 
2058  i = start;
2059  while (i < real->len)
2060  {
2061  if (real->str[i] == ' ' ||
2062  real->str[i] == '\t')
2063  {
2064  if (found)
2065  *found = i;
2066  return TRUE;
2067  }
2068 
2069  ++i;
2070  }
2071 
2072  if (found)
2073  *found = real->len;
2074 
2075  return FALSE;
2076 }
2077 
2086 void
2088  int start,
2089  int *end)
2090 {
2091  int i;
2093  _dbus_assert (start <= real->len);
2094  _dbus_assert (start >= 0);
2095 
2096  i = start;
2097  while (i < real->len)
2098  {
2099  if (!DBUS_IS_ASCII_BLANK (real->str[i]))
2100  break;
2101 
2102  ++i;
2103  }
2104 
2105  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
2106 
2107  if (end)
2108  *end = i;
2109 }
2110 
2111 
2120 void
2122  int start,
2123  int *end)
2124 {
2125  int i;
2127  _dbus_assert (start <= real->len);
2128  _dbus_assert (start >= 0);
2129 
2130  i = start;
2131  while (i < real->len)
2132  {
2133  if (!DBUS_IS_ASCII_WHITE (real->str[i]))
2134  break;
2135 
2136  ++i;
2137  }
2138 
2139  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
2140 
2141  if (end)
2142  *end = i;
2143 }
2144 
2153 void
2155  int end,
2156  int *start)
2157 {
2158  int i;
2160  _dbus_assert (end <= real->len);
2161  _dbus_assert (end >= 0);
2162 
2163  i = end;
2164  while (i > 0)
2165  {
2166  if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
2167  break;
2168  --i;
2169  }
2170 
2171  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
2172 
2173  if (start)
2174  *start = i;
2175 }
2176 
2194  DBusString *dest)
2195 {
2196  int eol, eol_len;
2197 
2198  _dbus_string_set_length (dest, 0);
2199 
2200  eol = 0;
2201  eol_len = 0;
2202  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
2203  {
2204  _dbus_assert (eol == _dbus_string_get_length (source));
2205  if (eol == 0)
2206  {
2207  /* If there's no newline and source has zero length, we're done */
2208  return FALSE;
2209  }
2210  /* otherwise, the last line of the file has no eol characters */
2211  }
2212 
2213  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
2214  * since find_eol returned TRUE
2215  */
2216 
2217  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
2218  return FALSE;
2219 
2220  /* remove line ending */
2221  if (!_dbus_string_set_length (dest, eol))
2222  {
2223  _dbus_assert_not_reached ("out of memory when shortening a string");
2224  return FALSE;
2225  }
2226 
2227  return TRUE;
2228 }
2229 
2230 #ifdef DBUS_BUILD_TESTS
2231 
2237 void
2238 _dbus_string_delete_first_word (DBusString *str)
2239 {
2240  int i;
2241 
2242  if (_dbus_string_find_blank (str, 0, &i))
2243  _dbus_string_skip_blank (str, i, &i);
2244 
2245  _dbus_string_delete (str, 0, i);
2246 }
2247 #endif
2248 
2249 #ifdef DBUS_BUILD_TESTS
2250 
2255 void
2256 _dbus_string_delete_leading_blanks (DBusString *str)
2257 {
2258  int i;
2259 
2260  _dbus_string_skip_blank (str, 0, &i);
2261 
2262  if (i > 0)
2263  _dbus_string_delete (str, 0, i);
2264 }
2265 #endif
2266 
2272 void
2274 {
2275  int i;
2276 
2277  _dbus_string_skip_white (str, 0, &i);
2278 
2279  if (i > 0)
2280  _dbus_string_delete (str, 0, i);
2281 
2283 
2284  _dbus_string_set_length (str, i);
2285 }
2286 
2298  const DBusString *b)
2299 {
2300  const unsigned char *ap;
2301  const unsigned char *bp;
2302  const unsigned char *a_end;
2303  const DBusRealString *real_a = (const DBusRealString*) a;
2304  const DBusRealString *real_b = (const DBusRealString*) b;
2307 
2308  if (real_a->len != real_b->len)
2309  return FALSE;
2310 
2311  ap = real_a->str;
2312  bp = real_b->str;
2313  a_end = real_a->str + real_a->len;
2314  while (ap != a_end)
2315  {
2316  if (*ap != *bp)
2317  return FALSE;
2318 
2319  ++ap;
2320  ++bp;
2321  }
2322 
2323  return TRUE;
2324 }
2325 
2341  const DBusString *b,
2342  int len)
2343 {
2344  const unsigned char *ap;
2345  const unsigned char *bp;
2346  const unsigned char *a_end;
2347  const DBusRealString *real_a = (const DBusRealString*) a;
2348  const DBusRealString *real_b = (const DBusRealString*) b;
2351 
2352  if (real_a->len != real_b->len &&
2353  (real_a->len < len || real_b->len < len))
2354  return FALSE;
2355 
2356  ap = real_a->str;
2357  bp = real_b->str;
2358  a_end = real_a->str + MIN (real_a->len, len);
2359  while (ap != a_end)
2360  {
2361  if (*ap != *bp)
2362  return FALSE;
2363 
2364  ++ap;
2365  ++bp;
2366  }
2367 
2368  return TRUE;
2369 }
2370 
2389  int a_start,
2390  int a_len,
2391  const DBusString *b,
2392  int b_start)
2393 {
2394  const unsigned char *ap;
2395  const unsigned char *bp;
2396  const unsigned char *a_end;
2397  const DBusRealString *real_a = (const DBusRealString*) a;
2398  const DBusRealString *real_b = (const DBusRealString*) b;
2401  _dbus_assert (a_start >= 0);
2402  _dbus_assert (a_len >= 0);
2403  _dbus_assert (a_start <= real_a->len);
2404  _dbus_assert (a_len <= real_a->len - a_start);
2405  _dbus_assert (b_start >= 0);
2406  _dbus_assert (b_start <= real_b->len);
2407 
2408  if (a_len > real_b->len - b_start)
2409  return FALSE;
2410 
2411  ap = real_a->str + a_start;
2412  bp = real_b->str + b_start;
2413  a_end = ap + a_len;
2414  while (ap != a_end)
2415  {
2416  if (*ap != *bp)
2417  return FALSE;
2418 
2419  ++ap;
2420  ++bp;
2421  }
2422 
2423  _dbus_assert (bp <= (real_b->str + real_b->len));
2424 
2425  return TRUE;
2426 }
2427 
2437  const char *c_str)
2438 {
2439  const unsigned char *ap;
2440  const unsigned char *bp;
2441  const unsigned char *a_end;
2442  const DBusRealString *real_a = (const DBusRealString*) a;
2444  _dbus_assert (c_str != NULL);
2445 
2446  ap = real_a->str;
2447  bp = (const unsigned char*) c_str;
2448  a_end = real_a->str + real_a->len;
2449  while (ap != a_end && *bp)
2450  {
2451  if (*ap != *bp)
2452  return FALSE;
2453 
2454  ++ap;
2455  ++bp;
2456  }
2457 
2458  if (ap != a_end || *bp)
2459  return FALSE;
2460 
2461  return TRUE;
2462 }
2463 
2464 #ifdef DBUS_BUILD_TESTS
2465 
2473 _dbus_string_starts_with_c_str (const DBusString *a,
2474  const char *c_str)
2475 {
2476  const unsigned char *ap;
2477  const unsigned char *bp;
2478  const unsigned char *a_end;
2479  const DBusRealString *real_a = (const DBusRealString*) a;
2481  _dbus_assert (c_str != NULL);
2482 
2483  ap = real_a->str;
2484  bp = (const unsigned char*) c_str;
2485  a_end = real_a->str + real_a->len;
2486  while (ap != a_end && *bp)
2487  {
2488  if (*ap != *bp)
2489  return FALSE;
2490 
2491  ++ap;
2492  ++bp;
2493  }
2494 
2495  if (*bp == '\0')
2496  return TRUE;
2497  else
2498  return FALSE;
2499 }
2500 #endif /* DBUS_BUILD_TESTS */
2501 
2512  int byte)
2513 {
2514  const char hexdigits[16] = {
2515  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2516  'a', 'b', 'c', 'd', 'e', 'f'
2517  };
2518 
2519  if (!_dbus_string_append_byte (str,
2520  hexdigits[(byte >> 4)]))
2521  return FALSE;
2522 
2523  if (!_dbus_string_append_byte (str,
2524  hexdigits[(byte & 0x0f)]))
2525  {
2527  _dbus_string_get_length (str) - 1);
2528  return FALSE;
2529  }
2530 
2531  return TRUE;
2532 }
2533 
2546  int start,
2547  DBusString *dest,
2548  int insert_at)
2549 {
2550  DBusString result;
2551  const unsigned char *p;
2552  const unsigned char *end;
2553  dbus_bool_t retval;
2554 
2555  _dbus_assert (start <= _dbus_string_get_length (source));
2556 
2557  if (!_dbus_string_init (&result))
2558  return FALSE;
2559 
2560  retval = FALSE;
2561 
2562  p = (const unsigned char*) _dbus_string_get_const_data (source);
2563  end = p + _dbus_string_get_length (source);
2564  p += start;
2565 
2566  while (p != end)
2567  {
2568  if (!_dbus_string_append_byte_as_hex (&result, *p))
2569  goto out;
2570 
2571  ++p;
2572  }
2573 
2574  if (!_dbus_string_move (&result, 0, dest, insert_at))
2575  goto out;
2576 
2577  retval = TRUE;
2578 
2579  out:
2580  _dbus_string_free (&result);
2581  return retval;
2582 }
2583 
2596  int start,
2597  int *end_return,
2598  DBusString *dest,
2599  int insert_at)
2600 {
2601  DBusString result;
2602  const unsigned char *p;
2603  const unsigned char *end;
2604  dbus_bool_t retval;
2605  dbus_bool_t high_bits;
2606 
2607  _dbus_assert (start <= _dbus_string_get_length (source));
2608 
2609  if (!_dbus_string_init (&result))
2610  return FALSE;
2611 
2612  retval = FALSE;
2613 
2614  high_bits = TRUE;
2615  p = (const unsigned char*) _dbus_string_get_const_data (source);
2616  end = p + _dbus_string_get_length (source);
2617  p += start;
2618 
2619  while (p != end)
2620  {
2621  unsigned int val;
2622 
2623  switch (*p)
2624  {
2625  case '0':
2626  val = 0;
2627  break;
2628  case '1':
2629  val = 1;
2630  break;
2631  case '2':
2632  val = 2;
2633  break;
2634  case '3':
2635  val = 3;
2636  break;
2637  case '4':
2638  val = 4;
2639  break;
2640  case '5':
2641  val = 5;
2642  break;
2643  case '6':
2644  val = 6;
2645  break;
2646  case '7':
2647  val = 7;
2648  break;
2649  case '8':
2650  val = 8;
2651  break;
2652  case '9':
2653  val = 9;
2654  break;
2655  case 'a':
2656  case 'A':
2657  val = 10;
2658  break;
2659  case 'b':
2660  case 'B':
2661  val = 11;
2662  break;
2663  case 'c':
2664  case 'C':
2665  val = 12;
2666  break;
2667  case 'd':
2668  case 'D':
2669  val = 13;
2670  break;
2671  case 'e':
2672  case 'E':
2673  val = 14;
2674  break;
2675  case 'f':
2676  case 'F':
2677  val = 15;
2678  break;
2679  default:
2680  goto done;
2681  }
2682 
2683  if (high_bits)
2684  {
2685  if (!_dbus_string_append_byte (&result,
2686  val << 4))
2687  goto out;
2688  }
2689  else
2690  {
2691  int len;
2692  unsigned char b;
2693 
2694  len = _dbus_string_get_length (&result);
2695 
2696  b = _dbus_string_get_byte (&result, len - 1);
2697 
2698  b |= val;
2699 
2700  _dbus_string_set_byte (&result, len - 1, b);
2701  }
2702 
2703  high_bits = !high_bits;
2704 
2705  ++p;
2706  }
2707 
2708  done:
2709  if (!_dbus_string_move (&result, 0, dest, insert_at))
2710  goto out;
2711 
2712  if (end_return)
2713  *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2714 
2715  retval = TRUE;
2716 
2717  out:
2718  _dbus_string_free (&result);
2719  return retval;
2720 }
2721 
2737  int start,
2738  int len)
2739 {
2740  const unsigned char *s;
2741  const unsigned char *end;
2743  _dbus_assert (start >= 0);
2744  _dbus_assert (start <= real->len);
2745  _dbus_assert (len >= 0);
2746 
2747  if (len > real->len - start)
2748  return FALSE;
2749 
2750  s = real->str + start;
2751  end = s + len;
2752  while (s != end)
2753  {
2754  if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2755  return FALSE;
2756 
2757  ++s;
2758  }
2759 
2760  return TRUE;
2761 }
2762 
2770 void
2772  int start,
2773  int len)
2774 {
2775  unsigned char *s;
2776  unsigned char *end;
2777  DBUS_STRING_PREAMBLE (str);
2778  _dbus_assert (start >= 0);
2779  _dbus_assert (start <= real->len);
2780  _dbus_assert (len >= 0);
2781  _dbus_assert (len <= real->len - start);
2782 
2783  s = real->str + start;
2784  end = s + len;
2785 
2786  while (s != end)
2787  {
2788  if (*s >= 'A' && *s <= 'Z')
2789  *s += 'a' - 'A';
2790  ++s;
2791  }
2792 }
2793 
2801 void
2803  int start,
2804  int len)
2805 {
2806  unsigned char *s;
2807  unsigned char *end;
2808  DBUS_STRING_PREAMBLE (str);
2809  _dbus_assert (start >= 0);
2810  _dbus_assert (start <= real->len);
2811  _dbus_assert (len >= 0);
2812  _dbus_assert (len <= real->len - start);
2813 
2814  s = real->str + start;
2815  end = s + len;
2816 
2817  while (s != end)
2818  {
2819  if (*s >= 'a' && *s <= 'z')
2820  *s += 'A' - 'a';
2821  ++s;
2822  }
2823 }
2824 
2842  int start,
2843  int len)
2844 {
2845  const unsigned char *p;
2846  const unsigned char *end;
2848  _dbus_assert (start >= 0);
2849  _dbus_assert (start <= real->len);
2850  _dbus_assert (len >= 0);
2851 
2852  /* we are doing _DBUS_UNLIKELY() here which might be
2853  * dubious in a generic library like GLib, but in D-Bus
2854  * we know we're validating messages and that it would
2855  * only be evil/broken apps that would have invalid
2856  * UTF-8. Also, this function seems to be a performance
2857  * bottleneck in profiles.
2858  */
2859 
2860  if (_DBUS_UNLIKELY (len > real->len - start))
2861  return FALSE;
2862 
2863  p = real->str + start;
2864  end = p + len;
2865 
2866  while (p < end)
2867  {
2868  int i, mask, char_len;
2869  dbus_unichar_t result;
2870 
2871  /* nul bytes considered invalid */
2872  if (*p == '\0')
2873  break;
2874 
2875  /* Special-case ASCII; this makes us go a lot faster in
2876  * D-Bus profiles where we are typically validating
2877  * function names and such. We have to know that
2878  * all following checks will pass for ASCII though,
2879  * comments follow ...
2880  */
2881  if (*p < 128)
2882  {
2883  ++p;
2884  continue;
2885  }
2886 
2887  UTF8_COMPUTE (*p, mask, char_len);
2888 
2889  if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2890  break;
2891 
2892  /* check that the expected number of bytes exists in the remaining length */
2893  if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2894  break;
2895 
2896  UTF8_GET (result, p, i, mask, char_len);
2897 
2898  /* Check for overlong UTF-8 */
2899  if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2900  break;
2901 #if 0
2902  /* The UNICODE_VALID check below will catch this */
2903  if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2904  break;
2905 #endif
2906 
2907  if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2908  break;
2909 
2910  /* UNICODE_VALID should have caught it */
2911  _dbus_assert (result != (dbus_unichar_t)-1);
2912 
2913  p += char_len;
2914  }
2915 
2916  /* See that we covered the entire length if a length was
2917  * passed in
2918  */
2919  if (_DBUS_UNLIKELY (p != end))
2920  return FALSE;
2921  else
2922  return TRUE;
2923 }
2924 
2940  int start,
2941  int len)
2942 {
2943  const unsigned char *s;
2944  const unsigned char *end;
2946  _dbus_assert (start >= 0);
2947  _dbus_assert (len >= 0);
2948  _dbus_assert (start <= real->len);
2949 
2950  if (len > real->len - start)
2951  return FALSE;
2952 
2953  s = real->str + start;
2954  end = s + len;
2955  while (s != end)
2956  {
2957  if (_DBUS_UNLIKELY (*s != '\0'))
2958  return FALSE;
2959  ++s;
2960  }
2961 
2962  return TRUE;
2963 }
2964 
2970 void
2972 {
2973  DBUS_STRING_PREAMBLE (str);
2974 
2975  memset (real->str - real->align_offset, '\0', real->allocated);
2976 }
2979 /* tests are in dbus-string-util.c */