D-Bus  1.8.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 (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
5  * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-string.h"
28 /* we allow a system header here, for speed/convenience */
29 #include <string.h>
30 /* for vsnprintf */
31 #include <stdio.h>
32 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
33 #include "dbus-string-private.h"
34 #include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
35  * into the marshaling-related files
36  */
37 /* for DBUS_VA_COPY */
38 #include "dbus-sysdeps.h"
39 
78 static void
79 fixup_alignment (DBusRealString *real)
80 {
81  unsigned char *aligned;
82  unsigned char *real_block;
83  unsigned int old_align_offset;
84 
85  /* we have to have extra space in real->allocated for the align offset and nul byte */
86  _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
87 
88  old_align_offset = real->align_offset;
89  real_block = real->str - old_align_offset;
90 
91  aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
92 
93  real->align_offset = aligned - real_block;
94  real->str = aligned;
95 
96  if (old_align_offset != real->align_offset)
97  {
98  /* Here comes the suck */
99  memmove (real_block + real->align_offset,
100  real_block + old_align_offset,
101  real->len + 1);
102  }
103 
104  _dbus_assert (real->align_offset < 8);
105  _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
106 }
107 
108 static void
109 undo_alignment (DBusRealString *real)
110 {
111  if (real->align_offset != 0)
112  {
113  memmove (real->str - real->align_offset,
114  real->str,
115  real->len + 1);
116 
117  real->str = real->str - real->align_offset;
118  real->align_offset = 0;
119  }
120 }
121 
133  int allocate_size)
134 {
135  DBusRealString *real;
136 
137  _dbus_assert (str != NULL);
138 
139  _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
140 
141  real = (DBusRealString*) str;
142 
143  /* It's very important not to touch anything
144  * other than real->str if we're going to fail,
145  * since we also use this function to reset
146  * an existing string, e.g. in _dbus_string_steal_data()
147  */
148 
149  real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
150  if (real->str == NULL)
151  return FALSE;
152 
153  real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
154  real->len = 0;
155  real->str[real->len] = '\0';
156 
157  real->constant = FALSE;
158  real->locked = FALSE;
159  real->invalid = FALSE;
160  real->align_offset = 0;
161 
162  fixup_alignment (real);
163 
164  return TRUE;
165 }
166 
176 {
177  return _dbus_string_init_preallocated (str, 0);
178 }
179 
189 void
191  const char *value)
192 {
193  _dbus_assert (value != NULL);
194 
195  _dbus_string_init_const_len (str, value,
196  strlen (value));
197 }
198 
209 void
211  const char *value,
212  int len)
213 {
214  DBusRealString *real;
215 
216  _dbus_assert (str != NULL);
217  _dbus_assert (len == 0 || value != NULL);
219  _dbus_assert (len >= 0);
220 
221  real = (DBusRealString*) str;
222 
223  real->str = (unsigned char*) value;
224  real->len = len;
225  real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
226  real->constant = TRUE;
227  real->locked = TRUE;
228  real->invalid = FALSE;
229  real->align_offset = 0;
230 
231  /* We don't require const strings to be 8-byte aligned as the
232  * memory is coming from elsewhere.
233  */
234 }
235 
241 void
243 {
244  DBusRealString *real = (DBusRealString*) str;
246 
247  if (real->constant)
248  return;
249 
250  /* so it's safe if @p str returned by a failed
251  * _dbus_string_init call
252  * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
253  */
254  if (real->str == NULL)
255  return;
256 
257  dbus_free (real->str - real->align_offset);
258 
259  real->invalid = TRUE;
260 }
261 
262 static dbus_bool_t
263 compact (DBusRealString *real,
264  int max_waste)
265 {
266  unsigned char *new_str;
267  int new_allocated;
268  int waste;
269 
270  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
271 
272  if (waste <= max_waste)
273  return TRUE;
274 
275  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
276 
277  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
278  if (_DBUS_UNLIKELY (new_str == NULL))
279  return FALSE;
280 
281  real->str = new_str + real->align_offset;
282  real->allocated = new_allocated;
283  fixup_alignment (real);
284 
285  return TRUE;
286 }
287 
288 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
289 /* Not using this feature at the moment,
290  * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
291  */
301 void
302 _dbus_string_lock (DBusString *str)
303 {
304  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
305 
306  real->locked = TRUE;
307 
308  /* Try to realloc to avoid excess memory usage, since
309  * we know we won't change the string further
310  */
311 #define MAX_WASTE 48
312  compact (real, MAX_WASTE);
313 }
314 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
315 
316 static dbus_bool_t
317 reallocate_for_length (DBusRealString *real,
318  int new_length)
319 {
320  int new_allocated;
321  unsigned char *new_str;
322 
323  /* at least double our old allocation to avoid O(n), avoiding
324  * overflow
325  */
326  if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
327  new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
328  else
329  new_allocated = real->allocated * 2;
330 
331  /* if you change the code just above here, run the tests without
332  * the following assert-only hack before you commit
333  */
334  /* This is keyed off asserts in addition to tests so when you
335  * disable asserts to profile, you don't get this destroyer
336  * of profiles.
337  */
338 #if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
339  new_allocated = 0; /* ensure a realloc every time so that we go
340  * through all malloc failure codepaths
341  */
342 #endif
343 
344  /* But be sure we always alloc at least space for the new length */
345  new_allocated = MAX (new_allocated,
346  new_length + _DBUS_STRING_ALLOCATION_PADDING);
347 
348  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
349  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
350  if (_DBUS_UNLIKELY (new_str == NULL))
351  return FALSE;
352 
353  real->str = new_str + real->align_offset;
354  real->allocated = new_allocated;
355  fixup_alignment (real);
356 
357  return TRUE;
358 }
359 
373  int max_waste)
374 {
375  DBUS_STRING_PREAMBLE (str);
376 
377  return compact (real, max_waste);
378 }
379 
380 static dbus_bool_t
381 set_length (DBusRealString *real,
382  int new_length)
383 {
384  /* Note, we are setting the length not including nul termination */
385 
386  /* exceeding max length is the same as failure to allocate memory */
387  if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
388  return FALSE;
389  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
390  _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
391  return FALSE;
392  else
393  {
394  real->len = new_length;
395  real->str[new_length] = '\0';
396  return TRUE;
397  }
398 }
399 
400 static dbus_bool_t
401 open_gap (int len,
402  DBusRealString *dest,
403  int insert_at)
404 {
405  if (len == 0)
406  return TRUE;
407 
408  if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
409  return FALSE; /* detected overflow of dest->len + len below */
410 
411  if (!set_length (dest, dest->len + len))
412  return FALSE;
413 
414  memmove (dest->str + insert_at + len,
415  dest->str + insert_at,
416  dest->len - len - insert_at);
417 
418  return TRUE;
419 }
420 
421 #ifndef _dbus_string_get_data
422 
433 char*
434 _dbus_string_get_data (DBusString *str)
435 {
436  DBUS_STRING_PREAMBLE (str);
437 
438  return (char*) real->str;
439 }
440 #endif /* _dbus_string_get_data */
441 
442 /* only do the function if we don't have the macro */
443 #ifndef _dbus_string_get_const_data
444 
450 const char*
451 _dbus_string_get_const_data (const DBusString *str)
452 {
454 
455  return (const char*) real->str;
456 }
457 #endif /* _dbus_string_get_const_data */
458 
472 char*
474  int start,
475  int len)
476 {
477  DBUS_STRING_PREAMBLE (str);
478  _dbus_assert (start >= 0);
479  _dbus_assert (len >= 0);
480  _dbus_assert (start <= real->len);
481  _dbus_assert (len <= real->len - start);
482 
483  return (char*) real->str + start;
484 }
485 
486 /* only do the function if we don't have the macro */
487 #ifndef _dbus_string_get_const_data_len
488 
496 const char*
497 _dbus_string_get_const_data_len (const DBusString *str,
498  int start,
499  int len)
500 {
502  _dbus_assert (start >= 0);
503  _dbus_assert (len >= 0);
504  _dbus_assert (start <= real->len);
505  _dbus_assert (len <= real->len - start);
506 
507  return (const char*) real->str + start;
508 }
509 #endif /* _dbus_string_get_const_data_len */
510 
511 /* only do the function if we don't have the macro */
512 #ifndef _dbus_string_set_byte
513 
520 void
521 _dbus_string_set_byte (DBusString *str,
522  int i,
523  unsigned char byte)
524 {
525  DBUS_STRING_PREAMBLE (str);
526  _dbus_assert (i < real->len);
527  _dbus_assert (i >= 0);
528 
529  real->str[i] = byte;
530 }
531 #endif /* _dbus_string_set_byte */
532 
533 /* only have the function if we didn't create a macro */
534 #ifndef _dbus_string_get_byte
535 
544 unsigned char
545 _dbus_string_get_byte (const DBusString *str,
546  int start)
547 {
549  _dbus_assert (start <= real->len);
550  _dbus_assert (start >= 0);
551 
552  return real->str[start];
553 }
554 #endif /* _dbus_string_get_byte */
555 
568  int i,
569  int n_bytes,
570  unsigned char byte)
571 {
572  DBUS_STRING_PREAMBLE (str);
573  _dbus_assert (i <= real->len);
574  _dbus_assert (i >= 0);
575  _dbus_assert (n_bytes >= 0);
576 
577  if (n_bytes == 0)
578  return TRUE;
579 
580  if (!open_gap (n_bytes, real, i))
581  return FALSE;
582 
583  memset (real->str + i, byte, n_bytes);
584 
585  return TRUE;
586 }
587 
598  int i,
599  unsigned char byte)
600 {
601  DBUS_STRING_PREAMBLE (str);
602  _dbus_assert (i <= real->len);
603  _dbus_assert (i >= 0);
604 
605  if (!open_gap (1, real, i))
606  return FALSE;
607 
608  real->str[i] = byte;
609 
610  return TRUE;
611 }
612 
625  char **data_return)
626 {
627  DBUS_STRING_PREAMBLE (str);
628  _dbus_assert (data_return != NULL);
629 
630  undo_alignment (real);
631 
632  *data_return = (char*) real->str;
633 
634  /* reset the string */
635  if (!_dbus_string_init (str))
636  {
637  /* hrm, put it back then */
638  real->str = (unsigned char*) *data_return;
639  *data_return = NULL;
640  fixup_alignment (real);
641  return FALSE;
642  }
643 
644  return TRUE;
645 }
646 
656  char **data_return)
657 {
659  _dbus_assert (data_return != NULL);
660 
661  *data_return = dbus_malloc (real->len + 1);
662  if (*data_return == NULL)
663  return FALSE;
664 
665  memcpy (*data_return, real->str, real->len + 1);
666 
667  return TRUE;
668 }
669 
679 void
681  char *buffer,
682  int avail_len)
683 {
685 
686  _dbus_assert (avail_len >= 0);
687  _dbus_assert (avail_len >= real->len);
688 
689  memcpy (buffer, real->str, real->len);
690 }
691 
701 void
703  char *buffer,
704  int avail_len)
705 {
707 
708  _dbus_assert (avail_len >= 0);
709  _dbus_assert (avail_len > real->len);
710 
711  memcpy (buffer, real->str, real->len+1);
712 }
713 
714 /* Only have the function if we don't have the macro */
715 #ifndef _dbus_string_get_length
716 
721 int
722 _dbus_string_get_length (const DBusString *str)
723 {
725 
726  return real->len;
727 }
728 #endif /* !_dbus_string_get_length */
729 
744  int additional_length)
745 {
746  DBUS_STRING_PREAMBLE (str);
747  _dbus_assert (additional_length >= 0);
748 
749  if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
750  return FALSE; /* would overflow */
751 
752  return set_length (real,
753  real->len + additional_length);
754 }
755 
762 void
764  int length_to_remove)
765 {
766  DBUS_STRING_PREAMBLE (str);
767  _dbus_assert (length_to_remove >= 0);
768  _dbus_assert (length_to_remove <= real->len);
769 
770  set_length (real,
771  real->len - length_to_remove);
772 }
773 
786  int length)
787 {
788  DBUS_STRING_PREAMBLE (str);
789  _dbus_assert (length >= 0);
790 
791  return set_length (real, length);
792 }
793 
794 static dbus_bool_t
795 align_insert_point_then_open_gap (DBusString *str,
796  int *insert_at_p,
797  int alignment,
798  int gap_size)
799 {
800  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
801  unsigned long gap_pos;
802  int insert_at;
803  int delta;
804  DBUS_STRING_PREAMBLE (str);
805  _dbus_assert (alignment >= 1);
806  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
807 
808  insert_at = *insert_at_p;
809 
810  _dbus_assert (insert_at <= real->len);
811 
812  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
813  new_len = real->len + (gap_pos - insert_at) + gap_size;
814 
815  if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
816  return FALSE;
817 
818  delta = new_len - real->len;
819  _dbus_assert (delta >= 0);
820 
821  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
822  {
823  _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
824  return TRUE;
825  }
826 
827  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
828  real, insert_at)))
829  return FALSE;
830 
831  /* nul the padding if we had to add any padding */
832  if (gap_size < delta)
833  {
834  memset (&real->str[insert_at], '\0',
835  gap_pos - insert_at);
836  }
837 
838  *insert_at_p = gap_pos;
839 
840  return TRUE;
841 }
842 
843 static dbus_bool_t
844 align_length_then_lengthen (DBusString *str,
845  int alignment,
846  int then_lengthen_by)
847 {
848  int insert_at;
849 
850  insert_at = _dbus_string_get_length (str);
851 
852  return align_insert_point_then_open_gap (str,
853  &insert_at,
854  alignment, then_lengthen_by);
855 }
856 
867  int alignment)
868 {
869  return align_length_then_lengthen (str, alignment, 0);
870 }
871 
883  int extra_bytes)
884 {
885  if (!_dbus_string_lengthen (str, extra_bytes))
886  return FALSE;
887  _dbus_string_shorten (str, extra_bytes);
888 
889  return TRUE;
890 }
891 
892 static dbus_bool_t
893 append (DBusRealString *real,
894  const char *buffer,
895  int buffer_len)
896 {
897  if (buffer_len == 0)
898  return TRUE;
899 
900  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
901  return FALSE;
902 
903  memcpy (real->str + (real->len - buffer_len),
904  buffer,
905  buffer_len);
906 
907  return TRUE;
908 }
909 
919  const char *buffer)
920 {
921  unsigned long buffer_len;
922 
923  DBUS_STRING_PREAMBLE (str);
924  _dbus_assert (buffer != NULL);
925 
926  buffer_len = strlen (buffer);
927  if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
928  return FALSE;
929 
930  return append (real, buffer, buffer_len);
931 }
932 
934 #define ASSIGN_2_OCTETS(p, octets) \
935  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
936 
938 #define ASSIGN_4_OCTETS(p, octets) \
939  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
940 
942 #define ASSIGN_8_OCTETS(p, octets) \
943  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
944 
956  int insert_at,
957  const unsigned char octets[2])
958 {
959  DBUS_STRING_PREAMBLE (str);
960 
961  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
962  return FALSE;
963 
964  ASSIGN_2_OCTETS (real->str + insert_at, octets);
965 
966  return TRUE;
967 }
968 
980  int insert_at,
981  const unsigned char octets[4])
982 {
983  DBUS_STRING_PREAMBLE (str);
984 
985  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
986  return FALSE;
987 
988  ASSIGN_4_OCTETS (real->str + insert_at, octets);
989 
990  return TRUE;
991 }
992 
1004  int insert_at,
1005  const unsigned char octets[8])
1006 {
1007  DBUS_STRING_PREAMBLE (str);
1008 
1009  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1010  return FALSE;
1011 
1012  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1013 
1014  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1015 
1016  return TRUE;
1017 }
1018 
1019 
1032  int *insert_at,
1033  int alignment)
1034 {
1035  DBUS_STRING_PREAMBLE (str);
1036 
1037  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1038  return FALSE;
1039 
1040  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1041 
1042  return TRUE;
1043 }
1044 
1056  const char *format,
1057  va_list args)
1058 {
1059  int len;
1060  va_list args_copy;
1061 
1062  DBUS_STRING_PREAMBLE (str);
1063 
1064  DBUS_VA_COPY (args_copy, args);
1065 
1066  /* Measure the message length without terminating nul */
1067  len = _dbus_printf_string_upper_bound (format, args);
1068 
1069  if (len < 0)
1070  return FALSE;
1071 
1072  if (!_dbus_string_lengthen (str, len))
1073  {
1074  /* don't leak the copy */
1075  va_end (args_copy);
1076  return FALSE;
1077  }
1078 
1079  vsprintf ((char*) (real->str + (real->len - len)),
1080  format, args_copy);
1081 
1082  va_end (args_copy);
1083 
1084  return TRUE;
1085 }
1086 
1097  const char *format,
1098  ...)
1099 {
1100  va_list args;
1101  dbus_bool_t retval;
1102 
1103  va_start (args, format);
1104  retval = _dbus_string_append_printf_valist (str, format, args);
1105  va_end (args);
1106 
1107  return retval;
1108 }
1109 
1120  const char *buffer,
1121  int len)
1122 {
1123  DBUS_STRING_PREAMBLE (str);
1124  _dbus_assert (buffer != NULL);
1125  _dbus_assert (len >= 0);
1126 
1127  return append (real, buffer, len);
1128 }
1129 
1140  unsigned char byte)
1141 {
1142  DBUS_STRING_PREAMBLE (str);
1143 
1144  if (!set_length (real, real->len + 1))
1145  return FALSE;
1146 
1147  real->str[real->len-1] = byte;
1148 
1149  return TRUE;
1150 }
1151 
1152 static void
1153 delete (DBusRealString *real,
1154  int start,
1155  int len)
1156 {
1157  if (len == 0)
1158  return;
1159 
1160  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1161  real->len -= len;
1162  real->str[real->len] = '\0';
1163 }
1164 
1174 void
1176  int start,
1177  int len)
1178 {
1179  DBUS_STRING_PREAMBLE (str);
1180  _dbus_assert (start >= 0);
1181  _dbus_assert (len >= 0);
1182  _dbus_assert (start <= real->len);
1183  _dbus_assert (len <= real->len - start);
1184 
1185  delete (real, start, len);
1186 }
1187 
1188 static dbus_bool_t
1189 copy (DBusRealString *source,
1190  int start,
1191  int len,
1192  DBusRealString *dest,
1193  int insert_at)
1194 {
1195  if (len == 0)
1196  return TRUE;
1197 
1198  if (!open_gap (len, dest, insert_at))
1199  return FALSE;
1200 
1201  memmove (dest->str + insert_at,
1202  source->str + start,
1203  len);
1204 
1205  return TRUE;
1206 }
1207 
1217 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1218  DBusRealString *real_source = (DBusRealString*) source; \
1219  DBusRealString *real_dest = (DBusRealString*) dest; \
1220  _dbus_assert ((source) != (dest)); \
1221  DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1222  DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1223  _dbus_assert (!real_dest->constant); \
1224  _dbus_assert (!real_dest->locked); \
1225  _dbus_assert ((start) >= 0); \
1226  _dbus_assert ((start) <= real_source->len); \
1227  _dbus_assert ((insert_at) >= 0); \
1228  _dbus_assert ((insert_at) <= real_dest->len)
1229 
1242  int start,
1243  DBusString *dest,
1244  int insert_at)
1245 {
1246  DBusRealString *real_source = (DBusRealString*) source;
1247  _dbus_assert (start <= real_source->len);
1248 
1249  return _dbus_string_move_len (source, start,
1250  real_source->len - start,
1251  dest, insert_at);
1252 }
1253 
1266  int start,
1267  DBusString *dest,
1268  int insert_at)
1269 {
1270  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1271 
1272  return copy (real_source, start,
1273  real_source->len - start,
1274  real_dest,
1275  insert_at);
1276 }
1277 
1291  int start,
1292  int len,
1293  DBusString *dest,
1294  int insert_at)
1295 
1296 {
1297  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1298  _dbus_assert (len >= 0);
1299  _dbus_assert ((start + len) <= real_source->len);
1300 
1301 
1302  if (len == 0)
1303  {
1304  return TRUE;
1305  }
1306  else if (start == 0 &&
1307  len == real_source->len &&
1308  real_dest->len == 0)
1309  {
1310  /* Short-circuit moving an entire existing string to an empty string
1311  * by just swapping the buffers.
1312  */
1313  /* we assume ->constant doesn't matter as you can't have
1314  * a constant string involved in a move.
1315  */
1316 #define ASSIGN_DATA(a, b) do { \
1317  (a)->str = (b)->str; \
1318  (a)->len = (b)->len; \
1319  (a)->allocated = (b)->allocated; \
1320  (a)->align_offset = (b)->align_offset; \
1321  } while (0)
1322 
1323  DBusRealString tmp;
1324 
1325  ASSIGN_DATA (&tmp, real_source);
1326  ASSIGN_DATA (real_source, real_dest);
1327  ASSIGN_DATA (real_dest, &tmp);
1328 
1329  return TRUE;
1330  }
1331  else
1332  {
1333  if (!copy (real_source, start, len,
1334  real_dest,
1335  insert_at))
1336  return FALSE;
1337 
1338  delete (real_source, start,
1339  len);
1340 
1341  return TRUE;
1342  }
1343 }
1344 
1358  int start,
1359  int len,
1360  DBusString *dest,
1361  int insert_at)
1362 {
1363  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1364  _dbus_assert (len >= 0);
1365  _dbus_assert (start <= real_source->len);
1366  _dbus_assert (len <= real_source->len - start);
1367 
1368  return copy (real_source, start, len,
1369  real_dest,
1370  insert_at);
1371 }
1372 
1387  int start,
1388  int len,
1389  DBusString *dest,
1390  int replace_at,
1391  int replace_len)
1392 {
1393  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1394  _dbus_assert (len >= 0);
1395  _dbus_assert (start <= real_source->len);
1396  _dbus_assert (len <= real_source->len - start);
1397  _dbus_assert (replace_at >= 0);
1398  _dbus_assert (replace_at <= real_dest->len);
1399  _dbus_assert (replace_len <= real_dest->len - replace_at);
1400 
1401  if (len == replace_len)
1402  {
1403  memmove (real_dest->str + replace_at,
1404  real_source->str + start, len);
1405  }
1406  else if (len < replace_len)
1407  {
1408  memmove (real_dest->str + replace_at,
1409  real_source->str + start, len);
1410  delete (real_dest, replace_at + len,
1411  replace_len - len);
1412  }
1413  else
1414  {
1415  int diff;
1416 
1417  _dbus_assert (len > replace_len);
1418 
1419  diff = len - replace_len;
1420 
1421  /* First of all we check if destination string can be enlarged as
1422  * required, then we overwrite previous bytes
1423  */
1424 
1425  if (!copy (real_source, start + replace_len, diff,
1426  real_dest, replace_at + replace_len))
1427  return FALSE;
1428 
1429  memmove (real_dest->str + replace_at,
1430  real_source->str + start, replace_len);
1431  }
1432 
1433  return TRUE;
1434 }
1435 
1450  unsigned char byte,
1451  DBusString *tail)
1452 {
1453  int byte_position;
1454  char byte_string[2] = "";
1455  int head_length;
1456  int tail_length;
1457 
1458  byte_string[0] = (char) byte;
1459 
1460  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1461  return FALSE;
1462 
1463  head_length = byte_position;
1464  tail_length = _dbus_string_get_length (source) - head_length - 1;
1465 
1466  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1467  tail, 0))
1468  return FALSE;
1469 
1470  /* remove the trailing delimiter byte from the head now.
1471  */
1472  if (!_dbus_string_set_length (source, head_length))
1473  return FALSE;
1474 
1475  return TRUE;
1476 }
1477 
1478 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1479  * Pennington, and Tom Tromey are the authors and authorized relicense.
1480  */
1481 
1487 #define UTF8_COMPUTE(Char, Mask, Len) \
1488  if (Char < 128) \
1489  { \
1490  Len = 1; \
1491  Mask = 0x7f; \
1492  } \
1493  else if ((Char & 0xe0) == 0xc0) \
1494  { \
1495  Len = 2; \
1496  Mask = 0x1f; \
1497  } \
1498  else if ((Char & 0xf0) == 0xe0) \
1499  { \
1500  Len = 3; \
1501  Mask = 0x0f; \
1502  } \
1503  else if ((Char & 0xf8) == 0xf0) \
1504  { \
1505  Len = 4; \
1506  Mask = 0x07; \
1507  } \
1508  else if ((Char & 0xfc) == 0xf8) \
1509  { \
1510  Len = 5; \
1511  Mask = 0x03; \
1512  } \
1513  else if ((Char & 0xfe) == 0xfc) \
1514  { \
1515  Len = 6; \
1516  Mask = 0x01; \
1517  } \
1518  else \
1519  { \
1520  Len = 0; \
1521  Mask = 0; \
1522  }
1523 
1528 #define UTF8_LENGTH(Char) \
1529  ((Char) < 0x80 ? 1 : \
1530  ((Char) < 0x800 ? 2 : \
1531  ((Char) < 0x10000 ? 3 : \
1532  ((Char) < 0x200000 ? 4 : \
1533  ((Char) < 0x4000000 ? 5 : 6)))))
1534 
1544 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
1545  (Result) = (Chars)[0] & (Mask); \
1546  for ((Count) = 1; (Count) < (Len); ++(Count)) \
1547  { \
1548  if (((Chars)[(Count)] & 0xc0) != 0x80) \
1549  { \
1550  (Result) = -1; \
1551  break; \
1552  } \
1553  (Result) <<= 6; \
1554  (Result) |= ((Chars)[(Count)] & 0x3f); \
1555  }
1556 
1567 #define UNICODE_VALID(Char) \
1568  ((Char) < 0x110000 && \
1569  (((Char) & 0xFFFFF800) != 0xD800))
1570 
1587  int start,
1588  const char *substr,
1589  int *found)
1590 {
1591  return _dbus_string_find_to (str, start,
1592  ((const DBusRealString*)str)->len,
1593  substr, found);
1594 }
1595 
1610  int start,
1611  int *found,
1612  int *found_len)
1613 {
1614  int i;
1615 
1617  _dbus_assert (start <= real->len);
1618  _dbus_assert (start >= 0);
1619 
1620  i = start;
1621  while (i < real->len)
1622  {
1623  if (real->str[i] == '\r')
1624  {
1625  if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1626  {
1627  if (found)
1628  *found = i;
1629  if (found_len)
1630  *found_len = 2;
1631  return TRUE;
1632  }
1633  else /* only "\r" */
1634  {
1635  if (found)
1636  *found = i;
1637  if (found_len)
1638  *found_len = 1;
1639  return TRUE;
1640  }
1641  }
1642  else if (real->str[i] == '\n') /* only "\n" */
1643  {
1644  if (found)
1645  *found = i;
1646  if (found_len)
1647  *found_len = 1;
1648  return TRUE;
1649  }
1650  ++i;
1651  }
1652 
1653  if (found)
1654  *found = real->len;
1655 
1656  if (found_len)
1657  *found_len = 0;
1658 
1659  return FALSE;
1660 }
1661 
1680  int start,
1681  int end,
1682  const char *substr,
1683  int *found)
1684 {
1685  int i;
1687  _dbus_assert (substr != NULL);
1688  _dbus_assert (start <= real->len);
1689  _dbus_assert (start >= 0);
1690  _dbus_assert (substr != NULL);
1691  _dbus_assert (end <= real->len);
1692  _dbus_assert (start <= end);
1693 
1694  /* we always "find" an empty string */
1695  if (*substr == '\0')
1696  {
1697  if (found)
1698  *found = start;
1699  return TRUE;
1700  }
1701 
1702  i = start;
1703  while (i < end)
1704  {
1705  if (real->str[i] == substr[0])
1706  {
1707  int j = i + 1;
1708 
1709  while (j < end)
1710  {
1711  if (substr[j - i] == '\0')
1712  break;
1713  else if (real->str[j] != substr[j - i])
1714  break;
1715 
1716  ++j;
1717  }
1718 
1719  if (substr[j - i] == '\0')
1720  {
1721  if (found)
1722  *found = i;
1723  return TRUE;
1724  }
1725  }
1726 
1727  ++i;
1728  }
1729 
1730  if (found)
1731  *found = end;
1732 
1733  return FALSE;
1734 }
1735 
1748  int start,
1749  int *found)
1750 {
1751  int i;
1753  _dbus_assert (start <= real->len);
1754  _dbus_assert (start >= 0);
1755 
1756  i = start;
1757  while (i < real->len)
1758  {
1759  if (real->str[i] == ' ' ||
1760  real->str[i] == '\t')
1761  {
1762  if (found)
1763  *found = i;
1764  return TRUE;
1765  }
1766 
1767  ++i;
1768  }
1769 
1770  if (found)
1771  *found = real->len;
1772 
1773  return FALSE;
1774 }
1775 
1784 void
1786  int start,
1787  int *end)
1788 {
1789  int i;
1791  _dbus_assert (start <= real->len);
1792  _dbus_assert (start >= 0);
1793 
1794  i = start;
1795  while (i < real->len)
1796  {
1797  if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1798  break;
1799 
1800  ++i;
1801  }
1802 
1803  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1804 
1805  if (end)
1806  *end = i;
1807 }
1808 
1809 
1818 void
1820  int start,
1821  int *end)
1822 {
1823  int i;
1825  _dbus_assert (start <= real->len);
1826  _dbus_assert (start >= 0);
1827 
1828  i = start;
1829  while (i < real->len)
1830  {
1831  if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1832  break;
1833 
1834  ++i;
1835  }
1836 
1837  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1838 
1839  if (end)
1840  *end = i;
1841 }
1842 
1851 void
1853  int end,
1854  int *start)
1855 {
1856  int i;
1858  _dbus_assert (end <= real->len);
1859  _dbus_assert (end >= 0);
1860 
1861  i = end;
1862  while (i > 0)
1863  {
1864  if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1865  break;
1866  --i;
1867  }
1868 
1869  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1870 
1871  if (start)
1872  *start = i;
1873 }
1874 
1892  DBusString *dest)
1893 {
1894  int eol, eol_len;
1895 
1896  _dbus_string_set_length (dest, 0);
1897 
1898  eol = 0;
1899  eol_len = 0;
1900  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1901  {
1902  _dbus_assert (eol == _dbus_string_get_length (source));
1903  if (eol == 0)
1904  {
1905  /* If there's no newline and source has zero length, we're done */
1906  return FALSE;
1907  }
1908  /* otherwise, the last line of the file has no eol characters */
1909  }
1910 
1911  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1912  * since find_eol returned TRUE
1913  */
1914 
1915  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1916  return FALSE;
1917 
1918  /* remove line ending */
1919  if (!_dbus_string_set_length (dest, eol))
1920  {
1921  _dbus_assert_not_reached ("out of memory when shortening a string");
1922  return FALSE;
1923  }
1924 
1925  return TRUE;
1926 }
1927 
1928 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1929 
1935 void
1936 _dbus_string_delete_first_word (DBusString *str)
1937 {
1938  int i;
1939 
1940  if (_dbus_string_find_blank (str, 0, &i))
1941  _dbus_string_skip_blank (str, i, &i);
1942 
1943  _dbus_string_delete (str, 0, i);
1944 }
1945 #endif
1946 
1947 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1948 
1953 void
1954 _dbus_string_delete_leading_blanks (DBusString *str)
1955 {
1956  int i;
1957 
1958  _dbus_string_skip_blank (str, 0, &i);
1959 
1960  if (i > 0)
1961  _dbus_string_delete (str, 0, i);
1962 }
1963 #endif
1964 
1970 void
1972 {
1973  int i;
1974 
1975  _dbus_string_skip_white (str, 0, &i);
1976 
1977  if (i > 0)
1978  _dbus_string_delete (str, 0, i);
1979 
1980  _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
1981 
1982  _dbus_string_set_length (str, i);
1983 }
1984 
1996  const DBusString *b)
1997 {
1998  const unsigned char *ap;
1999  const unsigned char *bp;
2000  const unsigned char *a_end;
2001  const DBusRealString *real_a = (const DBusRealString*) a;
2002  const DBusRealString *real_b = (const DBusRealString*) b;
2005 
2006  if (real_a->len != real_b->len)
2007  return FALSE;
2008 
2009  ap = real_a->str;
2010  bp = real_b->str;
2011  a_end = real_a->str + real_a->len;
2012  while (ap != a_end)
2013  {
2014  if (*ap != *bp)
2015  return FALSE;
2016 
2017  ++ap;
2018  ++bp;
2019  }
2020 
2021  return TRUE;
2022 }
2023 
2039  const DBusString *b,
2040  int len)
2041 {
2042  const unsigned char *ap;
2043  const unsigned char *bp;
2044  const unsigned char *a_end;
2045  const DBusRealString *real_a = (const DBusRealString*) a;
2046  const DBusRealString *real_b = (const DBusRealString*) b;
2049 
2050  if (real_a->len != real_b->len &&
2051  (real_a->len < len || real_b->len < len))
2052  return FALSE;
2053 
2054  ap = real_a->str;
2055  bp = real_b->str;
2056  a_end = real_a->str + MIN (real_a->len, len);
2057  while (ap != a_end)
2058  {
2059  if (*ap != *bp)
2060  return FALSE;
2061 
2062  ++ap;
2063  ++bp;
2064  }
2065 
2066  return TRUE;
2067 }
2068 
2087  int a_start,
2088  int a_len,
2089  const DBusString *b,
2090  int b_start)
2091 {
2092  const unsigned char *ap;
2093  const unsigned char *bp;
2094  const unsigned char *a_end;
2095  const DBusRealString *real_a = (const DBusRealString*) a;
2096  const DBusRealString *real_b = (const DBusRealString*) b;
2099  _dbus_assert (a_start >= 0);
2100  _dbus_assert (a_len >= 0);
2101  _dbus_assert (a_start <= real_a->len);
2102  _dbus_assert (a_len <= real_a->len - a_start);
2103  _dbus_assert (b_start >= 0);
2104  _dbus_assert (b_start <= real_b->len);
2105 
2106  if (a_len > real_b->len - b_start)
2107  return FALSE;
2108 
2109  ap = real_a->str + a_start;
2110  bp = real_b->str + b_start;
2111  a_end = ap + a_len;
2112  while (ap != a_end)
2113  {
2114  if (*ap != *bp)
2115  return FALSE;
2116 
2117  ++ap;
2118  ++bp;
2119  }
2120 
2121  _dbus_assert (bp <= (real_b->str + real_b->len));
2122 
2123  return TRUE;
2124 }
2125 
2135  const char *c_str)
2136 {
2137  const unsigned char *ap;
2138  const unsigned char *bp;
2139  const unsigned char *a_end;
2140  const DBusRealString *real_a = (const DBusRealString*) a;
2142  _dbus_assert (c_str != NULL);
2143 
2144  ap = real_a->str;
2145  bp = (const unsigned char*) c_str;
2146  a_end = real_a->str + real_a->len;
2147  while (ap != a_end && *bp)
2148  {
2149  if (*ap != *bp)
2150  return FALSE;
2151 
2152  ++ap;
2153  ++bp;
2154  }
2155 
2156  if (ap != a_end || *bp)
2157  return FALSE;
2158 
2159  return TRUE;
2160 }
2161 
2171  const char *c_str)
2172 {
2173  const unsigned char *ap;
2174  const unsigned char *bp;
2175  const unsigned char *a_end;
2176  const DBusRealString *real_a = (const DBusRealString*) a;
2178  _dbus_assert (c_str != NULL);
2179 
2180  ap = real_a->str;
2181  bp = (const unsigned char*) c_str;
2182  a_end = real_a->str + real_a->len;
2183  while (ap != a_end && *bp)
2184  {
2185  if (*ap != *bp)
2186  return FALSE;
2187 
2188  ++ap;
2189  ++bp;
2190  }
2191 
2192  if (*bp == '\0')
2193  return TRUE;
2194  else
2195  return FALSE;
2196 }
2197 
2208  unsigned char byte)
2209 {
2210  const char hexdigits[16] = {
2211  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2212  'a', 'b', 'c', 'd', 'e', 'f'
2213  };
2214 
2215  if (!_dbus_string_append_byte (str,
2216  hexdigits[(byte >> 4)]))
2217  return FALSE;
2218 
2219  if (!_dbus_string_append_byte (str,
2220  hexdigits[(byte & 0x0f)]))
2221  {
2223  _dbus_string_get_length (str) - 1);
2224  return FALSE;
2225  }
2226 
2227  return TRUE;
2228 }
2229 
2242  int start,
2243  DBusString *dest,
2244  int insert_at)
2245 {
2246  DBusString result;
2247  const unsigned char *p;
2248  const unsigned char *end;
2249  dbus_bool_t retval;
2250 
2251  _dbus_assert (start <= _dbus_string_get_length (source));
2252 
2253  if (!_dbus_string_init (&result))
2254  return FALSE;
2255 
2256  retval = FALSE;
2257 
2258  p = (const unsigned char*) _dbus_string_get_const_data (source);
2259  end = p + _dbus_string_get_length (source);
2260  p += start;
2261 
2262  while (p != end)
2263  {
2264  if (!_dbus_string_append_byte_as_hex (&result, *p))
2265  goto out;
2266 
2267  ++p;
2268  }
2269 
2270  if (!_dbus_string_move (&result, 0, dest, insert_at))
2271  goto out;
2272 
2273  retval = TRUE;
2274 
2275  out:
2276  _dbus_string_free (&result);
2277  return retval;
2278 }
2279 
2292  int start,
2293  int *end_return,
2294  DBusString *dest,
2295  int insert_at)
2296 {
2297  DBusString result;
2298  const unsigned char *p;
2299  const unsigned char *end;
2300  dbus_bool_t retval;
2301  dbus_bool_t high_bits;
2302 
2303  _dbus_assert (start <= _dbus_string_get_length (source));
2304 
2305  if (!_dbus_string_init (&result))
2306  return FALSE;
2307 
2308  retval = FALSE;
2309 
2310  high_bits = TRUE;
2311  p = (const unsigned char*) _dbus_string_get_const_data (source);
2312  end = p + _dbus_string_get_length (source);
2313  p += start;
2314 
2315  while (p != end)
2316  {
2317  unsigned int val;
2318 
2319  switch (*p)
2320  {
2321  case '0':
2322  val = 0;
2323  break;
2324  case '1':
2325  val = 1;
2326  break;
2327  case '2':
2328  val = 2;
2329  break;
2330  case '3':
2331  val = 3;
2332  break;
2333  case '4':
2334  val = 4;
2335  break;
2336  case '5':
2337  val = 5;
2338  break;
2339  case '6':
2340  val = 6;
2341  break;
2342  case '7':
2343  val = 7;
2344  break;
2345  case '8':
2346  val = 8;
2347  break;
2348  case '9':
2349  val = 9;
2350  break;
2351  case 'a':
2352  case 'A':
2353  val = 10;
2354  break;
2355  case 'b':
2356  case 'B':
2357  val = 11;
2358  break;
2359  case 'c':
2360  case 'C':
2361  val = 12;
2362  break;
2363  case 'd':
2364  case 'D':
2365  val = 13;
2366  break;
2367  case 'e':
2368  case 'E':
2369  val = 14;
2370  break;
2371  case 'f':
2372  case 'F':
2373  val = 15;
2374  break;
2375  default:
2376  goto done;
2377  }
2378 
2379  if (high_bits)
2380  {
2381  if (!_dbus_string_append_byte (&result,
2382  val << 4))
2383  goto out;
2384  }
2385  else
2386  {
2387  int len;
2388  unsigned char b;
2389 
2390  len = _dbus_string_get_length (&result);
2391 
2392  b = _dbus_string_get_byte (&result, len - 1);
2393 
2394  b |= val;
2395 
2396  _dbus_string_set_byte (&result, len - 1, b);
2397  }
2398 
2399  high_bits = !high_bits;
2400 
2401  ++p;
2402  }
2403 
2404  done:
2405  if (!_dbus_string_move (&result, 0, dest, insert_at))
2406  goto out;
2407 
2408  if (end_return)
2409  *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2410 
2411  retval = TRUE;
2412 
2413  out:
2414  _dbus_string_free (&result);
2415  return retval;
2416 }
2417 
2433  int start,
2434  int len)
2435 {
2436  const unsigned char *s;
2437  const unsigned char *end;
2439  _dbus_assert (start >= 0);
2440  _dbus_assert (start <= real->len);
2441  _dbus_assert (len >= 0);
2442 
2443  if (len > real->len - start)
2444  return FALSE;
2445 
2446  s = real->str + start;
2447  end = s + len;
2448  while (s != end)
2449  {
2450  if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2451  return FALSE;
2452 
2453  ++s;
2454  }
2455 
2456  return TRUE;
2457 }
2458 
2466 void
2468  int start,
2469  int len)
2470 {
2471  unsigned char *s;
2472  unsigned char *end;
2473  DBUS_STRING_PREAMBLE (str);
2474  _dbus_assert (start >= 0);
2475  _dbus_assert (start <= real->len);
2476  _dbus_assert (len >= 0);
2477  _dbus_assert (len <= real->len - start);
2478 
2479  s = real->str + start;
2480  end = s + len;
2481 
2482  while (s != end)
2483  {
2484  if (*s >= 'A' && *s <= 'Z')
2485  *s += 'a' - 'A';
2486  ++s;
2487  }
2488 }
2489 
2497 void
2499  int start,
2500  int len)
2501 {
2502  unsigned char *s;
2503  unsigned char *end;
2504  DBUS_STRING_PREAMBLE (str);
2505  _dbus_assert (start >= 0);
2506  _dbus_assert (start <= real->len);
2507  _dbus_assert (len >= 0);
2508  _dbus_assert (len <= real->len - start);
2509 
2510  s = real->str + start;
2511  end = s + len;
2512 
2513  while (s != end)
2514  {
2515  if (*s >= 'a' && *s <= 'z')
2516  *s += 'A' - 'a';
2517  ++s;
2518  }
2519 }
2520 
2538  int start,
2539  int len)
2540 {
2541  const unsigned char *p;
2542  const unsigned char *end;
2544  _dbus_assert (start >= 0);
2545  _dbus_assert (start <= real->len);
2546  _dbus_assert (len >= 0);
2547 
2548  /* we are doing _DBUS_UNLIKELY() here which might be
2549  * dubious in a generic library like GLib, but in D-Bus
2550  * we know we're validating messages and that it would
2551  * only be evil/broken apps that would have invalid
2552  * UTF-8. Also, this function seems to be a performance
2553  * bottleneck in profiles.
2554  */
2555 
2556  if (_DBUS_UNLIKELY (len > real->len - start))
2557  return FALSE;
2558 
2559  p = real->str + start;
2560  end = p + len;
2561 
2562  while (p < end)
2563  {
2564  int i, mask, char_len;
2565  dbus_unichar_t result;
2566 
2567  /* nul bytes considered invalid */
2568  if (*p == '\0')
2569  break;
2570 
2571  /* Special-case ASCII; this makes us go a lot faster in
2572  * D-Bus profiles where we are typically validating
2573  * function names and such. We have to know that
2574  * all following checks will pass for ASCII though,
2575  * comments follow ...
2576  */
2577  if (*p < 128)
2578  {
2579  ++p;
2580  continue;
2581  }
2582 
2583  UTF8_COMPUTE (*p, mask, char_len);
2584 
2585  if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2586  break;
2587 
2588  /* check that the expected number of bytes exists in the remaining length */
2589  if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2590  break;
2591 
2592  UTF8_GET (result, p, i, mask, char_len);
2593 
2594  /* Check for overlong UTF-8 */
2595  if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2596  break;
2597 #if 0
2598  /* The UNICODE_VALID check below will catch this */
2599  if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2600  break;
2601 #endif
2602 
2603  if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2604  break;
2605 
2606  /* UNICODE_VALID should have caught it */
2607  _dbus_assert (result != (dbus_unichar_t)-1);
2608 
2609  p += char_len;
2610  }
2611 
2612  /* See that we covered the entire length if a length was
2613  * passed in
2614  */
2615  if (_DBUS_UNLIKELY (p != end))
2616  return FALSE;
2617  else
2618  return TRUE;
2619 }
2620 
2636  int start,
2637  int len)
2638 {
2639  const unsigned char *s;
2640  const unsigned char *end;
2642  _dbus_assert (start >= 0);
2643  _dbus_assert (len >= 0);
2644  _dbus_assert (start <= real->len);
2645 
2646  if (len > real->len - start)
2647  return FALSE;
2648 
2649  s = real->str + start;
2650  end = s + len;
2651  while (s != end)
2652  {
2653  if (_DBUS_UNLIKELY (*s != '\0'))
2654  return FALSE;
2655  ++s;
2656  }
2657 
2658  return TRUE;
2659 }
2660 
2666 void
2668 {
2669  DBUS_STRING_PREAMBLE (str);
2670 
2671  memset (real->str - real->align_offset, '\0', real->allocated);
2672 }
2675 /* tests are in dbus-string-util.c */
#define DBUS_IS_ASCII_WHITE(c)
Checks for ASCII whitespace byte.
dbus_bool_t _dbus_string_insert_bytes(DBusString *str, int i, int n_bytes, unsigned char byte)
Inserts a number of bytes of a given value at the given position.
Definition: dbus-string.c:567
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:918
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:680
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)
Checks assertions for two strings we're copying a segment between, and declares real_source/real_dest...
Definition: dbus-string.c:1217
Internals of DBusString.
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:1995
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:1609
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:743
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:601
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:938
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
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:702
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:2241
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:942
dbus_bool_t _dbus_string_starts_with_c_str(const DBusString *a, const char *c_str)
Checks whether a string starts with the given C string.
Definition: dbus-string.c:2170
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:1971
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:1003
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
void _dbus_string_tolower_ascii(const DBusString *str, int start, int len)
Converts the given range of the string to lower case.
Definition: dbus-string.c:2467
unsigned int invalid
DBusString is invalid (e.g.
#define DBUS_CONST_STRING_PREAMBLE(str)
Checks assertions about a string that may be const or locked.
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:473
#define _DBUS_STRING_MAX_LENGTH
The maximum length of a DBusString.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_bool_t _dbus_string_append_printf_valist(DBusString *str, const char *format, va_list args)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1055
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:763
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:1265
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1544
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:1586
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:1819
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:934
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:1241
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:461
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1567
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:2134
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:372
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:655
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
#define DBUS_GENERIC_STRING_PREAMBLE(real)
Checks a bunch of assertions about a string object.
dbus_bool_t _dbus_string_replace_len(const DBusString *source, int start, int len, DBusString *dest, int replace_at, int replace_len)
Replaces a segment of dest string with a segment of source string.
Definition: dbus-string.c:1386
#define DBUS_STRING_PREAMBLE(str)
Checks assertions about a string object that needs to be modifiable - may not be locked or const...
void _dbus_string_skip_blank(const DBusString *str, int start, int *end)
Skips blanks from start, storing the first non-blank in *end (blank is space or tab).
Definition: dbus-string.c:1785
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1528
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:1891
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:1175
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
int len
Length without nul.
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1096
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2667
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:2537
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:866
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:2086
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:2038
unsigned int locked
DBusString has been locked and can't be changed.
dbus_bool_t _dbus_string_insert_byte(DBusString *str, int i, unsigned char byte)
Inserts a single byte at the given position.
Definition: dbus-string.c:597
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:1139
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
#define TRUE
Expands to "1".
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
int allocated
Allocated size of data.
#define DBUS_IS_ASCII_BLANK(c)
Checks for ASCII blank byte.
dbus_bool_t _dbus_string_find_blank(const DBusString *str, int start, int *found)
Finds a blank (space or tab) in the string.
Definition: dbus-string.c:1747
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:882
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:2291
unsigned int align_offset
str - align_offset is the actual malloc block
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:2207
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:1119
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:1679
unsigned char * str
String data, plus nul termination.
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
Definition: dbus-string.c:2635
#define FALSE
Expands to "0".
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:979
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:1852
#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:785
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:955
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:1357
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
Definition: dbus-string.c:624
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:2498
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1487
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:1031
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:2432
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
dbus_bool_t _dbus_string_move_len(DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_move(), but can move a segment from the middle of the source string.
Definition: dbus-string.c:1290
unsigned int constant
String data is not owned by DBusString.
dbus_bool_t _dbus_string_split_on_byte(DBusString *source, unsigned char byte, DBusString *tail)
Looks for the first occurance of a byte, deletes that byte, and moves everything after the byte to th...
Definition: dbus-string.c:1449