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