D-Bus 1.15.2
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
83static void
84fixup_alignment (DBusRealString *real)
85{
86 unsigned char *aligned;
87 unsigned char *real_block;
88 unsigned int old_align_offset;
89
90 /* we have to have extra space in real->allocated for the align offset and nul byte */
91 _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
92
93 old_align_offset = real->align_offset;
94 real_block = real->str - old_align_offset;
95
96 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
97
98 real->align_offset = aligned - real_block;
99 real->str = aligned;
100
101 if (old_align_offset != real->align_offset)
102 {
103 /* Here comes the suck */
104 memmove (real_block + real->align_offset,
105 real_block + old_align_offset,
106 real->len + 1);
107 }
108
109 _dbus_assert (real->align_offset < 8);
110 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
111}
112
113static void
114undo_alignment (DBusRealString *real)
115{
116 if (real->align_offset != 0)
117 {
118 memmove (real->str - real->align_offset,
119 real->str,
120 real->len + 1);
121
122 real->str = real->str - real->align_offset;
123 real->align_offset = 0;
124 }
125}
126
138 int allocate_size)
139{
140 DBusRealString *real;
141
142 _DBUS_STATIC_ASSERT (sizeof (DBusString) == sizeof (DBusRealString));
143
144 _dbus_assert (str != NULL);
145
146 real = (DBusRealString*) str;
147
148 /* It's very important not to touch anything
149 * other than real->str if we're going to fail,
150 * since we also use this function to reset
151 * an existing string, e.g. in _dbus_string_steal_data()
152 */
153
154 real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
155 if (real->str == NULL)
156 return FALSE;
157
158 real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
159 real->len = 0;
160 real->str[real->len] = '\0';
161
162 real->constant = FALSE;
163 real->locked = FALSE;
164 real->valid = TRUE;
165 real->align_offset = 0;
166
167 fixup_alignment (real);
168
169 return TRUE;
170}
171
181{
182 return _dbus_string_init_preallocated (str, 0);
183}
184
194void
196 const char *value)
197{
198 _dbus_assert (value != NULL);
199
200 _dbus_string_init_const_len (str, value,
201 strlen (value));
202}
203
214void
216 const char *value,
217 int len)
218{
219 DBusRealString *real;
220
221 _dbus_assert (str != NULL);
222 _dbus_assert (len == 0 || value != NULL);
224 _dbus_assert (len >= 0);
225
226 real = (DBusRealString*) str;
227
228 real->str = (unsigned char*) value;
229 real->len = len;
230 real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
231 real->constant = TRUE;
232 real->locked = TRUE;
233 real->valid = TRUE;
234 real->align_offset = 0;
235
236 /* We don't require const strings to be 8-byte aligned as the
237 * memory is coming from elsewhere.
238 */
239}
240
253 const DBusString *from)
254{
255 if (!_dbus_string_init (str))
256 return FALSE;
258 {
259 _dbus_string_free (str);
260 return FALSE;
261 }
262 return TRUE;
263}
264
275void
277{
278 DBusRealString *real = (DBusRealString*) str;
279 /* DBusRealString and DBusString have the same members in the same order,
280 * just differently-named */
281 DBusRealString invalid = _DBUS_STRING_INIT_INVALID;
282
283 /* Allow for the _DBUS_STRING_INIT_INVALID case */
284 if (real->str == NULL && real->len == 0 && real->allocated == 0 &&
285 !real->constant && !real->locked && !real->valid &&
286 real->align_offset == 0)
287 return;
288
290
291 if (real->constant)
292 goto wipe;
293
294 /* so it's safe if @p str returned by a failed
295 * _dbus_string_init call
296 * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
297 */
298 if (real->str == NULL)
299 goto wipe;
300
301 dbus_free (real->str - real->align_offset);
302
303wipe:
304 *real = invalid;
305 real->valid = FALSE;
306}
307
308static dbus_bool_t
309compact (DBusRealString *real,
310 int max_waste)
311{
312 unsigned char *new_str;
313 int new_allocated;
314 int waste;
315
316 waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
317
318 if (waste <= max_waste)
319 return TRUE;
320
321 new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
322
323 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
324 if (_DBUS_UNLIKELY (new_str == NULL))
325 return FALSE;
326
327 real->str = new_str + real->align_offset;
328 real->allocated = new_allocated;
329 fixup_alignment (real);
330
331 return TRUE;
332}
333
334#ifdef DBUS_ENABLE_EMBEDDED_TESTS
335/* Not using this feature at the moment,
336 * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
337 */
347void
348_dbus_string_lock (DBusString *str)
349{
350 DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
351
352 real->locked = TRUE;
353
354 /* Try to realloc to avoid excess memory usage, since
355 * we know we won't change the string further
356 */
357#define MAX_WASTE 48
358 compact (real, MAX_WASTE);
359}
360#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
361
362static dbus_bool_t
363reallocate_for_length (DBusRealString *real,
364 int new_length)
365{
366 int new_allocated;
367 unsigned char *new_str;
368
369 /* at least double our old allocation to avoid O(n), avoiding
370 * overflow
371 */
372 if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
373 new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
374 else
375 new_allocated = real->allocated * 2;
376
377 /* if you change the code just above here, run the tests without
378 * the following assert-only hack before you commit
379 */
380 /* This is keyed off asserts in addition to tests so when you
381 * disable asserts to profile, you don't get this destroyer
382 * of profiles.
383 */
384#if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
385 new_allocated = 0; /* ensure a realloc every time so that we go
386 * through all malloc failure codepaths
387 */
388#endif
389
390 /* But be sure we always alloc at least space for the new length */
391 new_allocated = MAX (new_allocated,
392 new_length + _DBUS_STRING_ALLOCATION_PADDING);
393
394 _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
395 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
396 if (_DBUS_UNLIKELY (new_str == NULL))
397 return FALSE;
398
399 real->str = new_str + real->align_offset;
400 real->allocated = new_allocated;
401 fixup_alignment (real);
402
403 return TRUE;
404}
405
419 int max_waste)
420{
422
423 return compact (real, max_waste);
424}
425
426static dbus_bool_t
427set_length (DBusRealString *real,
428 int new_length)
429{
430 /* Note, we are setting the length not including nul termination */
431
432 /* exceeding max length is the same as failure to allocate memory */
433 if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
434 return FALSE;
435 else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
436 _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
437 return FALSE;
438 else
439 {
440 real->len = new_length;
441 real->str[new_length] = '\0';
442 return TRUE;
443 }
444}
445
446static dbus_bool_t
447open_gap (int len,
448 DBusRealString *dest,
449 int insert_at)
450{
451 if (len == 0)
452 return TRUE;
453
454 if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
455 return FALSE; /* detected overflow of dest->len + len below */
456
457 if (!set_length (dest, dest->len + len))
458 return FALSE;
459
460 memmove (dest->str + insert_at + len,
461 dest->str + insert_at,
462 dest->len - len - insert_at);
463
464 return TRUE;
465}
466
473int
475{
477
478 return real->allocated;
479}
480
481#ifndef _dbus_string_get_data
493char*
495{
497
498 return (char*) real->str;
499}
500#endif /* _dbus_string_get_data */
501
502/* only do the function if we don't have the macro */
503#ifndef _dbus_string_get_const_data
510const char*
512{
514
515 return (const char*) real->str;
516}
517#endif /* _dbus_string_get_const_data */
518
532char*
534 int start,
535 int len)
536{
538 _dbus_assert (start >= 0);
539 _dbus_assert (len >= 0);
540 _dbus_assert (start <= real->len);
541 _dbus_assert (len <= real->len - start);
542
543 return (char*) real->str + start;
544}
545
546/* only do the function if we don't have the macro */
547#ifndef _dbus_string_get_const_data_len
556const char*
558 int start,
559 int len)
560{
562 _dbus_assert (start >= 0);
563 _dbus_assert (len >= 0);
564 _dbus_assert (start <= real->len);
565 _dbus_assert (len <= real->len - start);
566
567 return (const char*) real->str + start;
568}
569#endif /* _dbus_string_get_const_data_len */
570
571/* only do the function if we don't have the macro */
572#ifndef _dbus_string_set_byte
580void
582 int i,
583 unsigned char byte)
584{
586 _dbus_assert (i < real->len);
587 _dbus_assert (i >= 0);
588
589 real->str[i] = byte;
590}
591#endif /* _dbus_string_set_byte */
592
593/* only have the function if we didn't create a macro */
594#ifndef _dbus_string_get_byte
604unsigned char
606 int start)
607{
609 _dbus_assert (start <= real->len);
610 _dbus_assert (start >= 0);
611
612 return real->str[start];
613}
614#endif /* _dbus_string_get_byte */
615
628 int i,
629 int n_bytes,
630 unsigned char byte)
631{
633 _dbus_assert (i <= real->len);
634 _dbus_assert (i >= 0);
635 _dbus_assert (n_bytes >= 0);
636
637 if (n_bytes == 0)
638 return TRUE;
639
640 if (!open_gap (n_bytes, real, i))
641 return FALSE;
642
643 memset (real->str + i, byte, n_bytes);
644
645 return TRUE;
646}
647
658 int i,
659 unsigned char byte)
660{
662 _dbus_assert (i <= real->len);
663 _dbus_assert (i >= 0);
664
665 if (!open_gap (1, real, i))
666 return FALSE;
667
668 real->str[i] = byte;
669
670 return TRUE;
671}
672
685 char **data_return)
686{
688 _dbus_assert (data_return != NULL);
689
690 undo_alignment (real);
691
692 *data_return = (char*) real->str;
693
694 /* reset the string */
695 if (!_dbus_string_init (str))
696 {
697 /* hrm, put it back then */
698 real->str = (unsigned char*) *data_return;
699 *data_return = NULL;
700 fixup_alignment (real);
701 return FALSE;
702 }
703
704 return TRUE;
705}
706
716 char **data_return)
717{
719 _dbus_assert (data_return != NULL);
720
721 *data_return = dbus_malloc (real->len + 1);
722 if (*data_return == NULL)
723 return FALSE;
724
725 memcpy (*data_return, real->str, real->len + 1);
726
727 return TRUE;
728}
729
739void
741 char *buffer,
742 int avail_len)
743{
745
746 _dbus_assert (avail_len >= 0);
747 _dbus_assert (avail_len >= real->len);
748
749 memcpy (buffer, real->str, real->len);
750}
751
761void
763 char *buffer,
764 int avail_len)
765{
767
768 _dbus_assert (avail_len >= 0);
769 _dbus_assert (avail_len > real->len);
770
771 memcpy (buffer, real->str, real->len+1);
772}
773
774/* Only have the function if we don't have the macro */
775#ifndef _dbus_string_get_length
781int
783{
785
786 return real->len;
787}
788#endif /* !_dbus_string_get_length */
789
804 int additional_length)
805{
807 _dbus_assert (additional_length >= 0);
808
809 if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
810 return FALSE; /* would overflow */
811
812 return set_length (real,
813 real->len + additional_length);
814}
815
822void
824 int length_to_remove)
825{
827 _dbus_assert (length_to_remove >= 0);
828 _dbus_assert (length_to_remove <= real->len);
829
830 set_length (real,
831 real->len - length_to_remove);
832}
833
846 int length)
847{
849 _dbus_assert (length >= 0);
850
851 return set_length (real, length);
852}
853
854static dbus_bool_t
855align_insert_point_then_open_gap (DBusString *str,
856 int *insert_at_p,
857 int alignment,
858 int gap_size)
859{
860 unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
861 unsigned long gap_pos;
862 int insert_at;
863 int delta;
865 _dbus_assert (alignment >= 1);
866 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
867
868 insert_at = *insert_at_p;
869
870 _dbus_assert (insert_at <= real->len);
871
872 gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
873 new_len = real->len + (gap_pos - insert_at) + gap_size;
874
875 if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
876 return FALSE;
877
878 delta = new_len - real->len;
879 _dbus_assert (delta >= 0);
880
881 if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
882 {
883 _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
884 return TRUE;
885 }
886
887 if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
888 real, insert_at)))
889 return FALSE;
890
891 /* nul the padding if we had to add any padding */
892 if (gap_size < delta)
893 {
894 memset (&real->str[insert_at], '\0',
895 gap_pos - insert_at);
896 }
897
898 *insert_at_p = gap_pos;
899
900 return TRUE;
901}
902
903static dbus_bool_t
904align_length_then_lengthen (DBusString *str,
905 int alignment,
906 int then_lengthen_by)
907{
908 int insert_at;
909
910 insert_at = _dbus_string_get_length (str);
911
912 return align_insert_point_then_open_gap (str,
913 &insert_at,
914 alignment, then_lengthen_by);
915}
916
927 int alignment)
928{
929 return align_length_then_lengthen (str, alignment, 0);
930}
931
943 int extra_bytes)
944{
945 if (!_dbus_string_lengthen (str, extra_bytes))
946 return FALSE;
947 _dbus_string_shorten (str, extra_bytes);
948
949 return TRUE;
950}
951
952static dbus_bool_t
953append (DBusRealString *real,
954 const char *buffer,
955 int buffer_len)
956{
957 if (buffer_len == 0)
958 return TRUE;
959
960 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
961 return FALSE;
962
963 memcpy (real->str + (real->len - buffer_len),
964 buffer,
965 buffer_len);
966
967 return TRUE;
968}
969
979 const char *buffer)
980{
981 unsigned long buffer_len;
982
984 _dbus_assert (buffer != NULL);
985
986 buffer_len = strlen (buffer);
987 if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
988 return FALSE;
989
990 return append (real, buffer, buffer_len);
991}
992
1004 int insert_at,
1005 const unsigned char octets[2])
1006{
1008
1009 if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
1010 return FALSE;
1011
1012 memcpy (real->str + insert_at, octets, 2);
1013
1014 return TRUE;
1015}
1016
1028 int insert_at,
1029 const unsigned char octets[4])
1030{
1032
1033 if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1034 return FALSE;
1035
1036 memcpy (real->str + insert_at, octets, 4);
1037
1038 return TRUE;
1039}
1040
1052 int insert_at,
1053 const unsigned char octets[8])
1054{
1056
1057 if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1058 return FALSE;
1059
1060 _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1061
1062 memcpy (real->str + insert_at, octets, 8);
1063
1064 return TRUE;
1065}
1066
1067
1080 int *insert_at,
1081 int alignment)
1082{
1084
1085 if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1086 return FALSE;
1087
1088 _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1089
1090 return TRUE;
1091}
1092
1104 const char *format,
1105 va_list args)
1106{
1107 dbus_bool_t ret = FALSE;
1108 int len;
1109 va_list args_copy;
1110
1112
1113 va_copy (args_copy, args);
1114
1115 /* Measure the message length without terminating nul */
1116 len = _dbus_printf_string_upper_bound (format, args);
1117
1118 if (len < 0)
1119 goto out;
1120
1121 if (!_dbus_string_lengthen (str, len))
1122 {
1123 goto out;
1124 }
1125
1126 vsprintf ((char*) (real->str + (real->len - len)),
1127 format, args_copy);
1128 ret = TRUE;
1129
1130out:
1131 va_end (args_copy);
1132
1133 return ret;
1134}
1135
1146 const char *format,
1147 ...)
1148{
1149 va_list args;
1150 dbus_bool_t retval;
1151
1152 va_start (args, format);
1153 retval = _dbus_string_append_printf_valist (str, format, args);
1154 va_end (args);
1155
1156 return retval;
1157}
1158
1169 const char *buffer,
1170 int len)
1171{
1173 _dbus_assert (buffer != NULL);
1174 _dbus_assert (len >= 0);
1175
1176 return append (real, buffer, len);
1177}
1178
1189 unsigned char byte)
1190{
1192
1193 if (!set_length (real, real->len + 1))
1194 return FALSE;
1195
1196 real->str[real->len-1] = byte;
1197
1198 return TRUE;
1199}
1200
1211_dbus_string_append_strings (DBusString *str, char **strings, char separator)
1212{
1213 int i;
1214
1215 if (strings == NULL)
1216 return TRUE;
1217
1218 for (i = 0; strings[i]; i++)
1219 {
1220 if (i > 0 && !_dbus_string_append_byte (str, (unsigned char) separator))
1221 return FALSE;
1222
1223 if (!_dbus_string_append (str, strings[i]))
1224 return FALSE;
1225 }
1226
1227 return TRUE;
1228}
1229
1230static void
1231delete (DBusRealString *real,
1232 int start,
1233 int len)
1234{
1235 if (len == 0)
1236 return;
1237
1238 memmove (real->str + start, real->str + start + len, real->len - (start + len));
1239 real->len -= len;
1240 real->str[real->len] = '\0';
1241}
1242
1252void
1254 int start,
1255 int len)
1256{
1258 _dbus_assert (start >= 0);
1259 _dbus_assert (len >= 0);
1260 _dbus_assert (start <= real->len);
1261 _dbus_assert (len <= real->len - start);
1262
1263 delete (real, start, len);
1264}
1265
1266static dbus_bool_t
1267copy (DBusRealString *source,
1268 int start,
1269 int len,
1270 DBusRealString *dest,
1271 int insert_at)
1272{
1273 if (len == 0)
1274 return TRUE;
1275
1276 if (!open_gap (len, dest, insert_at))
1277 return FALSE;
1278
1279 memmove (dest->str + insert_at,
1280 source->str + start,
1281 len);
1282
1283 return TRUE;
1284}
1285
1295#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1296 DBusRealString *real_source = (DBusRealString*) source; \
1297 DBusRealString *real_dest = (DBusRealString*) dest; \
1298 _dbus_assert ((source) != (dest)); \
1299 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1300 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1301 _dbus_assert (!real_dest->constant); \
1302 _dbus_assert (!real_dest->locked); \
1303 _dbus_assert ((start) >= 0); \
1304 _dbus_assert ((start) <= real_source->len); \
1305 _dbus_assert ((insert_at) >= 0); \
1306 _dbus_assert ((insert_at) <= real_dest->len)
1307
1320 int start,
1321 DBusString *dest,
1322 int insert_at)
1323{
1324 DBusRealString *real_source = (DBusRealString*) source;
1325 _dbus_assert (start <= real_source->len);
1326
1327 return _dbus_string_move_len (source, start,
1328 real_source->len - start,
1329 dest, insert_at);
1330}
1331
1344 int start,
1345 DBusString *dest,
1346 int insert_at)
1347{
1348 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1349
1350 return copy (real_source, start,
1351 real_source->len - start,
1352 real_dest,
1353 insert_at);
1354}
1355
1369 int start,
1370 int len,
1371 DBusString *dest,
1372 int insert_at)
1373
1374{
1375 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1376 _dbus_assert (len >= 0);
1377 _dbus_assert ((start + len) <= real_source->len);
1378
1379
1380 if (len == 0)
1381 {
1382 return TRUE;
1383 }
1384 else if (start == 0 &&
1385 len == real_source->len &&
1386 real_dest->len == 0)
1387 {
1388 /* Short-circuit moving an entire existing string to an empty string
1389 * by just swapping the buffers.
1390 */
1391 /* we assume ->constant doesn't matter as you can't have
1392 * a constant string involved in a move.
1393 */
1394#define ASSIGN_DATA(a, b) do { \
1395 (a)->str = (b)->str; \
1396 (a)->len = (b)->len; \
1397 (a)->allocated = (b)->allocated; \
1398 (a)->align_offset = (b)->align_offset; \
1399 } while (0)
1400
1401 DBusRealString tmp;
1402
1403 ASSIGN_DATA (&tmp, real_source);
1404 ASSIGN_DATA (real_source, real_dest);
1405 ASSIGN_DATA (real_dest, &tmp);
1406
1407 return TRUE;
1408 }
1409 else
1410 {
1411 if (!copy (real_source, start, len,
1412 real_dest,
1413 insert_at))
1414 return FALSE;
1415
1416 delete (real_source, start,
1417 len);
1418
1419 return TRUE;
1420 }
1421}
1422
1436 int start,
1437 int len,
1438 DBusString *dest,
1439 int insert_at)
1440{
1441 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1442 _dbus_assert (len >= 0);
1443 _dbus_assert (start <= real_source->len);
1444 _dbus_assert (len <= real_source->len - start);
1445
1446 return copy (real_source, start, len,
1447 real_dest,
1448 insert_at);
1449}
1450
1465 int start,
1466 int len,
1467 DBusString *dest,
1468 int replace_at,
1469 int replace_len)
1470{
1471 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1472 _dbus_assert (len >= 0);
1473 _dbus_assert (start <= real_source->len);
1474 _dbus_assert (len <= real_source->len - start);
1475 _dbus_assert (replace_at >= 0);
1476 _dbus_assert (replace_at <= real_dest->len);
1477 _dbus_assert (replace_len <= real_dest->len - replace_at);
1478
1479 if (len == replace_len)
1480 {
1481 memmove (real_dest->str + replace_at,
1482 real_source->str + start, len);
1483 }
1484 else if (len < replace_len)
1485 {
1486 memmove (real_dest->str + replace_at,
1487 real_source->str + start, len);
1488 delete (real_dest, replace_at + len,
1489 replace_len - len);
1490 }
1491 else
1492 {
1493 int diff;
1494
1495 _dbus_assert (len > replace_len);
1496
1497 diff = len - replace_len;
1498
1499 /* First of all we check if destination string can be enlarged as
1500 * required, then we overwrite previous bytes
1501 */
1502
1503 if (!copy (real_source, start + replace_len, diff,
1504 real_dest, replace_at + replace_len))
1505 return FALSE;
1506
1507 memmove (real_dest->str + replace_at,
1508 real_source->str + start, replace_len);
1509 }
1510
1511 return TRUE;
1512}
1513
1528 unsigned char byte,
1529 DBusString *tail)
1530{
1531 int byte_position;
1532 char byte_string[2] = "";
1533 int head_length;
1534 int tail_length;
1535
1536 byte_string[0] = (char) byte;
1537
1538 if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1539 return FALSE;
1540
1541 head_length = byte_position;
1542 tail_length = _dbus_string_get_length (source) - head_length - 1;
1543
1544 if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1545 tail, 0))
1546 return FALSE;
1547
1548 /* remove the trailing delimiter byte from the head now.
1549 */
1550 if (!_dbus_string_set_length (source, head_length))
1551 return FALSE;
1552
1553 return TRUE;
1554}
1555
1556/* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1557 * Pennington, and Tom Tromey are the authors and authorized relicense.
1558 */
1559
1565#define UTF8_COMPUTE(Char, Mask, Len) \
1566 if (Char < 128) \
1567 { \
1568 Len = 1; \
1569 Mask = 0x7f; \
1570 } \
1571 else if ((Char & 0xe0) == 0xc0) \
1572 { \
1573 Len = 2; \
1574 Mask = 0x1f; \
1575 } \
1576 else if ((Char & 0xf0) == 0xe0) \
1577 { \
1578 Len = 3; \
1579 Mask = 0x0f; \
1580 } \
1581 else if ((Char & 0xf8) == 0xf0) \
1582 { \
1583 Len = 4; \
1584 Mask = 0x07; \
1585 } \
1586 else if ((Char & 0xfc) == 0xf8) \
1587 { \
1588 Len = 5; \
1589 Mask = 0x03; \
1590 } \
1591 else if ((Char & 0xfe) == 0xfc) \
1592 { \
1593 Len = 6; \
1594 Mask = 0x01; \
1595 } \
1596 else \
1597 { \
1598 Len = 0; \
1599 Mask = 0; \
1600 }
1601
1606#define UTF8_LENGTH(Char) \
1607 ((Char) < 0x80 ? 1 : \
1608 ((Char) < 0x800 ? 2 : \
1609 ((Char) < 0x10000 ? 3 : \
1610 ((Char) < 0x200000 ? 4 : \
1611 ((Char) < 0x4000000 ? 5 : 6)))))
1612
1622#define UTF8_GET(Result, Chars, Count, Mask, Len) \
1623 (Result) = (Chars)[0] & (Mask); \
1624 for ((Count) = 1; (Count) < (Len); ++(Count)) \
1625 { \
1626 if (((Chars)[(Count)] & 0xc0) != 0x80) \
1627 { \
1628 (Result) = -1; \
1629 break; \
1630 } \
1631 (Result) <<= 6; \
1632 (Result) |= ((Chars)[(Count)] & 0x3f); \
1633 }
1634
1645#define UNICODE_VALID(Char) \
1646 ((Char) < 0x110000 && \
1647 (((Char) & 0xFFFFF800) != 0xD800))
1648
1665 int start,
1666 const char *substr,
1667 int *found)
1668{
1669 return _dbus_string_find_to (str, start,
1670 ((const DBusRealString*)str)->len,
1671 substr, found);
1672}
1673
1688 int start,
1689 int *found,
1690 int *found_len)
1691{
1692 int i;
1693
1695 _dbus_assert (start <= real->len);
1696 _dbus_assert (start >= 0);
1697
1698 i = start;
1699 while (i < real->len)
1700 {
1701 if (real->str[i] == '\r')
1702 {
1703 if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1704 {
1705 if (found)
1706 *found = i;
1707 if (found_len)
1708 *found_len = 2;
1709 return TRUE;
1710 }
1711 else /* only "\r" */
1712 {
1713 if (found)
1714 *found = i;
1715 if (found_len)
1716 *found_len = 1;
1717 return TRUE;
1718 }
1719 }
1720 else if (real->str[i] == '\n') /* only "\n" */
1721 {
1722 if (found)
1723 *found = i;
1724 if (found_len)
1725 *found_len = 1;
1726 return TRUE;
1727 }
1728 ++i;
1729 }
1730
1731 if (found)
1732 *found = real->len;
1733
1734 if (found_len)
1735 *found_len = 0;
1736
1737 return FALSE;
1738}
1739
1758 int start,
1759 int end,
1760 const char *substr,
1761 int *found)
1762{
1763 int i;
1765 _dbus_assert (substr != NULL);
1766 _dbus_assert (start <= real->len);
1767 _dbus_assert (start >= 0);
1768 _dbus_assert (substr != NULL);
1769 _dbus_assert (end <= real->len);
1770 _dbus_assert (start <= end);
1771
1772 /* we always "find" an empty string */
1773 if (*substr == '\0')
1774 {
1775 if (found)
1776 *found = start;
1777 return TRUE;
1778 }
1779
1780 i = start;
1781 while (i < end)
1782 {
1783 if (real->str[i] == substr[0])
1784 {
1785 int j = i + 1;
1786
1787 while (j < end)
1788 {
1789 if (substr[j - i] == '\0')
1790 break;
1791 else if (real->str[j] != substr[j - i])
1792 break;
1793
1794 ++j;
1795 }
1796
1797 if (substr[j - i] == '\0')
1798 {
1799 if (found)
1800 *found = i;
1801 return TRUE;
1802 }
1803 }
1804
1805 ++i;
1806 }
1807
1808 if (found)
1809 *found = end;
1810
1811 return FALSE;
1812}
1813
1826 int start,
1827 int *found)
1828{
1829 int i;
1831 _dbus_assert (start <= real->len);
1832 _dbus_assert (start >= 0);
1833
1834 i = start;
1835 while (i < real->len)
1836 {
1837 if (real->str[i] == ' ' ||
1838 real->str[i] == '\t')
1839 {
1840 if (found)
1841 *found = i;
1842 return TRUE;
1843 }
1844
1845 ++i;
1846 }
1847
1848 if (found)
1849 *found = real->len;
1850
1851 return FALSE;
1852}
1853
1862void
1864 int start,
1865 int *end)
1866{
1867 int i;
1869 _dbus_assert (start <= real->len);
1870 _dbus_assert (start >= 0);
1871
1872 i = start;
1873 while (i < real->len)
1874 {
1875 if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1876 break;
1877
1878 ++i;
1879 }
1880
1881 _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1882
1883 if (end)
1884 *end = i;
1885}
1886
1887
1896void
1898 int start,
1899 int *end)
1900{
1901 int i;
1903 _dbus_assert (start <= real->len);
1904 _dbus_assert (start >= 0);
1905
1906 i = start;
1907 while (i < real->len)
1908 {
1909 if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1910 break;
1911
1912 ++i;
1913 }
1914
1915 _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1916
1917 if (end)
1918 *end = i;
1919}
1920
1929void
1931 int end,
1932 int *start)
1933{
1934 int i;
1936 _dbus_assert (end <= real->len);
1937 _dbus_assert (end >= 0);
1938
1939 i = end;
1940 while (i > 0)
1941 {
1942 if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1943 break;
1944 --i;
1945 }
1946
1947 _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1948
1949 if (start)
1950 *start = i;
1951}
1952
1970 DBusString *dest)
1971{
1972 int eol, eol_len;
1973
1974 _dbus_string_set_length (dest, 0);
1975
1976 eol = 0;
1977 eol_len = 0;
1978 if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1979 {
1980 _dbus_assert (eol == _dbus_string_get_length (source));
1981 if (eol == 0)
1982 {
1983 /* If there's no newline and source has zero length, we're done */
1984 return FALSE;
1985 }
1986 /* otherwise, the last line of the file has no eol characters */
1987 }
1988
1989 /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1990 * since find_eol returned TRUE
1991 */
1992
1993 if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1994 return FALSE;
1995
1996 /* remove line ending */
1997 if (!_dbus_string_set_length (dest, eol))
1998 {
1999 _dbus_assert_not_reached ("out of memory when shortening a string");
2000 return FALSE;
2001 }
2002
2003 return TRUE;
2004}
2005
2006#ifdef DBUS_ENABLE_EMBEDDED_TESTS
2013void
2014_dbus_string_delete_first_word (DBusString *str)
2015{
2016 int i;
2017
2018 if (_dbus_string_find_blank (str, 0, &i))
2019 _dbus_string_skip_blank (str, i, &i);
2020
2021 _dbus_string_delete (str, 0, i);
2022}
2023#endif
2024
2025#ifdef DBUS_ENABLE_EMBEDDED_TESTS
2031void
2032_dbus_string_delete_leading_blanks (DBusString *str)
2033{
2034 int i;
2035
2036 _dbus_string_skip_blank (str, 0, &i);
2037
2038 if (i > 0)
2039 _dbus_string_delete (str, 0, i);
2040}
2041#endif
2042
2048void
2050{
2051 int i;
2052
2053 _dbus_string_skip_white (str, 0, &i);
2054
2055 if (i > 0)
2056 _dbus_string_delete (str, 0, i);
2057
2059
2060 _dbus_string_set_length (str, i);
2061}
2062
2074 const DBusString *b)
2075{
2076 const unsigned char *ap;
2077 const unsigned char *bp;
2078 const unsigned char *a_end;
2079 const DBusRealString *real_a = (const DBusRealString*) a;
2080 const DBusRealString *real_b = (const DBusRealString*) b;
2083
2084 if (real_a->len != real_b->len)
2085 return FALSE;
2086
2087 ap = real_a->str;
2088 bp = real_b->str;
2089 a_end = real_a->str + real_a->len;
2090 while (ap != a_end)
2091 {
2092 if (*ap != *bp)
2093 return FALSE;
2094
2095 ++ap;
2096 ++bp;
2097 }
2098
2099 return TRUE;
2100}
2101
2117 const DBusString *b,
2118 int len)
2119{
2120 const unsigned char *ap;
2121 const unsigned char *bp;
2122 const unsigned char *a_end;
2123 const DBusRealString *real_a = (const DBusRealString*) a;
2124 const DBusRealString *real_b = (const DBusRealString*) b;
2127
2128 if (real_a->len != real_b->len &&
2129 (real_a->len < len || real_b->len < len))
2130 return FALSE;
2131
2132 ap = real_a->str;
2133 bp = real_b->str;
2134 a_end = real_a->str + MIN (real_a->len, len);
2135 while (ap != a_end)
2136 {
2137 if (*ap != *bp)
2138 return FALSE;
2139
2140 ++ap;
2141 ++bp;
2142 }
2143
2144 return TRUE;
2145}
2146
2165 int a_start,
2166 int a_len,
2167 const DBusString *b,
2168 int b_start)
2169{
2170 const unsigned char *ap;
2171 const unsigned char *bp;
2172 const unsigned char *a_end;
2173 const DBusRealString *real_a = (const DBusRealString*) a;
2174 const DBusRealString *real_b = (const DBusRealString*) b;
2177 _dbus_assert (a_start >= 0);
2178 _dbus_assert (a_len >= 0);
2179 _dbus_assert (a_start <= real_a->len);
2180 _dbus_assert (a_len <= real_a->len - a_start);
2181 _dbus_assert (b_start >= 0);
2182 _dbus_assert (b_start <= real_b->len);
2183
2184 if (a_len > real_b->len - b_start)
2185 return FALSE;
2186
2187 ap = real_a->str + a_start;
2188 bp = real_b->str + b_start;
2189 a_end = ap + a_len;
2190 while (ap != a_end)
2191 {
2192 if (*ap != *bp)
2193 return FALSE;
2194
2195 ++ap;
2196 ++bp;
2197 }
2198
2199 _dbus_assert (bp <= (real_b->str + real_b->len));
2200
2201 return TRUE;
2202}
2203
2213 const char *c_str)
2214{
2215 const unsigned char *ap;
2216 const unsigned char *bp;
2217 const unsigned char *a_end;
2218 const DBusRealString *real_a = (const DBusRealString*) a;
2220 _dbus_assert (c_str != NULL);
2221
2222 ap = real_a->str;
2223 bp = (const unsigned char*) c_str;
2224 a_end = real_a->str + real_a->len;
2225 while (ap != a_end && *bp)
2226 {
2227 if (*ap != *bp)
2228 return FALSE;
2229
2230 ++ap;
2231 ++bp;
2232 }
2233
2234 if (ap != a_end || *bp)
2235 return FALSE;
2236
2237 return TRUE;
2238}
2239
2249 const char *c_str)
2250{
2251 const unsigned char *ap;
2252 const unsigned char *bp;
2253 const unsigned char *a_end;
2254 const DBusRealString *real_a = (const DBusRealString*) a;
2256 _dbus_assert (c_str != NULL);
2257
2258 ap = real_a->str;
2259 bp = (const unsigned char*) c_str;
2260 a_end = real_a->str + real_a->len;
2261 while (ap != a_end && *bp)
2262 {
2263 if (*ap != *bp)
2264 return FALSE;
2265
2266 ++ap;
2267 ++bp;
2268 }
2269
2270 if (*bp == '\0')
2271 return TRUE;
2272 else
2273 return FALSE;
2274}
2275
2287 const char *c_str,
2288 char word_separator)
2289{
2290 char next_char;
2291 const char *data;
2292 _dbus_assert (c_str != NULL);
2293
2294 if (!_dbus_string_starts_with_c_str (a, c_str))
2295 return FALSE;
2296
2297 data = _dbus_string_get_const_data (a);
2298 next_char = data[strlen (c_str)];
2299 return next_char == '\0' || next_char == word_separator;
2300}
2301
2312 unsigned char byte)
2313{
2314 const char hexdigits[16] = {
2315 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2316 'a', 'b', 'c', 'd', 'e', 'f'
2317 };
2318
2319 if (!_dbus_string_append_byte (str,
2320 hexdigits[(byte >> 4)]))
2321 return FALSE;
2322
2323 if (!_dbus_string_append_byte (str,
2324 hexdigits[(byte & 0x0f)]))
2325 {
2327 _dbus_string_get_length (str) - 1);
2328 return FALSE;
2329 }
2330
2331 return TRUE;
2332}
2333
2334/* Currently only used when embedded tests are enabled */
2335#ifdef DBUS_ENABLE_EMBEDDED_TESTS
2347_dbus_string_append_buffer_as_hex (DBusString *str,
2348 void *buf,
2349 int size)
2350{
2351 unsigned char *p;
2352 int i;
2353
2354 _dbus_assert (size >= 0);
2355 _dbus_assert (size == 0 || buf != NULL);
2356
2357 p = (unsigned char *) buf;
2358
2359 for (i = 0; i < size; i++)
2360 {
2361 if (!_dbus_string_append_byte_as_hex (str, p[i]))
2362 return FALSE;
2363 }
2364
2365 return TRUE;
2366}
2367#endif
2368
2381 int start,
2382 DBusString *dest,
2383 int insert_at)
2384{
2385 DBusString result;
2386 const unsigned char *p;
2387 const unsigned char *end;
2388 dbus_bool_t retval;
2389
2390 _dbus_assert (start <= _dbus_string_get_length (source));
2391
2392 if (!_dbus_string_init (&result))
2393 return FALSE;
2394
2395 retval = FALSE;
2396
2397 p = (const unsigned char*) _dbus_string_get_const_data (source);
2398 end = p + _dbus_string_get_length (source);
2399 p += start;
2400
2401 while (p != end)
2402 {
2403 if (!_dbus_string_append_byte_as_hex (&result, *p))
2404 goto out;
2405
2406 ++p;
2407 }
2408
2409 if (!_dbus_string_move (&result, 0, dest, insert_at))
2410 goto out;
2411
2412 retval = TRUE;
2413
2414 out:
2415 _dbus_string_free (&result);
2416 return retval;
2417}
2418
2431 int start,
2432 int *end_return,
2433 DBusString *dest,
2434 int insert_at)
2435{
2436 DBusString result;
2437 const unsigned char *p;
2438 const unsigned char *end;
2439 dbus_bool_t retval;
2440 dbus_bool_t high_bits;
2441
2442 _dbus_assert (start <= _dbus_string_get_length (source));
2443
2444 if (!_dbus_string_init (&result))
2445 return FALSE;
2446
2447 retval = FALSE;
2448
2449 high_bits = TRUE;
2450 p = (const unsigned char*) _dbus_string_get_const_data (source);
2451 end = p + _dbus_string_get_length (source);
2452 p += start;
2453
2454 while (p != end)
2455 {
2456 unsigned int val;
2457
2458 switch (*p)
2459 {
2460 case '0':
2461 val = 0;
2462 break;
2463 case '1':
2464 val = 1;
2465 break;
2466 case '2':
2467 val = 2;
2468 break;
2469 case '3':
2470 val = 3;
2471 break;
2472 case '4':
2473 val = 4;
2474 break;
2475 case '5':
2476 val = 5;
2477 break;
2478 case '6':
2479 val = 6;
2480 break;
2481 case '7':
2482 val = 7;
2483 break;
2484 case '8':
2485 val = 8;
2486 break;
2487 case '9':
2488 val = 9;
2489 break;
2490 case 'a':
2491 case 'A':
2492 val = 10;
2493 break;
2494 case 'b':
2495 case 'B':
2496 val = 11;
2497 break;
2498 case 'c':
2499 case 'C':
2500 val = 12;
2501 break;
2502 case 'd':
2503 case 'D':
2504 val = 13;
2505 break;
2506 case 'e':
2507 case 'E':
2508 val = 14;
2509 break;
2510 case 'f':
2511 case 'F':
2512 val = 15;
2513 break;
2514 default:
2515 goto done;
2516 }
2517
2518 if (high_bits)
2519 {
2520 if (!_dbus_string_append_byte (&result,
2521 val << 4))
2522 goto out;
2523 }
2524 else
2525 {
2526 int len;
2527 unsigned char b;
2528
2529 len = _dbus_string_get_length (&result);
2530
2531 b = _dbus_string_get_byte (&result, len - 1);
2532
2533 b |= val;
2534
2535 _dbus_string_set_byte (&result, len - 1, b);
2536 }
2537
2538 high_bits = !high_bits;
2539
2540 ++p;
2541 }
2542
2543 done:
2544 if (!_dbus_string_move (&result, 0, dest, insert_at))
2545 goto out;
2546
2547 if (end_return)
2548 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2549
2550 retval = TRUE;
2551
2552 out:
2553 _dbus_string_free (&result);
2554 return retval;
2555}
2556
2572 int start,
2573 int len)
2574{
2575 const unsigned char *s;
2576 const unsigned char *end;
2578 _dbus_assert (start >= 0);
2579 _dbus_assert (start <= real->len);
2580 _dbus_assert (len >= 0);
2581
2582 if (len > real->len - start)
2583 return FALSE;
2584
2585 s = real->str + start;
2586 end = s + len;
2587 while (s != end)
2588 {
2589 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2590 return FALSE;
2591
2592 ++s;
2593 }
2594
2595 return TRUE;
2596}
2597
2605void
2607 int start,
2608 int len)
2609{
2610 unsigned char *s;
2611 unsigned char *end;
2613 _dbus_assert (start >= 0);
2614 _dbus_assert (start <= real->len);
2615 _dbus_assert (len >= 0);
2616 _dbus_assert (len <= real->len - start);
2617
2618 s = real->str + start;
2619 end = s + len;
2620
2621 while (s != end)
2622 {
2623 if (*s >= 'A' && *s <= 'Z')
2624 *s += 'a' - 'A';
2625 ++s;
2626 }
2627}
2628
2636void
2638 int start,
2639 int len)
2640{
2641 unsigned char *s;
2642 unsigned char *end;
2644 _dbus_assert (start >= 0);
2645 _dbus_assert (start <= real->len);
2646 _dbus_assert (len >= 0);
2647 _dbus_assert (len <= real->len - start);
2648
2649 s = real->str + start;
2650 end = s + len;
2651
2652 while (s != end)
2653 {
2654 if (*s >= 'a' && *s <= 'z')
2655 *s += 'A' - 'a';
2656 ++s;
2657 }
2658}
2659
2677 int start,
2678 int len)
2679{
2680 const unsigned char *p;
2681 const unsigned char *end;
2683 _dbus_assert (start >= 0);
2684 _dbus_assert (start <= real->len);
2685 _dbus_assert (len >= 0);
2686
2687 /* we are doing _DBUS_UNLIKELY() here which might be
2688 * dubious in a generic library like GLib, but in D-Bus
2689 * we know we're validating messages and that it would
2690 * only be evil/broken apps that would have invalid
2691 * UTF-8. Also, this function seems to be a performance
2692 * bottleneck in profiles.
2693 */
2694
2695 if (_DBUS_UNLIKELY (len > real->len - start))
2696 return FALSE;
2697
2698 p = real->str + start;
2699 end = p + len;
2700
2701 while (p < end)
2702 {
2703 int i, mask, char_len;
2704 dbus_unichar_t result;
2705
2706 /* nul bytes considered invalid */
2707 if (*p == '\0')
2708 break;
2709
2710 /* Special-case ASCII; this makes us go a lot faster in
2711 * D-Bus profiles where we are typically validating
2712 * function names and such. We have to know that
2713 * all following checks will pass for ASCII though,
2714 * comments follow ...
2715 */
2716 if (*p < 128)
2717 {
2718 ++p;
2719 continue;
2720 }
2721
2722 UTF8_COMPUTE (*p, mask, char_len);
2723
2724 if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2725 break;
2726
2727 /* check that the expected number of bytes exists in the remaining length */
2728 if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2729 break;
2730
2731 UTF8_GET (result, p, i, mask, char_len);
2732
2733 /* Check for overlong UTF-8 */
2734 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2735 break;
2736#if 0
2737 /* The UNICODE_VALID check below will catch this */
2738 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2739 break;
2740#endif
2741
2742 if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2743 break;
2744
2745 /* UNICODE_VALID should have caught it */
2746 _dbus_assert (result != (dbus_unichar_t)-1);
2747
2748 p += char_len;
2749 }
2750
2751 /* See that we covered the entire length if a length was
2752 * passed in
2753 */
2754 if (_DBUS_UNLIKELY (p != end))
2755 return FALSE;
2756 else
2757 return TRUE;
2758}
2759
2775 int start,
2776 int len)
2777{
2778 const unsigned char *s;
2779 const unsigned char *end;
2781 _dbus_assert (start >= 0);
2782 _dbus_assert (len >= 0);
2783 _dbus_assert (start <= real->len);
2784
2785 if (len > real->len - start)
2786 return FALSE;
2787
2788 s = real->str + start;
2789 end = s + len;
2790 while (s != end)
2791 {
2792 if (_DBUS_UNLIKELY (*s != '\0'))
2793 return FALSE;
2794 ++s;
2795 }
2796
2797 return TRUE;
2798}
2799
2805void
2807{
2809
2810 memset (real->str - real->align_offset, '\0', real->allocated);
2811}
2814/* tests are in dbus-string-util.c */
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:692
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:592
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:452
#define _DBUS_STRING_MAX_LENGTH
The maximum length of a DBusString.
#define DBUS_STRING_PREAMBLE(str)
Checks assertions about a string object that needs to be modifiable - may not be locked or const.
#define DBUS_CONST_STRING_PREAMBLE(str)
Checks assertions about a string that may be const or locked.
#define DBUS_GENERIC_STRING_PREAMBLE(real)
Checks a bunch of assertions about a string object.
#define DBUS_IS_ASCII_BLANK(c)
Checks for ASCII blank byte.
#define DBUS_IS_ASCII_WHITE(c)
Checks for ASCII whitespace byte.
#define DBUS_LOCKED_STRING_PREAMBLE(str)
Checks assertions about a string object that may be locked but can't be const.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:845
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:2430
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:978
dbus_bool_t _dbus_string_insert_8_aligned(DBusString *str, int insert_at, const unsigned char octets[8])
Inserts 8 bytes aligned on an 8 byte boundary with any alignment padding initialized to 0.
Definition: dbus-string.c:1051
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
Definition: dbus-string.c:2774
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
Definition: dbus-string.c:2164
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1645
dbus_bool_t _dbus_string_insert_alignment(DBusString *str, int *insert_at, int alignment)
Inserts padding at *insert_at such to align it to the given boundary.
Definition: dbus-string.c:1079
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1565
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:180
dbus_bool_t _dbus_string_append_strings(DBusString *str, char **strings, char separator)
Append vector with strings connected by separator.
Definition: dbus-string.c:1211
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:195
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1343
dbus_bool_t _dbus_string_find_eol(const DBusString *str, int start, int *found, int *found_len)
Finds end of line ("\r\n" or "\n") in the string, returning TRUE and filling in the byte index where ...
Definition: dbus-string.c:1687
dbus_bool_t _dbus_string_starts_with_c_str(const DBusString *a, const char *c_str)
Checks whether a string starts with the given C string.
Definition: dbus-string.c:2248
dbus_bool_t _dbus_string_alloc_space(DBusString *str, int extra_bytes)
Preallocate extra_bytes such that a future lengthening of the string by extra_bytes is guaranteed to ...
Definition: dbus-string.c:942
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:684
void _dbus_string_skip_blank(const DBusString *str, int start, int *end)
Skips blanks from start, storing the first non-blank in *end (blank is space or tab).
Definition: dbus-string.c:1863
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc.
Definition: dbus-string.c:137
void _dbus_string_skip_white_reverse(const DBusString *str, int end, int *start)
Skips whitespace from end, storing the start index of the trailing whitespace in *start.
Definition: dbus-string.c:1930
dbus_bool_t _dbus_string_init_from_string(DBusString *str, const DBusString *from)
Initializes a string from another string.
Definition: dbus-string.c: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:1527
dbus_bool_t _dbus_string_find(const DBusString *str, int start, const char *substr, int *found)
Finds the given substring in the string, returning TRUE and filling in the byte index where the subst...
Definition: dbus-string.c:1664
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:533
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:2676
dbus_bool_t _dbus_string_find_blank(const DBusString *str, int start, int *found)
Finds a blank (space or tab) in the string.
Definition: dbus-string.c:1825
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:215
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:2606
dbus_bool_t _dbus_string_append_len(DBusString *str, const char *buffer, int len)
Appends block of bytes with the given length to a DBusString.
Definition: dbus-string.c:1168
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:494
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:276
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:823
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1253
dbus_bool_t _dbus_string_copy_data(const DBusString *str, char **data_return)
Copies the data from the string into a char*.
Definition: dbus-string.c:715
dbus_bool_t _dbus_string_equal_c_str(const DBusString *a, const char *c_str)
Checks whether a string is equal to a C string.
Definition: dbus-string.c:2212
void _dbus_string_skip_white(const DBusString *str, int start, int *end)
Skips whitespace from start, storing the first non-whitespace in *end.
Definition: dbus-string.c:1897
dbus_bool_t _dbus_string_pop_line(DBusString *source, DBusString *dest)
Assigns a newline-terminated or \r\n-terminated line from the front of the string to the given dest s...
Definition: dbus-string.c:1969
dbus_bool_t _dbus_string_append_printf_valist(DBusString *str, const char *format, va_list args)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1103
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:803
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2806
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1606
void _dbus_string_toupper_ascii(const DBusString *str, int start, int len)
Converts the given range of the string to upper case.
Definition: dbus-string.c:2637
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:627
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:2571
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:782
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1188
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:2049
dbus_bool_t _dbus_string_starts_with_words_c_str(const DBusString *a, const char *c_str, char word_separator)
Checks whether a string starts with the given C string, after which it ends or is separated from the ...
Definition: dbus-string.c:2286
dbus_bool_t _dbus_string_hex_encode(const DBusString *source, int start, DBusString *dest, int insert_at)
Encodes a string in hex, the way MD5 and SHA-1 are usually encoded.
Definition: dbus-string.c:2380
#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)
Checks assertions for two strings we're copying a segment between, and declares real_source/real_dest...
Definition: dbus-string.c:1295
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1145
dbus_bool_t _dbus_string_insert_byte(DBusString *str, int i, unsigned char byte)
Inserts a single byte at the given position.
Definition: dbus-string.c:657
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1622
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:557
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:581
dbus_bool_t _dbus_string_move_len(DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_move(), but can move a segment from the middle of the source string.
Definition: dbus-string.c:1368
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:511
int _dbus_string_get_allocated_size(const DBusString *str)
Returns the allocated size of the string.
Definition: dbus-string.c:474
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:605
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:762
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:418
dbus_bool_t _dbus_string_equal_len(const DBusString *a, const DBusString *b, int len)
Tests two DBusString for equality up to the given length.
Definition: dbus-string.c:2116
dbus_bool_t _dbus_string_move(DBusString *source, int start, DBusString *dest, int insert_at)
Moves the end of one string into another string.
Definition: dbus-string.c:1319
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2073
dbus_bool_t _dbus_string_insert_4_aligned(DBusString *str, int insert_at, const unsigned char octets[4])
Inserts 4 bytes aligned on a 4 byte boundary with any alignment padding initialized to 0.
Definition: dbus-string.c:1027
dbus_bool_t _dbus_string_insert_2_aligned(DBusString *str, int insert_at, const unsigned char octets[2])
Inserts 2 bytes aligned on a 2 byte boundary with any alignment padding initialized to 0.
Definition: dbus-string.c:1003
dbus_bool_t _dbus_string_append_byte_as_hex(DBusString *str, unsigned char byte)
Appends a two-character hex digit to a string, where the hex digit has the value of the given byte.
Definition: dbus-string.c:2311
dbus_bool_t _dbus_string_align_length(DBusString *str, int alignment)
Align the length of a string to a specific alignment (typically 4 or 8) by appending nul bytes to the...
Definition: dbus-string.c:926
dbus_bool_t _dbus_string_find_to(const DBusString *str, int start, int end, const char *substr, int *found)
Finds the given substring in the string, up to a certain position, returning TRUE and filling in the ...
Definition: dbus-string.c:1757
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1435
void _dbus_string_copy_to_buffer(const DBusString *str, char *buffer, int avail_len)
Copies the contents of a DBusString into a different buffer.
Definition: dbus-string.c:740
dbus_bool_t _dbus_string_replace_len(const DBusString *source, int start, int len, DBusString *dest, int replace_at, int replace_len)
Replaces a segment of dest string with a segment of source string.
Definition: dbus-string.c:1464
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
Internals of DBusString.
unsigned int align_offset
str - align_offset is the actual malloc block
unsigned int valid
DBusString is valid (initialized and not freed)
unsigned int constant
String data is not owned by DBusString.
unsigned int locked
DBusString has been locked and can't be changed.
unsigned char * str
String data, plus nul termination.
int allocated
Allocated size of data.
int len
Length without nul.