D-Bus  1.13.16
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
463 
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
485 
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
529 
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
554 
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
576 
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
757 
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
1971 
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
1990 
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 */
DBusRealString::str
unsigned char * str
String data, plus nul termination.
Definition: dbus-string-private.h:45
_dbus_string_copy_to_buffer_with_nul
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
DBusRealString::len
int len
Length without nul.
Definition: dbus-string-private.h:46
dbus_realloc
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
_dbus_string_hex_decode
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_string_copy_to_buffer
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_string_skip_white_reverse
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
DBusRealString::valid
unsigned int valid
DBusString is valid (initialized and not freed)
Definition: dbus-string-private.h:50
_dbus_string_free
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
ASSIGN_4_OCTETS
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:979
UTF8_GET
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1586
_dbus_string_compact
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:413
DBUS_GENERIC_STRING_PREAMBLE
#define DBUS_GENERIC_STRING_PREAMBLE(real)
Checks a bunch of assertions about a string object.
Definition: dbus-string-private.h:76
DBUS_STRING_PREAMBLE
#define DBUS_STRING_PREAMBLE(str)
Checks assertions about a string object that needs to be modifiable - may not be locked or const.
Definition: dbus-string-private.h:93
DBusRealString
Internals of DBusString.
Definition: dbus-string-private.h:43
DBUS_LOCKED_STRING_PREAMBLE
#define DBUS_LOCKED_STRING_PREAMBLE(str)
Checks assertions about a string object that may be locked but can't be const.
Definition: dbus-string-private.h:105
UTF8_LENGTH
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1570
_dbus_string_copy
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_string_lengthen
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
_dbus_string_copy_data
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_string_equal_len
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
_dbus_string_validate_ascii
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_string_append_len
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
_dbus_string_zero
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2735
_dbus_string_split_on_byte
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_IS_ASCII_BLANK
#define DBUS_IS_ASCII_BLANK(c)
Checks for ASCII blank byte.
Definition: dbus-string-private.h:121
_dbus_string_append_byte
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
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
_dbus_string_append_printf_valist
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_string_chop_white
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:2013
_dbus_string_validate_nul
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
TRUE
#define TRUE
_dbus_string_find
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_STRING_COPY_PREAMBLE
#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_string_insert_2_aligned
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
DBUS_IS_ASCII_WHITE
#define DBUS_IS_ASCII_WHITE(c)
Checks for ASCII whitespace byte.
Definition: dbus-string-private.h:127
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:704
dbus_malloc
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:464
_dbus_string_init_preallocated
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
DBusString
Definition: dbus-string.h:42
DBusRealString::locked
unsigned int locked
DBusString has been locked and can't be changed.
Definition: dbus-string-private.h:49
_dbus_string_append_printf
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_string_find_to
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_string_insert_byte
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
_dbus_string_insert_8_aligned
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_string_move_len
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
_dbus_string_skip_white
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_CONST_STRING_PREAMBLE
#define DBUS_CONST_STRING_PREAMBLE(str)
Checks assertions about a string that may be const or locked.
Definition: dbus-string-private.h:114
_dbus_printf_string_upper_bound
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.
Definition: dbus-sysdeps-unix.c:3779
_dbus_string_insert_bytes
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_string_find_blank
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
FALSE
#define FALSE
_dbus_string_starts_with_words_c_str
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_string_get_data_len
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
_dbus_string_find_eol
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
_dbus_string_replace_len
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
DBusRealString::align_offset
unsigned int align_offset
str - align_offset is the actual malloc block
Definition: dbus-string-private.h:51
_dbus_string_pop_line
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_string_delete
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_STRING_MAX_LENGTH
#define _DBUS_STRING_MAX_LENGTH
The maximum length of a DBusString.
Definition: dbus-string-private.h:69
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Definition: dbus-internals.h:164
_dbus_string_append_byte_as_hex
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_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:826
ASSIGN_8_OCTETS
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:983
_dbus_string_toupper_ascii
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_string_tolower_ascii
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_string_insert_alignment
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
UNICODE_VALID
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1609
_dbus_assert
#define _dbus_assert(condition)
Definition: dbus-internals.h:153
_dbus_string_init_from_string
dbus_bool_t _dbus_string_init_from_string(DBusString *str, const DBusString *from)
Initializes a string from another string.
Definition: dbus-string.c:252
DBusRealString::constant
unsigned int constant
String data is not owned by DBusString.
Definition: dbus-string-private.h:48
_dbus_string_skip_blank
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_string_validate_utf8
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_string_hex_encode
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
_dbus_string_equal_substring
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
_dbus_string_steal_data
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
_dbus_string_starts_with_c_str
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_string_alloc_space
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_string_align_length
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
ASSIGN_2_OCTETS
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:975
_dbus_string_move
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_string_equal_c_str
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
_dbus_string_insert_4_aligned
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_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
_dbus_string_copy_len
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
_dbus_string_shorten
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
UTF8_COMPUTE
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1529
_dbus_string_append
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
DBusRealString::allocated
int allocated
Allocated size of data.
Definition: dbus-string-private.h:47
_dbus_string_init_const_len
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
dbus_bool_t
dbus_uint32_t dbus_bool_t
Definition: dbus-types.h:35
NULL
#define NULL
_dbus_string_equal
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2037