D-Bus  1.14.10
dbus-string.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-string.c String utility class (internal to D-Bus implementation)
3  *
4  * Copyright 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 
255  const DBusString *from)
256 {
257  if (!_dbus_string_init (str))
258  return FALSE;
259  if (!_dbus_string_append (str, _dbus_string_get_const_data (from)))
260  {
261  _dbus_string_free (str);
262  return FALSE;
263  }
264  return TRUE;
265 }
266 
277 void
279 {
280  DBusRealString *real = (DBusRealString*) str;
281  /* DBusRealString and DBusString have the same members in the same order,
282  * just differently-named */
283  DBusRealString invalid = _DBUS_STRING_INIT_INVALID;
284 
285  /* Allow for the _DBUS_STRING_INIT_INVALID case */
286  if (real->str == NULL && real->len == 0 && real->allocated == 0 &&
287  !real->constant && !real->locked && !real->valid &&
288  real->align_offset == 0)
289  return;
290 
292 
293  if (real->constant)
294  goto wipe;
295 
296  /* so it's safe if @p str returned by a failed
297  * _dbus_string_init call
298  * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
299  */
300  if (real->str == NULL)
301  goto wipe;
302 
303  dbus_free (real->str - real->align_offset);
304 
305 wipe:
306  *real = invalid;
307  real->valid = FALSE;
308 }
309 
310 static dbus_bool_t
311 compact (DBusRealString *real,
312  int max_waste)
313 {
314  unsigned char *new_str;
315  int new_allocated;
316  int waste;
317 
318  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
319 
320  if (waste <= max_waste)
321  return TRUE;
322 
323  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
324 
325  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
326  if (_DBUS_UNLIKELY (new_str == NULL))
327  return FALSE;
328 
329  real->str = new_str + real->align_offset;
330  real->allocated = new_allocated;
331  fixup_alignment (real);
332 
333  return TRUE;
334 }
335 
336 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
337 /* Not using this feature at the moment,
338  * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
339  */
349 void
350 _dbus_string_lock (DBusString *str)
351 {
352  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
353 
354  real->locked = TRUE;
355 
356  /* Try to realloc to avoid excess memory usage, since
357  * we know we won't change the string further
358  */
359 #define MAX_WASTE 48
360  compact (real, MAX_WASTE);
361 }
362 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
363 
364 static dbus_bool_t
365 reallocate_for_length (DBusRealString *real,
366  int new_length)
367 {
368  int new_allocated;
369  unsigned char *new_str;
370 
371  /* at least double our old allocation to avoid O(n), avoiding
372  * overflow
373  */
374  if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
375  new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
376  else
377  new_allocated = real->allocated * 2;
378 
379  /* if you change the code just above here, run the tests without
380  * the following assert-only hack before you commit
381  */
382  /* This is keyed off asserts in addition to tests so when you
383  * disable asserts to profile, you don't get this destroyer
384  * of profiles.
385  */
386 #if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
387  new_allocated = 0; /* ensure a realloc every time so that we go
388  * through all malloc failure codepaths
389  */
390 #endif
391 
392  /* But be sure we always alloc at least space for the new length */
393  new_allocated = MAX (new_allocated,
394  new_length + _DBUS_STRING_ALLOCATION_PADDING);
395 
396  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
397  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
398  if (_DBUS_UNLIKELY (new_str == NULL))
399  return FALSE;
400 
401  real->str = new_str + real->align_offset;
402  real->allocated = new_allocated;
403  fixup_alignment (real);
404 
405  return TRUE;
406 }
407 
421  int max_waste)
422 {
423  DBUS_STRING_PREAMBLE (str);
424 
425  return compact (real, max_waste);
426 }
427 
428 static dbus_bool_t
429 set_length (DBusRealString *real,
430  int new_length)
431 {
432  /* Note, we are setting the length not including nul termination */
433 
434  /* exceeding max length is the same as failure to allocate memory */
435  if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
436  return FALSE;
437  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
438  _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
439  return FALSE;
440  else
441  {
442  real->len = new_length;
443  real->str[new_length] = '\0';
444  return TRUE;
445  }
446 }
447 
448 static dbus_bool_t
449 open_gap (int len,
450  DBusRealString *dest,
451  int insert_at)
452 {
453  if (len == 0)
454  return TRUE;
455 
456  if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
457  return FALSE; /* detected overflow of dest->len + len below */
458 
459  if (!set_length (dest, dest->len + len))
460  return FALSE;
461 
462  memmove (dest->str + insert_at + len,
463  dest->str + insert_at,
464  dest->len - len - insert_at);
465 
466  return TRUE;
467 }
468 
469 #ifndef _dbus_string_get_data
481 char*
482 _dbus_string_get_data (DBusString *str)
483 {
484  DBUS_STRING_PREAMBLE (str);
485 
486  return (char*) real->str;
487 }
488 #endif /* _dbus_string_get_data */
489 
490 /* only do the function if we don't have the macro */
491 #ifndef _dbus_string_get_const_data
498 const char*
499 _dbus_string_get_const_data (const DBusString *str)
500 {
502 
503  return (const char*) real->str;
504 }
505 #endif /* _dbus_string_get_const_data */
506 
520 char*
522  int start,
523  int len)
524 {
525  DBUS_STRING_PREAMBLE (str);
526  _dbus_assert (start >= 0);
527  _dbus_assert (len >= 0);
528  _dbus_assert (start <= real->len);
529  _dbus_assert (len <= real->len - start);
530 
531  return (char*) real->str + start;
532 }
533 
534 /* only do the function if we don't have the macro */
535 #ifndef _dbus_string_get_const_data_len
544 const char*
545 _dbus_string_get_const_data_len (const DBusString *str,
546  int start,
547  int len)
548 {
550  _dbus_assert (start >= 0);
551  _dbus_assert (len >= 0);
552  _dbus_assert (start <= real->len);
553  _dbus_assert (len <= real->len - start);
554 
555  return (const char*) real->str + start;
556 }
557 #endif /* _dbus_string_get_const_data_len */
558 
559 /* only do the function if we don't have the macro */
560 #ifndef _dbus_string_set_byte
568 void
569 _dbus_string_set_byte (DBusString *str,
570  int i,
571  unsigned char byte)
572 {
573  DBUS_STRING_PREAMBLE (str);
574  _dbus_assert (i < real->len);
575  _dbus_assert (i >= 0);
576 
577  real->str[i] = byte;
578 }
579 #endif /* _dbus_string_set_byte */
580 
581 /* only have the function if we didn't create a macro */
582 #ifndef _dbus_string_get_byte
592 unsigned char
593 _dbus_string_get_byte (const DBusString *str,
594  int start)
595 {
597  _dbus_assert (start <= real->len);
598  _dbus_assert (start >= 0);
599 
600  return real->str[start];
601 }
602 #endif /* _dbus_string_get_byte */
603 
616  int i,
617  int n_bytes,
618  unsigned char byte)
619 {
620  DBUS_STRING_PREAMBLE (str);
621  _dbus_assert (i <= real->len);
622  _dbus_assert (i >= 0);
623  _dbus_assert (n_bytes >= 0);
624 
625  if (n_bytes == 0)
626  return TRUE;
627 
628  if (!open_gap (n_bytes, real, i))
629  return FALSE;
630 
631  memset (real->str + i, byte, n_bytes);
632 
633  return TRUE;
634 }
635 
646  int i,
647  unsigned char byte)
648 {
649  DBUS_STRING_PREAMBLE (str);
650  _dbus_assert (i <= real->len);
651  _dbus_assert (i >= 0);
652 
653  if (!open_gap (1, real, i))
654  return FALSE;
655 
656  real->str[i] = byte;
657 
658  return TRUE;
659 }
660 
673  char **data_return)
674 {
675  DBUS_STRING_PREAMBLE (str);
676  _dbus_assert (data_return != NULL);
677 
678  undo_alignment (real);
679 
680  *data_return = (char*) real->str;
681 
682  /* reset the string */
683  if (!_dbus_string_init (str))
684  {
685  /* hrm, put it back then */
686  real->str = (unsigned char*) *data_return;
687  *data_return = NULL;
688  fixup_alignment (real);
689  return FALSE;
690  }
691 
692  return TRUE;
693 }
694 
704  char **data_return)
705 {
707  _dbus_assert (data_return != NULL);
708 
709  *data_return = dbus_malloc (real->len + 1);
710  if (*data_return == NULL)
711  return FALSE;
712 
713  memcpy (*data_return, real->str, real->len + 1);
714 
715  return TRUE;
716 }
717 
727 void
729  char *buffer,
730  int avail_len)
731 {
733 
734  _dbus_assert (avail_len >= 0);
735  _dbus_assert (avail_len >= real->len);
736 
737  memcpy (buffer, real->str, real->len);
738 }
739 
749 void
751  char *buffer,
752  int avail_len)
753 {
755 
756  _dbus_assert (avail_len >= 0);
757  _dbus_assert (avail_len > real->len);
758 
759  memcpy (buffer, real->str, real->len+1);
760 }
761 
762 /* Only have the function if we don't have the macro */
763 #ifndef _dbus_string_get_length
769 int
770 _dbus_string_get_length (const DBusString *str)
771 {
773 
774  return real->len;
775 }
776 #endif /* !_dbus_string_get_length */
777 
792  int additional_length)
793 {
794  DBUS_STRING_PREAMBLE (str);
795  _dbus_assert (additional_length >= 0);
796 
797  if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
798  return FALSE; /* would overflow */
799 
800  return set_length (real,
801  real->len + additional_length);
802 }
803 
810 void
812  int length_to_remove)
813 {
814  DBUS_STRING_PREAMBLE (str);
815  _dbus_assert (length_to_remove >= 0);
816  _dbus_assert (length_to_remove <= real->len);
817 
818  set_length (real,
819  real->len - length_to_remove);
820 }
821 
834  int length)
835 {
836  DBUS_STRING_PREAMBLE (str);
837  _dbus_assert (length >= 0);
838 
839  return set_length (real, length);
840 }
841 
842 static dbus_bool_t
843 align_insert_point_then_open_gap (DBusString *str,
844  int *insert_at_p,
845  int alignment,
846  int gap_size)
847 {
848  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
849  unsigned long gap_pos;
850  int insert_at;
851  int delta;
852  DBUS_STRING_PREAMBLE (str);
853  _dbus_assert (alignment >= 1);
854  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
855 
856  insert_at = *insert_at_p;
857 
858  _dbus_assert (insert_at <= real->len);
859 
860  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
861  new_len = real->len + (gap_pos - insert_at) + gap_size;
862 
863  if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
864  return FALSE;
865 
866  delta = new_len - real->len;
867  _dbus_assert (delta >= 0);
868 
869  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
870  {
871  _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
872  return TRUE;
873  }
874 
875  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
876  real, insert_at)))
877  return FALSE;
878 
879  /* nul the padding if we had to add any padding */
880  if (gap_size < delta)
881  {
882  memset (&real->str[insert_at], '\0',
883  gap_pos - insert_at);
884  }
885 
886  *insert_at_p = gap_pos;
887 
888  return TRUE;
889 }
890 
891 static dbus_bool_t
892 align_length_then_lengthen (DBusString *str,
893  int alignment,
894  int then_lengthen_by)
895 {
896  int insert_at;
897 
898  insert_at = _dbus_string_get_length (str);
899 
900  return align_insert_point_then_open_gap (str,
901  &insert_at,
902  alignment, then_lengthen_by);
903 }
904 
915  int alignment)
916 {
917  return align_length_then_lengthen (str, alignment, 0);
918 }
919 
931  int extra_bytes)
932 {
933  if (!_dbus_string_lengthen (str, extra_bytes))
934  return FALSE;
935  _dbus_string_shorten (str, extra_bytes);
936 
937  return TRUE;
938 }
939 
940 static dbus_bool_t
941 append (DBusRealString *real,
942  const char *buffer,
943  int buffer_len)
944 {
945  if (buffer_len == 0)
946  return TRUE;
947 
948  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
949  return FALSE;
950 
951  memcpy (real->str + (real->len - buffer_len),
952  buffer,
953  buffer_len);
954 
955  return TRUE;
956 }
957 
967  const char *buffer)
968 {
969  unsigned long buffer_len;
970 
971  DBUS_STRING_PREAMBLE (str);
972  _dbus_assert (buffer != NULL);
973 
974  buffer_len = strlen (buffer);
975  if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
976  return FALSE;
977 
978  return append (real, buffer, buffer_len);
979 }
980 
982 #define ASSIGN_2_OCTETS(p, octets) \
983  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
984 
986 #define ASSIGN_4_OCTETS(p, octets) \
987  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
988 
990 #define ASSIGN_8_OCTETS(p, octets) \
991  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
992 
1004  int insert_at,
1005  const unsigned char octets[2])
1006 {
1007  DBUS_STRING_PREAMBLE (str);
1008 
1009  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
1010  return FALSE;
1011 
1012  ASSIGN_2_OCTETS (real->str + insert_at, octets);
1013 
1014  return TRUE;
1015 }
1016 
1028  int insert_at,
1029  const unsigned char octets[4])
1030 {
1031  DBUS_STRING_PREAMBLE (str);
1032 
1033  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1034  return FALSE;
1035 
1036  ASSIGN_4_OCTETS (real->str + insert_at, octets);
1037 
1038  return TRUE;
1039 }
1040 
1052  int insert_at,
1053  const unsigned char octets[8])
1054 {
1055  DBUS_STRING_PREAMBLE (str);
1056 
1057  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1058  return FALSE;
1059 
1060  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1061 
1062  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1063 
1064  return TRUE;
1065 }
1066 
1067 
1080  int *insert_at,
1081  int alignment)
1082 {
1083  DBUS_STRING_PREAMBLE (str);
1084 
1085  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1086  return FALSE;
1087 
1088  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1089 
1090  return TRUE;
1091 }
1092 
1104  const char *format,
1105  va_list args)
1106 {
1107  dbus_bool_t ret = FALSE;
1108  int len;
1109  va_list args_copy;
1110 
1111  DBUS_STRING_PREAMBLE (str);
1112 
1113  DBUS_VA_COPY (args_copy, args);
1114 
1115  /* Measure the message length without terminating nul */
1116  len = _dbus_printf_string_upper_bound (format, args);
1117 
1118  if (len < 0)
1119  goto out;
1120 
1121  if (!_dbus_string_lengthen (str, len))
1122  {
1123  goto out;
1124  }
1125 
1126  vsprintf ((char*) (real->str + (real->len - len)),
1127  format, args_copy);
1128  ret = TRUE;
1129 
1130 out:
1131  va_end (args_copy);
1132 
1133  return ret;
1134 }
1135 
1146  const char *format,
1147  ...)
1148 {
1149  va_list args;
1150  dbus_bool_t retval;
1151 
1152  va_start (args, format);
1153  retval = _dbus_string_append_printf_valist (str, format, args);
1154  va_end (args);
1155 
1156  return retval;
1157 }
1158 
1169  const char *buffer,
1170  int len)
1171 {
1172  DBUS_STRING_PREAMBLE (str);
1173  _dbus_assert (buffer != NULL);
1174  _dbus_assert (len >= 0);
1175 
1176  return append (real, buffer, len);
1177 }
1178 
1189  unsigned char byte)
1190 {
1191  DBUS_STRING_PREAMBLE (str);
1192 
1193  if (!set_length (real, real->len + 1))
1194  return FALSE;
1195 
1196  real->str[real->len-1] = byte;
1197 
1198  return TRUE;
1199 }
1200 
1211 _dbus_string_append_strings (DBusString *str, char **strings, char separator)
1212 {
1213  int i;
1214 
1215  if (strings == NULL)
1216  return TRUE;
1217 
1218  for (i = 0; strings[i]; i++)
1219  {
1220  if (i > 0 && !_dbus_string_append_byte (str, (unsigned char) separator))
1221  return FALSE;
1222 
1223  if (!_dbus_string_append (str, strings[i]))
1224  return FALSE;
1225  }
1226 
1227  return TRUE;
1228 }
1229 
1230 static void
1231 delete (DBusRealString *real,
1232  int start,
1233  int len)
1234 {
1235  if (len == 0)
1236  return;
1237 
1238  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1239  real->len -= len;
1240  real->str[real->len] = '\0';
1241 }
1242 
1252 void
1254  int start,
1255  int len)
1256 {
1257  DBUS_STRING_PREAMBLE (str);
1258  _dbus_assert (start >= 0);
1259  _dbus_assert (len >= 0);
1260  _dbus_assert (start <= real->len);
1261  _dbus_assert (len <= real->len - start);
1262 
1263  delete (real, start, len);
1264 }
1265 
1266 static dbus_bool_t
1267 copy (DBusRealString *source,
1268  int start,
1269  int len,
1270  DBusRealString *dest,
1271  int insert_at)
1272 {
1273  if (len == 0)
1274  return TRUE;
1275 
1276  if (!open_gap (len, dest, insert_at))
1277  return FALSE;
1278 
1279  memmove (dest->str + insert_at,
1280  source->str + start,
1281  len);
1282 
1283  return TRUE;
1284 }
1285 
1295 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1296  DBusRealString *real_source = (DBusRealString*) source; \
1297  DBusRealString *real_dest = (DBusRealString*) dest; \
1298  _dbus_assert ((source) != (dest)); \
1299  DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1300  DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1301  _dbus_assert (!real_dest->constant); \
1302  _dbus_assert (!real_dest->locked); \
1303  _dbus_assert ((start) >= 0); \
1304  _dbus_assert ((start) <= real_source->len); \
1305  _dbus_assert ((insert_at) >= 0); \
1306  _dbus_assert ((insert_at) <= real_dest->len)
1307 
1320  int start,
1321  DBusString *dest,
1322  int insert_at)
1323 {
1324  DBusRealString *real_source = (DBusRealString*) source;
1325  _dbus_assert (start <= real_source->len);
1326 
1327  return _dbus_string_move_len (source, start,
1328  real_source->len - start,
1329  dest, insert_at);
1330 }
1331 
1344  int start,
1345  DBusString *dest,
1346  int insert_at)
1347 {
1348  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1349 
1350  return copy (real_source, start,
1351  real_source->len - start,
1352  real_dest,
1353  insert_at);
1354 }
1355 
1369  int start,
1370  int len,
1371  DBusString *dest,
1372  int insert_at)
1373 
1374 {
1375  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1376  _dbus_assert (len >= 0);
1377  _dbus_assert ((start + len) <= real_source->len);
1378 
1379 
1380  if (len == 0)
1381  {
1382  return TRUE;
1383  }
1384  else if (start == 0 &&
1385  len == real_source->len &&
1386  real_dest->len == 0)
1387  {
1388  /* Short-circuit moving an entire existing string to an empty string
1389  * by just swapping the buffers.
1390  */
1391  /* we assume ->constant doesn't matter as you can't have
1392  * a constant string involved in a move.
1393  */
1394 #define ASSIGN_DATA(a, b) do { \
1395  (a)->str = (b)->str; \
1396  (a)->len = (b)->len; \
1397  (a)->allocated = (b)->allocated; \
1398  (a)->align_offset = (b)->align_offset; \
1399  } while (0)
1400 
1401  DBusRealString tmp;
1402 
1403  ASSIGN_DATA (&tmp, real_source);
1404  ASSIGN_DATA (real_source, real_dest);
1405  ASSIGN_DATA (real_dest, &tmp);
1406 
1407  return TRUE;
1408  }
1409  else
1410  {
1411  if (!copy (real_source, start, len,
1412  real_dest,
1413  insert_at))
1414  return FALSE;
1415 
1416  delete (real_source, start,
1417  len);
1418 
1419  return TRUE;
1420  }
1421 }
1422 
1436  int start,
1437  int len,
1438  DBusString *dest,
1439  int insert_at)
1440 {
1441  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1442  _dbus_assert (len >= 0);
1443  _dbus_assert (start <= real_source->len);
1444  _dbus_assert (len <= real_source->len - start);
1445 
1446  return copy (real_source, start, len,
1447  real_dest,
1448  insert_at);
1449 }
1450 
1465  int start,
1466  int len,
1467  DBusString *dest,
1468  int replace_at,
1469  int replace_len)
1470 {
1471  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1472  _dbus_assert (len >= 0);
1473  _dbus_assert (start <= real_source->len);
1474  _dbus_assert (len <= real_source->len - start);
1475  _dbus_assert (replace_at >= 0);
1476  _dbus_assert (replace_at <= real_dest->len);
1477  _dbus_assert (replace_len <= real_dest->len - replace_at);
1478 
1479  if (len == replace_len)
1480  {
1481  memmove (real_dest->str + replace_at,
1482  real_source->str + start, len);
1483  }
1484  else if (len < replace_len)
1485  {
1486  memmove (real_dest->str + replace_at,
1487  real_source->str + start, len);
1488  delete (real_dest, replace_at + len,
1489  replace_len - len);
1490  }
1491  else
1492  {
1493  int diff;
1494 
1495  _dbus_assert (len > replace_len);
1496 
1497  diff = len - replace_len;
1498 
1499  /* First of all we check if destination string can be enlarged as
1500  * required, then we overwrite previous bytes
1501  */
1502 
1503  if (!copy (real_source, start + replace_len, diff,
1504  real_dest, replace_at + replace_len))
1505  return FALSE;
1506 
1507  memmove (real_dest->str + replace_at,
1508  real_source->str + start, replace_len);
1509  }
1510 
1511  return TRUE;
1512 }
1513 
1528  unsigned char byte,
1529  DBusString *tail)
1530 {
1531  int byte_position;
1532  char byte_string[2] = "";
1533  int head_length;
1534  int tail_length;
1535 
1536  byte_string[0] = (char) byte;
1537 
1538  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1539  return FALSE;
1540 
1541  head_length = byte_position;
1542  tail_length = _dbus_string_get_length (source) - head_length - 1;
1543 
1544  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1545  tail, 0))
1546  return FALSE;
1547 
1548  /* remove the trailing delimiter byte from the head now.
1549  */
1550  if (!_dbus_string_set_length (source, head_length))
1551  return FALSE;
1552 
1553  return TRUE;
1554 }
1555 
1556 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1557  * Pennington, and Tom Tromey are the authors and authorized relicense.
1558  */
1559 
1565 #define UTF8_COMPUTE(Char, Mask, Len) \
1566  if (Char < 128) \
1567  { \
1568  Len = 1; \
1569  Mask = 0x7f; \
1570  } \
1571  else if ((Char & 0xe0) == 0xc0) \
1572  { \
1573  Len = 2; \
1574  Mask = 0x1f; \
1575  } \
1576  else if ((Char & 0xf0) == 0xe0) \
1577  { \
1578  Len = 3; \
1579  Mask = 0x0f; \
1580  } \
1581  else if ((Char & 0xf8) == 0xf0) \
1582  { \
1583  Len = 4; \
1584  Mask = 0x07; \
1585  } \
1586  else if ((Char & 0xfc) == 0xf8) \
1587  { \
1588  Len = 5; \
1589  Mask = 0x03; \
1590  } \
1591  else if ((Char & 0xfe) == 0xfc) \
1592  { \
1593  Len = 6; \
1594  Mask = 0x01; \
1595  } \
1596  else \
1597  { \
1598  Len = 0; \
1599  Mask = 0; \
1600  }
1601 
1606 #define UTF8_LENGTH(Char) \
1607  ((Char) < 0x80 ? 1 : \
1608  ((Char) < 0x800 ? 2 : \
1609  ((Char) < 0x10000 ? 3 : \
1610  ((Char) < 0x200000 ? 4 : \
1611  ((Char) < 0x4000000 ? 5 : 6)))))
1612 
1622 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
1623  (Result) = (Chars)[0] & (Mask); \
1624  for ((Count) = 1; (Count) < (Len); ++(Count)) \
1625  { \
1626  if (((Chars)[(Count)] & 0xc0) != 0x80) \
1627  { \
1628  (Result) = -1; \
1629  break; \
1630  } \
1631  (Result) <<= 6; \
1632  (Result) |= ((Chars)[(Count)] & 0x3f); \
1633  }
1634 
1645 #define UNICODE_VALID(Char) \
1646  ((Char) < 0x110000 && \
1647  (((Char) & 0xFFFFF800) != 0xD800))
1648 
1665  int start,
1666  const char *substr,
1667  int *found)
1668 {
1669  return _dbus_string_find_to (str, start,
1670  ((const DBusRealString*)str)->len,
1671  substr, found);
1672 }
1673 
1688  int start,
1689  int *found,
1690  int *found_len)
1691 {
1692  int i;
1693 
1695  _dbus_assert (start <= real->len);
1696  _dbus_assert (start >= 0);
1697 
1698  i = start;
1699  while (i < real->len)
1700  {
1701  if (real->str[i] == '\r')
1702  {
1703  if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1704  {
1705  if (found)
1706  *found = i;
1707  if (found_len)
1708  *found_len = 2;
1709  return TRUE;
1710  }
1711  else /* only "\r" */
1712  {
1713  if (found)
1714  *found = i;
1715  if (found_len)
1716  *found_len = 1;
1717  return TRUE;
1718  }
1719  }
1720  else if (real->str[i] == '\n') /* only "\n" */
1721  {
1722  if (found)
1723  *found = i;
1724  if (found_len)
1725  *found_len = 1;
1726  return TRUE;
1727  }
1728  ++i;
1729  }
1730 
1731  if (found)
1732  *found = real->len;
1733 
1734  if (found_len)
1735  *found_len = 0;
1736 
1737  return FALSE;
1738 }
1739 
1758  int start,
1759  int end,
1760  const char *substr,
1761  int *found)
1762 {
1763  int i;
1765  _dbus_assert (substr != NULL);
1766  _dbus_assert (start <= real->len);
1767  _dbus_assert (start >= 0);
1768  _dbus_assert (substr != NULL);
1769  _dbus_assert (end <= real->len);
1770  _dbus_assert (start <= end);
1771 
1772  /* we always "find" an empty string */
1773  if (*substr == '\0')
1774  {
1775  if (found)
1776  *found = start;
1777  return TRUE;
1778  }
1779 
1780  i = start;
1781  while (i < end)
1782  {
1783  if (real->str[i] == substr[0])
1784  {
1785  int j = i + 1;
1786 
1787  while (j < end)
1788  {
1789  if (substr[j - i] == '\0')
1790  break;
1791  else if (real->str[j] != substr[j - i])
1792  break;
1793 
1794  ++j;
1795  }
1796 
1797  if (substr[j - i] == '\0')
1798  {
1799  if (found)
1800  *found = i;
1801  return TRUE;
1802  }
1803  }
1804 
1805  ++i;
1806  }
1807 
1808  if (found)
1809  *found = end;
1810 
1811  return FALSE;
1812 }
1813 
1826  int start,
1827  int *found)
1828 {
1829  int i;
1831  _dbus_assert (start <= real->len);
1832  _dbus_assert (start >= 0);
1833 
1834  i = start;
1835  while (i < real->len)
1836  {
1837  if (real->str[i] == ' ' ||
1838  real->str[i] == '\t')
1839  {
1840  if (found)
1841  *found = i;
1842  return TRUE;
1843  }
1844 
1845  ++i;
1846  }
1847 
1848  if (found)
1849  *found = real->len;
1850 
1851  return FALSE;
1852 }
1853 
1862 void
1864  int start,
1865  int *end)
1866 {
1867  int i;
1869  _dbus_assert (start <= real->len);
1870  _dbus_assert (start >= 0);
1871 
1872  i = start;
1873  while (i < real->len)
1874  {
1875  if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1876  break;
1877 
1878  ++i;
1879  }
1880 
1881  _dbus_assert (i == real->len || !DBUS_IS_ASCII_BLANK (real->str[i]));
1882 
1883  if (end)
1884  *end = i;
1885 }
1886 
1887 
1896 void
1898  int start,
1899  int *end)
1900 {
1901  int i;
1903  _dbus_assert (start <= real->len);
1904  _dbus_assert (start >= 0);
1905 
1906  i = start;
1907  while (i < real->len)
1908  {
1909  if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1910  break;
1911 
1912  ++i;
1913  }
1914 
1915  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1916 
1917  if (end)
1918  *end = i;
1919 }
1920 
1929 void
1931  int end,
1932  int *start)
1933 {
1934  int i;
1936  _dbus_assert (end <= real->len);
1937  _dbus_assert (end >= 0);
1938 
1939  i = end;
1940  while (i > 0)
1941  {
1942  if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1943  break;
1944  --i;
1945  }
1946 
1947  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1948 
1949  if (start)
1950  *start = i;
1951 }
1952 
1970  DBusString *dest)
1971 {
1972  int eol, eol_len;
1973 
1974  _dbus_string_set_length (dest, 0);
1975 
1976  eol = 0;
1977  eol_len = 0;
1978  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1979  {
1980  _dbus_assert (eol == _dbus_string_get_length (source));
1981  if (eol == 0)
1982  {
1983  /* If there's no newline and source has zero length, we're done */
1984  return FALSE;
1985  }
1986  /* otherwise, the last line of the file has no eol characters */
1987  }
1988 
1989  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1990  * since find_eol returned TRUE
1991  */
1992 
1993  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1994  return FALSE;
1995 
1996  /* remove line ending */
1997  if (!_dbus_string_set_length (dest, eol))
1998  {
1999  _dbus_assert_not_reached ("out of memory when shortening a string");
2000  return FALSE;
2001  }
2002 
2003  return TRUE;
2004 }
2005 
2006 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
2013 void
2014 _dbus_string_delete_first_word (DBusString *str)
2015 {
2016  int i;
2017 
2018  if (_dbus_string_find_blank (str, 0, &i))
2019  _dbus_string_skip_blank (str, i, &i);
2020 
2021  _dbus_string_delete (str, 0, i);
2022 }
2023 #endif
2024 
2025 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
2031 void
2032 _dbus_string_delete_leading_blanks (DBusString *str)
2033 {
2034  int i;
2035 
2036  _dbus_string_skip_blank (str, 0, &i);
2037 
2038  if (i > 0)
2039  _dbus_string_delete (str, 0, i);
2040 }
2041 #endif
2042 
2048 void
2050 {
2051  int i;
2052 
2053  _dbus_string_skip_white (str, 0, &i);
2054 
2055  if (i > 0)
2056  _dbus_string_delete (str, 0, i);
2057 
2058  _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
2059 
2060  _dbus_string_set_length (str, i);
2061 }
2062 
2074  const DBusString *b)
2075 {
2076  const unsigned char *ap;
2077  const unsigned char *bp;
2078  const unsigned char *a_end;
2079  const DBusRealString *real_a = (const DBusRealString*) a;
2080  const DBusRealString *real_b = (const DBusRealString*) b;
2083 
2084  if (real_a->len != real_b->len)
2085  return FALSE;
2086 
2087  ap = real_a->str;
2088  bp = real_b->str;
2089  a_end = real_a->str + real_a->len;
2090  while (ap != a_end)
2091  {
2092  if (*ap != *bp)
2093  return FALSE;
2094 
2095  ++ap;
2096  ++bp;
2097  }
2098 
2099  return TRUE;
2100 }
2101 
2117  const DBusString *b,
2118  int len)
2119 {
2120  const unsigned char *ap;
2121  const unsigned char *bp;
2122  const unsigned char *a_end;
2123  const DBusRealString *real_a = (const DBusRealString*) a;
2124  const DBusRealString *real_b = (const DBusRealString*) b;
2127 
2128  if (real_a->len != real_b->len &&
2129  (real_a->len < len || real_b->len < len))
2130  return FALSE;
2131 
2132  ap = real_a->str;
2133  bp = real_b->str;
2134  a_end = real_a->str + MIN (real_a->len, len);
2135  while (ap != a_end)
2136  {
2137  if (*ap != *bp)
2138  return FALSE;
2139 
2140  ++ap;
2141  ++bp;
2142  }
2143 
2144  return TRUE;
2145 }
2146 
2165  int a_start,
2166  int a_len,
2167  const DBusString *b,
2168  int b_start)
2169 {
2170  const unsigned char *ap;
2171  const unsigned char *bp;
2172  const unsigned char *a_end;
2173  const DBusRealString *real_a = (const DBusRealString*) a;
2174  const DBusRealString *real_b = (const DBusRealString*) b;
2177  _dbus_assert (a_start >= 0);
2178  _dbus_assert (a_len >= 0);
2179  _dbus_assert (a_start <= real_a->len);
2180  _dbus_assert (a_len <= real_a->len - a_start);
2181  _dbus_assert (b_start >= 0);
2182  _dbus_assert (b_start <= real_b->len);
2183 
2184  if (a_len > real_b->len - b_start)
2185  return FALSE;
2186 
2187  ap = real_a->str + a_start;
2188  bp = real_b->str + b_start;
2189  a_end = ap + a_len;
2190  while (ap != a_end)
2191  {
2192  if (*ap != *bp)
2193  return FALSE;
2194 
2195  ++ap;
2196  ++bp;
2197  }
2198 
2199  _dbus_assert (bp <= (real_b->str + real_b->len));
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 (ap != a_end || *bp)
2235  return FALSE;
2236 
2237  return TRUE;
2238 }
2239 
2249  const char *c_str)
2250 {
2251  const unsigned char *ap;
2252  const unsigned char *bp;
2253  const unsigned char *a_end;
2254  const DBusRealString *real_a = (const DBusRealString*) a;
2256  _dbus_assert (c_str != NULL);
2257 
2258  ap = real_a->str;
2259  bp = (const unsigned char*) c_str;
2260  a_end = real_a->str + real_a->len;
2261  while (ap != a_end && *bp)
2262  {
2263  if (*ap != *bp)
2264  return FALSE;
2265 
2266  ++ap;
2267  ++bp;
2268  }
2269 
2270  if (*bp == '\0')
2271  return TRUE;
2272  else
2273  return FALSE;
2274 }
2275 
2287  const char *c_str,
2288  char word_separator)
2289 {
2290  char next_char;
2291  const char *data;
2292  _dbus_assert (c_str != NULL);
2293 
2294  if (!_dbus_string_starts_with_c_str (a, c_str))
2295  return FALSE;
2296 
2297  data = _dbus_string_get_const_data (a);
2298  next_char = data[strlen (c_str)];
2299  return next_char == '\0' || next_char == word_separator;
2300 }
2301 
2312  unsigned char byte)
2313 {
2314  const char hexdigits[16] = {
2315  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2316  'a', 'b', 'c', 'd', 'e', 'f'
2317  };
2318 
2319  if (!_dbus_string_append_byte (str,
2320  hexdigits[(byte >> 4)]))
2321  return FALSE;
2322 
2323  if (!_dbus_string_append_byte (str,
2324  hexdigits[(byte & 0x0f)]))
2325  {
2327  _dbus_string_get_length (str) - 1);
2328  return FALSE;
2329  }
2330 
2331  return TRUE;
2332 }
2333 
2346  int start,
2347  DBusString *dest,
2348  int insert_at)
2349 {
2350  DBusString result;
2351  const unsigned char *p;
2352  const unsigned char *end;
2353  dbus_bool_t retval;
2354 
2355  _dbus_assert (start <= _dbus_string_get_length (source));
2356 
2357  if (!_dbus_string_init (&result))
2358  return FALSE;
2359 
2360  retval = FALSE;
2361 
2362  p = (const unsigned char*) _dbus_string_get_const_data (source);
2363  end = p + _dbus_string_get_length (source);
2364  p += start;
2365 
2366  while (p != end)
2367  {
2368  if (!_dbus_string_append_byte_as_hex (&result, *p))
2369  goto out;
2370 
2371  ++p;
2372  }
2373 
2374  if (!_dbus_string_move (&result, 0, dest, insert_at))
2375  goto out;
2376 
2377  retval = TRUE;
2378 
2379  out:
2380  _dbus_string_free (&result);
2381  return retval;
2382 }
2383 
2396  int start,
2397  int *end_return,
2398  DBusString *dest,
2399  int insert_at)
2400 {
2401  DBusString result;
2402  const unsigned char *p;
2403  const unsigned char *end;
2404  dbus_bool_t retval;
2405  dbus_bool_t high_bits;
2406 
2407  _dbus_assert (start <= _dbus_string_get_length (source));
2408 
2409  if (!_dbus_string_init (&result))
2410  return FALSE;
2411 
2412  retval = FALSE;
2413 
2414  high_bits = TRUE;
2415  p = (const unsigned char*) _dbus_string_get_const_data (source);
2416  end = p + _dbus_string_get_length (source);
2417  p += start;
2418 
2419  while (p != end)
2420  {
2421  unsigned int val;
2422 
2423  switch (*p)
2424  {
2425  case '0':
2426  val = 0;
2427  break;
2428  case '1':
2429  val = 1;
2430  break;
2431  case '2':
2432  val = 2;
2433  break;
2434  case '3':
2435  val = 3;
2436  break;
2437  case '4':
2438  val = 4;
2439  break;
2440  case '5':
2441  val = 5;
2442  break;
2443  case '6':
2444  val = 6;
2445  break;
2446  case '7':
2447  val = 7;
2448  break;
2449  case '8':
2450  val = 8;
2451  break;
2452  case '9':
2453  val = 9;
2454  break;
2455  case 'a':
2456  case 'A':
2457  val = 10;
2458  break;
2459  case 'b':
2460  case 'B':
2461  val = 11;
2462  break;
2463  case 'c':
2464  case 'C':
2465  val = 12;
2466  break;
2467  case 'd':
2468  case 'D':
2469  val = 13;
2470  break;
2471  case 'e':
2472  case 'E':
2473  val = 14;
2474  break;
2475  case 'f':
2476  case 'F':
2477  val = 15;
2478  break;
2479  default:
2480  goto done;
2481  }
2482 
2483  if (high_bits)
2484  {
2485  if (!_dbus_string_append_byte (&result,
2486  val << 4))
2487  goto out;
2488  }
2489  else
2490  {
2491  int len;
2492  unsigned char b;
2493 
2494  len = _dbus_string_get_length (&result);
2495 
2496  b = _dbus_string_get_byte (&result, len - 1);
2497 
2498  b |= val;
2499 
2500  _dbus_string_set_byte (&result, len - 1, b);
2501  }
2502 
2503  high_bits = !high_bits;
2504 
2505  ++p;
2506  }
2507 
2508  done:
2509  if (!_dbus_string_move (&result, 0, dest, insert_at))
2510  goto out;
2511 
2512  if (end_return)
2513  *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2514 
2515  retval = TRUE;
2516 
2517  out:
2518  _dbus_string_free (&result);
2519  return retval;
2520 }
2521 
2537  int start,
2538  int len)
2539 {
2540  const unsigned char *s;
2541  const unsigned char *end;
2543  _dbus_assert (start >= 0);
2544  _dbus_assert (start <= real->len);
2545  _dbus_assert (len >= 0);
2546 
2547  if (len > real->len - start)
2548  return FALSE;
2549 
2550  s = real->str + start;
2551  end = s + len;
2552  while (s != end)
2553  {
2554  if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2555  return FALSE;
2556 
2557  ++s;
2558  }
2559 
2560  return TRUE;
2561 }
2562 
2570 void
2572  int start,
2573  int len)
2574 {
2575  unsigned char *s;
2576  unsigned char *end;
2577  DBUS_STRING_PREAMBLE (str);
2578  _dbus_assert (start >= 0);
2579  _dbus_assert (start <= real->len);
2580  _dbus_assert (len >= 0);
2581  _dbus_assert (len <= real->len - start);
2582 
2583  s = real->str + start;
2584  end = s + len;
2585 
2586  while (s != end)
2587  {
2588  if (*s >= 'A' && *s <= 'Z')
2589  *s += 'a' - 'A';
2590  ++s;
2591  }
2592 }
2593 
2601 void
2603  int start,
2604  int len)
2605 {
2606  unsigned char *s;
2607  unsigned char *end;
2608  DBUS_STRING_PREAMBLE (str);
2609  _dbus_assert (start >= 0);
2610  _dbus_assert (start <= real->len);
2611  _dbus_assert (len >= 0);
2612  _dbus_assert (len <= real->len - start);
2613 
2614  s = real->str + start;
2615  end = s + len;
2616 
2617  while (s != end)
2618  {
2619  if (*s >= 'a' && *s <= 'z')
2620  *s += 'A' - 'a';
2621  ++s;
2622  }
2623 }
2624 
2642  int start,
2643  int len)
2644 {
2645  const unsigned char *p;
2646  const unsigned char *end;
2648  _dbus_assert (start >= 0);
2649  _dbus_assert (start <= real->len);
2650  _dbus_assert (len >= 0);
2651 
2652  /* we are doing _DBUS_UNLIKELY() here which might be
2653  * dubious in a generic library like GLib, but in D-Bus
2654  * we know we're validating messages and that it would
2655  * only be evil/broken apps that would have invalid
2656  * UTF-8. Also, this function seems to be a performance
2657  * bottleneck in profiles.
2658  */
2659 
2660  if (_DBUS_UNLIKELY (len > real->len - start))
2661  return FALSE;
2662 
2663  p = real->str + start;
2664  end = p + len;
2665 
2666  while (p < end)
2667  {
2668  int i, mask, char_len;
2669  dbus_unichar_t result;
2670 
2671  /* nul bytes considered invalid */
2672  if (*p == '\0')
2673  break;
2674 
2675  /* Special-case ASCII; this makes us go a lot faster in
2676  * D-Bus profiles where we are typically validating
2677  * function names and such. We have to know that
2678  * all following checks will pass for ASCII though,
2679  * comments follow ...
2680  */
2681  if (*p < 128)
2682  {
2683  ++p;
2684  continue;
2685  }
2686 
2687  UTF8_COMPUTE (*p, mask, char_len);
2688 
2689  if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2690  break;
2691 
2692  /* check that the expected number of bytes exists in the remaining length */
2693  if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2694  break;
2695 
2696  UTF8_GET (result, p, i, mask, char_len);
2697 
2698  /* Check for overlong UTF-8 */
2699  if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2700  break;
2701 #if 0
2702  /* The UNICODE_VALID check below will catch this */
2703  if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2704  break;
2705 #endif
2706 
2707  if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2708  break;
2709 
2710  /* UNICODE_VALID should have caught it */
2711  _dbus_assert (result != (dbus_unichar_t)-1);
2712 
2713  p += char_len;
2714  }
2715 
2716  /* See that we covered the entire length if a length was
2717  * passed in
2718  */
2719  if (_DBUS_UNLIKELY (p != end))
2720  return FALSE;
2721  else
2722  return TRUE;
2723 }
2724 
2740  int start,
2741  int len)
2742 {
2743  const unsigned char *s;
2744  const unsigned char *end;
2746  _dbus_assert (start >= 0);
2747  _dbus_assert (len >= 0);
2748  _dbus_assert (start <= real->len);
2749 
2750  if (len > real->len - start)
2751  return FALSE;
2752 
2753  s = real->str + start;
2754  end = s + len;
2755  while (s != end)
2756  {
2757  if (_DBUS_UNLIKELY (*s != '\0'))
2758  return FALSE;
2759  ++s;
2760  }
2761 
2762  return TRUE;
2763 }
2764 
2770 void
2772 {
2773  DBUS_STRING_PREAMBLE (str);
2774 
2775  memset (real->str - real->align_offset, '\0', real->allocated);
2776 }
2779 /* 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:692
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:592
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:452
#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:833
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:2395
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:966
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:1051
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:2739
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:2164
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1645
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:1079
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1565
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
dbus_bool_t _dbus_string_append_strings(DBusString *str, char **strings, char separator)
Append vector with strings connected by separator.
Definition: dbus-string.c:1211
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:1343
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:1687
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:982
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:2248
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:930
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:672
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:1863
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:1930
dbus_bool_t _dbus_string_init_from_string(DBusString *str, const DBusString *from)
Initializes a string from another string.
Definition: dbus-string.c:254
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:1527
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:1664
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:2641
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:1825
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:2571
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:1168
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:278
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:521
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:811
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:1253
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:703
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:2212
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:1897
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:1969
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:1103
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:791
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2771
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1606
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:2602
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:615
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:2536
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:1188
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:2049
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:2286
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:2345
#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:1295
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:1145
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:645
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1622
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:1368
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:750
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:420
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:2116
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:990
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:1319
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2073
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:1027
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:1003
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:986
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:2311
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:914
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:1757
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:1435
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:728
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:1464
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.