D-Bus  1.6.12
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 
157  real->constant = FALSE;
158  real->locked = FALSE;
159  real->invalid = FALSE;
160  real->align_offset = 0;
161 
162  fixup_alignment (real);
163 
164  return TRUE;
165 }
166 
176 {
177  return _dbus_string_init_preallocated (str, 0);
178 }
179 
189 void
191  const char *value)
192 {
193  _dbus_assert (value != NULL);
194 
195  _dbus_string_init_const_len (str, value,
196  strlen (value));
197 }
198 
209 void
211  const char *value,
212  int len)
213 {
214  DBusRealString *real;
215 
216  _dbus_assert (str != NULL);
217  _dbus_assert (len == 0 || value != NULL);
219  _dbus_assert (len >= 0);
220 
221  real = (DBusRealString*) str;
222 
223  real->str = (unsigned char*) value;
224  real->len = len;
225  real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
226  real->constant = TRUE;
227  real->locked = TRUE;
228  real->invalid = FALSE;
229  real->align_offset = 0;
230 
231  /* We don't require const strings to be 8-byte aligned as the
232  * memory is coming from elsewhere.
233  */
234 }
235 
241 void
243 {
244  DBusRealString *real = (DBusRealString*) str;
246 
247  if (real->constant)
248  return;
249  dbus_free (real->str - real->align_offset);
250 
251  real->invalid = TRUE;
252 }
253 
254 static dbus_bool_t
255 compact (DBusRealString *real,
256  int max_waste)
257 {
258  unsigned char *new_str;
259  int new_allocated;
260  int waste;
261 
262  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
263 
264  if (waste <= max_waste)
265  return TRUE;
266 
267  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
268 
269  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
270  if (_DBUS_UNLIKELY (new_str == NULL))
271  return FALSE;
272 
273  real->str = new_str + real->align_offset;
274  real->allocated = new_allocated;
275  fixup_alignment (real);
276 
277  return TRUE;
278 }
279 
280 #ifdef DBUS_BUILD_TESTS
281 /* Not using this feature at the moment,
282  * so marked DBUS_BUILD_TESTS-only
283  */
293 void
294 _dbus_string_lock (DBusString *str)
295 {
296  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
297 
298  real->locked = TRUE;
299 
300  /* Try to realloc to avoid excess memory usage, since
301  * we know we won't change the string further
302  */
303 #define MAX_WASTE 48
304  compact (real, MAX_WASTE);
305 }
306 #endif /* DBUS_BUILD_TESTS */
307 
308 static dbus_bool_t
309 reallocate_for_length (DBusRealString *real,
310  int new_length)
311 {
312  int new_allocated;
313  unsigned char *new_str;
314 
315  /* at least double our old allocation to avoid O(n), avoiding
316  * overflow
317  */
318  if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
319  new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
320  else
321  new_allocated = real->allocated * 2;
322 
323  /* if you change the code just above here, run the tests without
324  * the following assert-only hack before you commit
325  */
326  /* This is keyed off asserts in addition to tests so when you
327  * disable asserts to profile, you don't get this destroyer
328  * of profiles.
329  */
330 #ifdef DBUS_DISABLE_ASSERT
331 #else
332 #ifdef DBUS_BUILD_TESTS
333  new_allocated = 0; /* ensure a realloc every time so that we go
334  * through all malloc failure codepaths
335  */
336 #endif /* DBUS_BUILD_TESTS */
337 #endif /* !DBUS_DISABLE_ASSERT */
338 
339  /* But be sure we always alloc at least space for the new length */
340  new_allocated = MAX (new_allocated,
341  new_length + _DBUS_STRING_ALLOCATION_PADDING);
342 
343  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
344  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
345  if (_DBUS_UNLIKELY (new_str == NULL))
346  return FALSE;
347 
348  real->str = new_str + real->align_offset;
349  real->allocated = new_allocated;
350  fixup_alignment (real);
351 
352  return TRUE;
353 }
354 
368  int max_waste)
369 {
370  DBUS_STRING_PREAMBLE (str);
371 
372  return compact (real, max_waste);
373 }
374 
375 static dbus_bool_t
376 set_length (DBusRealString *real,
377  int new_length)
378 {
379  /* Note, we are setting the length not including nul termination */
380 
381  /* exceeding max length is the same as failure to allocate memory */
382  if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
383  return FALSE;
384  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
385  _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
386  return FALSE;
387  else
388  {
389  real->len = new_length;
390  real->str[new_length] = '\0';
391  return TRUE;
392  }
393 }
394 
395 static dbus_bool_t
396 open_gap (int len,
397  DBusRealString *dest,
398  int insert_at)
399 {
400  if (len == 0)
401  return TRUE;
402 
403  if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
404  return FALSE; /* detected overflow of dest->len + len below */
405 
406  if (!set_length (dest, dest->len + len))
407  return FALSE;
408 
409  memmove (dest->str + insert_at + len,
410  dest->str + insert_at,
411  dest->len - len - insert_at);
412 
413  return TRUE;
414 }
415 
416 #ifndef _dbus_string_get_data
417 
428 char*
430 {
431  DBUS_STRING_PREAMBLE (str);
432 
433  return (char*) real->str;
434 }
435 #endif /* _dbus_string_get_data */
436 
437 /* only do the function if we don't have the macro */
438 #ifndef _dbus_string_get_const_data
439 
445 const char*
447 {
449 
450  return (const char*) real->str;
451 }
452 #endif /* _dbus_string_get_const_data */
453 
467 char*
469  int start,
470  int len)
471 {
472  DBUS_STRING_PREAMBLE (str);
473  _dbus_assert (start >= 0);
474  _dbus_assert (len >= 0);
475  _dbus_assert (start <= real->len);
476  _dbus_assert (len <= real->len - start);
477 
478  return (char*) real->str + start;
479 }
480 
481 /* only do the function if we don't have the macro */
482 #ifndef _dbus_string_get_const_data_len
483 
491 const char*
493  int start,
494  int len)
495 {
497  _dbus_assert (start >= 0);
498  _dbus_assert (len >= 0);
499  _dbus_assert (start <= real->len);
500  _dbus_assert (len <= real->len - start);
501 
502  return (const char*) real->str + start;
503 }
504 #endif /* _dbus_string_get_const_data_len */
505 
506 /* only do the function if we don't have the macro */
507 #ifndef _dbus_string_set_byte
508 
515 void
517  int i,
518  unsigned char byte)
519 {
520  DBUS_STRING_PREAMBLE (str);
521  _dbus_assert (i < real->len);
522  _dbus_assert (i >= 0);
523 
524  real->str[i] = byte;
525 }
526 #endif /* _dbus_string_set_byte */
527 
528 /* only have the function if we didn't create a macro */
529 #ifndef _dbus_string_get_byte
530 
539 unsigned char
541  int start)
542 {
544  _dbus_assert (start <= real->len);
545  _dbus_assert (start >= 0);
546 
547  return real->str[start];
548 }
549 #endif /* _dbus_string_get_byte */
550 
563  int i,
564  int n_bytes,
565  unsigned char byte)
566 {
567  DBUS_STRING_PREAMBLE (str);
568  _dbus_assert (i <= real->len);
569  _dbus_assert (i >= 0);
570  _dbus_assert (n_bytes >= 0);
571 
572  if (n_bytes == 0)
573  return TRUE;
574 
575  if (!open_gap (n_bytes, real, i))
576  return FALSE;
577 
578  memset (real->str + i, byte, n_bytes);
579 
580  return TRUE;
581 }
582 
593  int i,
594  unsigned char byte)
595 {
596  DBUS_STRING_PREAMBLE (str);
597  _dbus_assert (i <= real->len);
598  _dbus_assert (i >= 0);
599 
600  if (!open_gap (1, real, i))
601  return FALSE;
602 
603  real->str[i] = byte;
604 
605  return TRUE;
606 }
607 
620  char **data_return)
621 {
622  DBUS_STRING_PREAMBLE (str);
623  _dbus_assert (data_return != NULL);
624 
625  undo_alignment (real);
626 
627  *data_return = (char*) real->str;
628 
629  /* reset the string */
630  if (!_dbus_string_init (str))
631  {
632  /* hrm, put it back then */
633  real->str = (unsigned char*) *data_return;
634  *data_return = NULL;
635  fixup_alignment (real);
636  return FALSE;
637  }
638 
639  return TRUE;
640 }
641 
651  char **data_return)
652 {
654  _dbus_assert (data_return != NULL);
655 
656  *data_return = dbus_malloc (real->len + 1);
657  if (*data_return == NULL)
658  return FALSE;
659 
660  memcpy (*data_return, real->str, real->len + 1);
661 
662  return TRUE;
663 }
664 
674 void
676  char *buffer,
677  int avail_len)
678 {
680 
681  _dbus_assert (avail_len >= 0);
682  _dbus_assert (avail_len >= real->len);
683 
684  memcpy (buffer, real->str, real->len);
685 }
686 
696 void
698  char *buffer,
699  int avail_len)
700 {
702 
703  _dbus_assert (avail_len >= 0);
704  _dbus_assert (avail_len > real->len);
705 
706  memcpy (buffer, real->str, real->len+1);
707 }
708 
709 /* Only have the function if we don't have the macro */
710 #ifndef _dbus_string_get_length
711 
716 int
718 {
720 
721  return real->len;
722 }
723 #endif /* !_dbus_string_get_length */
724 
739  int additional_length)
740 {
741  DBUS_STRING_PREAMBLE (str);
742  _dbus_assert (additional_length >= 0);
743 
744  if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
745  return FALSE; /* would overflow */
746 
747  return set_length (real,
748  real->len + additional_length);
749 }
750 
757 void
759  int length_to_remove)
760 {
761  DBUS_STRING_PREAMBLE (str);
762  _dbus_assert (length_to_remove >= 0);
763  _dbus_assert (length_to_remove <= real->len);
764 
765  set_length (real,
766  real->len - length_to_remove);
767 }
768 
781  int length)
782 {
783  DBUS_STRING_PREAMBLE (str);
784  _dbus_assert (length >= 0);
785 
786  return set_length (real, length);
787 }
788 
789 static dbus_bool_t
790 align_insert_point_then_open_gap (DBusString *str,
791  int *insert_at_p,
792  int alignment,
793  int gap_size)
794 {
795  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
796  unsigned long gap_pos;
797  int insert_at;
798  int delta;
799  DBUS_STRING_PREAMBLE (str);
800  _dbus_assert (alignment >= 1);
801  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
802 
803  insert_at = *insert_at_p;
804 
805  _dbus_assert (insert_at <= real->len);
806 
807  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
808  new_len = real->len + (gap_pos - insert_at) + gap_size;
809 
810  if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
811  return FALSE;
812 
813  delta = new_len - real->len;
814  _dbus_assert (delta >= 0);
815 
816  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
817  {
818  _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
819  return TRUE;
820  }
821 
822  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
823  real, insert_at)))
824  return FALSE;
825 
826  /* nul the padding if we had to add any padding */
827  if (gap_size < delta)
828  {
829  memset (&real->str[insert_at], '\0',
830  gap_pos - insert_at);
831  }
832 
833  *insert_at_p = gap_pos;
834 
835  return TRUE;
836 }
837 
838 static dbus_bool_t
839 align_length_then_lengthen (DBusString *str,
840  int alignment,
841  int then_lengthen_by)
842 {
843  int insert_at;
844 
845  insert_at = _dbus_string_get_length (str);
846 
847  return align_insert_point_then_open_gap (str,
848  &insert_at,
849  alignment, then_lengthen_by);
850 }
851 
862  int alignment)
863 {
864  return align_length_then_lengthen (str, alignment, 0);
865 }
866 
878  int extra_bytes)
879 {
880  if (!_dbus_string_lengthen (str, extra_bytes))
881  return FALSE;
882  _dbus_string_shorten (str, extra_bytes);
883 
884  return TRUE;
885 }
886 
887 static dbus_bool_t
888 append (DBusRealString *real,
889  const char *buffer,
890  int buffer_len)
891 {
892  if (buffer_len == 0)
893  return TRUE;
894 
895  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
896  return FALSE;
897 
898  memcpy (real->str + (real->len - buffer_len),
899  buffer,
900  buffer_len);
901 
902  return TRUE;
903 }
904 
914  const char *buffer)
915 {
916  unsigned long buffer_len;
917 
918  DBUS_STRING_PREAMBLE (str);
919  _dbus_assert (buffer != NULL);
920 
921  buffer_len = strlen (buffer);
922  if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
923  return FALSE;
924 
925  return append (real, buffer, buffer_len);
926 }
927 
929 #define ASSIGN_2_OCTETS(p, octets) \
930  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
931 
933 #define ASSIGN_4_OCTETS(p, octets) \
934  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
935 
936 #ifdef DBUS_HAVE_INT64
937 
938 #define ASSIGN_8_OCTETS(p, octets) \
939  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
940 #else
941 
942 #define ASSIGN_8_OCTETS(p, octets) \
943 do { \
944  unsigned char *b; \
945  \
946  b = p; \
947  \
948  *b++ = octets[0]; \
949  *b++ = octets[1]; \
950  *b++ = octets[2]; \
951  *b++ = octets[3]; \
952  *b++ = octets[4]; \
953  *b++ = octets[5]; \
954  *b++ = octets[6]; \
955  *b++ = octets[7]; \
956  _dbus_assert (b == p + 8); \
957 } while (0)
958 #endif /* DBUS_HAVE_INT64 */
959 
971  int insert_at,
972  const unsigned char octets[4])
973 {
974  DBUS_STRING_PREAMBLE (str);
975 
976  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
977  return FALSE;
978 
979  ASSIGN_2_OCTETS (real->str + insert_at, octets);
980 
981  return TRUE;
982 }
983 
995  int insert_at,
996  const unsigned char octets[4])
997 {
998  DBUS_STRING_PREAMBLE (str);
999 
1000  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1001  return FALSE;
1002 
1003  ASSIGN_4_OCTETS (real->str + insert_at, octets);
1004 
1005  return TRUE;
1006 }
1007 
1019  int insert_at,
1020  const unsigned char octets[8])
1021 {
1022  DBUS_STRING_PREAMBLE (str);
1023 
1024  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1025  return FALSE;
1026 
1027  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1028 
1029  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1030 
1031  return TRUE;
1032 }
1033 
1034 
1047  int *insert_at,
1048  int alignment)
1049 {
1050  DBUS_STRING_PREAMBLE (str);
1051 
1052  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1053  return FALSE;
1054 
1055  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1056 
1057  return TRUE;
1058 }
1059 
1071  const char *format,
1072  va_list args)
1073 {
1074  int len;
1075  va_list args_copy;
1076 
1077  DBUS_STRING_PREAMBLE (str);
1078 
1079  DBUS_VA_COPY (args_copy, args);
1080 
1081  /* Measure the message length without terminating nul */
1082  len = _dbus_printf_string_upper_bound (format, args);
1083 
1084  if (len < 0)
1085  return FALSE;
1086 
1087  if (!_dbus_string_lengthen (str, len))
1088  {
1089  /* don't leak the copy */
1090  va_end (args_copy);
1091  return FALSE;
1092  }
1093 
1094  vsprintf ((char*) (real->str + (real->len - len)),
1095  format, args_copy);
1096 
1097  va_end (args_copy);
1098 
1099  return TRUE;
1100 }
1101 
1112  const char *format,
1113  ...)
1114 {
1115  va_list args;
1116  dbus_bool_t retval;
1117 
1118  va_start (args, format);
1119  retval = _dbus_string_append_printf_valist (str, format, args);
1120  va_end (args);
1121 
1122  return retval;
1123 }
1124 
1135  const char *buffer,
1136  int len)
1137 {
1138  DBUS_STRING_PREAMBLE (str);
1139  _dbus_assert (buffer != NULL);
1140  _dbus_assert (len >= 0);
1141 
1142  return append (real, buffer, len);
1143 }
1144 
1155  unsigned char byte)
1156 {
1157  DBUS_STRING_PREAMBLE (str);
1158 
1159  if (!set_length (real, real->len + 1))
1160  return FALSE;
1161 
1162  real->str[real->len-1] = byte;
1163 
1164  return TRUE;
1165 }
1166 
1167 static void
1168 delete (DBusRealString *real,
1169  int start,
1170  int len)
1171 {
1172  if (len == 0)
1173  return;
1174 
1175  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1176  real->len -= len;
1177  real->str[real->len] = '\0';
1178 }
1179 
1189 void
1191  int start,
1192  int len)
1193 {
1194  DBUS_STRING_PREAMBLE (str);
1195  _dbus_assert (start >= 0);
1196  _dbus_assert (len >= 0);
1197  _dbus_assert (start <= real->len);
1198  _dbus_assert (len <= real->len - start);
1199 
1200  delete (real, start, len);
1201 }
1202 
1203 static dbus_bool_t
1204 copy (DBusRealString *source,
1205  int start,
1206  int len,
1207  DBusRealString *dest,
1208  int insert_at)
1209 {
1210  if (len == 0)
1211  return TRUE;
1212 
1213  if (!open_gap (len, dest, insert_at))
1214  return FALSE;
1215 
1216  memmove (dest->str + insert_at,
1217  source->str + start,
1218  len);
1219 
1220  return TRUE;
1221 }
1222 
1232 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1233  DBusRealString *real_source = (DBusRealString*) source; \
1234  DBusRealString *real_dest = (DBusRealString*) dest; \
1235  _dbus_assert ((source) != (dest)); \
1236  DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1237  DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1238  _dbus_assert (!real_dest->constant); \
1239  _dbus_assert (!real_dest->locked); \
1240  _dbus_assert ((start) >= 0); \
1241  _dbus_assert ((start) <= real_source->len); \
1242  _dbus_assert ((insert_at) >= 0); \
1243  _dbus_assert ((insert_at) <= real_dest->len)
1244 
1257  int start,
1258  DBusString *dest,
1259  int insert_at)
1260 {
1261  DBusRealString *real_source = (DBusRealString*) source;
1262  _dbus_assert (start <= real_source->len);
1263 
1264  return _dbus_string_move_len (source, start,
1265  real_source->len - start,
1266  dest, insert_at);
1267 }
1268 
1281  int start,
1282  DBusString *dest,
1283  int insert_at)
1284 {
1285  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1286 
1287  return copy (real_source, start,
1288  real_source->len - start,
1289  real_dest,
1290  insert_at);
1291 }
1292 
1306  int start,
1307  int len,
1308  DBusString *dest,
1309  int insert_at)
1310 
1311 {
1312  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1313  _dbus_assert (len >= 0);
1314  _dbus_assert ((start + len) <= real_source->len);
1315 
1316 
1317  if (len == 0)
1318  {
1319  return TRUE;
1320  }
1321  else if (start == 0 &&
1322  len == real_source->len &&
1323  real_dest->len == 0)
1324  {
1325  /* Short-circuit moving an entire existing string to an empty string
1326  * by just swapping the buffers.
1327  */
1328  /* we assume ->constant doesn't matter as you can't have
1329  * a constant string involved in a move.
1330  */
1331 #define ASSIGN_DATA(a, b) do { \
1332  (a)->str = (b)->str; \
1333  (a)->len = (b)->len; \
1334  (a)->allocated = (b)->allocated; \
1335  (a)->align_offset = (b)->align_offset; \
1336  } while (0)
1337 
1338  DBusRealString tmp;
1339 
1340  ASSIGN_DATA (&tmp, real_source);
1341  ASSIGN_DATA (real_source, real_dest);
1342  ASSIGN_DATA (real_dest, &tmp);
1343 
1344  return TRUE;
1345  }
1346  else
1347  {
1348  if (!copy (real_source, start, len,
1349  real_dest,
1350  insert_at))
1351  return FALSE;
1352 
1353  delete (real_source, start,
1354  len);
1355 
1356  return TRUE;
1357  }
1358 }
1359 
1373  int start,
1374  int len,
1375  DBusString *dest,
1376  int insert_at)
1377 {
1378  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1379  _dbus_assert (len >= 0);
1380  _dbus_assert (start <= real_source->len);
1381  _dbus_assert (len <= real_source->len - start);
1382 
1383  return copy (real_source, start, len,
1384  real_dest,
1385  insert_at);
1386 }
1387 
1402  int start,
1403  int len,
1404  DBusString *dest,
1405  int replace_at,
1406  int replace_len)
1407 {
1408  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1409  _dbus_assert (len >= 0);
1410  _dbus_assert (start <= real_source->len);
1411  _dbus_assert (len <= real_source->len - start);
1412  _dbus_assert (replace_at >= 0);
1413  _dbus_assert (replace_at <= real_dest->len);
1414  _dbus_assert (replace_len <= real_dest->len - replace_at);
1415 
1416  if (len == replace_len)
1417  {
1418  memmove (real_dest->str + replace_at,
1419  real_source->str + start, len);
1420  }
1421  else if (len < replace_len)
1422  {
1423  memmove (real_dest->str + replace_at,
1424  real_source->str + start, len);
1425  delete (real_dest, replace_at + len,
1426  replace_len - len);
1427  }
1428  else
1429  {
1430  int diff;
1431 
1432  _dbus_assert (len > replace_len);
1433 
1434  diff = len - replace_len;
1435 
1436  /* First of all we check if destination string can be enlarged as
1437  * required, then we overwrite previous bytes
1438  */
1439 
1440  if (!copy (real_source, start + replace_len, diff,
1441  real_dest, replace_at + replace_len))
1442  return FALSE;
1443 
1444  memmove (real_dest->str + replace_at,
1445  real_source->str + start, replace_len);
1446  }
1447 
1448  return TRUE;
1449 }
1450 
1465  unsigned char byte,
1466  DBusString *tail)
1467 {
1468  int byte_position;
1469  char byte_string[2] = "";
1470  int head_length;
1471  int tail_length;
1472 
1473  byte_string[0] = (char) byte;
1474 
1475  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1476  return FALSE;
1477 
1478  head_length = byte_position;
1479  tail_length = _dbus_string_get_length (source) - head_length - 1;
1480 
1481  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1482  tail, 0))
1483  return FALSE;
1484 
1485  /* remove the trailing delimiter byte from the head now.
1486  */
1487  if (!_dbus_string_set_length (source, head_length))
1488  return FALSE;
1489 
1490  return TRUE;
1491 }
1492 
1493 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1494  * Pennington, and Tom Tromey are the authors and authorized relicense.
1495  */
1496 
1502 #define UTF8_COMPUTE(Char, Mask, Len) \
1503  if (Char < 128) \
1504  { \
1505  Len = 1; \
1506  Mask = 0x7f; \
1507  } \
1508  else if ((Char & 0xe0) == 0xc0) \
1509  { \
1510  Len = 2; \
1511  Mask = 0x1f; \
1512  } \
1513  else if ((Char & 0xf0) == 0xe0) \
1514  { \
1515  Len = 3; \
1516  Mask = 0x0f; \
1517  } \
1518  else if ((Char & 0xf8) == 0xf0) \
1519  { \
1520  Len = 4; \
1521  Mask = 0x07; \
1522  } \
1523  else if ((Char & 0xfc) == 0xf8) \
1524  { \
1525  Len = 5; \
1526  Mask = 0x03; \
1527  } \
1528  else if ((Char & 0xfe) == 0xfc) \
1529  { \
1530  Len = 6; \
1531  Mask = 0x01; \
1532  } \
1533  else \
1534  { \
1535  Len = 0; \
1536  Mask = 0; \
1537  }
1538 
1543 #define UTF8_LENGTH(Char) \
1544  ((Char) < 0x80 ? 1 : \
1545  ((Char) < 0x800 ? 2 : \
1546  ((Char) < 0x10000 ? 3 : \
1547  ((Char) < 0x200000 ? 4 : \
1548  ((Char) < 0x4000000 ? 5 : 6)))))
1549 
1559 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
1560  (Result) = (Chars)[0] & (Mask); \
1561  for ((Count) = 1; (Count) < (Len); ++(Count)) \
1562  { \
1563  if (((Chars)[(Count)] & 0xc0) != 0x80) \
1564  { \
1565  (Result) = -1; \
1566  break; \
1567  } \
1568  (Result) <<= 6; \
1569  (Result) |= ((Chars)[(Count)] & 0x3f); \
1570  }
1571 
1582 #define UNICODE_VALID(Char) \
1583  ((Char) < 0x110000 && \
1584  (((Char) & 0xFFFFF800) != 0xD800))
1585 
1602  int start,
1603  const char *substr,
1604  int *found)
1605 {
1606  return _dbus_string_find_to (str, start,
1607  ((const DBusRealString*)str)->len,
1608  substr, found);
1609 }
1610 
1625  int start,
1626  int *found,
1627  int *found_len)
1628 {
1629  int i;
1630 
1632  _dbus_assert (start <= real->len);
1633  _dbus_assert (start >= 0);
1634 
1635  i = start;
1636  while (i < real->len)
1637  {
1638  if (real->str[i] == '\r')
1639  {
1640  if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1641  {
1642  if (found)
1643  *found = i;
1644  if (found_len)
1645  *found_len = 2;
1646  return TRUE;
1647  }
1648  else /* only "\r" */
1649  {
1650  if (found)
1651  *found = i;
1652  if (found_len)
1653  *found_len = 1;
1654  return TRUE;
1655  }
1656  }
1657  else if (real->str[i] == '\n') /* only "\n" */
1658  {
1659  if (found)
1660  *found = i;
1661  if (found_len)
1662  *found_len = 1;
1663  return TRUE;
1664  }
1665  ++i;
1666  }
1667 
1668  if (found)
1669  *found = real->len;
1670 
1671  if (found_len)
1672  *found_len = 0;
1673 
1674  return FALSE;
1675 }
1676 
1695  int start,
1696  int end,
1697  const char *substr,
1698  int *found)
1699 {
1700  int i;
1702  _dbus_assert (substr != NULL);
1703  _dbus_assert (start <= real->len);
1704  _dbus_assert (start >= 0);
1705  _dbus_assert (substr != NULL);
1706  _dbus_assert (end <= real->len);
1707  _dbus_assert (start <= end);
1708 
1709  /* we always "find" an empty string */
1710  if (*substr == '\0')
1711  {
1712  if (found)
1713  *found = start;
1714  return TRUE;
1715  }
1716 
1717  i = start;
1718  while (i < end)
1719  {
1720  if (real->str[i] == substr[0])
1721  {
1722  int j = i + 1;
1723 
1724  while (j < end)
1725  {
1726  if (substr[j - i] == '\0')
1727  break;
1728  else if (real->str[j] != substr[j - i])
1729  break;
1730 
1731  ++j;
1732  }
1733 
1734  if (substr[j - i] == '\0')
1735  {
1736  if (found)
1737  *found = i;
1738  return TRUE;
1739  }
1740  }
1741 
1742  ++i;
1743  }
1744 
1745  if (found)
1746  *found = end;
1747 
1748  return FALSE;
1749 }
1750 
1763  int start,
1764  int *found)
1765 {
1766  int i;
1768  _dbus_assert (start <= real->len);
1769  _dbus_assert (start >= 0);
1770 
1771  i = start;
1772  while (i < real->len)
1773  {
1774  if (real->str[i] == ' ' ||
1775  real->str[i] == '\t')
1776  {
1777  if (found)
1778  *found = i;
1779  return TRUE;
1780  }
1781 
1782  ++i;
1783  }
1784 
1785  if (found)
1786  *found = real->len;
1787 
1788  return FALSE;
1789 }
1790 
1799 void
1801  int start,
1802  int *end)
1803 {
1804  int i;
1806  _dbus_assert (start <= real->len);
1807  _dbus_assert (start >= 0);
1808 
1809  i = start;
1810  while (i < real->len)
1811  {
1812  if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1813  break;
1814 
1815  ++i;
1816  }
1817 
1818  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1819 
1820  if (end)
1821  *end = i;
1822 }
1823 
1824 
1833 void
1835  int start,
1836  int *end)
1837 {
1838  int i;
1840  _dbus_assert (start <= real->len);
1841  _dbus_assert (start >= 0);
1842 
1843  i = start;
1844  while (i < real->len)
1845  {
1846  if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1847  break;
1848 
1849  ++i;
1850  }
1851 
1852  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1853 
1854  if (end)
1855  *end = i;
1856 }
1857 
1866 void
1868  int end,
1869  int *start)
1870 {
1871  int i;
1873  _dbus_assert (end <= real->len);
1874  _dbus_assert (end >= 0);
1875 
1876  i = end;
1877  while (i > 0)
1878  {
1879  if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1880  break;
1881  --i;
1882  }
1883 
1884  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1885 
1886  if (start)
1887  *start = i;
1888 }
1889 
1907  DBusString *dest)
1908 {
1909  int eol, eol_len;
1910 
1911  _dbus_string_set_length (dest, 0);
1912 
1913  eol = 0;
1914  eol_len = 0;
1915  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1916  {
1917  _dbus_assert (eol == _dbus_string_get_length (source));
1918  if (eol == 0)
1919  {
1920  /* If there's no newline and source has zero length, we're done */
1921  return FALSE;
1922  }
1923  /* otherwise, the last line of the file has no eol characters */
1924  }
1925 
1926  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1927  * since find_eol returned TRUE
1928  */
1929 
1930  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1931  return FALSE;
1932 
1933  /* remove line ending */
1934  if (!_dbus_string_set_length (dest, eol))
1935  {
1936  _dbus_assert_not_reached ("out of memory when shortening a string");
1937  return FALSE;
1938  }
1939 
1940  return TRUE;
1941 }
1942 
1943 #ifdef DBUS_BUILD_TESTS
1944 
1950 void
1951 _dbus_string_delete_first_word (DBusString *str)
1952 {
1953  int i;
1954 
1955  if (_dbus_string_find_blank (str, 0, &i))
1956  _dbus_string_skip_blank (str, i, &i);
1957 
1958  _dbus_string_delete (str, 0, i);
1959 }
1960 #endif
1961 
1962 #ifdef DBUS_BUILD_TESTS
1963 
1968 void
1969 _dbus_string_delete_leading_blanks (DBusString *str)
1970 {
1971  int i;
1972 
1973  _dbus_string_skip_blank (str, 0, &i);
1974 
1975  if (i > 0)
1976  _dbus_string_delete (str, 0, i);
1977 }
1978 #endif
1979 
1985 void
1987 {
1988  int i;
1989 
1990  _dbus_string_skip_white (str, 0, &i);
1991 
1992  if (i > 0)
1993  _dbus_string_delete (str, 0, i);
1994 
1996 
1997  _dbus_string_set_length (str, i);
1998 }
1999 
2011  const DBusString *b)
2012 {
2013  const unsigned char *ap;
2014  const unsigned char *bp;
2015  const unsigned char *a_end;
2016  const DBusRealString *real_a = (const DBusRealString*) a;
2017  const DBusRealString *real_b = (const DBusRealString*) b;
2020 
2021  if (real_a->len != real_b->len)
2022  return FALSE;
2023 
2024  ap = real_a->str;
2025  bp = real_b->str;
2026  a_end = real_a->str + real_a->len;
2027  while (ap != a_end)
2028  {
2029  if (*ap != *bp)
2030  return FALSE;
2031 
2032  ++ap;
2033  ++bp;
2034  }
2035 
2036  return TRUE;
2037 }
2038 
2054  const DBusString *b,
2055  int len)
2056 {
2057  const unsigned char *ap;
2058  const unsigned char *bp;
2059  const unsigned char *a_end;
2060  const DBusRealString *real_a = (const DBusRealString*) a;
2061  const DBusRealString *real_b = (const DBusRealString*) b;
2064 
2065  if (real_a->len != real_b->len &&
2066  (real_a->len < len || real_b->len < len))
2067  return FALSE;
2068 
2069  ap = real_a->str;
2070  bp = real_b->str;
2071  a_end = real_a->str + MIN (real_a->len, len);
2072  while (ap != a_end)
2073  {
2074  if (*ap != *bp)
2075  return FALSE;
2076 
2077  ++ap;
2078  ++bp;
2079  }
2080 
2081  return TRUE;
2082 }
2083 
2102  int a_start,
2103  int a_len,
2104  const DBusString *b,
2105  int b_start)
2106 {
2107  const unsigned char *ap;
2108  const unsigned char *bp;
2109  const unsigned char *a_end;
2110  const DBusRealString *real_a = (const DBusRealString*) a;
2111  const DBusRealString *real_b = (const DBusRealString*) b;
2114  _dbus_assert (a_start >= 0);
2115  _dbus_assert (a_len >= 0);
2116  _dbus_assert (a_start <= real_a->len);
2117  _dbus_assert (a_len <= real_a->len - a_start);
2118  _dbus_assert (b_start >= 0);
2119  _dbus_assert (b_start <= real_b->len);
2120 
2121  if (a_len > real_b->len - b_start)
2122  return FALSE;
2123 
2124  ap = real_a->str + a_start;
2125  bp = real_b->str + b_start;
2126  a_end = ap + a_len;
2127  while (ap != a_end)
2128  {
2129  if (*ap != *bp)
2130  return FALSE;
2131 
2132  ++ap;
2133  ++bp;
2134  }
2135 
2136  _dbus_assert (bp <= (real_b->str + real_b->len));
2137 
2138  return TRUE;
2139 }
2140 
2150  const char *c_str)
2151 {
2152  const unsigned char *ap;
2153  const unsigned char *bp;
2154  const unsigned char *a_end;
2155  const DBusRealString *real_a = (const DBusRealString*) a;
2157  _dbus_assert (c_str != NULL);
2158 
2159  ap = real_a->str;
2160  bp = (const unsigned char*) c_str;
2161  a_end = real_a->str + real_a->len;
2162  while (ap != a_end && *bp)
2163  {
2164  if (*ap != *bp)
2165  return FALSE;
2166 
2167  ++ap;
2168  ++bp;
2169  }
2170 
2171  if (ap != a_end || *bp)
2172  return FALSE;
2173 
2174  return TRUE;
2175 }
2176 
2186  const char *c_str)
2187 {
2188  const unsigned char *ap;
2189  const unsigned char *bp;
2190  const unsigned char *a_end;
2191  const DBusRealString *real_a = (const DBusRealString*) a;
2193  _dbus_assert (c_str != NULL);
2194 
2195  ap = real_a->str;
2196  bp = (const unsigned char*) c_str;
2197  a_end = real_a->str + real_a->len;
2198  while (ap != a_end && *bp)
2199  {
2200  if (*ap != *bp)
2201  return FALSE;
2202 
2203  ++ap;
2204  ++bp;
2205  }
2206 
2207  if (*bp == '\0')
2208  return TRUE;
2209  else
2210  return FALSE;
2211 }
2212 
2223  int byte)
2224 {
2225  const char hexdigits[16] = {
2226  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2227  'a', 'b', 'c', 'd', 'e', 'f'
2228  };
2229 
2230  if (!_dbus_string_append_byte (str,
2231  hexdigits[(byte >> 4)]))
2232  return FALSE;
2233 
2234  if (!_dbus_string_append_byte (str,
2235  hexdigits[(byte & 0x0f)]))
2236  {
2238  _dbus_string_get_length (str) - 1);
2239  return FALSE;
2240  }
2241 
2242  return TRUE;
2243 }
2244 
2257  int start,
2258  DBusString *dest,
2259  int insert_at)
2260 {
2261  DBusString result;
2262  const unsigned char *p;
2263  const unsigned char *end;
2264  dbus_bool_t retval;
2265 
2266  _dbus_assert (start <= _dbus_string_get_length (source));
2267 
2268  if (!_dbus_string_init (&result))
2269  return FALSE;
2270 
2271  retval = FALSE;
2272 
2273  p = (const unsigned char*) _dbus_string_get_const_data (source);
2274  end = p + _dbus_string_get_length (source);
2275  p += start;
2276 
2277  while (p != end)
2278  {
2279  if (!_dbus_string_append_byte_as_hex (&result, *p))
2280  goto out;
2281 
2282  ++p;
2283  }
2284 
2285  if (!_dbus_string_move (&result, 0, dest, insert_at))
2286  goto out;
2287 
2288  retval = TRUE;
2289 
2290  out:
2291  _dbus_string_free (&result);
2292  return retval;
2293 }
2294 
2307  int start,
2308  int *end_return,
2309  DBusString *dest,
2310  int insert_at)
2311 {
2312  DBusString result;
2313  const unsigned char *p;
2314  const unsigned char *end;
2315  dbus_bool_t retval;
2316  dbus_bool_t high_bits;
2317 
2318  _dbus_assert (start <= _dbus_string_get_length (source));
2319 
2320  if (!_dbus_string_init (&result))
2321  return FALSE;
2322 
2323  retval = FALSE;
2324 
2325  high_bits = TRUE;
2326  p = (const unsigned char*) _dbus_string_get_const_data (source);
2327  end = p + _dbus_string_get_length (source);
2328  p += start;
2329 
2330  while (p != end)
2331  {
2332  unsigned int val;
2333 
2334  switch (*p)
2335  {
2336  case '0':
2337  val = 0;
2338  break;
2339  case '1':
2340  val = 1;
2341  break;
2342  case '2':
2343  val = 2;
2344  break;
2345  case '3':
2346  val = 3;
2347  break;
2348  case '4':
2349  val = 4;
2350  break;
2351  case '5':
2352  val = 5;
2353  break;
2354  case '6':
2355  val = 6;
2356  break;
2357  case '7':
2358  val = 7;
2359  break;
2360  case '8':
2361  val = 8;
2362  break;
2363  case '9':
2364  val = 9;
2365  break;
2366  case 'a':
2367  case 'A':
2368  val = 10;
2369  break;
2370  case 'b':
2371  case 'B':
2372  val = 11;
2373  break;
2374  case 'c':
2375  case 'C':
2376  val = 12;
2377  break;
2378  case 'd':
2379  case 'D':
2380  val = 13;
2381  break;
2382  case 'e':
2383  case 'E':
2384  val = 14;
2385  break;
2386  case 'f':
2387  case 'F':
2388  val = 15;
2389  break;
2390  default:
2391  goto done;
2392  }
2393 
2394  if (high_bits)
2395  {
2396  if (!_dbus_string_append_byte (&result,
2397  val << 4))
2398  goto out;
2399  }
2400  else
2401  {
2402  int len;
2403  unsigned char b;
2404 
2405  len = _dbus_string_get_length (&result);
2406 
2407  b = _dbus_string_get_byte (&result, len - 1);
2408 
2409  b |= val;
2410 
2411  _dbus_string_set_byte (&result, len - 1, b);
2412  }
2413 
2414  high_bits = !high_bits;
2415 
2416  ++p;
2417  }
2418 
2419  done:
2420  if (!_dbus_string_move (&result, 0, dest, insert_at))
2421  goto out;
2422 
2423  if (end_return)
2424  *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2425 
2426  retval = TRUE;
2427 
2428  out:
2429  _dbus_string_free (&result);
2430  return retval;
2431 }
2432 
2448  int start,
2449  int len)
2450 {
2451  const unsigned char *s;
2452  const unsigned char *end;
2454  _dbus_assert (start >= 0);
2455  _dbus_assert (start <= real->len);
2456  _dbus_assert (len >= 0);
2457 
2458  if (len > real->len - start)
2459  return FALSE;
2460 
2461  s = real->str + start;
2462  end = s + len;
2463  while (s != end)
2464  {
2465  if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2466  return FALSE;
2467 
2468  ++s;
2469  }
2470 
2471  return TRUE;
2472 }
2473 
2481 void
2483  int start,
2484  int len)
2485 {
2486  unsigned char *s;
2487  unsigned char *end;
2488  DBUS_STRING_PREAMBLE (str);
2489  _dbus_assert (start >= 0);
2490  _dbus_assert (start <= real->len);
2491  _dbus_assert (len >= 0);
2492  _dbus_assert (len <= real->len - start);
2493 
2494  s = real->str + start;
2495  end = s + len;
2496 
2497  while (s != end)
2498  {
2499  if (*s >= 'A' && *s <= 'Z')
2500  *s += 'a' - 'A';
2501  ++s;
2502  }
2503 }
2504 
2512 void
2514  int start,
2515  int len)
2516 {
2517  unsigned char *s;
2518  unsigned char *end;
2519  DBUS_STRING_PREAMBLE (str);
2520  _dbus_assert (start >= 0);
2521  _dbus_assert (start <= real->len);
2522  _dbus_assert (len >= 0);
2523  _dbus_assert (len <= real->len - start);
2524 
2525  s = real->str + start;
2526  end = s + len;
2527 
2528  while (s != end)
2529  {
2530  if (*s >= 'a' && *s <= 'z')
2531  *s += 'A' - 'a';
2532  ++s;
2533  }
2534 }
2535 
2553  int start,
2554  int len)
2555 {
2556  const unsigned char *p;
2557  const unsigned char *end;
2559  _dbus_assert (start >= 0);
2560  _dbus_assert (start <= real->len);
2561  _dbus_assert (len >= 0);
2562 
2563  /* we are doing _DBUS_UNLIKELY() here which might be
2564  * dubious in a generic library like GLib, but in D-Bus
2565  * we know we're validating messages and that it would
2566  * only be evil/broken apps that would have invalid
2567  * UTF-8. Also, this function seems to be a performance
2568  * bottleneck in profiles.
2569  */
2570 
2571  if (_DBUS_UNLIKELY (len > real->len - start))
2572  return FALSE;
2573 
2574  p = real->str + start;
2575  end = p + len;
2576 
2577  while (p < end)
2578  {
2579  int i, mask, char_len;
2580  dbus_unichar_t result;
2581 
2582  /* nul bytes considered invalid */
2583  if (*p == '\0')
2584  break;
2585 
2586  /* Special-case ASCII; this makes us go a lot faster in
2587  * D-Bus profiles where we are typically validating
2588  * function names and such. We have to know that
2589  * all following checks will pass for ASCII though,
2590  * comments follow ...
2591  */
2592  if (*p < 128)
2593  {
2594  ++p;
2595  continue;
2596  }
2597 
2598  UTF8_COMPUTE (*p, mask, char_len);
2599 
2600  if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2601  break;
2602 
2603  /* check that the expected number of bytes exists in the remaining length */
2604  if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2605  break;
2606 
2607  UTF8_GET (result, p, i, mask, char_len);
2608 
2609  /* Check for overlong UTF-8 */
2610  if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2611  break;
2612 #if 0
2613  /* The UNICODE_VALID check below will catch this */
2614  if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2615  break;
2616 #endif
2617 
2618  if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2619  break;
2620 
2621  /* UNICODE_VALID should have caught it */
2622  _dbus_assert (result != (dbus_unichar_t)-1);
2623 
2624  p += char_len;
2625  }
2626 
2627  /* See that we covered the entire length if a length was
2628  * passed in
2629  */
2630  if (_DBUS_UNLIKELY (p != end))
2631  return FALSE;
2632  else
2633  return TRUE;
2634 }
2635 
2651  int start,
2652  int len)
2653 {
2654  const unsigned char *s;
2655  const unsigned char *end;
2657  _dbus_assert (start >= 0);
2658  _dbus_assert (len >= 0);
2659  _dbus_assert (start <= real->len);
2660 
2661  if (len > real->len - start)
2662  return FALSE;
2663 
2664  s = real->str + start;
2665  end = s + len;
2666  while (s != end)
2667  {
2668  if (_DBUS_UNLIKELY (*s != '\0'))
2669  return FALSE;
2670  ++s;
2671  }
2672 
2673  return TRUE;
2674 }
2675 
2681 void
2683 {
2684  DBUS_STRING_PREAMBLE (str);
2685 
2686  memset (real->str - real->align_offset, '\0', real->allocated);
2687 }
2690 /* tests are in dbus-string-util.c */
#define DBUS_IS_ASCII_WHITE(c)
Checks for ASCII whitespace byte.
dbus_bool_t _dbus_string_insert_bytes(DBusString *str, int i, int n_bytes, unsigned char byte)
Inserts a number of bytes of a given value at the given position.
Definition: dbus-string.c:562
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:913
void _dbus_string_copy_to_buffer(const DBusString *str, char *buffer, int avail_len)
Copies the contents of a DBusString into a different buffer.
Definition: dbus-string.c:675
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)
Checks assertions for two strings we&#39;re copying a segment between, and declares real_source/real_dest...
Definition: dbus-string.c:1232
Internals of DBusString.
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2010
dbus_bool_t _dbus_string_find_eol(const DBusString *str, int start, int *found, int *found_len)
Finds end of line (&quot;\r\n&quot; or &quot;\n&quot;) in the string, returning TRUE and filling in the byte index where ...
Definition: dbus-string.c:1624
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:738
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:600
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:933
dbus_bool_t _dbus_string_append_byte_as_hex(DBusString *str, int byte)
Appends a two-character hex digit to a string, where the hex digit has the value of the given byte...
Definition: dbus-string.c:2222
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:700
void _dbus_string_copy_to_buffer_with_nul(const DBusString *str, char *buffer, int avail_len)
Copies the contents of a DBusString into a different buffer.
Definition: dbus-string.c:697
dbus_bool_t _dbus_string_hex_encode(const DBusString *source, int start, DBusString *dest, int insert_at)
Encodes a string in hex, the way MD5 and SHA-1 are usually encoded.
Definition: dbus-string.c:2256
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:942
dbus_bool_t _dbus_string_starts_with_c_str(const DBusString *a, const char *c_str)
Checks whether a string starts with the given C string.
Definition: dbus-string.c:2185
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:1986
dbus_bool_t _dbus_string_insert_8_aligned(DBusString *str, int insert_at, const unsigned char octets[8])
Inserts 8 bytes aligned on an 8 byte boundary with any alignment padding initialized to 0...
Definition: dbus-string.c:1018
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
void _dbus_string_tolower_ascii(const DBusString *str, int start, int len)
Converts the given range of the string to lower case.
Definition: dbus-string.c:2482
unsigned int invalid
DBusString is invalid (e.g.
#define DBUS_CONST_STRING_PREAMBLE(str)
Checks assertions about a string that may be const or locked.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:540
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:468
#define _DBUS_STRING_MAX_LENGTH
The maximum length of a DBusString.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_bool_t _dbus_string_append_printf_valist(DBusString *str, const char *format, va_list args)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1070
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:758
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1280
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1559
dbus_bool_t _dbus_string_find(const DBusString *str, int start, const char *substr, int *found)
Finds the given substring in the string, returning TRUE and filling in the byte index where the subst...
Definition: dbus-string.c:1601
void _dbus_string_skip_white(const DBusString *str, int start, int *end)
Skips whitespace from start, storing the first non-whitespace in *end.
Definition: dbus-string.c:1834
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:929
dbus_bool_t _dbus_string_move(DBusString *source, int start, DBusString *dest, int insert_at)
Moves the end of one string into another string.
Definition: dbus-string.c:1256
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:460
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1582
dbus_bool_t _dbus_string_equal_c_str(const DBusString *a, const char *c_str)
Checks whether a string is equal to a C string.
Definition: dbus-string.c:2149
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:367
dbus_bool_t _dbus_string_copy_data(const DBusString *str, char **data_return)
Copies the data from the string into a char*.
Definition: dbus-string.c:650
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:429
#define DBUS_GENERIC_STRING_PREAMBLE(real)
Checks a bunch of assertions about a string object.
dbus_bool_t _dbus_string_replace_len(const DBusString *source, int start, int len, DBusString *dest, int replace_at, int replace_len)
Replaces a segment of dest string with a segment of source string.
Definition: dbus-string.c:1401
#define DBUS_STRING_PREAMBLE(str)
Checks assertions about a string object that needs to be modifiable - may not be locked or const...
void _dbus_string_skip_blank(const DBusString *str, int start, int *end)
Skips blanks from start, storing the first non-blank in *end (blank is space or tab).
Definition: dbus-string.c:1800
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1543
dbus_bool_t _dbus_string_pop_line(DBusString *source, DBusString *dest)
Assigns a newline-terminated or \r\n-terminated line from the front of the string to the given dest s...
Definition: dbus-string.c:1906
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1190
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
int len
Length without nul.
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1111
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:717
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2682
dbus_bool_t _dbus_string_validate_utf8(const DBusString *str, int start, int len)
Checks that the given range of the string is valid UTF-8.
Definition: dbus-string.c:2552
dbus_bool_t _dbus_string_align_length(DBusString *str, int alignment)
Align the length of a string to a specific alignment (typically 4 or 8) by appending nul bytes to the...
Definition: dbus-string.c:861
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
Definition: dbus-string.c:2101
dbus_bool_t _dbus_string_equal_len(const DBusString *a, const DBusString *b, int len)
Tests two DBusString for equality up to the given length.
Definition: dbus-string.c:2053
unsigned int locked
DBusString has been locked and can&#39;t be changed.
dbus_bool_t _dbus_string_insert_byte(DBusString *str, int i, unsigned char byte)
Inserts a single byte at the given position.
Definition: dbus-string.c:592
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1154
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
#define TRUE
Expands to &quot;1&quot;.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
int allocated
Allocated size of data.
#define DBUS_IS_ASCII_BLANK(c)
Checks for ASCII blank byte.
dbus_bool_t _dbus_string_find_blank(const DBusString *str, int start, int *found)
Finds a blank (space or tab) in the string.
Definition: dbus-string.c:1762
void _dbus_string_set_byte(DBusString *str, int i, unsigned char byte)
Sets the value of the byte at the given position.
Definition: dbus-string.c:516
dbus_bool_t _dbus_string_alloc_space(DBusString *str, int extra_bytes)
Preallocate extra_bytes such that a future lengthening of the string by extra_bytes is guaranteed to ...
Definition: dbus-string.c:877
dbus_bool_t _dbus_string_hex_decode(const DBusString *source, int start, int *end_return, DBusString *dest, int insert_at)
Decodes a string from hex encoding.
Definition: dbus-string.c:2306
unsigned int align_offset
str - align_offset is the actual malloc block
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:492
dbus_bool_t _dbus_string_append_len(DBusString *str, const char *buffer, int len)
Appends block of bytes with the given length to a DBusString.
Definition: dbus-string.c:1134
dbus_bool_t _dbus_string_find_to(const DBusString *str, int start, int end, const char *substr, int *found)
Finds the given substring in the string, up to a certain position, returning TRUE and filling in the ...
Definition: dbus-string.c:1694
unsigned char * str
String data, plus nul termination.
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
Definition: dbus-string.c:2650
#define FALSE
Expands to &quot;0&quot;.
dbus_bool_t _dbus_string_insert_4_aligned(DBusString *str, int insert_at, const unsigned char octets[4])
Inserts 4 bytes aligned on a 4 byte boundary with any alignment padding initialized to 0...
Definition: dbus-string.c:994
void _dbus_string_skip_white_reverse(const DBusString *str, int end, int *start)
Skips whitespace from end, storing the start index of the trailing whitespace in *start.
Definition: dbus-string.c:1867
#define DBUS_LOCKED_STRING_PREAMBLE(str)
Checks assertions about a string object that may be locked but can&#39;t be const.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:780
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1372
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
Definition: dbus-string.c:619
void _dbus_string_toupper_ascii(const DBusString *str, int start, int len)
Converts the given range of the string to upper case.
Definition: dbus-string.c:2513
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1502
dbus_bool_t _dbus_string_insert_2_aligned(DBusString *str, int insert_at, const unsigned char octets[4])
Inserts 2 bytes aligned on a 2 byte boundary with any alignment padding initialized to 0...
Definition: dbus-string.c:970
dbus_bool_t _dbus_string_insert_alignment(DBusString *str, int *insert_at, int alignment)
Inserts padding at *insert_at such to align it to the given boundary.
Definition: dbus-string.c:1046
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:446
dbus_bool_t _dbus_string_validate_ascii(const DBusString *str, int start, int len)
Checks that the given range of the string is valid ASCII with no nul bytes.
Definition: dbus-string.c:2447
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
dbus_bool_t _dbus_string_move_len(DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_move(), but can move a segment from the middle of the source string.
Definition: dbus-string.c:1305
unsigned int constant
String data is not owned by DBusString.
dbus_bool_t _dbus_string_split_on_byte(DBusString *source, unsigned char byte, DBusString *tail)
Looks for the first occurance of a byte, deletes that byte, and moves everything after the byte to th...
Definition: dbus-string.c:1464