D-Bus  1.13.18
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 2002-2007 Red Hat, Inc.
5  * Copyright 2003 CodeFactory AB
6  * Copyright 2003 Mark McLoughlin
7  * Copyright 2004 Michael Meeks
8  * Copyright 2006-2014 Ralf Habacker <ralf.habacker@freenet.de>
9  * Copyright 2006-2018 Collabora Ltd.
10  * Copyright 2007 Allison Lortie
11  * Copyright 2011 Roberto Guido
12  * Copyright 2013 Chengwei Yang / Intel
13  *
14  * Licensed under the Academic Free License version 2.1
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  *
30  */
31 
32 #include <config.h>
33 #include "dbus-internals.h"
34 #include "dbus-string.h"
35 /* we allow a system header here, for speed/convenience */
36 #include <string.h>
37 /* for vsnprintf */
38 #include <stdio.h>
39 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
40 #include "dbus-string-private.h"
41 #include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
42  * into the marshaling-related files
43  */
44 /* for DBUS_VA_COPY */
45 #include "dbus-sysdeps.h"
46 
85 static void
86 fixup_alignment (DBusRealString *real)
87 {
88  unsigned char *aligned;
89  unsigned char *real_block;
90  unsigned int old_align_offset;
91 
92  /* we have to have extra space in real->allocated for the align offset and nul byte */
93  _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
94 
95  old_align_offset = real->align_offset;
96  real_block = real->str - old_align_offset;
97 
98  aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
99 
100  real->align_offset = aligned - real_block;
101  real->str = aligned;
102 
103  if (old_align_offset != real->align_offset)
104  {
105  /* Here comes the suck */
106  memmove (real_block + real->align_offset,
107  real_block + old_align_offset,
108  real->len + 1);
109  }
110 
111  _dbus_assert (real->align_offset < 8);
112  _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
113 }
114 
115 static void
116 undo_alignment (DBusRealString *real)
117 {
118  if (real->align_offset != 0)
119  {
120  memmove (real->str - real->align_offset,
121  real->str,
122  real->len + 1);
123 
124  real->str = real->str - real->align_offset;
125  real->align_offset = 0;
126  }
127 }
128 
140  int allocate_size)
141 {
142  DBusRealString *real;
143 
144  _DBUS_STATIC_ASSERT (sizeof (DBusString) == sizeof (DBusRealString));
145 
146  _dbus_assert (str != NULL);
147 
148  real = (DBusRealString*) str;
149 
150  /* It's very important not to touch anything
151  * other than real->str if we're going to fail,
152  * since we also use this function to reset
153  * an existing string, e.g. in _dbus_string_steal_data()
154  */
155 
156  real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
157  if (real->str == NULL)
158  return FALSE;
159 
160  real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
161  real->len = 0;
162  real->str[real->len] = '\0';
163 
164  real->constant = FALSE;
165  real->locked = FALSE;
166  real->valid = TRUE;
167  real->align_offset = 0;
168 
169  fixup_alignment (real);
170 
171  return TRUE;
172 }
173 
183 {
184  return _dbus_string_init_preallocated (str, 0);
185 }
186 
196 void
198  const char *value)
199 {
200  _dbus_assert (value != NULL);
201 
202  _dbus_string_init_const_len (str, value,
203  strlen (value));
204 }
205 
216 void
218  const char *value,
219  int len)
220 {
221  DBusRealString *real;
222 
223  _dbus_assert (str != NULL);
224  _dbus_assert (len == 0 || value != NULL);
226  _dbus_assert (len >= 0);
227 
228  real = (DBusRealString*) str;
229 
230  real->str = (unsigned char*) value;
231  real->len = len;
232  real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
233  real->constant = TRUE;
234  real->locked = TRUE;
235  real->valid = TRUE;
236  real->align_offset = 0;
237 
238  /* We don't require const strings to be 8-byte aligned as the
239  * memory is coming from elsewhere.
240  */
241 }
242 
253  const DBusString *from)
254 {
255  if (!_dbus_string_init (str))
256  return FALSE;
257  return _dbus_string_append (str, _dbus_string_get_const_data (from));
258 }
259 
270 void
272 {
273  DBusRealString *real = (DBusRealString*) str;
274  /* DBusRealString and DBusString have the same members in the same order,
275  * just differently-named */
276  DBusRealString invalid = _DBUS_STRING_INIT_INVALID;
277 
278  /* Allow for the _DBUS_STRING_INIT_INVALID case */
279  if (real->str == NULL && real->len == 0 && real->allocated == 0 &&
280  !real->constant && !real->locked && !real->valid &&
281  real->align_offset == 0)
282  return;
283 
285 
286  if (real->constant)
287  goto wipe;
288 
289  /* so it's safe if @p str returned by a failed
290  * _dbus_string_init call
291  * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
292  */
293  if (real->str == NULL)
294  goto wipe;
295 
296  dbus_free (real->str - real->align_offset);
297 
298 wipe:
299  *real = invalid;
300  real->valid = FALSE;
301 }
302 
303 static dbus_bool_t
304 compact (DBusRealString *real,
305  int max_waste)
306 {
307  unsigned char *new_str;
308  int new_allocated;
309  int waste;
310 
311  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
312 
313  if (waste <= max_waste)
314  return TRUE;
315 
316  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
317 
318  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
319  if (_DBUS_UNLIKELY (new_str == NULL))
320  return FALSE;
321 
322  real->str = new_str + real->align_offset;
323  real->allocated = new_allocated;
324  fixup_alignment (real);
325 
326  return TRUE;
327 }
328 
329 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
330 /* Not using this feature at the moment,
331  * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
332  */
342 void
343 _dbus_string_lock (DBusString *str)
344 {
345  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
346 
347  real->locked = TRUE;
348 
349  /* Try to realloc to avoid excess memory usage, since
350  * we know we won't change the string further
351  */
352 #define MAX_WASTE 48
353  compact (real, MAX_WASTE);
354 }
355 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
356 
357 static dbus_bool_t
358 reallocate_for_length (DBusRealString *real,
359  int new_length)
360 {
361  int new_allocated;
362  unsigned char *new_str;
363 
364  /* at least double our old allocation to avoid O(n), avoiding
365  * overflow
366  */
367  if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
368  new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
369  else
370  new_allocated = real->allocated * 2;
371 
372  /* if you change the code just above here, run the tests without
373  * the following assert-only hack before you commit
374  */
375  /* This is keyed off asserts in addition to tests so when you
376  * disable asserts to profile, you don't get this destroyer
377  * of profiles.
378  */
379 #if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
380  new_allocated = 0; /* ensure a realloc every time so that we go
381  * through all malloc failure codepaths
382  */
383 #endif
384 
385  /* But be sure we always alloc at least space for the new length */
386  new_allocated = MAX (new_allocated,
387  new_length + _DBUS_STRING_ALLOCATION_PADDING);
388 
389  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
390  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
391  if (_DBUS_UNLIKELY (new_str == NULL))
392  return FALSE;
393 
394  real->str = new_str + real->align_offset;
395  real->allocated = new_allocated;
396  fixup_alignment (real);
397 
398  return TRUE;
399 }
400 
414  int max_waste)
415 {
416  DBUS_STRING_PREAMBLE (str);
417 
418  return compact (real, max_waste);
419 }
420 
421 static dbus_bool_t
422 set_length (DBusRealString *real,
423  int new_length)
424 {
425  /* Note, we are setting the length not including nul termination */
426 
427  /* exceeding max length is the same as failure to allocate memory */
428  if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
429  return FALSE;
430  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
431  _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
432  return FALSE;
433  else
434  {
435  real->len = new_length;
436  real->str[new_length] = '\0';
437  return TRUE;
438  }
439 }
440 
441 static dbus_bool_t
442 open_gap (int len,
443  DBusRealString *dest,
444  int insert_at)
445 {
446  if (len == 0)
447  return TRUE;
448 
449  if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
450  return FALSE; /* detected overflow of dest->len + len below */
451 
452  if (!set_length (dest, dest->len + len))
453  return FALSE;
454 
455  memmove (dest->str + insert_at + len,
456  dest->str + insert_at,
457  dest->len - len - insert_at);
458 
459  return TRUE;
460 }
461 
462 #ifndef _dbus_string_get_data
474 char*
475 _dbus_string_get_data (DBusString *str)
476 {
477  DBUS_STRING_PREAMBLE (str);
478 
479  return (char*) real->str;
480 }
481 #endif /* _dbus_string_get_data */
482 
483 /* only do the function if we don't have the macro */
484 #ifndef _dbus_string_get_const_data
491 const char*
492 _dbus_string_get_const_data (const DBusString *str)
493 {
495 
496  return (const char*) real->str;
497 }
498 #endif /* _dbus_string_get_const_data */
499 
513 char*
515  int start,
516  int len)
517 {
518  DBUS_STRING_PREAMBLE (str);
519  _dbus_assert (start >= 0);
520  _dbus_assert (len >= 0);
521  _dbus_assert (start <= real->len);
522  _dbus_assert (len <= real->len - start);
523 
524  return (char*) real->str + start;
525 }
526 
527 /* only do the function if we don't have the macro */
528 #ifndef _dbus_string_get_const_data_len
537 const char*
538 _dbus_string_get_const_data_len (const DBusString *str,
539  int start,
540  int len)
541 {
543  _dbus_assert (start >= 0);
544  _dbus_assert (len >= 0);
545  _dbus_assert (start <= real->len);
546  _dbus_assert (len <= real->len - start);
547 
548  return (const char*) real->str + start;
549 }
550 #endif /* _dbus_string_get_const_data_len */
551 
552 /* only do the function if we don't have the macro */
553 #ifndef _dbus_string_set_byte
561 void
562 _dbus_string_set_byte (DBusString *str,
563  int i,
564  unsigned char byte)
565 {
566  DBUS_STRING_PREAMBLE (str);
567  _dbus_assert (i < real->len);
568  _dbus_assert (i >= 0);
569 
570  real->str[i] = byte;
571 }
572 #endif /* _dbus_string_set_byte */
573 
574 /* only have the function if we didn't create a macro */
575 #ifndef _dbus_string_get_byte
585 unsigned char
586 _dbus_string_get_byte (const DBusString *str,
587  int start)
588 {
590  _dbus_assert (start <= real->len);
591  _dbus_assert (start >= 0);
592 
593  return real->str[start];
594 }
595 #endif /* _dbus_string_get_byte */
596 
609  int i,
610  int n_bytes,
611  unsigned char byte)
612 {
613  DBUS_STRING_PREAMBLE (str);
614  _dbus_assert (i <= real->len);
615  _dbus_assert (i >= 0);
616  _dbus_assert (n_bytes >= 0);
617 
618  if (n_bytes == 0)
619  return TRUE;
620 
621  if (!open_gap (n_bytes, real, i))
622  return FALSE;
623 
624  memset (real->str + i, byte, n_bytes);
625 
626  return TRUE;
627 }
628 
639  int i,
640  unsigned char byte)
641 {
642  DBUS_STRING_PREAMBLE (str);
643  _dbus_assert (i <= real->len);
644  _dbus_assert (i >= 0);
645 
646  if (!open_gap (1, real, i))
647  return FALSE;
648 
649  real->str[i] = byte;
650 
651  return TRUE;
652 }
653 
666  char **data_return)
667 {
668  DBUS_STRING_PREAMBLE (str);
669  _dbus_assert (data_return != NULL);
670 
671  undo_alignment (real);
672 
673  *data_return = (char*) real->str;
674 
675  /* reset the string */
676  if (!_dbus_string_init (str))
677  {
678  /* hrm, put it back then */
679  real->str = (unsigned char*) *data_return;
680  *data_return = NULL;
681  fixup_alignment (real);
682  return FALSE;
683  }
684 
685  return TRUE;
686 }
687 
697  char **data_return)
698 {
700  _dbus_assert (data_return != NULL);
701 
702  *data_return = dbus_malloc (real->len + 1);
703  if (*data_return == NULL)
704  return FALSE;
705 
706  memcpy (*data_return, real->str, real->len + 1);
707 
708  return TRUE;
709 }
710 
720 void
722  char *buffer,
723  int avail_len)
724 {
726 
727  _dbus_assert (avail_len >= 0);
728  _dbus_assert (avail_len >= real->len);
729 
730  memcpy (buffer, real->str, real->len);
731 }
732 
742 void
744  char *buffer,
745  int avail_len)
746 {
748 
749  _dbus_assert (avail_len >= 0);
750  _dbus_assert (avail_len > real->len);
751 
752  memcpy (buffer, real->str, real->len+1);
753 }
754 
755 /* Only have the function if we don't have the macro */
756 #ifndef _dbus_string_get_length
762 int
763 _dbus_string_get_length (const DBusString *str)
764 {
766 
767  return real->len;
768 }
769 #endif /* !_dbus_string_get_length */
770 
785  int additional_length)
786 {
787  DBUS_STRING_PREAMBLE (str);
788  _dbus_assert (additional_length >= 0);
789 
790  if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
791  return FALSE; /* would overflow */
792 
793  return set_length (real,
794  real->len + additional_length);
795 }
796 
803 void
805  int length_to_remove)
806 {
807  DBUS_STRING_PREAMBLE (str);
808  _dbus_assert (length_to_remove >= 0);
809  _dbus_assert (length_to_remove <= real->len);
810 
811  set_length (real,
812  real->len - length_to_remove);
813 }
814 
827  int length)
828 {
829  DBUS_STRING_PREAMBLE (str);
830  _dbus_assert (length >= 0);
831 
832  return set_length (real, length);
833 }
834 
835 static dbus_bool_t
836 align_insert_point_then_open_gap (DBusString *str,
837  int *insert_at_p,
838  int alignment,
839  int gap_size)
840 {
841  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
842  unsigned long gap_pos;
843  int insert_at;
844  int delta;
845  DBUS_STRING_PREAMBLE (str);
846  _dbus_assert (alignment >= 1);
847  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
848 
849  insert_at = *insert_at_p;
850 
851  _dbus_assert (insert_at <= real->len);
852 
853  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
854  new_len = real->len + (gap_pos - insert_at) + gap_size;
855 
856  if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
857  return FALSE;
858 
859  delta = new_len - real->len;
860  _dbus_assert (delta >= 0);
861 
862  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
863  {
864  _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
865  return TRUE;
866  }
867 
868  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
869  real, insert_at)))
870  return FALSE;
871 
872  /* nul the padding if we had to add any padding */
873  if (gap_size < delta)
874  {
875  memset (&real->str[insert_at], '\0',
876  gap_pos - insert_at);
877  }
878 
879  *insert_at_p = gap_pos;
880 
881  return TRUE;
882 }
883 
884 static dbus_bool_t
885 align_length_then_lengthen (DBusString *str,
886  int alignment,
887  int then_lengthen_by)
888 {
889  int insert_at;
890 
891  insert_at = _dbus_string_get_length (str);
892 
893  return align_insert_point_then_open_gap (str,
894  &insert_at,
895  alignment, then_lengthen_by);
896 }
897 
908  int alignment)
909 {
910  return align_length_then_lengthen (str, alignment, 0);
911 }
912 
924  int extra_bytes)
925 {
926  if (!_dbus_string_lengthen (str, extra_bytes))
927  return FALSE;
928  _dbus_string_shorten (str, extra_bytes);
929 
930  return TRUE;
931 }
932 
933 static dbus_bool_t
934 append (DBusRealString *real,
935  const char *buffer,
936  int buffer_len)
937 {
938  if (buffer_len == 0)
939  return TRUE;
940 
941  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
942  return FALSE;
943 
944  memcpy (real->str + (real->len - buffer_len),
945  buffer,
946  buffer_len);
947 
948  return TRUE;
949 }
950 
960  const char *buffer)
961 {
962  unsigned long buffer_len;
963 
964  DBUS_STRING_PREAMBLE (str);
965  _dbus_assert (buffer != NULL);
966 
967  buffer_len = strlen (buffer);
968  if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
969  return FALSE;
970 
971  return append (real, buffer, buffer_len);
972 }
973 
975 #define ASSIGN_2_OCTETS(p, octets) \
976  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
977 
979 #define ASSIGN_4_OCTETS(p, octets) \
980  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
981 
983 #define ASSIGN_8_OCTETS(p, octets) \
984  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
985 
997  int insert_at,
998  const unsigned char octets[2])
999 {
1000  DBUS_STRING_PREAMBLE (str);
1001 
1002  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
1003  return FALSE;
1004 
1005  ASSIGN_2_OCTETS (real->str + insert_at, octets);
1006 
1007  return TRUE;
1008 }
1009 
1021  int insert_at,
1022  const unsigned char octets[4])
1023 {
1024  DBUS_STRING_PREAMBLE (str);
1025 
1026  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1027  return FALSE;
1028 
1029  ASSIGN_4_OCTETS (real->str + insert_at, octets);
1030 
1031  return TRUE;
1032 }
1033 
1045  int insert_at,
1046  const unsigned char octets[8])
1047 {
1048  DBUS_STRING_PREAMBLE (str);
1049 
1050  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1051  return FALSE;
1052 
1053  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1054 
1055  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1056 
1057  return TRUE;
1058 }
1059 
1060 
1073  int *insert_at,
1074  int alignment)
1075 {
1076  DBUS_STRING_PREAMBLE (str);
1077 
1078  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1079  return FALSE;
1080 
1081  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1082 
1083  return TRUE;
1084 }
1085 
1097  const char *format,
1098  va_list args)
1099 {
1100  dbus_bool_t ret = FALSE;
1101  int len;
1102  va_list args_copy;
1103 
1104  DBUS_STRING_PREAMBLE (str);
1105 
1106  DBUS_VA_COPY (args_copy, args);
1107 
1108  /* Measure the message length without terminating nul */
1109  len = _dbus_printf_string_upper_bound (format, args);
1110 
1111  if (len < 0)
1112  goto out;
1113 
1114  if (!_dbus_string_lengthen (str, len))
1115  {
1116  goto out;
1117  }
1118 
1119  vsprintf ((char*) (real->str + (real->len - len)),
1120  format, args_copy);
1121  ret = TRUE;
1122 
1123 out:
1124  va_end (args_copy);
1125 
1126  return ret;
1127 }
1128 
1139  const char *format,
1140  ...)
1141 {
1142  va_list args;
1143  dbus_bool_t retval;
1144 
1145  va_start (args, format);
1146  retval = _dbus_string_append_printf_valist (str, format, args);
1147  va_end (args);
1148 
1149  return retval;
1150 }
1151 
1162  const char *buffer,
1163  int len)
1164 {
1165  DBUS_STRING_PREAMBLE (str);
1166  _dbus_assert (buffer != NULL);
1167  _dbus_assert (len >= 0);
1168 
1169  return append (real, buffer, len);
1170 }
1171 
1182  unsigned char byte)
1183 {
1184  DBUS_STRING_PREAMBLE (str);
1185 
1186  if (!set_length (real, real->len + 1))
1187  return FALSE;
1188 
1189  real->str[real->len-1] = byte;
1190 
1191  return TRUE;
1192 }
1193 
1194 static void
1195 delete (DBusRealString *real,
1196  int start,
1197  int len)
1198 {
1199  if (len == 0)
1200  return;
1201 
1202  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1203  real->len -= len;
1204  real->str[real->len] = '\0';
1205 }
1206 
1216 void
1218  int start,
1219  int len)
1220 {
1221  DBUS_STRING_PREAMBLE (str);
1222  _dbus_assert (start >= 0);
1223  _dbus_assert (len >= 0);
1224  _dbus_assert (start <= real->len);
1225  _dbus_assert (len <= real->len - start);
1226 
1227  delete (real, start, len);
1228 }
1229 
1230 static dbus_bool_t
1231 copy (DBusRealString *source,
1232  int start,
1233  int len,
1234  DBusRealString *dest,
1235  int insert_at)
1236 {
1237  if (len == 0)
1238  return TRUE;
1239 
1240  if (!open_gap (len, dest, insert_at))
1241  return FALSE;
1242 
1243  memmove (dest->str + insert_at,
1244  source->str + start,
1245  len);
1246 
1247  return TRUE;
1248 }
1249 
1259 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1260  DBusRealString *real_source = (DBusRealString*) source; \
1261  DBusRealString *real_dest = (DBusRealString*) dest; \
1262  _dbus_assert ((source) != (dest)); \
1263  DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1264  DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1265  _dbus_assert (!real_dest->constant); \
1266  _dbus_assert (!real_dest->locked); \
1267  _dbus_assert ((start) >= 0); \
1268  _dbus_assert ((start) <= real_source->len); \
1269  _dbus_assert ((insert_at) >= 0); \
1270  _dbus_assert ((insert_at) <= real_dest->len)
1271 
1284  int start,
1285  DBusString *dest,
1286  int insert_at)
1287 {
1288  DBusRealString *real_source = (DBusRealString*) source;
1289  _dbus_assert (start <= real_source->len);
1290 
1291  return _dbus_string_move_len (source, start,
1292  real_source->len - start,
1293  dest, insert_at);
1294 }
1295 
1308  int start,
1309  DBusString *dest,
1310  int insert_at)
1311 {
1312  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1313 
1314  return copy (real_source, start,
1315  real_source->len - start,
1316  real_dest,
1317  insert_at);
1318 }
1319 
1333  int start,
1334  int len,
1335  DBusString *dest,
1336  int insert_at)
1337 
1338 {
1339  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1340  _dbus_assert (len >= 0);
1341  _dbus_assert ((start + len) <= real_source->len);
1342 
1343 
1344  if (len == 0)
1345  {
1346  return TRUE;
1347  }
1348  else if (start == 0 &&
1349  len == real_source->len &&
1350  real_dest->len == 0)
1351  {
1352  /* Short-circuit moving an entire existing string to an empty string
1353  * by just swapping the buffers.
1354  */
1355  /* we assume ->constant doesn't matter as you can't have
1356  * a constant string involved in a move.
1357  */
1358 #define ASSIGN_DATA(a, b) do { \
1359  (a)->str = (b)->str; \
1360  (a)->len = (b)->len; \
1361  (a)->allocated = (b)->allocated; \
1362  (a)->align_offset = (b)->align_offset; \
1363  } while (0)
1364 
1365  DBusRealString tmp;
1366 
1367  ASSIGN_DATA (&tmp, real_source);
1368  ASSIGN_DATA (real_source, real_dest);
1369  ASSIGN_DATA (real_dest, &tmp);
1370 
1371  return TRUE;
1372  }
1373  else
1374  {
1375  if (!copy (real_source, start, len,
1376  real_dest,
1377  insert_at))
1378  return FALSE;
1379 
1380  delete (real_source, start,
1381  len);
1382 
1383  return TRUE;
1384  }
1385 }
1386 
1400  int start,
1401  int len,
1402  DBusString *dest,
1403  int insert_at)
1404 {
1405  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1406  _dbus_assert (len >= 0);
1407  _dbus_assert (start <= real_source->len);
1408  _dbus_assert (len <= real_source->len - start);
1409 
1410  return copy (real_source, start, len,
1411  real_dest,
1412  insert_at);
1413 }
1414 
1429  int start,
1430  int len,
1431  DBusString *dest,
1432  int replace_at,
1433  int replace_len)
1434 {
1435  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1436  _dbus_assert (len >= 0);
1437  _dbus_assert (start <= real_source->len);
1438  _dbus_assert (len <= real_source->len - start);
1439  _dbus_assert (replace_at >= 0);
1440  _dbus_assert (replace_at <= real_dest->len);
1441  _dbus_assert (replace_len <= real_dest->len - replace_at);
1442 
1443  if (len == replace_len)
1444  {
1445  memmove (real_dest->str + replace_at,
1446  real_source->str + start, len);
1447  }
1448  else if (len < replace_len)
1449  {
1450  memmove (real_dest->str + replace_at,
1451  real_source->str + start, len);
1452  delete (real_dest, replace_at + len,
1453  replace_len - len);
1454  }
1455  else
1456  {
1457  int diff;
1458 
1459  _dbus_assert (len > replace_len);
1460 
1461  diff = len - replace_len;
1462 
1463  /* First of all we check if destination string can be enlarged as
1464  * required, then we overwrite previous bytes
1465  */
1466 
1467  if (!copy (real_source, start + replace_len, diff,
1468  real_dest, replace_at + replace_len))
1469  return FALSE;
1470 
1471  memmove (real_dest->str + replace_at,
1472  real_source->str + start, replace_len);
1473  }
1474 
1475  return TRUE;
1476 }
1477 
1492  unsigned char byte,
1493  DBusString *tail)
1494 {
1495  int byte_position;
1496  char byte_string[2] = "";
1497  int head_length;
1498  int tail_length;
1499 
1500  byte_string[0] = (char) byte;
1501 
1502  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1503  return FALSE;
1504 
1505  head_length = byte_position;
1506  tail_length = _dbus_string_get_length (source) - head_length - 1;
1507 
1508  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1509  tail, 0))
1510  return FALSE;
1511 
1512  /* remove the trailing delimiter byte from the head now.
1513  */
1514  if (!_dbus_string_set_length (source, head_length))
1515  return FALSE;
1516 
1517  return TRUE;
1518 }
1519 
1520 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1521  * Pennington, and Tom Tromey are the authors and authorized relicense.
1522  */
1523 
1529 #define UTF8_COMPUTE(Char, Mask, Len) \
1530  if (Char < 128) \
1531  { \
1532  Len = 1; \
1533  Mask = 0x7f; \
1534  } \
1535  else if ((Char & 0xe0) == 0xc0) \
1536  { \
1537  Len = 2; \
1538  Mask = 0x1f; \
1539  } \
1540  else if ((Char & 0xf0) == 0xe0) \
1541  { \
1542  Len = 3; \
1543  Mask = 0x0f; \
1544  } \
1545  else if ((Char & 0xf8) == 0xf0) \
1546  { \
1547  Len = 4; \
1548  Mask = 0x07; \
1549  } \
1550  else if ((Char & 0xfc) == 0xf8) \
1551  { \
1552  Len = 5; \
1553  Mask = 0x03; \
1554  } \
1555  else if ((Char & 0xfe) == 0xfc) \
1556  { \
1557  Len = 6; \
1558  Mask = 0x01; \
1559  } \
1560  else \
1561  { \
1562  Len = 0; \
1563  Mask = 0; \
1564  }
1565 
1570 #define UTF8_LENGTH(Char) \
1571  ((Char) < 0x80 ? 1 : \
1572  ((Char) < 0x800 ? 2 : \
1573  ((Char) < 0x10000 ? 3 : \
1574  ((Char) < 0x200000 ? 4 : \
1575  ((Char) < 0x4000000 ? 5 : 6)))))
1576 
1586 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
1587  (Result) = (Chars)[0] & (Mask); \
1588  for ((Count) = 1; (Count) < (Len); ++(Count)) \
1589  { \
1590  if (((Chars)[(Count)] & 0xc0) != 0x80) \
1591  { \
1592  (Result) = -1; \
1593  break; \
1594  } \
1595  (Result) <<= 6; \
1596  (Result) |= ((Chars)[(Count)] & 0x3f); \
1597  }
1598 
1609 #define UNICODE_VALID(Char) \
1610  ((Char) < 0x110000 && \
1611  (((Char) & 0xFFFFF800) != 0xD800))
1612 
1629  int start,
1630  const char *substr,
1631  int *found)
1632 {
1633  return _dbus_string_find_to (str, start,
1634  ((const DBusRealString*)str)->len,
1635  substr, found);
1636 }
1637 
1652  int start,
1653  int *found,
1654  int *found_len)
1655 {
1656  int i;
1657 
1659  _dbus_assert (start <= real->len);
1660  _dbus_assert (start >= 0);
1661 
1662  i = start;
1663  while (i < real->len)
1664  {
1665  if (real->str[i] == '\r')
1666  {
1667  if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1668  {
1669  if (found)
1670  *found = i;
1671  if (found_len)
1672  *found_len = 2;
1673  return TRUE;
1674  }
1675  else /* only "\r" */
1676  {
1677  if (found)
1678  *found = i;
1679  if (found_len)
1680  *found_len = 1;
1681  return TRUE;
1682  }
1683  }
1684  else if (real->str[i] == '\n') /* only "\n" */
1685  {
1686  if (found)
1687  *found = i;
1688  if (found_len)
1689  *found_len = 1;
1690  return TRUE;
1691  }
1692  ++i;
1693  }
1694 
1695  if (found)
1696  *found = real->len;
1697 
1698  if (found_len)
1699  *found_len = 0;
1700 
1701  return FALSE;
1702 }
1703 
1722  int start,
1723  int end,
1724  const char *substr,
1725  int *found)
1726 {
1727  int i;
1729  _dbus_assert (substr != NULL);
1730  _dbus_assert (start <= real->len);
1731  _dbus_assert (start >= 0);
1732  _dbus_assert (substr != NULL);
1733  _dbus_assert (end <= real->len);
1734  _dbus_assert (start <= end);
1735 
1736  /* we always "find" an empty string */
1737  if (*substr == '\0')
1738  {
1739  if (found)
1740  *found = start;
1741  return TRUE;
1742  }
1743 
1744  i = start;
1745  while (i < end)
1746  {
1747  if (real->str[i] == substr[0])
1748  {
1749  int j = i + 1;
1750 
1751  while (j < end)
1752  {
1753  if (substr[j - i] == '\0')
1754  break;
1755  else if (real->str[j] != substr[j - i])
1756  break;
1757 
1758  ++j;
1759  }
1760 
1761  if (substr[j - i] == '\0')
1762  {
1763  if (found)
1764  *found = i;
1765  return TRUE;
1766  }
1767  }
1768 
1769  ++i;
1770  }
1771 
1772  if (found)
1773  *found = end;
1774 
1775  return FALSE;
1776 }
1777 
1790  int start,
1791  int *found)
1792 {
1793  int i;
1795  _dbus_assert (start <= real->len);
1796  _dbus_assert (start >= 0);
1797 
1798  i = start;
1799  while (i < real->len)
1800  {
1801  if (real->str[i] == ' ' ||
1802  real->str[i] == '\t')
1803  {
1804  if (found)
1805  *found = i;
1806  return TRUE;
1807  }
1808 
1809  ++i;
1810  }
1811 
1812  if (found)
1813  *found = real->len;
1814 
1815  return FALSE;
1816 }
1817 
1826 void
1828  int start,
1829  int *end)
1830 {
1831  int i;
1833  _dbus_assert (start <= real->len);
1834  _dbus_assert (start >= 0);
1835 
1836  i = start;
1837  while (i < real->len)
1838  {
1839  if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1840  break;
1841 
1842  ++i;
1843  }
1844 
1845  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1846 
1847  if (end)
1848  *end = i;
1849 }
1850 
1851 
1860 void
1862  int start,
1863  int *end)
1864 {
1865  int i;
1867  _dbus_assert (start <= real->len);
1868  _dbus_assert (start >= 0);
1869 
1870  i = start;
1871  while (i < real->len)
1872  {
1873  if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1874  break;
1875 
1876  ++i;
1877  }
1878 
1879  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1880 
1881  if (end)
1882  *end = i;
1883 }
1884 
1893 void
1895  int end,
1896  int *start)
1897 {
1898  int i;
1900  _dbus_assert (end <= real->len);
1901  _dbus_assert (end >= 0);
1902 
1903  i = end;
1904  while (i > 0)
1905  {
1906  if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1907  break;
1908  --i;
1909  }
1910 
1911  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1912 
1913  if (start)
1914  *start = i;
1915 }
1916 
1934  DBusString *dest)
1935 {
1936  int eol, eol_len;
1937 
1938  _dbus_string_set_length (dest, 0);
1939 
1940  eol = 0;
1941  eol_len = 0;
1942  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1943  {
1944  _dbus_assert (eol == _dbus_string_get_length (source));
1945  if (eol == 0)
1946  {
1947  /* If there's no newline and source has zero length, we're done */
1948  return FALSE;
1949  }
1950  /* otherwise, the last line of the file has no eol characters */
1951  }
1952 
1953  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1954  * since find_eol returned TRUE
1955  */
1956 
1957  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1958  return FALSE;
1959 
1960  /* remove line ending */
1961  if (!_dbus_string_set_length (dest, eol))
1962  {
1963  _dbus_assert_not_reached ("out of memory when shortening a string");
1964  return FALSE;
1965  }
1966 
1967  return TRUE;
1968 }
1969 
1970 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1977 void
1978 _dbus_string_delete_first_word (DBusString *str)
1979 {
1980  int i;
1981 
1982  if (_dbus_string_find_blank (str, 0, &i))
1983  _dbus_string_skip_blank (str, i, &i);
1984 
1985  _dbus_string_delete (str, 0, i);
1986 }
1987 #endif
1988 
1989 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1995 void
1996 _dbus_string_delete_leading_blanks (DBusString *str)
1997 {
1998  int i;
1999 
2000  _dbus_string_skip_blank (str, 0, &i);
2001 
2002  if (i > 0)
2003  _dbus_string_delete (str, 0, i);
2004 }
2005 #endif
2006 
2012 void
2014 {
2015  int i;
2016 
2017  _dbus_string_skip_white (str, 0, &i);
2018 
2019  if (i > 0)
2020  _dbus_string_delete (str, 0, i);
2021 
2022  _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
2023 
2024  _dbus_string_set_length (str, i);
2025 }
2026 
2038  const DBusString *b)
2039 {
2040  const unsigned char *ap;
2041  const unsigned char *bp;
2042  const unsigned char *a_end;
2043  const DBusRealString *real_a = (const DBusRealString*) a;
2044  const DBusRealString *real_b = (const DBusRealString*) b;
2047 
2048  if (real_a->len != real_b->len)
2049  return FALSE;
2050 
2051  ap = real_a->str;
2052  bp = real_b->str;
2053  a_end = real_a->str + real_a->len;
2054  while (ap != a_end)
2055  {
2056  if (*ap != *bp)
2057  return FALSE;
2058 
2059  ++ap;
2060  ++bp;
2061  }
2062 
2063  return TRUE;
2064 }
2065 
2081  const DBusString *b,
2082  int len)
2083 {
2084  const unsigned char *ap;
2085  const unsigned char *bp;
2086  const unsigned char *a_end;
2087  const DBusRealString *real_a = (const DBusRealString*) a;
2088  const DBusRealString *real_b = (const DBusRealString*) b;
2091 
2092  if (real_a->len != real_b->len &&
2093  (real_a->len < len || real_b->len < len))
2094  return FALSE;
2095 
2096  ap = real_a->str;
2097  bp = real_b->str;
2098  a_end = real_a->str + MIN (real_a->len, len);
2099  while (ap != a_end)
2100  {
2101  if (*ap != *bp)
2102  return FALSE;
2103 
2104  ++ap;
2105  ++bp;
2106  }
2107 
2108  return TRUE;
2109 }
2110 
2129  int a_start,
2130  int a_len,
2131  const DBusString *b,
2132  int b_start)
2133 {
2134  const unsigned char *ap;
2135  const unsigned char *bp;
2136  const unsigned char *a_end;
2137  const DBusRealString *real_a = (const DBusRealString*) a;
2138  const DBusRealString *real_b = (const DBusRealString*) b;
2141  _dbus_assert (a_start >= 0);
2142  _dbus_assert (a_len >= 0);
2143  _dbus_assert (a_start <= real_a->len);
2144  _dbus_assert (a_len <= real_a->len - a_start);
2145  _dbus_assert (b_start >= 0);
2146  _dbus_assert (b_start <= real_b->len);
2147 
2148  if (a_len > real_b->len - b_start)
2149  return FALSE;
2150 
2151  ap = real_a->str + a_start;
2152  bp = real_b->str + b_start;
2153  a_end = ap + a_len;
2154  while (ap != a_end)
2155  {
2156  if (*ap != *bp)
2157  return FALSE;
2158 
2159  ++ap;
2160  ++bp;
2161  }
2162 
2163  _dbus_assert (bp <= (real_b->str + real_b->len));
2164 
2165  return TRUE;
2166 }
2167 
2177  const char *c_str)
2178 {
2179  const unsigned char *ap;
2180  const unsigned char *bp;
2181  const unsigned char *a_end;
2182  const DBusRealString *real_a = (const DBusRealString*) a;
2184  _dbus_assert (c_str != NULL);
2185 
2186  ap = real_a->str;
2187  bp = (const unsigned char*) c_str;
2188  a_end = real_a->str + real_a->len;
2189  while (ap != a_end && *bp)
2190  {
2191  if (*ap != *bp)
2192  return FALSE;
2193 
2194  ++ap;
2195  ++bp;
2196  }
2197 
2198  if (ap != a_end || *bp)
2199  return FALSE;
2200 
2201  return TRUE;
2202 }
2203 
2213  const char *c_str)
2214 {
2215  const unsigned char *ap;
2216  const unsigned char *bp;
2217  const unsigned char *a_end;
2218  const DBusRealString *real_a = (const DBusRealString*) a;
2220  _dbus_assert (c_str != NULL);
2221 
2222  ap = real_a->str;
2223  bp = (const unsigned char*) c_str;
2224  a_end = real_a->str + real_a->len;
2225  while (ap != a_end && *bp)
2226  {
2227  if (*ap != *bp)
2228  return FALSE;
2229 
2230  ++ap;
2231  ++bp;
2232  }
2233 
2234  if (*bp == '\0')
2235  return TRUE;
2236  else
2237  return FALSE;
2238 }
2239 
2251  const char *c_str,
2252  char word_separator)
2253 {
2254  char next_char;
2255  const char *data;
2256  _dbus_assert (c_str != NULL);
2257 
2258  if (!_dbus_string_starts_with_c_str (a, c_str))
2259  return FALSE;
2260 
2261  data = _dbus_string_get_const_data (a);
2262  next_char = data[strlen (c_str)];
2263  return next_char == '\0' || next_char == word_separator;
2264 }
2265 
2276  unsigned char byte)
2277 {
2278  const char hexdigits[16] = {
2279  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2280  'a', 'b', 'c', 'd', 'e', 'f'
2281  };
2282 
2283  if (!_dbus_string_append_byte (str,
2284  hexdigits[(byte >> 4)]))
2285  return FALSE;
2286 
2287  if (!_dbus_string_append_byte (str,
2288  hexdigits[(byte & 0x0f)]))
2289  {
2291  _dbus_string_get_length (str) - 1);
2292  return FALSE;
2293  }
2294 
2295  return TRUE;
2296 }
2297 
2310  int start,
2311  DBusString *dest,
2312  int insert_at)
2313 {
2314  DBusString result;
2315  const unsigned char *p;
2316  const unsigned char *end;
2317  dbus_bool_t retval;
2318 
2319  _dbus_assert (start <= _dbus_string_get_length (source));
2320 
2321  if (!_dbus_string_init (&result))
2322  return FALSE;
2323 
2324  retval = FALSE;
2325 
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  if (!_dbus_string_append_byte_as_hex (&result, *p))
2333  goto out;
2334 
2335  ++p;
2336  }
2337 
2338  if (!_dbus_string_move (&result, 0, dest, insert_at))
2339  goto out;
2340 
2341  retval = TRUE;
2342 
2343  out:
2344  _dbus_string_free (&result);
2345  return retval;
2346 }
2347 
2360  int start,
2361  int *end_return,
2362  DBusString *dest,
2363  int insert_at)
2364 {
2365  DBusString result;
2366  const unsigned char *p;
2367  const unsigned char *end;
2368  dbus_bool_t retval;
2369  dbus_bool_t high_bits;
2370 
2371  _dbus_assert (start <= _dbus_string_get_length (source));
2372 
2373  if (!_dbus_string_init (&result))
2374  return FALSE;
2375 
2376  retval = FALSE;
2377 
2378  high_bits = TRUE;
2379  p = (const unsigned char*) _dbus_string_get_const_data (source);
2380  end = p + _dbus_string_get_length (source);
2381  p += start;
2382 
2383  while (p != end)
2384  {
2385  unsigned int val;
2386 
2387  switch (*p)
2388  {
2389  case '0':
2390  val = 0;
2391  break;
2392  case '1':
2393  val = 1;
2394  break;
2395  case '2':
2396  val = 2;
2397  break;
2398  case '3':
2399  val = 3;
2400  break;
2401  case '4':
2402  val = 4;
2403  break;
2404  case '5':
2405  val = 5;
2406  break;
2407  case '6':
2408  val = 6;
2409  break;
2410  case '7':
2411  val = 7;
2412  break;
2413  case '8':
2414  val = 8;
2415  break;
2416  case '9':
2417  val = 9;
2418  break;
2419  case 'a':
2420  case 'A':
2421  val = 10;
2422  break;
2423  case 'b':
2424  case 'B':
2425  val = 11;
2426  break;
2427  case 'c':
2428  case 'C':
2429  val = 12;
2430  break;
2431  case 'd':
2432  case 'D':
2433  val = 13;
2434  break;
2435  case 'e':
2436  case 'E':
2437  val = 14;
2438  break;
2439  case 'f':
2440  case 'F':
2441  val = 15;
2442  break;
2443  default:
2444  goto done;
2445  }
2446 
2447  if (high_bits)
2448  {
2449  if (!_dbus_string_append_byte (&result,
2450  val << 4))
2451  goto out;
2452  }
2453  else
2454  {
2455  int len;
2456  unsigned char b;
2457 
2458  len = _dbus_string_get_length (&result);
2459 
2460  b = _dbus_string_get_byte (&result, len - 1);
2461 
2462  b |= val;
2463 
2464  _dbus_string_set_byte (&result, len - 1, b);
2465  }
2466 
2467  high_bits = !high_bits;
2468 
2469  ++p;
2470  }
2471 
2472  done:
2473  if (!_dbus_string_move (&result, 0, dest, insert_at))
2474  goto out;
2475 
2476  if (end_return)
2477  *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2478 
2479  retval = TRUE;
2480 
2481  out:
2482  _dbus_string_free (&result);
2483  return retval;
2484 }
2485 
2501  int start,
2502  int len)
2503 {
2504  const unsigned char *s;
2505  const unsigned char *end;
2507  _dbus_assert (start >= 0);
2508  _dbus_assert (start <= real->len);
2509  _dbus_assert (len >= 0);
2510 
2511  if (len > real->len - start)
2512  return FALSE;
2513 
2514  s = real->str + start;
2515  end = s + len;
2516  while (s != end)
2517  {
2518  if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2519  return FALSE;
2520 
2521  ++s;
2522  }
2523 
2524  return TRUE;
2525 }
2526 
2534 void
2536  int start,
2537  int len)
2538 {
2539  unsigned char *s;
2540  unsigned char *end;
2541  DBUS_STRING_PREAMBLE (str);
2542  _dbus_assert (start >= 0);
2543  _dbus_assert (start <= real->len);
2544  _dbus_assert (len >= 0);
2545  _dbus_assert (len <= real->len - start);
2546 
2547  s = real->str + start;
2548  end = s + len;
2549 
2550  while (s != end)
2551  {
2552  if (*s >= 'A' && *s <= 'Z')
2553  *s += 'a' - 'A';
2554  ++s;
2555  }
2556 }
2557 
2565 void
2567  int start,
2568  int len)
2569 {
2570  unsigned char *s;
2571  unsigned char *end;
2572  DBUS_STRING_PREAMBLE (str);
2573  _dbus_assert (start >= 0);
2574  _dbus_assert (start <= real->len);
2575  _dbus_assert (len >= 0);
2576  _dbus_assert (len <= real->len - start);
2577 
2578  s = real->str + start;
2579  end = s + len;
2580 
2581  while (s != end)
2582  {
2583  if (*s >= 'a' && *s <= 'z')
2584  *s += 'A' - 'a';
2585  ++s;
2586  }
2587 }
2588 
2606  int start,
2607  int len)
2608 {
2609  const unsigned char *p;
2610  const unsigned char *end;
2612  _dbus_assert (start >= 0);
2613  _dbus_assert (start <= real->len);
2614  _dbus_assert (len >= 0);
2615 
2616  /* we are doing _DBUS_UNLIKELY() here which might be
2617  * dubious in a generic library like GLib, but in D-Bus
2618  * we know we're validating messages and that it would
2619  * only be evil/broken apps that would have invalid
2620  * UTF-8. Also, this function seems to be a performance
2621  * bottleneck in profiles.
2622  */
2623 
2624  if (_DBUS_UNLIKELY (len > real->len - start))
2625  return FALSE;
2626 
2627  p = real->str + start;
2628  end = p + len;
2629 
2630  while (p < end)
2631  {
2632  int i, mask, char_len;
2633  dbus_unichar_t result;
2634 
2635  /* nul bytes considered invalid */
2636  if (*p == '\0')
2637  break;
2638 
2639  /* Special-case ASCII; this makes us go a lot faster in
2640  * D-Bus profiles where we are typically validating
2641  * function names and such. We have to know that
2642  * all following checks will pass for ASCII though,
2643  * comments follow ...
2644  */
2645  if (*p < 128)
2646  {
2647  ++p;
2648  continue;
2649  }
2650 
2651  UTF8_COMPUTE (*p, mask, char_len);
2652 
2653  if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2654  break;
2655 
2656  /* check that the expected number of bytes exists in the remaining length */
2657  if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2658  break;
2659 
2660  UTF8_GET (result, p, i, mask, char_len);
2661 
2662  /* Check for overlong UTF-8 */
2663  if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2664  break;
2665 #if 0
2666  /* The UNICODE_VALID check below will catch this */
2667  if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2668  break;
2669 #endif
2670 
2671  if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2672  break;
2673 
2674  /* UNICODE_VALID should have caught it */
2675  _dbus_assert (result != (dbus_unichar_t)-1);
2676 
2677  p += char_len;
2678  }
2679 
2680  /* See that we covered the entire length if a length was
2681  * passed in
2682  */
2683  if (_DBUS_UNLIKELY (p != end))
2684  return FALSE;
2685  else
2686  return TRUE;
2687 }
2688 
2704  int start,
2705  int len)
2706 {
2707  const unsigned char *s;
2708  const unsigned char *end;
2710  _dbus_assert (start >= 0);
2711  _dbus_assert (len >= 0);
2712  _dbus_assert (start <= real->len);
2713 
2714  if (len > real->len - start)
2715  return FALSE;
2716 
2717  s = real->str + start;
2718  end = s + len;
2719  while (s != end)
2720  {
2721  if (_DBUS_UNLIKELY (*s != '\0'))
2722  return FALSE;
2723  ++s;
2724  }
2725 
2726  return TRUE;
2727 }
2728 
2734 void
2736 {
2737  DBUS_STRING_PREAMBLE (str);
2738 
2739  memset (real->str - real->align_offset, '\0', real->allocated);
2740 }
2743 /* tests are in dbus-string-util.c */
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:704
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:604
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:464
#define _DBUS_STRING_MAX_LENGTH
The maximum length of a DBusString.
#define DBUS_STRING_PREAMBLE(str)
Checks assertions about a string object that needs to be modifiable - may not be locked or const.
#define DBUS_CONST_STRING_PREAMBLE(str)
Checks assertions about a string that may be const or locked.
#define DBUS_GENERIC_STRING_PREAMBLE(real)
Checks a bunch of assertions about a string object.
#define DBUS_IS_ASCII_BLANK(c)
Checks for ASCII blank byte.
#define DBUS_IS_ASCII_WHITE(c)
Checks for ASCII whitespace byte.
#define DBUS_LOCKED_STRING_PREAMBLE(str)
Checks assertions about a string object that may be locked but can't be const.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:826
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:2359
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:959
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:1044
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:2703
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:2128
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1609
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:1072
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1529
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
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's copied to the d...
Definition: dbus-string.c:1307
dbus_bool_t _dbus_string_find_eol(const DBusString *str, int start, int *found, int *found_len)
Finds end of line ("\r\n" or "\n") in the string, returning TRUE and filling in the byte index where ...
Definition: dbus-string.c:1651
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:975
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:2212
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:923
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:665
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:1827
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:139
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:1894
dbus_bool_t _dbus_string_init_from_string(DBusString *str, const DBusString *from)
Initializes a string from another string.
Definition: dbus-string.c:252
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:1491
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:1628
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:2605
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:1789
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:217
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:2535
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:1161
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:271
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:514
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:804
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:1217
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:696
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:2176
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:1861
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:1933
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:1096
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:784
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2735
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1570
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:2566
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:608
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:2500
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:1181
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:2013
dbus_bool_t _dbus_string_starts_with_words_c_str(const DBusString *a, const char *c_str, char word_separator)
Checks whether a string starts with the given C string, after which it ends or is separated from the ...
Definition: dbus-string.c:2250
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:2309
#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)
Checks assertions for two strings we're copying a segment between, and declares real_source/real_dest...
Definition: dbus-string.c:1259
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:1138
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:638
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1586
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:1332
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:743
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:413
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:2080
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:983
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:1283
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2037
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:1020
dbus_bool_t _dbus_string_insert_2_aligned(DBusString *str, int insert_at, const unsigned char octets[2])
Inserts 2 bytes aligned on a 2 byte boundary with any alignment padding initialized to 0.
Definition: dbus-string.c:996
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:979
dbus_bool_t _dbus_string_append_byte_as_hex(DBusString *str, unsigned char 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:2275
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:907
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:1721
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:1399
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:721
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:1428
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_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
Internals of DBusString.
unsigned int align_offset
str - align_offset is the actual malloc block
unsigned int valid
DBusString is valid (initialized and not freed)
unsigned int constant
String data is not owned by DBusString.
unsigned int locked
DBusString has been locked and can't be changed.
unsigned char * str
String data, plus nul termination.
int allocated
Allocated size of data.
int len
Length without nul.