dbus-string.c revision 05a4ad6994919b352b5229d0b1b0a8ebebe2a42f
1/* -*- mode: C; c-file-style: "gnu" -*- */
2/* dbus-string.c String utility class (internal to D-BUS implementation)
3 *
4 * Copyright (C) 2002  Red Hat, Inc.
5 *
6 * Licensed under the Academic Free License version 1.2
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 *
22 */
23
24#include "dbus-internals.h"
25#include "dbus-string.h"
26/* we allow a system header here, for speed/convenience */
27#include <string.h>
28
29/**
30 * @defgroup DBusString string class
31 * @ingroup  DBusInternals
32 * @brief DBusString data structure
33 *
34 * Types and functions related to DBusString. DBusString is intended
35 * to be a string class that makes it hard to mess up security issues
36 * (and just in general harder to write buggy code).  It should be
37 * used (or extended and then used) rather than the libc stuff in
38 * string.h.  The string class is a bit inconvenient at spots because
39 * it handles out-of-memory failures and tries to be extra-robust.
40 *
41 * A DBusString has a maximum length set at initialization time; this
42 * can be used to ensure that a buffer doesn't get too big.  The
43 * _dbus_string_lengthen() method checks for overflow, and for max
44 * length being exceeded.
45 *
46 * Try to avoid conversion to a plain C string, i.e. add methods on
47 * the string object instead, only convert to C string when passing
48 * things out to the public API. In particular, no sprintf, strcpy,
49 * strcat, any of that should be used. The GString feature of
50 * accepting negative numbers for "length of string" is also absent,
51 * because it could keep us from detecting bogus huge lengths. i.e. if
52 * we passed in some bogus huge length it would be taken to mean
53 * "current length of string" instead of "broken crack"
54 */
55
56/**
57 * @defgroup DBusStringInternals DBusString implementation details
58 * @ingroup  DBusInternals
59 * @brief DBusString implementation details
60 *
61 * The guts of DBusString.
62 *
63 * @{
64 */
65
66/**
67 * @brief Internals of DBusString.
68 *
69 * DBusString internals. DBusString is an opaque objects, it must be
70 * used via accessor functions.
71 */
72typedef struct
73{
74  unsigned char *str;            /**< String data, plus nul termination */
75  int            len;            /**< Length without nul */
76  int            allocated;      /**< Allocated size of data */
77  int            max_length;     /**< Max length of this string. */
78  unsigned int   constant : 1;   /**< String data is not owned by DBusString */
79  unsigned int   locked : 1;     /**< DBusString has been locked and can't be changed */
80  unsigned int   invalid : 1;    /**< DBusString is invalid (e.g. already freed) */
81} DBusRealString;
82
83/**
84 * Checks a bunch of assertions about a string object
85 *
86 * @param real the DBusRealString
87 */
88#define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= (real)->allocated); _dbus_assert ((real)->len <= (real)->max_length)
89
90/**
91 * Checks assertions about a string object that needs to be
92 * modifiable - may not be locked or const. Also declares
93 * the "real" variable pointing to DBusRealString.
94 * @param str the string
95 */
96#define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
97  DBUS_GENERIC_STRING_PREAMBLE (real);                                          \
98  _dbus_assert (!(real)->constant);                                             \
99  _dbus_assert (!(real)->locked)
100
101/**
102 * Checks assertions about a string object that may be locked but
103 * can't be const. i.e. a string object that we can free.  Also
104 * declares the "real" variable pointing to DBusRealString.
105 *
106 * @param str the string
107 */
108#define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
109  DBUS_GENERIC_STRING_PREAMBLE (real);                                                 \
110  _dbus_assert (!(real)->constant)
111
112/**
113 * Checks assertions about a string that may be const or locked.  Also
114 * declares the "real" variable pointing to DBusRealString.
115 * @param str the string.
116 */
117#define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
118  DBUS_GENERIC_STRING_PREAMBLE (real)
119
120/** @} */
121
122/**
123 * @addtogroup DBusString
124 * @{
125 */
126
127/** Assert that the string's memory is 8-byte aligned.
128 *
129 *  @todo Currently we just hope libc returns 8-byte aligned memory
130 *  (which is true for GNU libc), but really we need to ensure it by
131 *  allocating 8 extra bytes and keeping an "align_offset : 3" field
132 *  in DBusString, or something along those lines.
133 */
134#define ASSERT_8_BYTE_ALIGNED(s) \
135  _dbus_assert (_DBUS_ALIGN_ADDRESS (((const DBusRealString*)s)->str, 8) == ((const DBusRealString*)s)->str)
136
137/**
138 * Initializes a string. The maximum length may be _DBUS_INT_MAX for
139 * no maximum. The string starts life with zero length.
140 * The string must eventually be freed with _dbus_string_free().
141 *
142 * @todo the max length feature is useless, because it looks
143 * to the app like out of memory, and the app might try
144 * to "recover" - but recovery in this case is impossible,
145 * as we can't ever "get more memory" - so should delete the
146 * max length feature I think.
147 *
148 * @todo we could make this init routine not alloc any memory and
149 * return void, would simplify a lot of code, however it might
150 * complexify things elsewhere because _dbus_string_get_data()
151 * etc. could suddenly fail as they'd need to alloc new memory.
152 *
153 * @param str memory to hold the string
154 * @param max_length the maximum size of the string
155 * @returns #TRUE on success
156 */
157dbus_bool_t
158_dbus_string_init (DBusString *str,
159                   int         max_length)
160{
161  DBusRealString *real;
162
163  _dbus_assert (str != NULL);
164  _dbus_assert (max_length >= 0);
165
166  _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
167
168  real = (DBusRealString*) str;
169
170  /* It's very important not to touch anything
171   * other than real->str if we're going to fail,
172   * since we also use this function to reset
173   * an existing string, e.g. in _dbus_string_steal_data()
174   */
175
176#define INITIAL_ALLOC 2
177
178  real->str = dbus_malloc (INITIAL_ALLOC);
179  if (real->str == NULL)
180    return FALSE;
181
182  real->allocated = INITIAL_ALLOC;
183  real->len = 0;
184  real->str[real->len] = '\0';
185
186  real->max_length = max_length;
187  real->constant = FALSE;
188  real->locked = FALSE;
189  real->invalid = FALSE;
190
191  ASSERT_8_BYTE_ALIGNED (str);
192
193  return TRUE;
194}
195
196/**
197 * Initializes a constant string. The value parameter is not copied
198 * (should be static), and the string may never be modified.
199 * It is safe but not necessary to call _dbus_string_free()
200 * on a const string.
201 *
202 * @param str memory to use for the string
203 * @param value a string to be stored in str (not copied!!!)
204 */
205void
206_dbus_string_init_const (DBusString *str,
207                         const char *value)
208{
209  _dbus_string_init_const_len (str, value,
210                               strlen (value));
211}
212
213/**
214 * Initializes a constant string with a length. The value parameter is
215 * not copied (should be static), and the string may never be
216 * modified.  It is safe but not necessary to call _dbus_string_free()
217 * on a const string.
218 *
219 * @param str memory to use for the string
220 * @param value a string to be stored in str (not copied!!!)
221 * @param len the length to use
222 */
223void
224_dbus_string_init_const_len (DBusString *str,
225                             const char *value,
226                             int         len)
227{
228  DBusRealString *real;
229
230  _dbus_assert (str != NULL);
231  _dbus_assert (value != NULL);
232
233  real = (DBusRealString*) str;
234
235  real->str = (char*) value;
236  real->len = len;
237  real->allocated = real->len;
238  real->max_length = real->len;
239  real->constant = TRUE;
240  real->invalid = FALSE;
241
242  /* We don't require const strings to be 8-byte aligned as the
243   * memory is coming from elsewhere.
244   */
245}
246
247/**
248 * Frees a string created by _dbus_string_init().
249 *
250 * @param str memory where the string is stored.
251 */
252void
253_dbus_string_free (DBusString *str)
254{
255  DBusRealString *real = (DBusRealString*) str;
256  DBUS_GENERIC_STRING_PREAMBLE (real);
257
258  if (real->constant)
259    return;
260  dbus_free (real->str);
261
262  real->invalid = TRUE;
263}
264
265/**
266 * Locks a string such that any attempts to change the string
267 * will result in aborting the program. Also, if the string
268 * is wasting a lot of memory (allocation is larger than what
269 * the string is really using), _dbus_string_lock() will realloc
270 * the string's data to "compact" it.
271 *
272 * @param str the string to lock.
273 */
274void
275_dbus_string_lock (DBusString *str)
276{
277  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
278
279  real->locked = TRUE;
280
281  /* Try to realloc to avoid excess memory usage, since
282   * we know we won't change the string further
283   */
284#define MAX_WASTE 24
285  if (real->allocated > (real->len + MAX_WASTE))
286    {
287      char *new_str;
288      int new_allocated;
289
290      new_allocated = real->len + 1;
291
292      new_str = dbus_realloc (real->str, new_allocated);
293      if (new_str != NULL)
294        {
295          real->str = new_str;
296          real->allocated = new_allocated;
297          ASSERT_8_BYTE_ALIGNED (str);
298        }
299    }
300}
301
302/**
303 * Gets the raw character buffer from the string.  The returned buffer
304 * will be nul-terminated, but note that strings may contain binary
305 * data so there may be extra nul characters prior to the termination.
306 * This function should be little-used, extend DBusString or add
307 * stuff to dbus-sysdeps.c instead. It's an error to use this
308 * function on a const string.
309 *
310 * @param str the string
311 * @param data_return place to store the returned data
312 */
313void
314_dbus_string_get_data (DBusString        *str,
315                       char             **data_return)
316{
317  DBUS_STRING_PREAMBLE (str);
318  _dbus_assert (data_return != NULL);
319
320  *data_return = real->str;
321}
322
323/**
324 * Gets the raw character buffer from a const string.
325 *
326 * @param str the string
327 * @param data_return location to store returned data
328 */
329void
330_dbus_string_get_const_data (const DBusString  *str,
331                             const char       **data_return)
332{
333  DBUS_CONST_STRING_PREAMBLE (str);
334  _dbus_assert (data_return != NULL);
335
336  *data_return = real->str;
337}
338
339/**
340 * Gets a sub-portion of the raw character buffer from the
341 * string. The "len" field is required simply for error
342 * checking, to be sure you don't try to use more
343 * string than exists. The nul termination of the
344 * returned buffer remains at the end of the entire
345 * string, not at start + len.
346 *
347 * @param str the string
348 * @param data_return location to return the buffer
349 * @param start byte offset to return
350 * @param len length of segment to return
351 */
352void
353_dbus_string_get_data_len (DBusString *str,
354                           char      **data_return,
355                           int         start,
356                           int         len)
357{
358  DBUS_STRING_PREAMBLE (str);
359  _dbus_assert (data_return != NULL);
360  _dbus_assert (start >= 0);
361  _dbus_assert (len >= 0);
362  _dbus_assert ((start + len) <= real->len);
363
364  *data_return = real->str + start;
365}
366
367/**
368 * const version of _dbus_string_get_data_len().
369 *
370 * @param str the string
371 * @param data_return location to return the buffer
372 * @param start byte offset to return
373 * @param len length of segment to return
374 */
375void
376_dbus_string_get_const_data_len (const DBusString  *str,
377                                 const char       **data_return,
378                                 int                start,
379                                 int                len)
380{
381  DBUS_CONST_STRING_PREAMBLE (str);
382  _dbus_assert (data_return != NULL);
383  _dbus_assert (start >= 0);
384  _dbus_assert (len >= 0);
385  _dbus_assert ((start + len) <= real->len);
386
387  *data_return = real->str + start;
388}
389
390/**
391 * Gets the byte at the given position.
392 *
393 * @param str the string
394 * @param start the position
395 * @returns the byte at that position
396 */
397char
398_dbus_string_get_byte (const DBusString  *str,
399                       int                start)
400{
401  DBUS_CONST_STRING_PREAMBLE (str);
402  _dbus_assert (start < real->len);
403
404  return real->str[start];
405}
406
407/**
408 * Like _dbus_string_get_data(), but removes the
409 * gotten data from the original string. The caller
410 * must free the data returned. This function may
411 * fail due to lack of memory, and return #FALSE.
412 *
413 * @param str the string
414 * @param data_return location to return the buffer
415 * @returns #TRUE on success
416 */
417dbus_bool_t
418_dbus_string_steal_data (DBusString        *str,
419                         char             **data_return)
420{
421  DBUS_STRING_PREAMBLE (str);
422  _dbus_assert (data_return != NULL);
423
424  *data_return = real->str;
425
426  /* reset the string */
427  if (!_dbus_string_init (str, real->max_length))
428    {
429      /* hrm, put it back then */
430      real->str = *data_return;
431      *data_return = NULL;
432      return FALSE;
433    }
434
435  return TRUE;
436}
437
438/**
439 * Like _dbus_string_get_data_len(), but removes the gotten data from
440 * the original string. The caller must free the data returned. This
441 * function may fail due to lack of memory, and return #FALSE.
442 * The returned string is nul-terminated and has length len.
443 *
444 * @param str the string
445 * @param data_return location to return the buffer
446 * @param start the start of segment to steal
447 * @param len the length of segment to steal
448 * @returns #TRUE on success
449 */
450dbus_bool_t
451_dbus_string_steal_data_len (DBusString        *str,
452                             char             **data_return,
453                             int                start,
454                             int                len)
455{
456  DBusString dest;
457
458  DBUS_STRING_PREAMBLE (str);
459  _dbus_assert (data_return != NULL);
460  _dbus_assert (start >= 0);
461  _dbus_assert (len >= 0);
462  _dbus_assert ((start + len) <= real->len);
463
464  if (!_dbus_string_init (&dest, real->max_length))
465    return FALSE;
466
467  if (!_dbus_string_move_len (str, start, len, &dest, 0))
468    {
469      _dbus_string_free (&dest);
470      return FALSE;
471    }
472
473  if (!_dbus_string_steal_data (&dest, data_return))
474    {
475      _dbus_string_free (&dest);
476      return FALSE;
477    }
478
479  _dbus_string_free (&dest);
480  return TRUE;
481}
482
483/**
484 * Gets the length of a string (not including nul termination).
485 *
486 * @returns the length.
487 */
488int
489_dbus_string_get_length (const DBusString  *str)
490{
491  DBUS_CONST_STRING_PREAMBLE (str);
492
493  return real->len;
494}
495
496static dbus_bool_t
497set_length (DBusRealString *real,
498            int             new_length)
499{
500  /* Note, we are setting the length without nul termination */
501
502  /* exceeding max length is the same as failure to allocate memory */
503  if (new_length > real->max_length)
504    return FALSE;
505
506  while (new_length >= real->allocated)
507    {
508      int new_allocated;
509      char *new_str;
510
511      new_allocated = 2 + real->allocated * 2;
512      if (new_allocated < real->allocated)
513        return FALSE; /* overflow */
514
515      new_str = dbus_realloc (real->str, new_allocated);
516      if (new_str == NULL)
517        return FALSE;
518
519      real->str = new_str;
520      real->allocated = new_allocated;
521
522      ASSERT_8_BYTE_ALIGNED (real);
523    }
524
525  real->len = new_length;
526  real->str[real->len] = '\0';
527
528  return TRUE;
529}
530
531/**
532 * Makes a string longer by the given number of bytes.  Checks whether
533 * adding additional_length to the current length would overflow an
534 * integer, and checks for exceeding a string's max length.
535 * The new bytes are not initialized, other than nul-terminating
536 * the end of the string. The uninitialized bytes may contain
537 * unexpected nul bytes or other junk.
538 *
539 * @param str a string
540 * @param additional_length length to add to the string.
541 * @returns #TRUE on success.
542 */
543dbus_bool_t
544_dbus_string_lengthen (DBusString *str,
545                       int         additional_length)
546{
547  DBUS_STRING_PREAMBLE (str);
548  _dbus_assert (additional_length >= 0);
549
550  if ((real->len + additional_length) < real->len)
551    return FALSE; /* overflow */
552
553  return set_length (real,
554                     real->len + additional_length);
555}
556
557/**
558 * Makes a string shorter by the given number of bytes.
559 *
560 * @param str a string
561 * @param length_to_remove length to remove from the string.
562 */
563void
564_dbus_string_shorten (DBusString *str,
565                      int         length_to_remove)
566{
567  DBUS_STRING_PREAMBLE (str);
568  _dbus_assert (length_to_remove >= 0);
569  _dbus_assert (length_to_remove <= real->len);
570
571  set_length (real,
572              real->len - length_to_remove);
573}
574
575/**
576 * Sets the length of a string. Can be used to truncate or lengthen
577 * the string. If the string is lengthened, the function may fail and
578 * return #FALSE. Newly-added bytes are not initialized, as with
579 * _dbus_string_lengthen().
580 *
581 * @param str a string
582 * @param length new length of the string.
583 * @returns #FALSE on failure.
584 */
585dbus_bool_t
586_dbus_string_set_length (DBusString *str,
587                         int         length)
588{
589  DBUS_STRING_PREAMBLE (str);
590  _dbus_assert (length >= 0);
591
592  return set_length (real, length);
593}
594
595/**
596 * Align the length of a string to a specific alignment (typically 4 or 8)
597 * by appending nul bytes to the string.
598 *
599 * @param str a string
600 * @param alignment the alignment
601 * @returns #FALSE if no memory
602 */
603dbus_bool_t
604_dbus_string_align_length (DBusString *str,
605                           int         alignment)
606{
607  int new_len;
608  int delta;
609  DBUS_STRING_PREAMBLE (str);
610  _dbus_assert (alignment >= 1);
611  _dbus_assert (alignment <= 16); /* arbitrary */
612
613  new_len = _DBUS_ALIGN_VALUE (real->len, alignment);
614
615  delta = new_len - real->len;
616  _dbus_assert (delta >= 0);
617
618  if (delta == 0)
619    return TRUE;
620
621  if (!set_length (real, new_len))
622    return FALSE;
623
624  memset (real->str + (new_len - delta),
625          '\0', delta);
626
627  return TRUE;
628}
629
630static dbus_bool_t
631append (DBusRealString *real,
632        const char     *buffer,
633        int             buffer_len)
634{
635  if (buffer_len == 0)
636    return TRUE;
637
638  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
639    return FALSE;
640
641  memcpy (real->str + (real->len - buffer_len),
642          buffer,
643          buffer_len);
644
645  return TRUE;
646}
647
648/**
649 * Appends a nul-terminated C-style string to a DBusString.
650 *
651 * @param str the DBusString
652 * @param buffer the nul-terminated characters to append
653 * @returns #FALSE if not enough memory.
654 */
655dbus_bool_t
656_dbus_string_append (DBusString *str,
657                     const char *buffer)
658{
659  int buffer_len;
660
661  DBUS_STRING_PREAMBLE (str);
662  _dbus_assert (buffer != NULL);
663
664  buffer_len = strlen (buffer);
665
666  return append (real, buffer, buffer_len);
667}
668
669/**
670 * Appends block of bytes with the given length to a DBusString.
671 *
672 * @param str the DBusString
673 * @param buffer the bytes to append
674 * @param len the number of bytes to append
675 * @returns #FALSE if not enough memory.
676 */
677dbus_bool_t
678_dbus_string_append_len (DBusString *str,
679                         const char *buffer,
680                         int         len)
681{
682  DBUS_STRING_PREAMBLE (str);
683  _dbus_assert (buffer != NULL);
684  _dbus_assert (len >= 0);
685
686  return append (real, buffer, len);
687}
688
689/**
690 * Appends a single byte to the string, returning #FALSE
691 * if not enough memory.
692 *
693 * @param str the string
694 * @param byte the byte to append
695 * @returns #TRUE on success
696 */
697dbus_bool_t
698_dbus_string_append_byte (DBusString    *str,
699                          unsigned char  byte)
700{
701  DBUS_STRING_PREAMBLE (str);
702
703  if (!set_length (real, real->len + 1))
704    return FALSE;
705
706  real->str[real->len-1] = byte;
707
708  return TRUE;
709}
710
711/**
712 * Appends a single Unicode character, encoding the character
713 * in UTF-8 format.
714 *
715 * @param str the string
716 * @param ch the Unicode character
717 */
718dbus_bool_t
719_dbus_string_append_unichar (DBusString    *str,
720                             dbus_unichar_t ch)
721{
722  int len;
723  int first;
724  int i;
725  char *out;
726
727  DBUS_STRING_PREAMBLE (str);
728
729  /* this code is from GLib but is pretty standard I think */
730
731  len = 0;
732
733  if (ch < 0x80)
734    {
735      first = 0;
736      len = 1;
737    }
738  else if (ch < 0x800)
739    {
740      first = 0xc0;
741      len = 2;
742    }
743  else if (ch < 0x10000)
744    {
745      first = 0xe0;
746      len = 3;
747    }
748   else if (ch < 0x200000)
749    {
750      first = 0xf0;
751      len = 4;
752    }
753  else if (ch < 0x4000000)
754    {
755      first = 0xf8;
756      len = 5;
757    }
758  else
759    {
760      first = 0xfc;
761      len = 6;
762    }
763
764  if (!set_length (real, real->len + len))
765    return FALSE;
766
767  out = real->str + (real->len - len);
768
769  for (i = len - 1; i > 0; --i)
770    {
771      out[i] = (ch & 0x3f) | 0x80;
772      ch >>= 6;
773    }
774  out[0] = ch | first;
775
776  return TRUE;
777}
778
779static void
780delete (DBusRealString *real,
781        int             start,
782        int             len)
783{
784  if (len == 0)
785    return;
786
787  memmove (real->str + start, real->str + start + len, real->len - (start + len));
788  real->len -= len;
789  real->str[real->len] = '\0';
790}
791
792/**
793 * Deletes a segment of a DBusString with length len starting at
794 * start. (Hint: to clear an entire string, setting length to 0
795 * with _dbus_string_set_length() is easier.)
796 *
797 * @param str the DBusString
798 * @param start where to start deleting
799 * @param len the number of bytes to delete
800 */
801void
802_dbus_string_delete (DBusString       *str,
803                     int               start,
804                     int               len)
805{
806  DBUS_STRING_PREAMBLE (str);
807  _dbus_assert (start >= 0);
808  _dbus_assert (len >= 0);
809  _dbus_assert ((start + len) <= real->len);
810
811  delete (real, start, len);
812}
813
814static dbus_bool_t
815open_gap (int             len,
816          DBusRealString *dest,
817          int             insert_at)
818{
819  if (len == 0)
820    return TRUE;
821
822  if (!set_length (dest, dest->len + len))
823    return FALSE;
824
825  memmove (dest->str + insert_at + len,
826           dest->str + insert_at,
827           dest->len - len - insert_at);
828
829  return TRUE;
830}
831
832static dbus_bool_t
833copy (DBusRealString *source,
834      int             start,
835      int             len,
836      DBusRealString *dest,
837      int             insert_at)
838{
839  if (len == 0)
840    return TRUE;
841
842  if (!open_gap (len, dest, insert_at))
843    return FALSE;
844
845  memcpy (dest->str + insert_at,
846          source->str + start,
847          len);
848
849  return TRUE;
850}
851
852/**
853 * Checks assertions for two strings we're copying a segment between,
854 * and declares real_source/real_dest variables.
855 *
856 * @param source the source string
857 * @param start the starting offset
858 * @param dest the dest string
859 * @param insert_at where the copied segment is inserted
860 */
861#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)       \
862  DBusRealString *real_source = (DBusRealString*) source;               \
863  DBusRealString *real_dest = (DBusRealString*) dest;                   \
864  _dbus_assert ((source) != (dest));                                    \
865  DBUS_GENERIC_STRING_PREAMBLE (real_source);                           \
866  DBUS_GENERIC_STRING_PREAMBLE (real_dest);                             \
867  _dbus_assert (!real_dest->constant);                                  \
868  _dbus_assert (!real_dest->locked);                                    \
869  _dbus_assert ((start) >= 0);                                          \
870  _dbus_assert ((start) <= real_source->len);                           \
871  _dbus_assert ((insert_at) >= 0);                                      \
872  _dbus_assert ((insert_at) <= real_dest->len)
873
874/**
875 * Moves the end of one string into another string. Both strings
876 * must be initialized, valid strings.
877 *
878 * @param source the source string
879 * @param start where to chop off the source string
880 * @param dest the destination string
881 * @param insert_at where to move the chopped-off part of source string
882 * @returns #FALSE if not enough memory
883 */
884dbus_bool_t
885_dbus_string_move (DBusString       *source,
886                   int               start,
887                   DBusString       *dest,
888                   int               insert_at)
889{
890  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
891
892  if (!copy (real_source, start,
893             real_source->len - start,
894             real_dest,
895             insert_at))
896    return FALSE;
897
898  delete (real_source, start,
899          real_source->len - start);
900
901  return TRUE;
902}
903
904/**
905 * Like _dbus_string_move(), but does not delete the section
906 * of the source string that's copied to the dest string.
907 *
908 * @param source the source string
909 * @param start where to start copying the source string
910 * @param dest the destination string
911 * @param insert_at where to place the copied part of source string
912 * @returns #FALSE if not enough memory
913 */
914dbus_bool_t
915_dbus_string_copy (const DBusString *source,
916                   int               start,
917                   DBusString       *dest,
918                   int               insert_at)
919{
920  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
921
922  return copy (real_source, start,
923               real_source->len - start,
924               real_dest,
925               insert_at);
926}
927
928/**
929 * Like _dbus_string_move(), but can move a segment from
930 * the middle of the source string.
931 *
932 * @param source the source string
933 * @param start first byte of source string to move
934 * @param len length of segment to move
935 * @param dest the destination string
936 * @param insert_at where to move the bytes from the source string
937 * @returns #FALSE if not enough memory
938 */
939dbus_bool_t
940_dbus_string_move_len (DBusString       *source,
941                       int               start,
942                       int               len,
943                       DBusString       *dest,
944                       int               insert_at)
945
946{
947  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
948  _dbus_assert (len >= 0);
949  _dbus_assert ((start + len) <= real_source->len);
950
951  if (!copy (real_source, start, len,
952             real_dest,
953             insert_at))
954    return FALSE;
955
956  delete (real_source, start,
957          len);
958
959  return TRUE;
960}
961
962/**
963 * Like _dbus_string_copy(), but can copy a segment from the middle of
964 * the source string.
965 *
966 * @param source the source string
967 * @param start where to start copying the source string
968 * @param len length of segment to copy
969 * @param dest the destination string
970 * @param insert_at where to place the copied segment of source string
971 * @returns #FALSE if not enough memory
972 */
973dbus_bool_t
974_dbus_string_copy_len (const DBusString *source,
975                       int               start,
976                       int               len,
977                       DBusString       *dest,
978                       int               insert_at)
979{
980  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
981  _dbus_assert (len >= 0);
982  _dbus_assert ((start + len) <= real_source->len);
983
984  return copy (real_source, start, len,
985               real_dest,
986               insert_at);
987}
988
989/**
990 * Replaces a segment of dest string with a segment of source string.
991 *
992 * @todo optimize the case where the two lengths are the same, and
993 * avoid memmoving the data in the trailing part of the string twice.
994 *
995 * @param source the source string
996 * @param start where to start copying the source string
997 * @param len length of segment to copy
998 * @param dest the destination string
999 * @param replace_at start of segment of dest string to replace
1000 * @param replace_len length of segment of dest string to replace
1001 * @returns #FALSE if not enough memory
1002 *
1003 */
1004dbus_bool_t
1005_dbus_string_replace_len (const DBusString *source,
1006                          int               start,
1007                          int               len,
1008                          DBusString       *dest,
1009                          int               replace_at,
1010                          int               replace_len)
1011{
1012  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1013  _dbus_assert (len >= 0);
1014  _dbus_assert ((start + len) <= real_source->len);
1015  _dbus_assert (replace_at >= 0);
1016  _dbus_assert ((replace_at + replace_len) <= real_dest->len);
1017
1018  if (!copy (real_source, start, len,
1019             real_dest, replace_at))
1020    return FALSE;
1021
1022  delete (real_dest, replace_at + len, replace_len);
1023
1024  return TRUE;
1025}
1026
1027/* Unicode macros from GLib */
1028
1029/** computes length and mask of a unicode character
1030 * @param Char the char
1031 * @param Mask the mask variable to assign to
1032 * @param Len the length variable to assign to
1033 */
1034#define UTF8_COMPUTE(Char, Mask, Len)					      \
1035  if (Char < 128)							      \
1036    {									      \
1037      Len = 1;								      \
1038      Mask = 0x7f;							      \
1039    }									      \
1040  else if ((Char & 0xe0) == 0xc0)					      \
1041    {									      \
1042      Len = 2;								      \
1043      Mask = 0x1f;							      \
1044    }									      \
1045  else if ((Char & 0xf0) == 0xe0)					      \
1046    {									      \
1047      Len = 3;								      \
1048      Mask = 0x0f;							      \
1049    }									      \
1050  else if ((Char & 0xf8) == 0xf0)					      \
1051    {									      \
1052      Len = 4;								      \
1053      Mask = 0x07;							      \
1054    }									      \
1055  else if ((Char & 0xfc) == 0xf8)					      \
1056    {									      \
1057      Len = 5;								      \
1058      Mask = 0x03;							      \
1059    }									      \
1060  else if ((Char & 0xfe) == 0xfc)					      \
1061    {									      \
1062      Len = 6;								      \
1063      Mask = 0x01;							      \
1064    }									      \
1065  else									      \
1066    Len = -1;
1067
1068/**
1069 * computes length of a unicode character in UTF-8
1070 * @param Char the char
1071 */
1072#define UTF8_LENGTH(Char)              \
1073  ((Char) < 0x80 ? 1 :                 \
1074   ((Char) < 0x800 ? 2 :               \
1075    ((Char) < 0x10000 ? 3 :            \
1076     ((Char) < 0x200000 ? 4 :          \
1077      ((Char) < 0x4000000 ? 5 : 6)))))
1078
1079/**
1080 * Gets a UTF-8 value.
1081 *
1082 * @param Result variable for extracted unicode char.
1083 * @param Chars the bytes to decode
1084 * @param Count counter variable
1085 * @param Mask mask for this char
1086 * @param Len length for this char in bytes
1087 */
1088#define UTF8_GET(Result, Chars, Count, Mask, Len)			      \
1089  (Result) = (Chars)[0] & (Mask);					      \
1090  for ((Count) = 1; (Count) < (Len); ++(Count))				      \
1091    {									      \
1092      if (((Chars)[(Count)] & 0xc0) != 0x80)				      \
1093	{								      \
1094	  (Result) = -1;						      \
1095	  break;							      \
1096	}								      \
1097      (Result) <<= 6;							      \
1098      (Result) |= ((Chars)[(Count)] & 0x3f);				      \
1099    }
1100
1101/**
1102 * Check whether a unicode char is in a valid range.
1103 *
1104 * @param Char the character
1105 */
1106#define UNICODE_VALID(Char)                   \
1107    ((Char) < 0x110000 &&                     \
1108     ((Char) < 0xD800 || (Char) >= 0xE000) && \
1109     (Char) != 0xFFFE && (Char) != 0xFFFF)
1110
1111/**
1112 * Gets a unicode character from a UTF-8 string. Does no validation;
1113 * you must verify that the string is valid UTF-8 in advance and must
1114 * pass in the start of a character.
1115 *
1116 * @param str the string
1117 * @param start the start of the UTF-8 character.
1118 * @param ch_return location to return the character
1119 * @param end_return location to return the byte index of next character
1120 * @returns #TRUE on success, #FALSE otherwise.
1121 */
1122void
1123_dbus_string_get_unichar (const DBusString *str,
1124                          int               start,
1125                          dbus_unichar_t   *ch_return,
1126                          int              *end_return)
1127{
1128  int i, mask, len;
1129  dbus_unichar_t result;
1130  unsigned char c;
1131  unsigned char *p;
1132  DBUS_CONST_STRING_PREAMBLE (str);
1133
1134  if (ch_return)
1135    *ch_return = 0;
1136  if (end_return)
1137    *end_return = real->len;
1138
1139  mask = 0;
1140  p = real->str + start;
1141  c = *p;
1142
1143  UTF8_COMPUTE (c, mask, len);
1144  if (len == -1)
1145    return;
1146  UTF8_GET (result, p, i, mask, len);
1147
1148  if (result == (dbus_unichar_t)-1)
1149    return;
1150
1151  if (ch_return)
1152    *ch_return = result;
1153  if (end_return)
1154    *end_return = start + len;
1155}
1156
1157/**
1158 * Finds the given substring in the string,
1159 * returning #TRUE and filling in the byte index
1160 * where the substring was found, if it was found.
1161 * Returns #FALSE if the substring wasn't found.
1162 * Sets *start to the length of the string if the substring
1163 * is not found.
1164 *
1165 * @param str the string
1166 * @param start where to start looking
1167 * @param substr the substring
1168 * @param found return location for where it was found, or #NULL
1169 * @returns #TRUE if found
1170 */
1171dbus_bool_t
1172_dbus_string_find (const DBusString *str,
1173                   int               start,
1174                   const char       *substr,
1175                   int              *found)
1176{
1177  int i;
1178  DBUS_CONST_STRING_PREAMBLE (str);
1179  _dbus_assert (substr != NULL);
1180  _dbus_assert (start <= real->len);
1181
1182  /* we always "find" an empty string */
1183  if (*substr == '\0')
1184    {
1185      if (found)
1186        *found = 0;
1187      return TRUE;
1188    }
1189
1190  i = start;
1191  while (i < real->len)
1192    {
1193      if (real->str[i] == substr[0])
1194        {
1195          int j = i + 1;
1196
1197          while (j < real->len)
1198            {
1199              if (substr[j - i] == '\0')
1200                break;
1201              else if (real->str[j] != substr[j - i])
1202                break;
1203
1204              ++j;
1205            }
1206
1207          if (substr[j - i] == '\0')
1208            {
1209              if (found)
1210                *found = i;
1211              return TRUE;
1212            }
1213        }
1214
1215      ++i;
1216    }
1217
1218  if (found)
1219    *found = real->len;
1220
1221  return FALSE;
1222}
1223
1224/**
1225 * Finds a blank (space or tab) in the string. Returns #TRUE
1226 * if found, #FALSE otherwise. If a blank is not found sets
1227 * *found to the length of the string.
1228 *
1229 * @param str the string
1230 * @param start byte index to start looking
1231 * @param found place to store the location of the first blank
1232 * @returns #TRUE if a blank was found
1233 */
1234dbus_bool_t
1235_dbus_string_find_blank (const DBusString *str,
1236                         int               start,
1237                         int              *found)
1238{
1239  int i;
1240  DBUS_CONST_STRING_PREAMBLE (str);
1241  _dbus_assert (start <= real->len);
1242
1243  i = start;
1244  while (i < real->len)
1245    {
1246      if (real->str[i] == ' ' ||
1247          real->str[i] == '\t')
1248        {
1249          if (found)
1250            *found = i;
1251          return TRUE;
1252        }
1253
1254      ++i;
1255    }
1256
1257  if (found)
1258    *found = real->len;
1259
1260  return FALSE;
1261}
1262
1263/**
1264 * Skips blanks from start, storing the first non-blank in *end
1265 *
1266 * @param str the string
1267 * @param start where to start
1268 * @param end where to store the first non-blank byte index
1269 */
1270void
1271_dbus_string_skip_blank (const DBusString *str,
1272                         int               start,
1273                         int              *end)
1274{
1275  int i;
1276  DBUS_CONST_STRING_PREAMBLE (str);
1277  _dbus_assert (start <= real->len);
1278
1279  i = start;
1280  while (i < real->len)
1281    {
1282      if (!(real->str[i] == ' ' ||
1283            real->str[i] == '\t'))
1284        break;
1285
1286      ++i;
1287    }
1288
1289  _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
1290                                    real->str[i] == '\t'));
1291
1292  if (end)
1293    *end = i;
1294}
1295
1296/**
1297 * Tests two DBusString for equality.
1298 *
1299 * @param a first string
1300 * @param b second string
1301 * @returns #TRUE if equal
1302 */
1303dbus_bool_t
1304_dbus_string_equal (const DBusString *a,
1305                    const DBusString *b)
1306{
1307  const unsigned char *ap;
1308  const unsigned char *bp;
1309  const unsigned char *a_end;
1310  const DBusRealString *real_a = (const DBusRealString*) a;
1311  const DBusRealString *real_b = (const DBusRealString*) b;
1312  DBUS_GENERIC_STRING_PREAMBLE (real_a);
1313  DBUS_GENERIC_STRING_PREAMBLE (real_b);
1314
1315  if (real_a->len != real_b->len)
1316    return FALSE;
1317
1318  ap = real_a->str;
1319  bp = real_b->str;
1320  a_end = real_a->str + real_a->len;
1321  while (ap != a_end)
1322    {
1323      if (*ap != *bp)
1324        return FALSE;
1325
1326      ++ap;
1327      ++bp;
1328    }
1329
1330  return TRUE;
1331}
1332
1333/**
1334 * Checks whether a string is equal to a C string.
1335 *
1336 * @param a the string
1337 * @param c_str the C string
1338 * @returns #TRUE if equal
1339 */
1340dbus_bool_t
1341_dbus_string_equal_c_str (const DBusString *a,
1342                          const char       *c_str)
1343{
1344  const unsigned char *ap;
1345  const unsigned char *bp;
1346  const unsigned char *a_end;
1347  const DBusRealString *real_a = (const DBusRealString*) a;
1348  DBUS_GENERIC_STRING_PREAMBLE (real_a);
1349
1350  ap = real_a->str;
1351  bp = (const unsigned char*) c_str;
1352  a_end = real_a->str + real_a->len;
1353  while (ap != a_end && *bp)
1354    {
1355      if (*ap != *bp)
1356        return FALSE;
1357
1358      ++ap;
1359      ++bp;
1360    }
1361
1362  if (*ap && *bp == '\0')
1363    return FALSE;
1364  else if (ap == a_end && *bp)
1365    return FALSE;
1366
1367  return TRUE;
1368}
1369
1370/**
1371 * Checks whether a string starts with the given C string.
1372 *
1373 * @param a the string
1374 * @param c_str the C string
1375 * @returns #TRUE if string starts with it
1376 */
1377dbus_bool_t
1378_dbus_string_starts_with_c_str (const DBusString *a,
1379                                const char       *c_str)
1380{
1381  const unsigned char *ap;
1382  const unsigned char *bp;
1383  const unsigned char *a_end;
1384  const DBusRealString *real_a = (const DBusRealString*) a;
1385  DBUS_GENERIC_STRING_PREAMBLE (real_a);
1386
1387  ap = real_a->str;
1388  bp = (const unsigned char*) c_str;
1389  a_end = real_a->str + real_a->len;
1390  while (ap != a_end && *bp)
1391    {
1392      if (*ap != *bp)
1393        return FALSE;
1394
1395      ++ap;
1396      ++bp;
1397    }
1398
1399  if (*bp == '\0')
1400    return TRUE;
1401  else
1402    return FALSE;
1403}
1404
1405/**
1406 * Returns whether a string ends with the given suffix
1407 *
1408 * @param a the string
1409 * @param c_str the C-style string
1410 * @returns #TRUE if the string ends with the suffix
1411 */
1412dbus_bool_t
1413_dbus_string_ends_with_c_str (const DBusString *a,
1414                              const char       *c_str)
1415{
1416  const unsigned char *ap;
1417  const unsigned char *bp;
1418  const unsigned char *a_end;
1419  int c_str_len;
1420  const DBusRealString *real_a = (const DBusRealString*) a;
1421  DBUS_GENERIC_STRING_PREAMBLE (real_a);
1422
1423  c_str_len = strlen (c_str);
1424  if (real_a->len < c_str_len)
1425    return FALSE;
1426
1427  ap = real_a->str + (real_a->len - c_str_len);
1428  bp = (const unsigned char*) c_str;
1429  a_end = real_a->str + real_a->len;
1430  while (ap != a_end)
1431    {
1432      if (*ap != *bp)
1433        return FALSE;
1434
1435      ++ap;
1436      ++bp;
1437    }
1438
1439  _dbus_assert (*ap == '\0');
1440  _dbus_assert (*bp == '\0');
1441
1442  return TRUE;
1443}
1444
1445static const signed char base64_table[] = {
1446  /* 0 */ 'A',
1447  /* 1 */ 'B',
1448  /* 2 */ 'C',
1449  /* 3 */ 'D',
1450  /* 4 */ 'E',
1451  /* 5 */ 'F',
1452  /* 6 */ 'G',
1453  /* 7 */ 'H',
1454  /* 8 */ 'I',
1455  /* 9 */ 'J',
1456  /* 10 */ 'K',
1457  /* 11 */ 'L',
1458  /* 12 */ 'M',
1459  /* 13 */ 'N',
1460  /* 14 */ 'O',
1461  /* 15 */ 'P',
1462  /* 16 */ 'Q',
1463  /* 17 */ 'R',
1464  /* 18 */ 'S',
1465  /* 19 */ 'T',
1466  /* 20 */ 'U',
1467  /* 21 */ 'V',
1468  /* 22 */ 'W',
1469  /* 23 */ 'X',
1470  /* 24 */ 'Y',
1471  /* 25 */ 'Z',
1472  /* 26 */ 'a',
1473  /* 27 */ 'b',
1474  /* 28 */ 'c',
1475  /* 29 */ 'd',
1476  /* 30 */ 'e',
1477  /* 31 */ 'f',
1478  /* 32 */ 'g',
1479  /* 33 */ 'h',
1480  /* 34 */ 'i',
1481  /* 35 */ 'j',
1482  /* 36 */ 'k',
1483  /* 37 */ 'l',
1484  /* 38 */ 'm',
1485  /* 39 */ 'n',
1486  /* 40 */ 'o',
1487  /* 41 */ 'p',
1488  /* 42 */ 'q',
1489  /* 43 */ 'r',
1490  /* 44 */ 's',
1491  /* 45 */ 't',
1492  /* 46 */ 'u',
1493  /* 47 */ 'v',
1494  /* 48 */ 'w',
1495  /* 49 */ 'x',
1496  /* 50 */ 'y',
1497  /* 51 */ 'z',
1498  /* 52 */ '0',
1499  /* 53 */ '1',
1500  /* 54 */ '2',
1501  /* 55 */ '3',
1502  /* 56 */ '4',
1503  /* 57 */ '5',
1504  /* 58 */ '6',
1505  /* 59 */ '7',
1506  /* 60 */ '8',
1507  /* 61 */ '9',
1508  /* 62 */ '+',
1509  /* 63 */ '/'
1510};
1511
1512/** The minimum char that's a valid char in Base64-encoded text */
1513#define UNBASE64_MIN_CHAR (43)
1514/** The maximum char that's a valid char in Base64-encoded text */
1515#define UNBASE64_MAX_CHAR (122)
1516/** Must subtract this from a char's integer value before offsetting
1517 * into unbase64_table
1518 */
1519#define UNBASE64_TABLE_OFFSET UNBASE64_MIN_CHAR
1520static const signed char unbase64_table[] = {
1521  /* 43 + */ 62,
1522  /* 44 , */ -1,
1523  /* 45 - */ -1,
1524  /* 46 . */ -1,
1525  /* 47 / */ 63,
1526  /* 48 0 */ 52,
1527  /* 49 1 */ 53,
1528  /* 50 2 */ 54,
1529  /* 51 3 */ 55,
1530  /* 52 4 */ 56,
1531  /* 53 5 */ 57,
1532  /* 54 6 */ 58,
1533  /* 55 7 */ 59,
1534  /* 56 8 */ 60,
1535  /* 57 9 */ 61,
1536  /* 58 : */ -1,
1537  /* 59 ; */ -1,
1538  /* 60 < */ -1,
1539  /* 61 = */ -1,
1540  /* 62 > */ -1,
1541  /* 63 ? */ -1,
1542  /* 64 @ */ -1,
1543  /* 65 A */ 0,
1544  /* 66 B */ 1,
1545  /* 67 C */ 2,
1546  /* 68 D */ 3,
1547  /* 69 E */ 4,
1548  /* 70 F */ 5,
1549  /* 71 G */ 6,
1550  /* 72 H */ 7,
1551  /* 73 I */ 8,
1552  /* 74 J */ 9,
1553  /* 75 K */ 10,
1554  /* 76 L */ 11,
1555  /* 77 M */ 12,
1556  /* 78 N */ 13,
1557  /* 79 O */ 14,
1558  /* 80 P */ 15,
1559  /* 81 Q */ 16,
1560  /* 82 R */ 17,
1561  /* 83 S */ 18,
1562  /* 84 T */ 19,
1563  /* 85 U */ 20,
1564  /* 86 V */ 21,
1565  /* 87 W */ 22,
1566  /* 88 X */ 23,
1567  /* 89 Y */ 24,
1568  /* 90 Z */ 25,
1569  /* 91 [ */ -1,
1570  /* 92 \ */ -1,
1571  /* 93 ] */ -1,
1572  /* 94 ^ */ -1,
1573  /* 95 _ */ -1,
1574  /* 96 ` */ -1,
1575  /* 97 a */ 26,
1576  /* 98 b */ 27,
1577  /* 99 c */ 28,
1578  /* 100 d */ 29,
1579  /* 101 e */ 30,
1580  /* 102 f */ 31,
1581  /* 103 g */ 32,
1582  /* 104 h */ 33,
1583  /* 105 i */ 34,
1584  /* 106 j */ 35,
1585  /* 107 k */ 36,
1586  /* 108 l */ 37,
1587  /* 109 m */ 38,
1588  /* 110 n */ 39,
1589  /* 111 o */ 40,
1590  /* 112 p */ 41,
1591  /* 113 q */ 42,
1592  /* 114 r */ 43,
1593  /* 115 s */ 44,
1594  /* 116 t */ 45,
1595  /* 117 u */ 46,
1596  /* 118 v */ 47,
1597  /* 119 w */ 48,
1598  /* 120 x */ 49,
1599  /* 121 y */ 50,
1600  /* 122 z */ 51
1601};
1602
1603/**
1604 * Encodes a string using Base64, as documented in RFC 2045.
1605 *
1606 * @param source the string to encode
1607 * @param start byte index to start encoding
1608 * @param dest string where encoded data should be placed
1609 * @param insert_at where to place encoded data
1610 * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
1611 */
1612dbus_bool_t
1613_dbus_string_base64_encode (const DBusString *source,
1614                            int               start,
1615                            DBusString       *dest,
1616                            int               insert_at)
1617{
1618  int source_len;
1619  int dest_len;
1620  const unsigned char *s;
1621  unsigned char *d;
1622  const unsigned char *triplet_end;
1623  const unsigned char *final_end;
1624  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1625  _dbus_assert (source != dest);
1626
1627  /* For each 24 bits (3 bytes) of input, we have 4 chars of
1628   * output.
1629   */
1630  source_len = real_source->len - start;
1631  dest_len = (source_len / 3) * 4;
1632  if (source_len % 3 != 0)
1633    dest_len += 4;
1634
1635  if (source_len == 0)
1636    return TRUE;
1637
1638  if (!open_gap (dest_len, real_dest, insert_at))
1639    return FALSE;
1640
1641  d = real_dest->str + insert_at;
1642  s = real_source->str + start;
1643  final_end = real_source->str + (start + source_len);
1644  triplet_end = final_end - (source_len % 3);
1645  _dbus_assert (triplet_end <= final_end);
1646  _dbus_assert ((final_end - triplet_end) < 3);
1647
1648#define ENCODE_64(v) (base64_table[ (unsigned char) (v) ])
1649#define SIX_BITS_MASK (0x3f)
1650  _dbus_assert (SIX_BITS_MASK < _DBUS_N_ELEMENTS (base64_table));
1651
1652  while (s != triplet_end)
1653    {
1654      unsigned int triplet;
1655
1656      triplet = s[0] | (s[1] << 8) | (s[2] << 16);
1657
1658      /* Encode each 6 bits */
1659
1660      *d++ = ENCODE_64 (triplet >> 18);
1661      *d++ = ENCODE_64 ((triplet >> 12) & SIX_BITS_MASK);
1662      *d++ = ENCODE_64 ((triplet >> 6) & SIX_BITS_MASK);
1663      *d++ = ENCODE_64 (triplet & SIX_BITS_MASK);
1664
1665      s += 3;
1666    }
1667
1668  switch (final_end - triplet_end)
1669    {
1670    case 2:
1671      {
1672        unsigned int doublet;
1673
1674        doublet = s[0] | (s[1] << 8);
1675
1676        *d++ = ENCODE_64 (doublet >> 12);
1677        *d++ = ENCODE_64 ((doublet >> 6) & SIX_BITS_MASK);
1678        *d++ = ENCODE_64 (doublet & SIX_BITS_MASK);
1679        *d++ = '=';
1680      }
1681      break;
1682    case 1:
1683      {
1684        unsigned int singlet;
1685
1686        singlet = s[0];
1687
1688        *d++ = ENCODE_64 ((singlet >> 6) & SIX_BITS_MASK);
1689        *d++ = ENCODE_64 (singlet & SIX_BITS_MASK);
1690        *d++ = '=';
1691        *d++ = '=';
1692      }
1693      break;
1694    case 0:
1695      break;
1696    }
1697
1698  _dbus_assert (d == (real_dest->str + (insert_at + dest_len)));
1699
1700  return TRUE;
1701}
1702
1703
1704/**
1705 * Decodes a string from Base64, as documented in RFC 2045.
1706 *
1707 * @param source the string to decode
1708 * @param start byte index to start decode
1709 * @param dest string where decoded data should be placed
1710 * @param insert_at where to place decoded data
1711 * @returns #TRUE if decoding was successful, #FALSE if no memory etc.
1712 */
1713dbus_bool_t
1714_dbus_string_base64_decode (const DBusString *source,
1715                            int               start,
1716                            DBusString       *dest,
1717                            int               insert_at)
1718{
1719  int source_len;
1720  const char *s;
1721  const char *end;
1722  DBusString result;
1723  unsigned int triplet = 0;
1724  int sextet_count;
1725  int pad_count;
1726  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1727  _dbus_assert (source != dest);
1728
1729  source_len = real_source->len - start;
1730  s = real_source->str + start;
1731  end = real_source->str + source_len;
1732
1733  if (source_len == 0)
1734    return TRUE;
1735
1736  if (!_dbus_string_init (&result, _DBUS_INT_MAX))
1737    return FALSE;
1738
1739  pad_count = 0;
1740  sextet_count = 0;
1741  while (s != end)
1742    {
1743      /* The idea is to just skip anything that isn't
1744       * a base64 char - it's allowed to have whitespace,
1745       * newlines, etc. in here. We also ignore trailing
1746       * base64 chars, though that's suspicious.
1747       */
1748
1749      if (*s >= UNBASE64_MIN_CHAR &&
1750          *s <= UNBASE64_MAX_CHAR)
1751        {
1752          if (*s == '=')
1753            {
1754              /* '=' is padding, doesn't represent additional data
1755               * but does increment our count.
1756               */
1757              pad_count += 1;
1758              sextet_count += 1;
1759            }
1760          else
1761            {
1762              int val;
1763
1764              val = unbase64_table[(*s) - UNBASE64_TABLE_OFFSET];
1765
1766              if (val >= 0)
1767                {
1768                  triplet <<= 6;
1769                  triplet |= (unsigned int) val;
1770                  sextet_count += 1;
1771                }
1772            }
1773
1774          if (sextet_count == 4)
1775            {
1776              /* no pad = 3 bytes, 1 pad = 2 bytes, 2 pad = 1 byte */
1777
1778              _dbus_string_append_byte (&result,
1779                                        triplet & 0xff);
1780
1781              if (pad_count < 2)
1782                _dbus_string_append_byte (&result,
1783                                          (triplet >> 8) & 0xff);
1784
1785              if (pad_count < 1)
1786                _dbus_string_append_byte (&result,
1787                                          triplet >> 16);
1788
1789              sextet_count = 0;
1790              pad_count = 0;
1791              triplet = 0;
1792            }
1793        }
1794
1795      ++s;
1796    }
1797
1798  if (!_dbus_string_move (&result, 0, dest, insert_at))
1799    {
1800      _dbus_string_free (&result);
1801      return FALSE;
1802    }
1803
1804  _dbus_string_free (&result);
1805
1806  return TRUE;
1807}
1808
1809/**
1810 * Checks that the given range of the string
1811 * is valid ASCII. If the given range is not contained
1812 * in the string, returns #FALSE.
1813 *
1814 * @param str the string
1815 * @param start first byte index to check
1816 * @param len number of bytes to check
1817 * @returns #TRUE if the byte range exists and is all valid ASCII
1818 */
1819dbus_bool_t
1820_dbus_string_validate_ascii (const DBusString *str,
1821                             int               start,
1822                             int               len)
1823{
1824  const unsigned char *s;
1825  const unsigned char *end;
1826  DBUS_CONST_STRING_PREAMBLE (str);
1827  _dbus_assert (start >= 0);
1828  _dbus_assert (len >= 0);
1829
1830  if ((start + len) > real->len)
1831    return FALSE;
1832
1833  s = real->str + start;
1834  end = s + len;
1835  while (s != end)
1836    {
1837      if (*s == '\0' ||
1838          ((*s & ~0x7f) != 0))
1839        return FALSE;
1840
1841      ++s;
1842    }
1843
1844  return TRUE;
1845}
1846
1847/** @} */
1848
1849#ifdef DBUS_BUILD_TESTS
1850#include "dbus-test.h"
1851#include <stdio.h>
1852
1853static void
1854test_max_len (DBusString *str,
1855              int         max_len)
1856{
1857  if (max_len > 0)
1858    {
1859      if (!_dbus_string_set_length (str, max_len - 1))
1860        _dbus_assert_not_reached ("setting len to one less than max should have worked");
1861    }
1862
1863  if (!_dbus_string_set_length (str, max_len))
1864    _dbus_assert_not_reached ("setting len to max len should have worked");
1865
1866  if (_dbus_string_set_length (str, max_len + 1))
1867    _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
1868
1869  if (!_dbus_string_set_length (str, 0))
1870    _dbus_assert_not_reached ("setting len to zero should have worked");
1871}
1872
1873static void
1874test_base64_roundtrip (const unsigned char *data,
1875                       int                  len)
1876{
1877  DBusString orig;
1878  DBusString encoded;
1879  DBusString decoded;
1880
1881  if (len < 0)
1882    len = strlen (data);
1883
1884  if (!_dbus_string_init (&orig, _DBUS_INT_MAX))
1885    _dbus_assert_not_reached ("could not init string");
1886
1887  if (!_dbus_string_init (&encoded, _DBUS_INT_MAX))
1888    _dbus_assert_not_reached ("could not init string");
1889
1890  if (!_dbus_string_init (&decoded, _DBUS_INT_MAX))
1891    _dbus_assert_not_reached ("could not init string");
1892
1893  if (!_dbus_string_append_len (&orig, data, len))
1894    _dbus_assert_not_reached ("couldn't append orig data");
1895
1896  if (!_dbus_string_base64_encode (&orig, 0, &encoded, 0))
1897    _dbus_assert_not_reached ("could not encode");
1898
1899  if (!_dbus_string_base64_decode (&encoded, 0, &decoded, 0))
1900    _dbus_assert_not_reached ("could not decode");
1901
1902  if (!_dbus_string_equal (&orig, &decoded))
1903    {
1904      const char *s;
1905
1906      printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
1907              _dbus_string_get_length (&orig),
1908              _dbus_string_get_length (&encoded),
1909              _dbus_string_get_length (&decoded));
1910      printf ("Original: %s\n", data);
1911      _dbus_string_get_const_data (&decoded, &s);
1912      printf ("Decoded: %s\n", s);
1913      _dbus_assert_not_reached ("original string not the same as string decoded from base64");
1914    }
1915
1916  _dbus_string_free (&orig);
1917  _dbus_string_free (&encoded);
1918  _dbus_string_free (&decoded);
1919}
1920
1921/**
1922 * @ingroup DBusStringInternals
1923 * Unit test for DBusString.
1924 *
1925 * @todo Need to write tests for _dbus_string_copy() and
1926 * _dbus_string_move() moving to/from each of start/middle/end of a
1927 * string. Also need tests for _dbus_string_move_len ()
1928 *
1929 * @returns #TRUE on success.
1930 */
1931dbus_bool_t
1932_dbus_string_test (void)
1933{
1934  DBusString str;
1935  DBusString other;
1936  int i, end;
1937  long v;
1938  double d;
1939  int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 };
1940  char *s;
1941  dbus_unichar_t ch;
1942
1943  i = 0;
1944  while (i < _DBUS_N_ELEMENTS (lens))
1945    {
1946      if (!_dbus_string_init (&str, lens[i]))
1947        _dbus_assert_not_reached ("failed to init string");
1948
1949      test_max_len (&str, lens[i]);
1950      _dbus_string_free (&str);
1951
1952      ++i;
1953    }
1954
1955  /* Test shortening and setting length */
1956  i = 0;
1957  while (i < _DBUS_N_ELEMENTS (lens))
1958    {
1959      int j;
1960
1961      if (!_dbus_string_init (&str, lens[i]))
1962        _dbus_assert_not_reached ("failed to init string");
1963
1964      if (!_dbus_string_set_length (&str, lens[i]))
1965        _dbus_assert_not_reached ("failed to set string length");
1966
1967      j = lens[i];
1968      while (j > 0)
1969        {
1970          _dbus_assert (_dbus_string_get_length (&str) == j);
1971          if (j > 0)
1972            {
1973              _dbus_string_shorten (&str, 1);
1974              _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
1975            }
1976          --j;
1977        }
1978
1979      _dbus_string_free (&str);
1980
1981      ++i;
1982    }
1983
1984  /* Test appending data */
1985  if (!_dbus_string_init (&str, _DBUS_INT_MAX))
1986    _dbus_assert_not_reached ("failed to init string");
1987
1988  i = 0;
1989  while (i < 10)
1990    {
1991      if (!_dbus_string_append (&str, "a"))
1992        _dbus_assert_not_reached ("failed to append string to string\n");
1993
1994      _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
1995
1996      if (!_dbus_string_append_byte (&str, 'b'))
1997        _dbus_assert_not_reached ("failed to append byte to string\n");
1998
1999      _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
2000
2001      ++i;
2002    }
2003
2004  _dbus_string_free (&str);
2005
2006  /* Check steal_data */
2007
2008  if (!_dbus_string_init (&str, _DBUS_INT_MAX))
2009    _dbus_assert_not_reached ("failed to init string");
2010
2011  if (!_dbus_string_append (&str, "Hello World"))
2012    _dbus_assert_not_reached ("could not append to string");
2013
2014  i = _dbus_string_get_length (&str);
2015
2016  if (!_dbus_string_steal_data (&str, &s))
2017    _dbus_assert_not_reached ("failed to steal data");
2018
2019  _dbus_assert (_dbus_string_get_length (&str) == 0);
2020  _dbus_assert (((int)strlen (s)) == i);
2021
2022  dbus_free (s);
2023
2024  /* Check move */
2025
2026  if (!_dbus_string_append (&str, "Hello World"))
2027    _dbus_assert_not_reached ("could not append to string");
2028
2029  i = _dbus_string_get_length (&str);
2030
2031  if (!_dbus_string_init (&other, _DBUS_INT_MAX))
2032    _dbus_assert_not_reached ("could not init string");
2033
2034  if (!_dbus_string_move (&str, 0, &other, 0))
2035    _dbus_assert_not_reached ("could not move");
2036
2037  _dbus_assert (_dbus_string_get_length (&str) == 0);
2038  _dbus_assert (_dbus_string_get_length (&other) == i);
2039
2040  if (!_dbus_string_append (&str, "Hello World"))
2041    _dbus_assert_not_reached ("could not append to string");
2042
2043  if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
2044    _dbus_assert_not_reached ("could not move");
2045
2046  _dbus_assert (_dbus_string_get_length (&str) == 0);
2047  _dbus_assert (_dbus_string_get_length (&other) == i * 2);
2048
2049    if (!_dbus_string_append (&str, "Hello World"))
2050    _dbus_assert_not_reached ("could not append to string");
2051
2052  if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
2053    _dbus_assert_not_reached ("could not move");
2054
2055  _dbus_assert (_dbus_string_get_length (&str) == 0);
2056  _dbus_assert (_dbus_string_get_length (&other) == i * 3);
2057
2058  _dbus_string_free (&other);
2059
2060  /* Check copy */
2061
2062  if (!_dbus_string_append (&str, "Hello World"))
2063    _dbus_assert_not_reached ("could not append to string");
2064
2065  i = _dbus_string_get_length (&str);
2066
2067  if (!_dbus_string_init (&other, _DBUS_INT_MAX))
2068    _dbus_assert_not_reached ("could not init string");
2069
2070  if (!_dbus_string_copy (&str, 0, &other, 0))
2071    _dbus_assert_not_reached ("could not copy");
2072
2073  _dbus_assert (_dbus_string_get_length (&str) == i);
2074  _dbus_assert (_dbus_string_get_length (&other) == i);
2075
2076  if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
2077    _dbus_assert_not_reached ("could not copy");
2078
2079  _dbus_assert (_dbus_string_get_length (&str) == i);
2080  _dbus_assert (_dbus_string_get_length (&other) == i * 2);
2081  _dbus_assert (_dbus_string_equal_c_str (&other,
2082                                          "Hello WorldHello World"));
2083
2084  if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
2085    _dbus_assert_not_reached ("could not copy");
2086
2087  _dbus_assert (_dbus_string_get_length (&str) == i);
2088  _dbus_assert (_dbus_string_get_length (&other) == i * 3);
2089  _dbus_assert (_dbus_string_equal_c_str (&other,
2090                                          "Hello WorldHello WorldHello World"));
2091
2092  _dbus_string_free (&str);
2093  _dbus_string_free (&other);
2094
2095  /* Check replace */
2096
2097  if (!_dbus_string_init (&str, _DBUS_INT_MAX))
2098    _dbus_assert_not_reached ("failed to init string");
2099
2100  if (!_dbus_string_append (&str, "Hello World"))
2101    _dbus_assert_not_reached ("could not append to string");
2102
2103  i = _dbus_string_get_length (&str);
2104
2105  if (!_dbus_string_init (&other, _DBUS_INT_MAX))
2106    _dbus_assert_not_reached ("could not init string");
2107
2108  if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
2109                                 &other, 0, _dbus_string_get_length (&other)))
2110    _dbus_assert_not_reached ("could not replace");
2111
2112  _dbus_assert (_dbus_string_get_length (&str) == i);
2113  _dbus_assert (_dbus_string_get_length (&other) == i);
2114  _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
2115
2116  if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
2117                                 &other, 5, 1))
2118    _dbus_assert_not_reached ("could not replace center space");
2119
2120  _dbus_assert (_dbus_string_get_length (&str) == i);
2121  _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
2122  _dbus_assert (_dbus_string_equal_c_str (&other,
2123                                          "HelloHello WorldWorld"));
2124
2125
2126  if (!_dbus_string_replace_len (&str, 1, 1,
2127                                 &other,
2128                                 _dbus_string_get_length (&other) - 1,
2129                                 1))
2130    _dbus_assert_not_reached ("could not replace end character");
2131
2132  _dbus_assert (_dbus_string_get_length (&str) == i);
2133  _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
2134  _dbus_assert (_dbus_string_equal_c_str (&other,
2135                                          "HelloHello WorldWorle"));
2136
2137  _dbus_string_free (&str);
2138  _dbus_string_free (&other);
2139
2140  /* Check append/get unichar */
2141
2142  if (!_dbus_string_init (&str, _DBUS_INT_MAX))
2143    _dbus_assert_not_reached ("failed to init string");
2144
2145  ch = 0;
2146  if (!_dbus_string_append_unichar (&str, 0xfffc))
2147    _dbus_assert_not_reached ("failed to append unichar");
2148
2149  _dbus_string_get_unichar (&str, 0, &ch, &i);
2150
2151  _dbus_assert (ch == 0xfffc);
2152  _dbus_assert (i == _dbus_string_get_length (&str));
2153
2154  _dbus_string_free (&str);
2155
2156  /* Check append/parse int/double */
2157
2158  if (!_dbus_string_init (&str, _DBUS_INT_MAX))
2159    _dbus_assert_not_reached ("failed to init string");
2160
2161  if (!_dbus_string_append_int (&str, 27))
2162    _dbus_assert_not_reached ("failed to append int");
2163
2164  i = _dbus_string_get_length (&str);
2165
2166  if (!_dbus_string_parse_int (&str, 0, &v, &end))
2167    _dbus_assert_not_reached ("failed to parse int");
2168
2169  _dbus_assert (v == 27);
2170  _dbus_assert (end == i);
2171
2172  _dbus_string_free (&str);
2173
2174  if (!_dbus_string_init (&str, _DBUS_INT_MAX))
2175    _dbus_assert_not_reached ("failed to init string");
2176
2177  if (!_dbus_string_append_double (&str, 50.3))
2178    _dbus_assert_not_reached ("failed to append float");
2179
2180  i = _dbus_string_get_length (&str);
2181
2182  if (!_dbus_string_parse_double (&str, 0, &d, &end))
2183    _dbus_assert_not_reached ("failed to parse float");
2184
2185  _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
2186  _dbus_assert (end == i);
2187
2188  _dbus_string_free (&str);
2189
2190  /* Test find */
2191  if (!_dbus_string_init (&str, _DBUS_INT_MAX))
2192    _dbus_assert_not_reached ("failed to init string");
2193
2194  if (!_dbus_string_append (&str, "Hello"))
2195    _dbus_assert_not_reached ("couldn't append to string");
2196
2197  if (!_dbus_string_find (&str, 0, "He", &i))
2198    _dbus_assert_not_reached ("didn't find 'He'");
2199  _dbus_assert (i == 0);
2200
2201  if (!_dbus_string_find (&str, 0, "ello", &i))
2202    _dbus_assert_not_reached ("didn't find 'ello'");
2203  _dbus_assert (i == 1);
2204
2205  if (!_dbus_string_find (&str, 0, "lo", &i))
2206    _dbus_assert_not_reached ("didn't find 'lo'");
2207  _dbus_assert (i == 3);
2208
2209  if (!_dbus_string_find (&str, 2, "lo", &i))
2210    _dbus_assert_not_reached ("didn't find 'lo'");
2211  _dbus_assert (i == 3);
2212
2213  if (_dbus_string_find (&str, 4, "lo", &i))
2214    _dbus_assert_not_reached ("did find 'lo'");
2215
2216  if (!_dbus_string_find (&str, 0, "l", &i))
2217    _dbus_assert_not_reached ("didn't find 'l'");
2218  _dbus_assert (i == 2);
2219
2220  if (!_dbus_string_find (&str, 0, "H", &i))
2221    _dbus_assert_not_reached ("didn't find 'H'");
2222  _dbus_assert (i == 0);
2223
2224  if (!_dbus_string_find (&str, 0, "", &i))
2225    _dbus_assert_not_reached ("didn't find ''");
2226  _dbus_assert (i == 0);
2227
2228  if (_dbus_string_find (&str, 0, "Hello!", NULL))
2229    _dbus_assert_not_reached ("Did find 'Hello!'");
2230
2231  if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
2232    _dbus_assert_not_reached ("Did find 'Oh, Hello'");
2233
2234  if (_dbus_string_find (&str, 0, "ill", NULL))
2235    _dbus_assert_not_reached ("Did find 'ill'");
2236
2237  if (_dbus_string_find (&str, 0, "q", NULL))
2238    _dbus_assert_not_reached ("Did find 'q'");
2239
2240  _dbus_string_free (&str);
2241
2242  /* Base 64 */
2243  test_base64_roundtrip ("Hello this is a string\n", -1);
2244  test_base64_roundtrip ("Hello this is a string\n1", -1);
2245  test_base64_roundtrip ("Hello this is a string\n12", -1);
2246  test_base64_roundtrip ("Hello this is a string\n123", -1);
2247  test_base64_roundtrip ("Hello this is a string\n1234", -1);
2248  test_base64_roundtrip ("Hello this is a string\n12345", -1);
2249  test_base64_roundtrip ("", 0);
2250  test_base64_roundtrip ("1", 1);
2251  test_base64_roundtrip ("12", 2);
2252  test_base64_roundtrip ("123", 3);
2253  test_base64_roundtrip ("1234", 4);
2254  test_base64_roundtrip ("12345", 5);
2255  test_base64_roundtrip ("", 1);
2256  test_base64_roundtrip ("1", 2);
2257  test_base64_roundtrip ("12", 3);
2258  test_base64_roundtrip ("123", 4);
2259  test_base64_roundtrip ("1234", 5);
2260  test_base64_roundtrip ("12345", 6);
2261  {
2262    unsigned char buf[512];
2263    i = 0;
2264    while (i < _DBUS_N_ELEMENTS (buf))
2265      {
2266        buf[i] = i;
2267        ++i;
2268      }
2269    i = 0;
2270    while (i < _DBUS_N_ELEMENTS (buf))
2271      {
2272        test_base64_roundtrip (buf, i);
2273        ++i;
2274      }
2275  }
2276
2277  return TRUE;
2278}
2279
2280#endif /* DBUS_BUILD_TESTS */
2281