D-Bus  1.13.4
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_STATIC_ASSERT (sizeof (DBusString) == sizeof (DBusRealString));
138 
139  _dbus_assert (str != NULL);
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->valid = TRUE;
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->valid = TRUE;
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 
246  const DBusString *from)
247 {
248  if (!_dbus_string_init (str))
249  return FALSE;
251 }
252 
263 void
265 {
266  DBusRealString *real = (DBusRealString*) str;
267  /* DBusRealString and DBusString have the same members in the same order,
268  * just differently-named */
269  DBusRealString invalid = _DBUS_STRING_INIT_INVALID;
270 
271  /* Allow for the _DBUS_STRING_INIT_INVALID case */
272  if (real->str == NULL && real->len == 0 && real->allocated == 0 &&
273  !real->constant && !real->locked && !real->valid &&
274  real->align_offset == 0)
275  return;
276 
278 
279  if (real->constant)
280  goto wipe;
281 
282  /* so it's safe if @p str returned by a failed
283  * _dbus_string_init call
284  * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
285  */
286  if (real->str == NULL)
287  goto wipe;
288 
289  dbus_free (real->str - real->align_offset);
290 
291 wipe:
292  *real = invalid;
293  real->valid = FALSE;
294 }
295 
296 static dbus_bool_t
297 compact (DBusRealString *real,
298  int max_waste)
299 {
300  unsigned char *new_str;
301  int new_allocated;
302  int waste;
303 
304  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
305 
306  if (waste <= max_waste)
307  return TRUE;
308 
309  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
310 
311  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
312  if (_DBUS_UNLIKELY (new_str == NULL))
313  return FALSE;
314 
315  real->str = new_str + real->align_offset;
316  real->allocated = new_allocated;
317  fixup_alignment (real);
318 
319  return TRUE;
320 }
321 
322 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
323 /* Not using this feature at the moment,
324  * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
325  */
335 void
336 _dbus_string_lock (DBusString *str)
337 {
338  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
339 
340  real->locked = TRUE;
341 
342  /* Try to realloc to avoid excess memory usage, since
343  * we know we won't change the string further
344  */
345 #define MAX_WASTE 48
346  compact (real, MAX_WASTE);
347 }
348 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
349 
350 static dbus_bool_t
351 reallocate_for_length (DBusRealString *real,
352  int new_length)
353 {
354  int new_allocated;
355  unsigned char *new_str;
356 
357  /* at least double our old allocation to avoid O(n), avoiding
358  * overflow
359  */
360  if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
361  new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
362  else
363  new_allocated = real->allocated * 2;
364 
365  /* if you change the code just above here, run the tests without
366  * the following assert-only hack before you commit
367  */
368  /* This is keyed off asserts in addition to tests so when you
369  * disable asserts to profile, you don't get this destroyer
370  * of profiles.
371  */
372 #if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
373  new_allocated = 0; /* ensure a realloc every time so that we go
374  * through all malloc failure codepaths
375  */
376 #endif
377 
378  /* But be sure we always alloc at least space for the new length */
379  new_allocated = MAX (new_allocated,
380  new_length + _DBUS_STRING_ALLOCATION_PADDING);
381 
382  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
383  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
384  if (_DBUS_UNLIKELY (new_str == NULL))
385  return FALSE;
386 
387  real->str = new_str + real->align_offset;
388  real->allocated = new_allocated;
389  fixup_alignment (real);
390 
391  return TRUE;
392 }
393 
407  int max_waste)
408 {
409  DBUS_STRING_PREAMBLE (str);
410 
411  return compact (real, max_waste);
412 }
413 
414 static dbus_bool_t
415 set_length (DBusRealString *real,
416  int new_length)
417 {
418  /* Note, we are setting the length not including nul termination */
419 
420  /* exceeding max length is the same as failure to allocate memory */
421  if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
422  return FALSE;
423  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
424  _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
425  return FALSE;
426  else
427  {
428  real->len = new_length;
429  real->str[new_length] = '\0';
430  return TRUE;
431  }
432 }
433 
434 static dbus_bool_t
435 open_gap (int len,
436  DBusRealString *dest,
437  int insert_at)
438 {
439  if (len == 0)
440  return TRUE;
441 
442  if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
443  return FALSE; /* detected overflow of dest->len + len below */
444 
445  if (!set_length (dest, dest->len + len))
446  return FALSE;
447 
448  memmove (dest->str + insert_at + len,
449  dest->str + insert_at,
450  dest->len - len - insert_at);
451 
452  return TRUE;
453 }
454 
455 #ifndef _dbus_string_get_data
456 
467 char*
469 {
470  DBUS_STRING_PREAMBLE (str);
471 
472  return (char*) real->str;
473 }
474 #endif /* _dbus_string_get_data */
475 
476 /* only do the function if we don't have the macro */
477 #ifndef _dbus_string_get_const_data
478 
484 const char*
486 {
488 
489  return (const char*) real->str;
490 }
491 #endif /* _dbus_string_get_const_data */
492 
506 char*
508  int start,
509  int len)
510 {
511  DBUS_STRING_PREAMBLE (str);
512  _dbus_assert (start >= 0);
513  _dbus_assert (len >= 0);
514  _dbus_assert (start <= real->len);
515  _dbus_assert (len <= real->len - start);
516 
517  return (char*) real->str + start;
518 }
519 
520 /* only do the function if we don't have the macro */
521 #ifndef _dbus_string_get_const_data_len
522 
530 const char*
532  int start,
533  int len)
534 {
536  _dbus_assert (start >= 0);
537  _dbus_assert (len >= 0);
538  _dbus_assert (start <= real->len);
539  _dbus_assert (len <= real->len - start);
540 
541  return (const char*) real->str + start;
542 }
543 #endif /* _dbus_string_get_const_data_len */
544 
545 /* only do the function if we don't have the macro */
546 #ifndef _dbus_string_set_byte
547 
554 void
556  int i,
557  unsigned char byte)
558 {
559  DBUS_STRING_PREAMBLE (str);
560  _dbus_assert (i < real->len);
561  _dbus_assert (i >= 0);
562 
563  real->str[i] = byte;
564 }
565 #endif /* _dbus_string_set_byte */
566 
567 /* only have the function if we didn't create a macro */
568 #ifndef _dbus_string_get_byte
569 
578 unsigned char
580  int start)
581 {
583  _dbus_assert (start <= real->len);
584  _dbus_assert (start >= 0);
585 
586  return real->str[start];
587 }
588 #endif /* _dbus_string_get_byte */
589 
602  int i,
603  int n_bytes,
604  unsigned char byte)
605 {
606  DBUS_STRING_PREAMBLE (str);
607  _dbus_assert (i <= real->len);
608  _dbus_assert (i >= 0);
609  _dbus_assert (n_bytes >= 0);
610 
611  if (n_bytes == 0)
612  return TRUE;
613 
614  if (!open_gap (n_bytes, real, i))
615  return FALSE;
616 
617  memset (real->str + i, byte, n_bytes);
618 
619  return TRUE;
620 }
621 
632  int i,
633  unsigned char byte)
634 {
635  DBUS_STRING_PREAMBLE (str);
636  _dbus_assert (i <= real->len);
637  _dbus_assert (i >= 0);
638 
639  if (!open_gap (1, real, i))
640  return FALSE;
641 
642  real->str[i] = byte;
643 
644  return TRUE;
645 }
646 
659  char **data_return)
660 {
661  DBUS_STRING_PREAMBLE (str);
662  _dbus_assert (data_return != NULL);
663 
664  undo_alignment (real);
665 
666  *data_return = (char*) real->str;
667 
668  /* reset the string */
669  if (!_dbus_string_init (str))
670  {
671  /* hrm, put it back then */
672  real->str = (unsigned char*) *data_return;
673  *data_return = NULL;
674  fixup_alignment (real);
675  return FALSE;
676  }
677 
678  return TRUE;
679 }
680 
690  char **data_return)
691 {
693  _dbus_assert (data_return != NULL);
694 
695  *data_return = dbus_malloc (real->len + 1);
696  if (*data_return == NULL)
697  return FALSE;
698 
699  memcpy (*data_return, real->str, real->len + 1);
700 
701  return TRUE;
702 }
703 
713 void
715  char *buffer,
716  int avail_len)
717 {
719 
720  _dbus_assert (avail_len >= 0);
721  _dbus_assert (avail_len >= real->len);
722 
723  memcpy (buffer, real->str, real->len);
724 }
725 
735 void
737  char *buffer,
738  int avail_len)
739 {
741 
742  _dbus_assert (avail_len >= 0);
743  _dbus_assert (avail_len > real->len);
744 
745  memcpy (buffer, real->str, real->len+1);
746 }
747 
748 /* Only have the function if we don't have the macro */
749 #ifndef _dbus_string_get_length
750 
755 int
757 {
759 
760  return real->len;
761 }
762 #endif /* !_dbus_string_get_length */
763 
778  int additional_length)
779 {
780  DBUS_STRING_PREAMBLE (str);
781  _dbus_assert (additional_length >= 0);
782 
783  if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
784  return FALSE; /* would overflow */
785 
786  return set_length (real,
787  real->len + additional_length);
788 }
789 
796 void
798  int length_to_remove)
799 {
800  DBUS_STRING_PREAMBLE (str);
801  _dbus_assert (length_to_remove >= 0);
802  _dbus_assert (length_to_remove <= real->len);
803 
804  set_length (real,
805  real->len - length_to_remove);
806 }
807 
820  int length)
821 {
822  DBUS_STRING_PREAMBLE (str);
823  _dbus_assert (length >= 0);
824 
825  return set_length (real, length);
826 }
827 
828 static dbus_bool_t
829 align_insert_point_then_open_gap (DBusString *str,
830  int *insert_at_p,
831  int alignment,
832  int gap_size)
833 {
834  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
835  unsigned long gap_pos;
836  int insert_at;
837  int delta;
838  DBUS_STRING_PREAMBLE (str);
839  _dbus_assert (alignment >= 1);
840  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
841 
842  insert_at = *insert_at_p;
843 
844  _dbus_assert (insert_at <= real->len);
845 
846  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
847  new_len = real->len + (gap_pos - insert_at) + gap_size;
848 
849  if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
850  return FALSE;
851 
852  delta = new_len - real->len;
853  _dbus_assert (delta >= 0);
854 
855  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
856  {
857  _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
858  return TRUE;
859  }
860 
861  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
862  real, insert_at)))
863  return FALSE;
864 
865  /* nul the padding if we had to add any padding */
866  if (gap_size < delta)
867  {
868  memset (&real->str[insert_at], '\0',
869  gap_pos - insert_at);
870  }
871 
872  *insert_at_p = gap_pos;
873 
874  return TRUE;
875 }
876 
877 static dbus_bool_t
878 align_length_then_lengthen (DBusString *str,
879  int alignment,
880  int then_lengthen_by)
881 {
882  int insert_at;
883 
884  insert_at = _dbus_string_get_length (str);
885 
886  return align_insert_point_then_open_gap (str,
887  &insert_at,
888  alignment, then_lengthen_by);
889 }
890 
901  int alignment)
902 {
903  return align_length_then_lengthen (str, alignment, 0);
904 }
905 
917  int extra_bytes)
918 {
919  if (!_dbus_string_lengthen (str, extra_bytes))
920  return FALSE;
921  _dbus_string_shorten (str, extra_bytes);
922 
923  return TRUE;
924 }
925 
926 static dbus_bool_t
927 append (DBusRealString *real,
928  const char *buffer,
929  int buffer_len)
930 {
931  if (buffer_len == 0)
932  return TRUE;
933 
934  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
935  return FALSE;
936 
937  memcpy (real->str + (real->len - buffer_len),
938  buffer,
939  buffer_len);
940 
941  return TRUE;
942 }
943 
953  const char *buffer)
954 {
955  unsigned long buffer_len;
956 
957  DBUS_STRING_PREAMBLE (str);
958  _dbus_assert (buffer != NULL);
959 
960  buffer_len = strlen (buffer);
961  if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
962  return FALSE;
963 
964  return append (real, buffer, buffer_len);
965 }
966 
968 #define ASSIGN_2_OCTETS(p, octets) \
969  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
970 
972 #define ASSIGN_4_OCTETS(p, octets) \
973  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
974 
976 #define ASSIGN_8_OCTETS(p, octets) \
977  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
978 
990  int insert_at,
991  const unsigned char octets[2])
992 {
993  DBUS_STRING_PREAMBLE (str);
994 
995  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
996  return FALSE;
997 
998  ASSIGN_2_OCTETS (real->str + insert_at, octets);
999 
1000  return TRUE;
1001 }
1002 
1014  int insert_at,
1015  const unsigned char octets[4])
1016 {
1017  DBUS_STRING_PREAMBLE (str);
1018 
1019  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1020  return FALSE;
1021 
1022  ASSIGN_4_OCTETS (real->str + insert_at, octets);
1023 
1024  return TRUE;
1025 }
1026 
1038  int insert_at,
1039  const unsigned char octets[8])
1040 {
1041  DBUS_STRING_PREAMBLE (str);
1042 
1043  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1044  return FALSE;
1045 
1046  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1047 
1048  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1049 
1050  return TRUE;
1051 }
1052 
1053 
1066  int *insert_at,
1067  int alignment)
1068 {
1069  DBUS_STRING_PREAMBLE (str);
1070 
1071  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1072  return FALSE;
1073 
1074  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1075 
1076  return TRUE;
1077 }
1078 
1090  const char *format,
1091  va_list args)
1092 {
1093  dbus_bool_t ret = FALSE;
1094  int len;
1095  va_list args_copy;
1096 
1097  DBUS_STRING_PREAMBLE (str);
1098 
1099  DBUS_VA_COPY (args_copy, args);
1100 
1101  /* Measure the message length without terminating nul */
1102  len = _dbus_printf_string_upper_bound (format, args);
1103 
1104  if (len < 0)
1105  goto out;
1106 
1107  if (!_dbus_string_lengthen (str, len))
1108  {
1109  goto out;
1110  }
1111 
1112  vsprintf ((char*) (real->str + (real->len - len)),
1113  format, args_copy);
1114  ret = TRUE;
1115 
1116 out:
1117  va_end (args_copy);
1118 
1119  return ret;
1120 }
1121 
1132  const char *format,
1133  ...)
1134 {
1135  va_list args;
1136  dbus_bool_t retval;
1137 
1138  va_start (args, format);
1139  retval = _dbus_string_append_printf_valist (str, format, args);
1140  va_end (args);
1141 
1142  return retval;
1143 }
1144 
1155  const char *buffer,
1156  int len)
1157 {
1158  DBUS_STRING_PREAMBLE (str);
1159  _dbus_assert (buffer != NULL);
1160  _dbus_assert (len >= 0);
1161 
1162  return append (real, buffer, len);
1163 }
1164 
1175  unsigned char byte)
1176 {
1177  DBUS_STRING_PREAMBLE (str);
1178 
1179  if (!set_length (real, real->len + 1))
1180  return FALSE;
1181 
1182  real->str[real->len-1] = byte;
1183 
1184  return TRUE;
1185 }
1186 
1187 static void
1188 delete (DBusRealString *real,
1189  int start,
1190  int len)
1191 {
1192  if (len == 0)
1193  return;
1194 
1195  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1196  real->len -= len;
1197  real->str[real->len] = '\0';
1198 }
1199 
1209 void
1211  int start,
1212  int len)
1213 {
1214  DBUS_STRING_PREAMBLE (str);
1215  _dbus_assert (start >= 0);
1216  _dbus_assert (len >= 0);
1217  _dbus_assert (start <= real->len);
1218  _dbus_assert (len <= real->len - start);
1219 
1220  delete (real, start, len);
1221 }
1222 
1223 static dbus_bool_t
1224 copy (DBusRealString *source,
1225  int start,
1226  int len,
1227  DBusRealString *dest,
1228  int insert_at)
1229 {
1230  if (len == 0)
1231  return TRUE;
1232 
1233  if (!open_gap (len, dest, insert_at))
1234  return FALSE;
1235 
1236  memmove (dest->str + insert_at,
1237  source->str + start,
1238  len);
1239 
1240  return TRUE;
1241 }
1242 
1252 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1253  DBusRealString *real_source = (DBusRealString*) source; \
1254  DBusRealString *real_dest = (DBusRealString*) dest; \
1255  _dbus_assert ((source) != (dest)); \
1256  DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1257  DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1258  _dbus_assert (!real_dest->constant); \
1259  _dbus_assert (!real_dest->locked); \
1260  _dbus_assert ((start) >= 0); \
1261  _dbus_assert ((start) <= real_source->len); \
1262  _dbus_assert ((insert_at) >= 0); \
1263  _dbus_assert ((insert_at) <= real_dest->len)
1264 
1277  int start,
1278  DBusString *dest,
1279  int insert_at)
1280 {
1281  DBusRealString *real_source = (DBusRealString*) source;
1282  _dbus_assert (start <= real_source->len);
1283 
1284  return _dbus_string_move_len (source, start,
1285  real_source->len - start,
1286  dest, insert_at);
1287 }
1288 
1301  int start,
1302  DBusString *dest,
1303  int insert_at)
1304 {
1305  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1306 
1307  return copy (real_source, start,
1308  real_source->len - start,
1309  real_dest,
1310  insert_at);
1311 }
1312 
1326  int start,
1327  int len,
1328  DBusString *dest,
1329  int insert_at)
1330 
1331 {
1332  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1333  _dbus_assert (len >= 0);
1334  _dbus_assert ((start + len) <= real_source->len);
1335 
1336 
1337  if (len == 0)
1338  {
1339  return TRUE;
1340  }
1341  else if (start == 0 &&
1342  len == real_source->len &&
1343  real_dest->len == 0)
1344  {
1345  /* Short-circuit moving an entire existing string to an empty string
1346  * by just swapping the buffers.
1347  */
1348  /* we assume ->constant doesn't matter as you can't have
1349  * a constant string involved in a move.
1350  */
1351 #define ASSIGN_DATA(a, b) do { \
1352  (a)->str = (b)->str; \
1353  (a)->len = (b)->len; \
1354  (a)->allocated = (b)->allocated; \
1355  (a)->align_offset = (b)->align_offset; \
1356  } while (0)
1357 
1358  DBusRealString tmp;
1359 
1360  ASSIGN_DATA (&tmp, real_source);
1361  ASSIGN_DATA (real_source, real_dest);
1362  ASSIGN_DATA (real_dest, &tmp);
1363 
1364  return TRUE;
1365  }
1366  else
1367  {
1368  if (!copy (real_source, start, len,
1369  real_dest,
1370  insert_at))
1371  return FALSE;
1372 
1373  delete (real_source, start,
1374  len);
1375 
1376  return TRUE;
1377  }
1378 }
1379 
1393  int start,
1394  int len,
1395  DBusString *dest,
1396  int insert_at)
1397 {
1398  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1399  _dbus_assert (len >= 0);
1400  _dbus_assert (start <= real_source->len);
1401  _dbus_assert (len <= real_source->len - start);
1402 
1403  return copy (real_source, start, len,
1404  real_dest,
1405  insert_at);
1406 }
1407 
1422  int start,
1423  int len,
1424  DBusString *dest,
1425  int replace_at,
1426  int replace_len)
1427 {
1428  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1429  _dbus_assert (len >= 0);
1430  _dbus_assert (start <= real_source->len);
1431  _dbus_assert (len <= real_source->len - start);
1432  _dbus_assert (replace_at >= 0);
1433  _dbus_assert (replace_at <= real_dest->len);
1434  _dbus_assert (replace_len <= real_dest->len - replace_at);
1435 
1436  if (len == replace_len)
1437  {
1438  memmove (real_dest->str + replace_at,
1439  real_source->str + start, len);
1440  }
1441  else if (len < replace_len)
1442  {
1443  memmove (real_dest->str + replace_at,
1444  real_source->str + start, len);
1445  delete (real_dest, replace_at + len,
1446  replace_len - len);
1447  }
1448  else
1449  {
1450  int diff;
1451 
1452  _dbus_assert (len > replace_len);
1453 
1454  diff = len - replace_len;
1455 
1456  /* First of all we check if destination string can be enlarged as
1457  * required, then we overwrite previous bytes
1458  */
1459 
1460  if (!copy (real_source, start + replace_len, diff,
1461  real_dest, replace_at + replace_len))
1462  return FALSE;
1463 
1464  memmove (real_dest->str + replace_at,
1465  real_source->str + start, replace_len);
1466  }
1467 
1468  return TRUE;
1469 }
1470 
1485  unsigned char byte,
1486  DBusString *tail)
1487 {
1488  int byte_position;
1489  char byte_string[2] = "";
1490  int head_length;
1491  int tail_length;
1492 
1493  byte_string[0] = (char) byte;
1494 
1495  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1496  return FALSE;
1497 
1498  head_length = byte_position;
1499  tail_length = _dbus_string_get_length (source) - head_length - 1;
1500 
1501  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1502  tail, 0))
1503  return FALSE;
1504 
1505  /* remove the trailing delimiter byte from the head now.
1506  */
1507  if (!_dbus_string_set_length (source, head_length))
1508  return FALSE;
1509 
1510  return TRUE;
1511 }
1512 
1513 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1514  * Pennington, and Tom Tromey are the authors and authorized relicense.
1515  */
1516 
1522 #define UTF8_COMPUTE(Char, Mask, Len) \
1523  if (Char < 128) \
1524  { \
1525  Len = 1; \
1526  Mask = 0x7f; \
1527  } \
1528  else if ((Char & 0xe0) == 0xc0) \
1529  { \
1530  Len = 2; \
1531  Mask = 0x1f; \
1532  } \
1533  else if ((Char & 0xf0) == 0xe0) \
1534  { \
1535  Len = 3; \
1536  Mask = 0x0f; \
1537  } \
1538  else if ((Char & 0xf8) == 0xf0) \
1539  { \
1540  Len = 4; \
1541  Mask = 0x07; \
1542  } \
1543  else if ((Char & 0xfc) == 0xf8) \
1544  { \
1545  Len = 5; \
1546  Mask = 0x03; \
1547  } \
1548  else if ((Char & 0xfe) == 0xfc) \
1549  { \
1550  Len = 6; \
1551  Mask = 0x01; \
1552  } \
1553  else \
1554  { \
1555  Len = 0; \
1556  Mask = 0; \
1557  }
1558 
1563 #define UTF8_LENGTH(Char) \
1564  ((Char) < 0x80 ? 1 : \
1565  ((Char) < 0x800 ? 2 : \
1566  ((Char) < 0x10000 ? 3 : \
1567  ((Char) < 0x200000 ? 4 : \
1568  ((Char) < 0x4000000 ? 5 : 6)))))
1569 
1579 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
1580  (Result) = (Chars)[0] & (Mask); \
1581  for ((Count) = 1; (Count) < (Len); ++(Count)) \
1582  { \
1583  if (((Chars)[(Count)] & 0xc0) != 0x80) \
1584  { \
1585  (Result) = -1; \
1586  break; \
1587  } \
1588  (Result) <<= 6; \
1589  (Result) |= ((Chars)[(Count)] & 0x3f); \
1590  }
1591 
1602 #define UNICODE_VALID(Char) \
1603  ((Char) < 0x110000 && \
1604  (((Char) & 0xFFFFF800) != 0xD800))
1605 
1622  int start,
1623  const char *substr,
1624  int *found)
1625 {
1626  return _dbus_string_find_to (str, start,
1627  ((const DBusRealString*)str)->len,
1628  substr, found);
1629 }
1630 
1645  int start,
1646  int *found,
1647  int *found_len)
1648 {
1649  int i;
1650 
1652  _dbus_assert (start <= real->len);
1653  _dbus_assert (start >= 0);
1654 
1655  i = start;
1656  while (i < real->len)
1657  {
1658  if (real->str[i] == '\r')
1659  {
1660  if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1661  {
1662  if (found)
1663  *found = i;
1664  if (found_len)
1665  *found_len = 2;
1666  return TRUE;
1667  }
1668  else /* only "\r" */
1669  {
1670  if (found)
1671  *found = i;
1672  if (found_len)
1673  *found_len = 1;
1674  return TRUE;
1675  }
1676  }
1677  else if (real->str[i] == '\n') /* only "\n" */
1678  {
1679  if (found)
1680  *found = i;
1681  if (found_len)
1682  *found_len = 1;
1683  return TRUE;
1684  }
1685  ++i;
1686  }
1687 
1688  if (found)
1689  *found = real->len;
1690 
1691  if (found_len)
1692  *found_len = 0;
1693 
1694  return FALSE;
1695 }
1696 
1715  int start,
1716  int end,
1717  const char *substr,
1718  int *found)
1719 {
1720  int i;
1722  _dbus_assert (substr != NULL);
1723  _dbus_assert (start <= real->len);
1724  _dbus_assert (start >= 0);
1725  _dbus_assert (substr != NULL);
1726  _dbus_assert (end <= real->len);
1727  _dbus_assert (start <= end);
1728 
1729  /* we always "find" an empty string */
1730  if (*substr == '\0')
1731  {
1732  if (found)
1733  *found = start;
1734  return TRUE;
1735  }
1736 
1737  i = start;
1738  while (i < end)
1739  {
1740  if (real->str[i] == substr[0])
1741  {
1742  int j = i + 1;
1743 
1744  while (j < end)
1745  {
1746  if (substr[j - i] == '\0')
1747  break;
1748  else if (real->str[j] != substr[j - i])
1749  break;
1750 
1751  ++j;
1752  }
1753 
1754  if (substr[j - i] == '\0')
1755  {
1756  if (found)
1757  *found = i;
1758  return TRUE;
1759  }
1760  }
1761 
1762  ++i;
1763  }
1764 
1765  if (found)
1766  *found = end;
1767 
1768  return FALSE;
1769 }
1770 
1783  int start,
1784  int *found)
1785 {
1786  int i;
1788  _dbus_assert (start <= real->len);
1789  _dbus_assert (start >= 0);
1790 
1791  i = start;
1792  while (i < real->len)
1793  {
1794  if (real->str[i] == ' ' ||
1795  real->str[i] == '\t')
1796  {
1797  if (found)
1798  *found = i;
1799  return TRUE;
1800  }
1801 
1802  ++i;
1803  }
1804 
1805  if (found)
1806  *found = real->len;
1807 
1808  return FALSE;
1809 }
1810 
1819 void
1821  int start,
1822  int *end)
1823 {
1824  int i;
1826  _dbus_assert (start <= real->len);
1827  _dbus_assert (start >= 0);
1828 
1829  i = start;
1830  while (i < real->len)
1831  {
1832  if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1833  break;
1834 
1835  ++i;
1836  }
1837 
1838  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1839 
1840  if (end)
1841  *end = i;
1842 }
1843 
1844 
1853 void
1855  int start,
1856  int *end)
1857 {
1858  int i;
1860  _dbus_assert (start <= real->len);
1861  _dbus_assert (start >= 0);
1862 
1863  i = start;
1864  while (i < real->len)
1865  {
1866  if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1867  break;
1868 
1869  ++i;
1870  }
1871 
1872  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1873 
1874  if (end)
1875  *end = i;
1876 }
1877 
1886 void
1888  int end,
1889  int *start)
1890 {
1891  int i;
1893  _dbus_assert (end <= real->len);
1894  _dbus_assert (end >= 0);
1895 
1896  i = end;
1897  while (i > 0)
1898  {
1899  if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1900  break;
1901  --i;
1902  }
1903 
1904  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1905 
1906  if (start)
1907  *start = i;
1908 }
1909 
1927  DBusString *dest)
1928 {
1929  int eol, eol_len;
1930 
1931  _dbus_string_set_length (dest, 0);
1932 
1933  eol = 0;
1934  eol_len = 0;
1935  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1936  {
1937  _dbus_assert (eol == _dbus_string_get_length (source));
1938  if (eol == 0)
1939  {
1940  /* If there's no newline and source has zero length, we're done */
1941  return FALSE;
1942  }
1943  /* otherwise, the last line of the file has no eol characters */
1944  }
1945 
1946  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1947  * since find_eol returned TRUE
1948  */
1949 
1950  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1951  return FALSE;
1952 
1953  /* remove line ending */
1954  if (!_dbus_string_set_length (dest, eol))
1955  {
1956  _dbus_assert_not_reached ("out of memory when shortening a string");
1957  return FALSE;
1958  }
1959 
1960  return TRUE;
1961 }
1962 
1963 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1964 
1970 void
1971 _dbus_string_delete_first_word (DBusString *str)
1972 {
1973  int i;
1974 
1975  if (_dbus_string_find_blank (str, 0, &i))
1976  _dbus_string_skip_blank (str, i, &i);
1977 
1978  _dbus_string_delete (str, 0, i);
1979 }
1980 #endif
1981 
1982 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1983 
1988 void
1989 _dbus_string_delete_leading_blanks (DBusString *str)
1990 {
1991  int i;
1992 
1993  _dbus_string_skip_blank (str, 0, &i);
1994 
1995  if (i > 0)
1996  _dbus_string_delete (str, 0, i);
1997 }
1998 #endif
1999 
2005 void
2007 {
2008  int i;
2009 
2010  _dbus_string_skip_white (str, 0, &i);
2011 
2012  if (i > 0)
2013  _dbus_string_delete (str, 0, i);
2014 
2016 
2017  _dbus_string_set_length (str, i);
2018 }
2019 
2031  const DBusString *b)
2032 {
2033  const unsigned char *ap;
2034  const unsigned char *bp;
2035  const unsigned char *a_end;
2036  const DBusRealString *real_a = (const DBusRealString*) a;
2037  const DBusRealString *real_b = (const DBusRealString*) b;
2040 
2041  if (real_a->len != real_b->len)
2042  return FALSE;
2043 
2044  ap = real_a->str;
2045  bp = real_b->str;
2046  a_end = real_a->str + real_a->len;
2047  while (ap != a_end)
2048  {
2049  if (*ap != *bp)
2050  return FALSE;
2051 
2052  ++ap;
2053  ++bp;
2054  }
2055 
2056  return TRUE;
2057 }
2058 
2074  const DBusString *b,
2075  int len)
2076 {
2077  const unsigned char *ap;
2078  const unsigned char *bp;
2079  const unsigned char *a_end;
2080  const DBusRealString *real_a = (const DBusRealString*) a;
2081  const DBusRealString *real_b = (const DBusRealString*) b;
2084 
2085  if (real_a->len != real_b->len &&
2086  (real_a->len < len || real_b->len < len))
2087  return FALSE;
2088 
2089  ap = real_a->str;
2090  bp = real_b->str;
2091  a_end = real_a->str + MIN (real_a->len, len);
2092  while (ap != a_end)
2093  {
2094  if (*ap != *bp)
2095  return FALSE;
2096 
2097  ++ap;
2098  ++bp;
2099  }
2100 
2101  return TRUE;
2102 }
2103 
2122  int a_start,
2123  int a_len,
2124  const DBusString *b,
2125  int b_start)
2126 {
2127  const unsigned char *ap;
2128  const unsigned char *bp;
2129  const unsigned char *a_end;
2130  const DBusRealString *real_a = (const DBusRealString*) a;
2131  const DBusRealString *real_b = (const DBusRealString*) b;
2134  _dbus_assert (a_start >= 0);
2135  _dbus_assert (a_len >= 0);
2136  _dbus_assert (a_start <= real_a->len);
2137  _dbus_assert (a_len <= real_a->len - a_start);
2138  _dbus_assert (b_start >= 0);
2139  _dbus_assert (b_start <= real_b->len);
2140 
2141  if (a_len > real_b->len - b_start)
2142  return FALSE;
2143 
2144  ap = real_a->str + a_start;
2145  bp = real_b->str + b_start;
2146  a_end = ap + a_len;
2147  while (ap != a_end)
2148  {
2149  if (*ap != *bp)
2150  return FALSE;
2151 
2152  ++ap;
2153  ++bp;
2154  }
2155 
2156  _dbus_assert (bp <= (real_b->str + real_b->len));
2157 
2158  return TRUE;
2159 }
2160 
2170  const char *c_str)
2171 {
2172  const unsigned char *ap;
2173  const unsigned char *bp;
2174  const unsigned char *a_end;
2175  const DBusRealString *real_a = (const DBusRealString*) a;
2177  _dbus_assert (c_str != NULL);
2178 
2179  ap = real_a->str;
2180  bp = (const unsigned char*) c_str;
2181  a_end = real_a->str + real_a->len;
2182  while (ap != a_end && *bp)
2183  {
2184  if (*ap != *bp)
2185  return FALSE;
2186 
2187  ++ap;
2188  ++bp;
2189  }
2190 
2191  if (ap != a_end || *bp)
2192  return FALSE;
2193 
2194  return TRUE;
2195 }
2196 
2206  const char *c_str)
2207 {
2208  const unsigned char *ap;
2209  const unsigned char *bp;
2210  const unsigned char *a_end;
2211  const DBusRealString *real_a = (const DBusRealString*) a;
2213  _dbus_assert (c_str != NULL);
2214 
2215  ap = real_a->str;
2216  bp = (const unsigned char*) c_str;
2217  a_end = real_a->str + real_a->len;
2218  while (ap != a_end && *bp)
2219  {
2220  if (*ap != *bp)
2221  return FALSE;
2222 
2223  ++ap;
2224  ++bp;
2225  }
2226 
2227  if (*bp == '\0')
2228  return TRUE;
2229  else
2230  return FALSE;
2231 }
2232 
2243  unsigned char byte)
2244 {
2245  const char hexdigits[16] = {
2246  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2247  'a', 'b', 'c', 'd', 'e', 'f'
2248  };
2249 
2250  if (!_dbus_string_append_byte (str,
2251  hexdigits[(byte >> 4)]))
2252  return FALSE;
2253 
2254  if (!_dbus_string_append_byte (str,
2255  hexdigits[(byte & 0x0f)]))
2256  {
2258  _dbus_string_get_length (str) - 1);
2259  return FALSE;
2260  }
2261 
2262  return TRUE;
2263 }
2264 
2277  int start,
2278  DBusString *dest,
2279  int insert_at)
2280 {
2281  DBusString result;
2282  const unsigned char *p;
2283  const unsigned char *end;
2284  dbus_bool_t retval;
2285 
2286  _dbus_assert (start <= _dbus_string_get_length (source));
2287 
2288  if (!_dbus_string_init (&result))
2289  return FALSE;
2290 
2291  retval = FALSE;
2292 
2293  p = (const unsigned char*) _dbus_string_get_const_data (source);
2294  end = p + _dbus_string_get_length (source);
2295  p += start;
2296 
2297  while (p != end)
2298  {
2299  if (!_dbus_string_append_byte_as_hex (&result, *p))
2300  goto out;
2301 
2302  ++p;
2303  }
2304 
2305  if (!_dbus_string_move (&result, 0, dest, insert_at))
2306  goto out;
2307 
2308  retval = TRUE;
2309 
2310  out:
2311  _dbus_string_free (&result);
2312  return retval;
2313 }
2314 
2327  int start,
2328  int *end_return,
2329  DBusString *dest,
2330  int insert_at)
2331 {
2332  DBusString result;
2333  const unsigned char *p;
2334  const unsigned char *end;
2335  dbus_bool_t retval;
2336  dbus_bool_t high_bits;
2337 
2338  _dbus_assert (start <= _dbus_string_get_length (source));
2339 
2340  if (!_dbus_string_init (&result))
2341  return FALSE;
2342 
2343  retval = FALSE;
2344 
2345  high_bits = TRUE;
2346  p = (const unsigned char*) _dbus_string_get_const_data (source);
2347  end = p + _dbus_string_get_length (source);
2348  p += start;
2349 
2350  while (p != end)
2351  {
2352  unsigned int val;
2353 
2354  switch (*p)
2355  {
2356  case '0':
2357  val = 0;
2358  break;
2359  case '1':
2360  val = 1;
2361  break;
2362  case '2':
2363  val = 2;
2364  break;
2365  case '3':
2366  val = 3;
2367  break;
2368  case '4':
2369  val = 4;
2370  break;
2371  case '5':
2372  val = 5;
2373  break;
2374  case '6':
2375  val = 6;
2376  break;
2377  case '7':
2378  val = 7;
2379  break;
2380  case '8':
2381  val = 8;
2382  break;
2383  case '9':
2384  val = 9;
2385  break;
2386  case 'a':
2387  case 'A':
2388  val = 10;
2389  break;
2390  case 'b':
2391  case 'B':
2392  val = 11;
2393  break;
2394  case 'c':
2395  case 'C':
2396  val = 12;
2397  break;
2398  case 'd':
2399  case 'D':
2400  val = 13;
2401  break;
2402  case 'e':
2403  case 'E':
2404  val = 14;
2405  break;
2406  case 'f':
2407  case 'F':
2408  val = 15;
2409  break;
2410  default:
2411  goto done;
2412  }
2413 
2414  if (high_bits)
2415  {
2416  if (!_dbus_string_append_byte (&result,
2417  val << 4))
2418  goto out;
2419  }
2420  else
2421  {
2422  int len;
2423  unsigned char b;
2424 
2425  len = _dbus_string_get_length (&result);
2426 
2427  b = _dbus_string_get_byte (&result, len - 1);
2428 
2429  b |= val;
2430 
2431  _dbus_string_set_byte (&result, len - 1, b);
2432  }
2433 
2434  high_bits = !high_bits;
2435 
2436  ++p;
2437  }
2438 
2439  done:
2440  if (!_dbus_string_move (&result, 0, dest, insert_at))
2441  goto out;
2442 
2443  if (end_return)
2444  *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2445 
2446  retval = TRUE;
2447 
2448  out:
2449  _dbus_string_free (&result);
2450  return retval;
2451 }
2452 
2468  int start,
2469  int len)
2470 {
2471  const unsigned char *s;
2472  const unsigned char *end;
2474  _dbus_assert (start >= 0);
2475  _dbus_assert (start <= real->len);
2476  _dbus_assert (len >= 0);
2477 
2478  if (len > real->len - start)
2479  return FALSE;
2480 
2481  s = real->str + start;
2482  end = s + len;
2483  while (s != end)
2484  {
2485  if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2486  return FALSE;
2487 
2488  ++s;
2489  }
2490 
2491  return TRUE;
2492 }
2493 
2501 void
2503  int start,
2504  int len)
2505 {
2506  unsigned char *s;
2507  unsigned char *end;
2508  DBUS_STRING_PREAMBLE (str);
2509  _dbus_assert (start >= 0);
2510  _dbus_assert (start <= real->len);
2511  _dbus_assert (len >= 0);
2512  _dbus_assert (len <= real->len - start);
2513 
2514  s = real->str + start;
2515  end = s + len;
2516 
2517  while (s != end)
2518  {
2519  if (*s >= 'A' && *s <= 'Z')
2520  *s += 'a' - 'A';
2521  ++s;
2522  }
2523 }
2524 
2532 void
2534  int start,
2535  int len)
2536 {
2537  unsigned char *s;
2538  unsigned char *end;
2539  DBUS_STRING_PREAMBLE (str);
2540  _dbus_assert (start >= 0);
2541  _dbus_assert (start <= real->len);
2542  _dbus_assert (len >= 0);
2543  _dbus_assert (len <= real->len - start);
2544 
2545  s = real->str + start;
2546  end = s + len;
2547 
2548  while (s != end)
2549  {
2550  if (*s >= 'a' && *s <= 'z')
2551  *s += 'A' - 'a';
2552  ++s;
2553  }
2554 }
2555 
2573  int start,
2574  int len)
2575 {
2576  const unsigned char *p;
2577  const unsigned char *end;
2579  _dbus_assert (start >= 0);
2580  _dbus_assert (start <= real->len);
2581  _dbus_assert (len >= 0);
2582 
2583  /* we are doing _DBUS_UNLIKELY() here which might be
2584  * dubious in a generic library like GLib, but in D-Bus
2585  * we know we're validating messages and that it would
2586  * only be evil/broken apps that would have invalid
2587  * UTF-8. Also, this function seems to be a performance
2588  * bottleneck in profiles.
2589  */
2590 
2591  if (_DBUS_UNLIKELY (len > real->len - start))
2592  return FALSE;
2593 
2594  p = real->str + start;
2595  end = p + len;
2596 
2597  while (p < end)
2598  {
2599  int i, mask, char_len;
2600  dbus_unichar_t result;
2601 
2602  /* nul bytes considered invalid */
2603  if (*p == '\0')
2604  break;
2605 
2606  /* Special-case ASCII; this makes us go a lot faster in
2607  * D-Bus profiles where we are typically validating
2608  * function names and such. We have to know that
2609  * all following checks will pass for ASCII though,
2610  * comments follow ...
2611  */
2612  if (*p < 128)
2613  {
2614  ++p;
2615  continue;
2616  }
2617 
2618  UTF8_COMPUTE (*p, mask, char_len);
2619 
2620  if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2621  break;
2622 
2623  /* check that the expected number of bytes exists in the remaining length */
2624  if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2625  break;
2626 
2627  UTF8_GET (result, p, i, mask, char_len);
2628 
2629  /* Check for overlong UTF-8 */
2630  if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2631  break;
2632 #if 0
2633  /* The UNICODE_VALID check below will catch this */
2634  if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2635  break;
2636 #endif
2637 
2638  if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2639  break;
2640 
2641  /* UNICODE_VALID should have caught it */
2642  _dbus_assert (result != (dbus_unichar_t)-1);
2643 
2644  p += char_len;
2645  }
2646 
2647  /* See that we covered the entire length if a length was
2648  * passed in
2649  */
2650  if (_DBUS_UNLIKELY (p != end))
2651  return FALSE;
2652  else
2653  return TRUE;
2654 }
2655 
2671  int start,
2672  int len)
2673 {
2674  const unsigned char *s;
2675  const unsigned char *end;
2677  _dbus_assert (start >= 0);
2678  _dbus_assert (len >= 0);
2679  _dbus_assert (start <= real->len);
2680 
2681  if (len > real->len - start)
2682  return FALSE;
2683 
2684  s = real->str + start;
2685  end = s + len;
2686  while (s != end)
2687  {
2688  if (_DBUS_UNLIKELY (*s != '\0'))
2689  return FALSE;
2690  ++s;
2691  }
2692 
2693  return TRUE;
2694 }
2695 
2701 void
2703 {
2704  DBUS_STRING_PREAMBLE (str);
2705 
2706  memset (real->str - real->align_offset, '\0', real->allocated);
2707 }
2710 /* 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:601
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:952
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:714
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)
Checks assertions for two strings we&#39;re copying a segment between, and declares real_source/real_dest...
Definition: dbus-string.c:1252
Internals of DBusString.
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2030
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:1644
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:777
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:603
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:972
unsigned int valid
DBusString is valid (initialized and not freed)
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:703
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:736
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:2276
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:976
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:2205
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:2006
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:1037
#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:2502
#define DBUS_CONST_STRING_PREAMBLE(str)
Checks assertions about a string that may be const or locked.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:579
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:507
#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:1089
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:797
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1300
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1579
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:1621
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:1854
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:968
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:1276
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:463
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1602
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:2169
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:406
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:689
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:468
#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:1421
#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:1820
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1563
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:1926
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:1210
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:1131
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:756
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2702
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:2572
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:900
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:2121
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:2073
unsigned int locked
DBusString has been locked and can&#39;t be changed.
dbus_bool_t _dbus_string_init_from_string(DBusString *str, const DBusString *from)
Initializes a string from another string.
Definition: dbus-string.c:245
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:631
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:1174
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:264
#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:1782
void _dbus_string_set_byte(DBusString *str, int i, unsigned char byte)
Sets the value of the byte at the given position.
Definition: dbus-string.c:555
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:916
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:2326
unsigned int align_offset
str - align_offset is the actual malloc block
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:531
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:2242
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:1154
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:1714
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:2670
#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:1013
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:1887
#define DBUS_LOCKED_STRING_PREAMBLE(str)
Checks assertions about a string object that may be locked but can&#39;t be const.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:819
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:989
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:1392
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:658
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:2533
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...
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1522
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:1065
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:485
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:2467
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:1325
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:1484