Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      2 /* dbus-string.c String utility class (internal to D-Bus implementation)
      3  *
      4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
      5  * Copyright (C) 2006 Ralf Habacker <ralf.habacker (at) freenet.de>
      6  *
      7  * Licensed under the Academic Free License version 2.1
      8  *
      9  * This program is free software; you can redistribute it and/or modify
     10  * it under the terms of the GNU General Public License as published by
     11  * the Free Software Foundation; either version 2 of the License, or
     12  * (at your option) any later version.
     13  *
     14  * This program is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  * GNU General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU General Public License
     20  * along with this program; if not, write to the Free Software
     21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     22  *
     23  */
     24 
     25 #include <config.h>
     26 #include "dbus-internals.h"
     27 #include "dbus-string.h"
     28 /* we allow a system header here, for speed/convenience */
     29 #include <string.h>
     30 /* for vsnprintf */
     31 #include <stdio.h>
     32 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
     33 #include "dbus-string-private.h"
     34 #include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
     35                                  * into the marshaling-related files
     36                                  */
     37 /* for DBUS_VA_COPY */
     38 #include "dbus-sysdeps.h"
     39 
     40 /**
     41  * @defgroup DBusString DBusString class
     42  * @ingroup  DBusInternals
     43  * @brief DBusString data structure for safer string handling
     44  *
     45  * Types and functions related to DBusString. DBusString is intended
     46  * to be a string class that makes it hard to mess up security issues
     47  * (and just in general harder to write buggy code).  It should be
     48  * used (or extended and then used) rather than the libc stuff in
     49  * string.h.  The string class is a bit inconvenient at spots because
     50  * it handles out-of-memory failures and tries to be extra-robust.
     51  *
     52  * A DBusString has a maximum length set at initialization time; this
     53  * can be used to ensure that a buffer doesn't get too big.  The
     54  * _dbus_string_lengthen() method checks for overflow, and for max
     55  * length being exceeded.
     56  *
     57  * Try to avoid conversion to a plain C string, i.e. add methods on
     58  * the string object instead, only convert to C string when passing
     59  * things out to the public API. In particular, no sprintf, strcpy,
     60  * strcat, any of that should be used. The GString feature of
     61  * accepting negative numbers for "length of string" is also absent,
     62  * because it could keep us from detecting bogus huge lengths. i.e. if
     63  * we passed in some bogus huge length it would be taken to mean
     64  * "current length of string" instead of "broken crack"
     65  *
     66  * @todo #DBusString needs a lot of cleaning up; some of the
     67  * API is no longer used, and the API is pretty inconsistent.
     68  * In particular all the "append" APIs, especially those involving
     69  * alignment but probably lots of them, are no longer used by the
     70  * marshaling code which always does "inserts" now.
     71  */
     72 
     73 /**
     74  * @addtogroup DBusString
     75  * @{
     76  */
     77 
     78 static void
     79 fixup_alignment (DBusRealString *real)
     80 {
     81   unsigned char *aligned;
     82   unsigned char *real_block;
     83   unsigned int old_align_offset;
     84 
     85   /* we have to have extra space in real->allocated for the align offset and nul byte */
     86   _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
     87 
     88   old_align_offset = real->align_offset;
     89   real_block = real->str - old_align_offset;
     90 
     91   aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
     92 
     93   real->align_offset = aligned - real_block;
     94   real->str = aligned;
     95 
     96   if (old_align_offset != real->align_offset)
     97     {
     98       /* Here comes the suck */
     99       memmove (real_block + real->align_offset,
    100                real_block + old_align_offset,
    101                real->len + 1);
    102     }
    103 
    104   _dbus_assert (real->align_offset < 8);
    105   _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
    106 }
    107 
    108 static void
    109 undo_alignment (DBusRealString *real)
    110 {
    111   if (real->align_offset != 0)
    112     {
    113       memmove (real->str - real->align_offset,
    114                real->str,
    115                real->len + 1);
    116 
    117       real->str = real->str - real->align_offset;
    118       real->align_offset = 0;
    119     }
    120 }
    121 
    122 /**
    123  * Initializes a string that can be up to the given allocation size
    124  * before it has to realloc. The string starts life with zero length.
    125  * The string must eventually be freed with _dbus_string_free().
    126  *
    127  * @param str memory to hold the string
    128  * @param allocate_size amount to preallocate
    129  * @returns #TRUE on success, #FALSE if no memory
    130  */
    131 dbus_bool_t
    132 _dbus_string_init_preallocated (DBusString *str,
    133                                 int         allocate_size)
    134 {
    135   DBusRealString *real;
    136 
    137   _dbus_assert (str != NULL);
    138 
    139   _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
    140 
    141   real = (DBusRealString*) str;
    142 
    143   /* It's very important not to touch anything
    144    * other than real->str if we're going to fail,
    145    * since we also use this function to reset
    146    * an existing string, e.g. in _dbus_string_steal_data()
    147    */
    148 
    149   real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
    150   if (real->str == NULL)
    151     return FALSE;
    152 
    153   real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
    154   real->len = 0;
    155   real->str[real->len] = '\0';
    156 
    157   real->constant = FALSE;
    158   real->locked = FALSE;
    159   real->invalid = FALSE;
    160   real->align_offset = 0;
    161 
    162   fixup_alignment (real);
    163 
    164   return TRUE;
    165 }
    166 
    167 /**
    168  * Initializes a string. The string starts life with zero length.  The
    169  * string must eventually be freed with _dbus_string_free().
    170  *
    171  * @param str memory to hold the string
    172  * @returns #TRUE on success, #FALSE if no memory
    173  */
    174 dbus_bool_t
    175 _dbus_string_init (DBusString *str)
    176 {
    177   return _dbus_string_init_preallocated (str, 0);
    178 }
    179 
    180 /**
    181  * Initializes a constant string. The value parameter is not copied
    182  * (should be static), and the string may never be modified.
    183  * It is safe but not necessary to call _dbus_string_free()
    184  * on a const string. The string has a length limit of MAXINT - 8.
    185  *
    186  * @param str memory to use for the string
    187  * @param value a string to be stored in str (not copied!!!)
    188  */
    189 void
    190 _dbus_string_init_const (DBusString *str,
    191                          const char *value)
    192 {
    193   _dbus_assert (value != NULL);
    194 
    195   _dbus_string_init_const_len (str, value,
    196                                strlen (value));
    197 }
    198 
    199 /**
    200  * Initializes a constant string with a length. The value parameter is
    201  * not copied (should be static), and the string may never be
    202  * modified.  It is safe but not necessary to call _dbus_string_free()
    203  * on a const string.
    204  *
    205  * @param str memory to use for the string
    206  * @param value a string to be stored in str (not copied!!!)
    207  * @param len the length to use
    208  */
    209 void
    210 _dbus_string_init_const_len (DBusString *str,
    211                              const char *value,
    212                              int         len)
    213 {
    214   DBusRealString *real;
    215 
    216   _dbus_assert (str != NULL);
    217   _dbus_assert (len == 0 || value != NULL);
    218   _dbus_assert (len <= _DBUS_STRING_MAX_LENGTH);
    219   _dbus_assert (len >= 0);
    220 
    221   real = (DBusRealString*) str;
    222 
    223   real->str = (unsigned char*) value;
    224   real->len = len;
    225   real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
    226   real->constant = TRUE;
    227   real->locked = TRUE;
    228   real->invalid = FALSE;
    229   real->align_offset = 0;
    230 
    231   /* We don't require const strings to be 8-byte aligned as the
    232    * memory is coming from elsewhere.
    233    */
    234 }
    235 
    236 /**
    237  * Frees a string created by _dbus_string_init().
    238  *
    239  * @param str memory where the string is stored.
    240  */
    241 void
    242 _dbus_string_free (DBusString *str)
    243 {
    244   DBusRealString *real = (DBusRealString*) str;
    245   DBUS_GENERIC_STRING_PREAMBLE (real);
    246 
    247   if (real->constant)
    248     return;
    249   dbus_free (real->str - real->align_offset);
    250 
    251   real->invalid = TRUE;
    252 }
    253 
    254 static dbus_bool_t
    255 compact (DBusRealString *real,
    256          int             max_waste)
    257 {
    258   unsigned char *new_str;
    259   int new_allocated;
    260   int waste;
    261 
    262   waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
    263 
    264   if (waste <= max_waste)
    265     return TRUE;
    266 
    267   new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
    268 
    269   new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
    270   if (_DBUS_UNLIKELY (new_str == NULL))
    271     return FALSE;
    272 
    273   real->str = new_str + real->align_offset;
    274   real->allocated = new_allocated;
    275   fixup_alignment (real);
    276 
    277   return TRUE;
    278 }
    279 
    280 #ifdef DBUS_BUILD_TESTS
    281 /* Not using this feature at the moment,
    282  * so marked DBUS_BUILD_TESTS-only
    283  */
    284 /**
    285  * Locks a string such that any attempts to change the string will
    286  * result in aborting the program. Also, if the string is wasting a
    287  * lot of memory (allocation is sufficiently larger than what the
    288  * string is really using), _dbus_string_lock() will realloc the
    289  * string's data to "compact" it.
    290  *
    291  * @param str the string to lock.
    292  */
    293 void
    294 _dbus_string_lock (DBusString *str)
    295 {
    296   DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
    297 
    298   real->locked = TRUE;
    299 
    300   /* Try to realloc to avoid excess memory usage, since
    301    * we know we won't change the string further
    302    */
    303 #define MAX_WASTE 48
    304   compact (real, MAX_WASTE);
    305 }
    306 #endif /* DBUS_BUILD_TESTS */
    307 
    308 static dbus_bool_t
    309 reallocate_for_length (DBusRealString *real,
    310                        int             new_length)
    311 {
    312   int new_allocated;
    313   unsigned char *new_str;
    314 
    315   /* at least double our old allocation to avoid O(n), avoiding
    316    * overflow
    317    */
    318   if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
    319     new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
    320   else
    321     new_allocated = real->allocated * 2;
    322 
    323   /* if you change the code just above here, run the tests without
    324    * the following assert-only hack before you commit
    325    */
    326   /* This is keyed off asserts in addition to tests so when you
    327    * disable asserts to profile, you don't get this destroyer
    328    * of profiles.
    329    */
    330 #ifdef DBUS_DISABLE_ASSERT
    331 #else
    332 #ifdef DBUS_BUILD_TESTS
    333   new_allocated = 0; /* ensure a realloc every time so that we go
    334                       * through all malloc failure codepaths
    335                       */
    336 #endif /* DBUS_BUILD_TESTS */
    337 #endif /* !DBUS_DISABLE_ASSERT */
    338 
    339   /* But be sure we always alloc at least space for the new length */
    340   new_allocated = MAX (new_allocated,
    341                        new_length + _DBUS_STRING_ALLOCATION_PADDING);
    342 
    343   _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
    344   new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
    345   if (_DBUS_UNLIKELY (new_str == NULL))
    346     return FALSE;
    347 
    348   real->str = new_str + real->align_offset;
    349   real->allocated = new_allocated;
    350   fixup_alignment (real);
    351 
    352   return TRUE;
    353 }
    354 
    355 /**
    356  * Compacts the string to avoid wasted memory.  Wasted memory is
    357  * memory that is allocated but not actually required to store the
    358  * current length of the string.  The compact is only done if more
    359  * than the given amount of memory is being wasted (otherwise the
    360  * waste is ignored and the call does nothing).
    361  *
    362  * @param str the string
    363  * @param max_waste the maximum amount of waste to ignore
    364  * @returns #FALSE if the compact failed due to realloc failure
    365  */
    366 dbus_bool_t
    367 _dbus_string_compact (DBusString *str,
    368                       int         max_waste)
    369 {
    370   DBUS_STRING_PREAMBLE (str);
    371 
    372   return compact (real, max_waste);
    373 }
    374 
    375 static dbus_bool_t
    376 set_length (DBusRealString *real,
    377             int             new_length)
    378 {
    379   /* Note, we are setting the length not including nul termination */
    380 
    381   /* exceeding max length is the same as failure to allocate memory */
    382   if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
    383     return FALSE;
    384   else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
    385            _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
    386     return FALSE;
    387   else
    388     {
    389       real->len = new_length;
    390       real->str[new_length] = '\0';
    391       return TRUE;
    392     }
    393 }
    394 
    395 static dbus_bool_t
    396 open_gap (int             len,
    397           DBusRealString *dest,
    398           int             insert_at)
    399 {
    400   if (len == 0)
    401     return TRUE;
    402 
    403   if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
    404     return FALSE; /* detected overflow of dest->len + len below */
    405 
    406   if (!set_length (dest, dest->len + len))
    407     return FALSE;
    408 
    409   memmove (dest->str + insert_at + len,
    410            dest->str + insert_at,
    411            dest->len - len - insert_at);
    412 
    413   return TRUE;
    414 }
    415 
    416 #ifndef _dbus_string_get_data
    417 /**
    418  * Gets the raw character buffer from the string.  The returned buffer
    419  * will be nul-terminated, but note that strings may contain binary
    420  * data so there may be extra nul characters prior to the termination.
    421  * This function should be little-used, extend DBusString or add
    422  * stuff to dbus-sysdeps.c instead. It's an error to use this
    423  * function on a const string.
    424  *
    425  * @param str the string
    426  * @returns the data
    427  */
    428 char*
    429 _dbus_string_get_data (DBusString *str)
    430 {
    431   DBUS_STRING_PREAMBLE (str);
    432 
    433   return (char*) real->str;
    434 }
    435 #endif /* _dbus_string_get_data */
    436 
    437 /* only do the function if we don't have the macro */
    438 #ifndef _dbus_string_get_const_data
    439 /**
    440  * Gets the raw character buffer from a const string.
    441  *
    442  * @param str the string
    443  * @returns the string data
    444  */
    445 const char*
    446 _dbus_string_get_const_data (const DBusString  *str)
    447 {
    448   DBUS_CONST_STRING_PREAMBLE (str);
    449 
    450   return (const char*) real->str;
    451 }
    452 #endif /* _dbus_string_get_const_data */
    453 
    454 /**
    455  * Gets a sub-portion of the raw character buffer from the
    456  * string. The "len" field is required simply for error
    457  * checking, to be sure you don't try to use more
    458  * string than exists. The nul termination of the
    459  * returned buffer remains at the end of the entire
    460  * string, not at start + len.
    461  *
    462  * @param str the string
    463  * @param start byte offset to return
    464  * @param len length of segment to return
    465  * @returns the string data
    466  */
    467 char*
    468 _dbus_string_get_data_len (DBusString *str,
    469                            int         start,
    470                            int         len)
    471 {
    472   DBUS_STRING_PREAMBLE (str);
    473   _dbus_assert (start >= 0);
    474   _dbus_assert (len >= 0);
    475   _dbus_assert (start <= real->len);
    476   _dbus_assert (len <= real->len - start);
    477 
    478   return (char*) real->str + start;
    479 }
    480 
    481 /* only do the function if we don't have the macro */
    482 #ifndef _dbus_string_get_const_data_len
    483 /**
    484  * const version of _dbus_string_get_data_len().
    485  *
    486  * @param str the string
    487  * @param start byte offset to return
    488  * @param len length of segment to return
    489  * @returns the string data
    490  */
    491 const char*
    492 _dbus_string_get_const_data_len (const DBusString  *str,
    493                                  int                start,
    494                                  int                len)
    495 {
    496   DBUS_CONST_STRING_PREAMBLE (str);
    497   _dbus_assert (start >= 0);
    498   _dbus_assert (len >= 0);
    499   _dbus_assert (start <= real->len);
    500   _dbus_assert (len <= real->len - start);
    501 
    502   return (const char*) real->str + start;
    503 }
    504 #endif /* _dbus_string_get_const_data_len */
    505 
    506 /* only do the function if we don't have the macro */
    507 #ifndef _dbus_string_set_byte
    508 /**
    509  * Sets the value of the byte at the given position.
    510  *
    511  * @param str the string
    512  * @param i the position
    513  * @param byte the new value
    514  */
    515 void
    516 _dbus_string_set_byte (DBusString    *str,
    517                        int            i,
    518                        unsigned char  byte)
    519 {
    520   DBUS_STRING_PREAMBLE (str);
    521   _dbus_assert (i < real->len);
    522   _dbus_assert (i >= 0);
    523 
    524   real->str[i] = byte;
    525 }
    526 #endif /* _dbus_string_set_byte */
    527 
    528 /* only have the function if we didn't create a macro */
    529 #ifndef _dbus_string_get_byte
    530 /**
    531  * Gets the byte at the given position. It is
    532  * allowed to ask for the nul byte at the end of
    533  * the string.
    534  *
    535  * @param str the string
    536  * @param start the position
    537  * @returns the byte at that position
    538  */
    539 unsigned char
    540 _dbus_string_get_byte (const DBusString  *str,
    541                        int                start)
    542 {
    543   DBUS_CONST_STRING_PREAMBLE (str);
    544   _dbus_assert (start <= real->len);
    545   _dbus_assert (start >= 0);
    546 
    547   return real->str[start];
    548 }
    549 #endif /* _dbus_string_get_byte */
    550 
    551 /**
    552  * Inserts a number of bytes of a given value at the
    553  * given position.
    554  *
    555  * @param str the string
    556  * @param i the position
    557  * @param n_bytes number of bytes
    558  * @param byte the value to insert
    559  * @returns #TRUE on success
    560  */
    561 dbus_bool_t
    562 _dbus_string_insert_bytes (DBusString   *str,
    563 			   int           i,
    564 			   int           n_bytes,
    565 			   unsigned char byte)
    566 {
    567   DBUS_STRING_PREAMBLE (str);
    568   _dbus_assert (i <= real->len);
    569   _dbus_assert (i >= 0);
    570   _dbus_assert (n_bytes >= 0);
    571 
    572   if (n_bytes == 0)
    573     return TRUE;
    574 
    575   if (!open_gap (n_bytes, real, i))
    576     return FALSE;
    577 
    578   memset (real->str + i, byte, n_bytes);
    579 
    580   return TRUE;
    581 }
    582 
    583 /**
    584  * Inserts a single byte at the given position.
    585  *
    586  * @param str the string
    587  * @param i the position
    588  * @param byte the value to insert
    589  * @returns #TRUE on success
    590  */
    591 dbus_bool_t
    592 _dbus_string_insert_byte (DBusString   *str,
    593 			   int           i,
    594 			   unsigned char byte)
    595 {
    596   DBUS_STRING_PREAMBLE (str);
    597   _dbus_assert (i <= real->len);
    598   _dbus_assert (i >= 0);
    599 
    600   if (!open_gap (1, real, i))
    601     return FALSE;
    602 
    603   real->str[i] = byte;
    604 
    605   return TRUE;
    606 }
    607 
    608 /**
    609  * Like _dbus_string_get_data(), but removes the
    610  * gotten data from the original string. The caller
    611  * must free the data returned. This function may
    612  * fail due to lack of memory, and return #FALSE.
    613  *
    614  * @param str the string
    615  * @param data_return location to return the buffer
    616  * @returns #TRUE on success
    617  */
    618 dbus_bool_t
    619 _dbus_string_steal_data (DBusString        *str,
    620                          char             **data_return)
    621 {
    622   DBUS_STRING_PREAMBLE (str);
    623   _dbus_assert (data_return != NULL);
    624 
    625   undo_alignment (real);
    626 
    627   *data_return = (char*) real->str;
    628 
    629   /* reset the string */
    630   if (!_dbus_string_init (str))
    631     {
    632       /* hrm, put it back then */
    633       real->str = (unsigned char*) *data_return;
    634       *data_return = NULL;
    635       fixup_alignment (real);
    636       return FALSE;
    637     }
    638 
    639   return TRUE;
    640 }
    641 
    642 /**
    643  * Copies the data from the string into a char*
    644  *
    645  * @param str the string
    646  * @param data_return place to return the data
    647  * @returns #TRUE on success, #FALSE on no memory
    648  */
    649 dbus_bool_t
    650 _dbus_string_copy_data (const DBusString  *str,
    651                         char             **data_return)
    652 {
    653   DBUS_CONST_STRING_PREAMBLE (str);
    654   _dbus_assert (data_return != NULL);
    655 
    656   *data_return = dbus_malloc (real->len + 1);
    657   if (*data_return == NULL)
    658     return FALSE;
    659 
    660   memcpy (*data_return, real->str, real->len + 1);
    661 
    662   return TRUE;
    663 }
    664 
    665 /**
    666  * Copies the contents of a DBusString into a different buffer. It is
    667  * a bug if avail_len is too short to hold the string contents. nul
    668  * termination is not copied, just the supplied bytes.
    669  *
    670  * @param str a string
    671  * @param buffer a C buffer to copy data to
    672  * @param avail_len maximum length of C buffer
    673  */
    674 void
    675 _dbus_string_copy_to_buffer (const DBusString  *str,
    676 			     char              *buffer,
    677 			     int                avail_len)
    678 {
    679   DBUS_CONST_STRING_PREAMBLE (str);
    680 
    681   _dbus_assert (avail_len >= 0);
    682   _dbus_assert (avail_len >= real->len);
    683 
    684   memcpy (buffer, real->str, real->len);
    685 }
    686 
    687 /**
    688  * Copies the contents of a DBusString into a different buffer. It is
    689  * a bug if avail_len is too short to hold the string contents plus a
    690  * nul byte.
    691  *
    692  * @param str a string
    693  * @param buffer a C buffer to copy data to
    694  * @param avail_len maximum length of C buffer
    695  */
    696 void
    697 _dbus_string_copy_to_buffer_with_nul (const DBusString  *str,
    698                                       char              *buffer,
    699                                       int                avail_len)
    700 {
    701   DBUS_CONST_STRING_PREAMBLE (str);
    702 
    703   _dbus_assert (avail_len >= 0);
    704   _dbus_assert (avail_len > real->len);
    705 
    706   memcpy (buffer, real->str, real->len+1);
    707 }
    708 
    709 /* Only have the function if we don't have the macro */
    710 #ifndef _dbus_string_get_length
    711 /**
    712  * Gets the length of a string (not including nul termination).
    713  *
    714  * @returns the length.
    715  */
    716 int
    717 _dbus_string_get_length (const DBusString  *str)
    718 {
    719   DBUS_CONST_STRING_PREAMBLE (str);
    720 
    721   return real->len;
    722 }
    723 #endif /* !_dbus_string_get_length */
    724 
    725 /**
    726  * Makes a string longer by the given number of bytes.  Checks whether
    727  * adding additional_length to the current length would overflow an
    728  * integer, and checks for exceeding a string's max length.
    729  * The new bytes are not initialized, other than nul-terminating
    730  * the end of the string. The uninitialized bytes may contain
    731  * nul bytes or other junk.
    732  *
    733  * @param str a string
    734  * @param additional_length length to add to the string.
    735  * @returns #TRUE on success.
    736  */
    737 dbus_bool_t
    738 _dbus_string_lengthen (DBusString *str,
    739                        int         additional_length)
    740 {
    741   DBUS_STRING_PREAMBLE (str);
    742   _dbus_assert (additional_length >= 0);
    743 
    744   if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
    745     return FALSE; /* would overflow */
    746 
    747   return set_length (real,
    748                      real->len + additional_length);
    749 }
    750 
    751 /**
    752  * Makes a string shorter by the given number of bytes.
    753  *
    754  * @param str a string
    755  * @param length_to_remove length to remove from the string.
    756  */
    757 void
    758 _dbus_string_shorten (DBusString *str,
    759                       int         length_to_remove)
    760 {
    761   DBUS_STRING_PREAMBLE (str);
    762   _dbus_assert (length_to_remove >= 0);
    763   _dbus_assert (length_to_remove <= real->len);
    764 
    765   set_length (real,
    766               real->len - length_to_remove);
    767 }
    768 
    769 /**
    770  * Sets the length of a string. Can be used to truncate or lengthen
    771  * the string. If the string is lengthened, the function may fail and
    772  * return #FALSE. Newly-added bytes are not initialized, as with
    773  * _dbus_string_lengthen().
    774  *
    775  * @param str a string
    776  * @param length new length of the string.
    777  * @returns #FALSE on failure.
    778  */
    779 dbus_bool_t
    780 _dbus_string_set_length (DBusString *str,
    781                          int         length)
    782 {
    783   DBUS_STRING_PREAMBLE (str);
    784   _dbus_assert (length >= 0);
    785 
    786   return set_length (real, length);
    787 }
    788 
    789 static dbus_bool_t
    790 align_insert_point_then_open_gap (DBusString *str,
    791                                   int        *insert_at_p,
    792                                   int         alignment,
    793                                   int         gap_size)
    794 {
    795   unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
    796   unsigned long gap_pos;
    797   int insert_at;
    798   int delta;
    799   DBUS_STRING_PREAMBLE (str);
    800   _dbus_assert (alignment >= 1);
    801   _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
    802 
    803   insert_at = *insert_at_p;
    804 
    805   _dbus_assert (insert_at <= real->len);
    806 
    807   gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
    808   new_len = real->len + (gap_pos - insert_at) + gap_size;
    809 
    810   if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
    811     return FALSE;
    812 
    813   delta = new_len - real->len;
    814   _dbus_assert (delta >= 0);
    815 
    816   if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
    817     {
    818       _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
    819       return TRUE;
    820     }
    821 
    822   if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
    823                                  real, insert_at)))
    824     return FALSE;
    825 
    826   /* nul the padding if we had to add any padding */
    827   if (gap_size < delta)
    828     {
    829       memset (&real->str[insert_at], '\0',
    830               gap_pos - insert_at);
    831     }
    832 
    833   *insert_at_p = gap_pos;
    834 
    835   return TRUE;
    836 }
    837 
    838 static dbus_bool_t
    839 align_length_then_lengthen (DBusString *str,
    840                             int         alignment,
    841                             int         then_lengthen_by)
    842 {
    843   int insert_at;
    844 
    845   insert_at = _dbus_string_get_length (str);
    846 
    847   return align_insert_point_then_open_gap (str,
    848                                            &insert_at,
    849                                            alignment, then_lengthen_by);
    850 }
    851 
    852 /**
    853  * Align the length of a string to a specific alignment (typically 4 or 8)
    854  * by appending nul bytes to the string.
    855  *
    856  * @param str a string
    857  * @param alignment the alignment
    858  * @returns #FALSE if no memory
    859  */
    860 dbus_bool_t
    861 _dbus_string_align_length (DBusString *str,
    862                            int         alignment)
    863 {
    864   return align_length_then_lengthen (str, alignment, 0);
    865 }
    866 
    867 /**
    868  * Preallocate extra_bytes such that a future lengthening of the
    869  * string by extra_bytes is guaranteed to succeed without an out of
    870  * memory error.
    871  *
    872  * @param str a string
    873  * @param extra_bytes bytes to alloc
    874  * @returns #FALSE if no memory
    875  */
    876 dbus_bool_t
    877 _dbus_string_alloc_space (DBusString        *str,
    878                           int                extra_bytes)
    879 {
    880   if (!_dbus_string_lengthen (str, extra_bytes))
    881     return FALSE;
    882   _dbus_string_shorten (str, extra_bytes);
    883 
    884   return TRUE;
    885 }
    886 
    887 static dbus_bool_t
    888 append (DBusRealString *real,
    889         const char     *buffer,
    890         int             buffer_len)
    891 {
    892   if (buffer_len == 0)
    893     return TRUE;
    894 
    895   if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
    896     return FALSE;
    897 
    898   memcpy (real->str + (real->len - buffer_len),
    899           buffer,
    900           buffer_len);
    901 
    902   return TRUE;
    903 }
    904 
    905 /**
    906  * Appends a nul-terminated C-style string to a DBusString.
    907  *
    908  * @param str the DBusString
    909  * @param buffer the nul-terminated characters to append
    910  * @returns #FALSE if not enough memory.
    911  */
    912 dbus_bool_t
    913 _dbus_string_append (DBusString *str,
    914                      const char *buffer)
    915 {
    916   unsigned long buffer_len;
    917 
    918   DBUS_STRING_PREAMBLE (str);
    919   _dbus_assert (buffer != NULL);
    920 
    921   buffer_len = strlen (buffer);
    922   if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
    923     return FALSE;
    924 
    925   return append (real, buffer, buffer_len);
    926 }
    927 
    928 /** assign 2 bytes from one string to another */
    929 #define ASSIGN_2_OCTETS(p, octets) \
    930   *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
    931 
    932 /** assign 4 bytes from one string to another */
    933 #define ASSIGN_4_OCTETS(p, octets) \
    934   *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
    935 
    936 #ifdef DBUS_HAVE_INT64
    937 /** assign 8 bytes from one string to another */
    938 #define ASSIGN_8_OCTETS(p, octets) \
    939   *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
    940 #else
    941 /** assign 8 bytes from one string to another */
    942 #define ASSIGN_8_OCTETS(p, octets)              \
    943 do {                                            \
    944   unsigned char *b;                             \
    945                                                 \
    946   b = p;                                        \
    947                                                 \
    948   *b++ = octets[0];                             \
    949   *b++ = octets[1];                             \
    950   *b++ = octets[2];                             \
    951   *b++ = octets[3];                             \
    952   *b++ = octets[4];                             \
    953   *b++ = octets[5];                             \
    954   *b++ = octets[6];                             \
    955   *b++ = octets[7];                             \
    956   _dbus_assert (b == p + 8);                    \
    957 } while (0)
    958 #endif /* DBUS_HAVE_INT64 */
    959 
    960 /**
    961  * Inserts 2 bytes aligned on a 2 byte boundary
    962  * with any alignment padding initialized to 0.
    963  *
    964  * @param str the DBusString
    965  * @param insert_at where to insert
    966  * @param octets 2 bytes to insert
    967  * @returns #FALSE if not enough memory.
    968  */
    969 dbus_bool_t
    970 _dbus_string_insert_2_aligned (DBusString         *str,
    971                                int                 insert_at,
    972                                const unsigned char octets[4])
    973 {
    974   DBUS_STRING_PREAMBLE (str);
    975 
    976   if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
    977     return FALSE;
    978 
    979   ASSIGN_2_OCTETS (real->str + insert_at, octets);
    980 
    981   return TRUE;
    982 }
    983 
    984 /**
    985  * Inserts 4 bytes aligned on a 4 byte boundary
    986  * with any alignment padding initialized to 0.
    987  *
    988  * @param str the DBusString
    989  * @param insert_at where to insert
    990  * @param octets 4 bytes to insert
    991  * @returns #FALSE if not enough memory.
    992  */
    993 dbus_bool_t
    994 _dbus_string_insert_4_aligned (DBusString         *str,
    995                                int                 insert_at,
    996                                const unsigned char octets[4])
    997 {
    998   DBUS_STRING_PREAMBLE (str);
    999 
   1000   if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
   1001     return FALSE;
   1002 
   1003   ASSIGN_4_OCTETS (real->str + insert_at, octets);
   1004 
   1005   return TRUE;
   1006 }
   1007 
   1008 /**
   1009  * Inserts 8 bytes aligned on an 8 byte boundary
   1010  * with any alignment padding initialized to 0.
   1011  *
   1012  * @param str the DBusString
   1013  * @param insert_at where to insert
   1014  * @param octets 8 bytes to insert
   1015  * @returns #FALSE if not enough memory.
   1016  */
   1017 dbus_bool_t
   1018 _dbus_string_insert_8_aligned (DBusString         *str,
   1019                                int                 insert_at,
   1020                                const unsigned char octets[8])
   1021 {
   1022   DBUS_STRING_PREAMBLE (str);
   1023 
   1024   if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
   1025     return FALSE;
   1026 
   1027   _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
   1028 
   1029   ASSIGN_8_OCTETS (real->str + insert_at, octets);
   1030 
   1031   return TRUE;
   1032 }
   1033 
   1034 
   1035 /**
   1036  * Inserts padding at *insert_at such to align it to the given
   1037  * boundary. Initializes the padding to nul bytes. Sets *insert_at
   1038  * to the aligned position.
   1039  *
   1040  * @param str the DBusString
   1041  * @param insert_at location to be aligned
   1042  * @param alignment alignment boundary (1, 2, 4, or 8)
   1043  * @returns #FALSE if not enough memory.
   1044  */
   1045 dbus_bool_t
   1046 _dbus_string_insert_alignment (DBusString        *str,
   1047                                int               *insert_at,
   1048                                int                alignment)
   1049 {
   1050   DBUS_STRING_PREAMBLE (str);
   1051 
   1052   if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
   1053     return FALSE;
   1054 
   1055   _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
   1056 
   1057   return TRUE;
   1058 }
   1059 
   1060 /**
   1061  * Appends a printf-style formatted string
   1062  * to the #DBusString.
   1063  *
   1064  * @param str the string
   1065  * @param format printf format
   1066  * @param args variable argument list
   1067  * @returns #FALSE if no memory
   1068  */
   1069 dbus_bool_t
   1070 _dbus_string_append_printf_valist  (DBusString        *str,
   1071                                     const char        *format,
   1072                                     va_list            args)
   1073 {
   1074   int len;
   1075   va_list args_copy;
   1076 
   1077   DBUS_STRING_PREAMBLE (str);
   1078 
   1079   DBUS_VA_COPY (args_copy, args);
   1080 
   1081   /* Measure the message length without terminating nul */
   1082   len = _dbus_printf_string_upper_bound (format, args);
   1083 
   1084   if (len < 0)
   1085     return FALSE;
   1086 
   1087   if (!_dbus_string_lengthen (str, len))
   1088     {
   1089       /* don't leak the copy */
   1090       va_end (args_copy);
   1091       return FALSE;
   1092     }
   1093 
   1094   vsprintf ((char*) (real->str + (real->len - len)),
   1095             format, args_copy);
   1096 
   1097   va_end (args_copy);
   1098 
   1099   return TRUE;
   1100 }
   1101 
   1102 /**
   1103  * Appends a printf-style formatted string
   1104  * to the #DBusString.
   1105  *
   1106  * @param str the string
   1107  * @param format printf format
   1108  * @returns #FALSE if no memory
   1109  */
   1110 dbus_bool_t
   1111 _dbus_string_append_printf (DBusString        *str,
   1112                             const char        *format,
   1113                             ...)
   1114 {
   1115   va_list args;
   1116   dbus_bool_t retval;
   1117 
   1118   va_start (args, format);
   1119   retval = _dbus_string_append_printf_valist (str, format, args);
   1120   va_end (args);
   1121 
   1122   return retval;
   1123 }
   1124 
   1125 /**
   1126  * Appends block of bytes with the given length to a DBusString.
   1127  *
   1128  * @param str the DBusString
   1129  * @param buffer the bytes to append
   1130  * @param len the number of bytes to append
   1131  * @returns #FALSE if not enough memory.
   1132  */
   1133 dbus_bool_t
   1134 _dbus_string_append_len (DBusString *str,
   1135                          const char *buffer,
   1136                          int         len)
   1137 {
   1138   DBUS_STRING_PREAMBLE (str);
   1139   _dbus_assert (buffer != NULL);
   1140   _dbus_assert (len >= 0);
   1141 
   1142   return append (real, buffer, len);
   1143 }
   1144 
   1145 /**
   1146  * Appends a single byte to the string, returning #FALSE
   1147  * if not enough memory.
   1148  *
   1149  * @param str the string
   1150  * @param byte the byte to append
   1151  * @returns #TRUE on success
   1152  */
   1153 dbus_bool_t
   1154 _dbus_string_append_byte (DBusString    *str,
   1155                           unsigned char  byte)
   1156 {
   1157   DBUS_STRING_PREAMBLE (str);
   1158 
   1159   if (!set_length (real, real->len + 1))
   1160     return FALSE;
   1161 
   1162   real->str[real->len-1] = byte;
   1163 
   1164   return TRUE;
   1165 }
   1166 
   1167 static void
   1168 delete (DBusRealString *real,
   1169         int             start,
   1170         int             len)
   1171 {
   1172   if (len == 0)
   1173     return;
   1174 
   1175   memmove (real->str + start, real->str + start + len, real->len - (start + len));
   1176   real->len -= len;
   1177   real->str[real->len] = '\0';
   1178 }
   1179 
   1180 /**
   1181  * Deletes a segment of a DBusString with length len starting at
   1182  * start. (Hint: to clear an entire string, setting length to 0
   1183  * with _dbus_string_set_length() is easier.)
   1184  *
   1185  * @param str the DBusString
   1186  * @param start where to start deleting
   1187  * @param len the number of bytes to delete
   1188  */
   1189 void
   1190 _dbus_string_delete (DBusString       *str,
   1191                      int               start,
   1192                      int               len)
   1193 {
   1194   DBUS_STRING_PREAMBLE (str);
   1195   _dbus_assert (start >= 0);
   1196   _dbus_assert (len >= 0);
   1197   _dbus_assert (start <= real->len);
   1198   _dbus_assert (len <= real->len - start);
   1199 
   1200   delete (real, start, len);
   1201 }
   1202 
   1203 static dbus_bool_t
   1204 copy (DBusRealString *source,
   1205       int             start,
   1206       int             len,
   1207       DBusRealString *dest,
   1208       int             insert_at)
   1209 {
   1210   if (len == 0)
   1211     return TRUE;
   1212 
   1213   if (!open_gap (len, dest, insert_at))
   1214     return FALSE;
   1215 
   1216   memmove (dest->str + insert_at,
   1217            source->str + start,
   1218            len);
   1219 
   1220   return TRUE;
   1221 }
   1222 
   1223 /**
   1224  * Checks assertions for two strings we're copying a segment between,
   1225  * and declares real_source/real_dest variables.
   1226  *
   1227  * @param source the source string
   1228  * @param start the starting offset
   1229  * @param dest the dest string
   1230  * @param insert_at where the copied segment is inserted
   1231  */
   1232 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)       \
   1233   DBusRealString *real_source = (DBusRealString*) source;               \
   1234   DBusRealString *real_dest = (DBusRealString*) dest;                   \
   1235   _dbus_assert ((source) != (dest));                                    \
   1236   DBUS_GENERIC_STRING_PREAMBLE (real_source);                           \
   1237   DBUS_GENERIC_STRING_PREAMBLE (real_dest);                             \
   1238   _dbus_assert (!real_dest->constant);                                  \
   1239   _dbus_assert (!real_dest->locked);                                    \
   1240   _dbus_assert ((start) >= 0);                                          \
   1241   _dbus_assert ((start) <= real_source->len);                           \
   1242   _dbus_assert ((insert_at) >= 0);                                      \
   1243   _dbus_assert ((insert_at) <= real_dest->len)
   1244 
   1245 /**
   1246  * Moves the end of one string into another string. Both strings
   1247  * must be initialized, valid strings.
   1248  *
   1249  * @param source the source string
   1250  * @param start where to chop off the source string
   1251  * @param dest the destination string
   1252  * @param insert_at where to move the chopped-off part of source string
   1253  * @returns #FALSE if not enough memory
   1254  */
   1255 dbus_bool_t
   1256 _dbus_string_move (DBusString       *source,
   1257                    int               start,
   1258                    DBusString       *dest,
   1259                    int               insert_at)
   1260 {
   1261   DBusRealString *real_source = (DBusRealString*) source;
   1262   _dbus_assert (start <= real_source->len);
   1263 
   1264   return _dbus_string_move_len (source, start,
   1265                                 real_source->len - start,
   1266                                 dest, insert_at);
   1267 }
   1268 
   1269 /**
   1270  * Like _dbus_string_move(), but does not delete the section
   1271  * of the source string that's copied to the dest string.
   1272  *
   1273  * @param source the source string
   1274  * @param start where to start copying the source string
   1275  * @param dest the destination string
   1276  * @param insert_at where to place the copied part of source string
   1277  * @returns #FALSE if not enough memory
   1278  */
   1279 dbus_bool_t
   1280 _dbus_string_copy (const DBusString *source,
   1281                    int               start,
   1282                    DBusString       *dest,
   1283                    int               insert_at)
   1284 {
   1285   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
   1286 
   1287   return copy (real_source, start,
   1288                real_source->len - start,
   1289                real_dest,
   1290                insert_at);
   1291 }
   1292 
   1293 /**
   1294  * Like _dbus_string_move(), but can move a segment from
   1295  * the middle of the source string.
   1296  *
   1297  * @param source the source string
   1298  * @param start first byte of source string to move
   1299  * @param len length of segment to move
   1300  * @param dest the destination string
   1301  * @param insert_at where to move the bytes from the source string
   1302  * @returns #FALSE if not enough memory
   1303  */
   1304 dbus_bool_t
   1305 _dbus_string_move_len (DBusString       *source,
   1306                        int               start,
   1307                        int               len,
   1308                        DBusString       *dest,
   1309                        int               insert_at)
   1310 
   1311 {
   1312   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
   1313   _dbus_assert (len >= 0);
   1314   _dbus_assert ((start + len) <= real_source->len);
   1315 
   1316 
   1317   if (len == 0)
   1318     {
   1319       return TRUE;
   1320     }
   1321   else if (start == 0 &&
   1322            len == real_source->len &&
   1323            real_dest->len == 0)
   1324     {
   1325       /* Short-circuit moving an entire existing string to an empty string
   1326        * by just swapping the buffers.
   1327        */
   1328       /* we assume ->constant doesn't matter as you can't have
   1329        * a constant string involved in a move.
   1330        */
   1331 #define ASSIGN_DATA(a, b) do {                  \
   1332         (a)->str = (b)->str;                    \
   1333         (a)->len = (b)->len;                    \
   1334         (a)->allocated = (b)->allocated;        \
   1335         (a)->align_offset = (b)->align_offset;  \
   1336       } while (0)
   1337 
   1338       DBusRealString tmp;
   1339 
   1340       ASSIGN_DATA (&tmp, real_source);
   1341       ASSIGN_DATA (real_source, real_dest);
   1342       ASSIGN_DATA (real_dest, &tmp);
   1343 
   1344       return TRUE;
   1345     }
   1346   else
   1347     {
   1348       if (!copy (real_source, start, len,
   1349                  real_dest,
   1350                  insert_at))
   1351         return FALSE;
   1352 
   1353       delete (real_source, start,
   1354               len);
   1355 
   1356       return TRUE;
   1357     }
   1358 }
   1359 
   1360 /**
   1361  * Like _dbus_string_copy(), but can copy a segment from the middle of
   1362  * the source string.
   1363  *
   1364  * @param source the source string
   1365  * @param start where to start copying the source string
   1366  * @param len length of segment to copy
   1367  * @param dest the destination string
   1368  * @param insert_at where to place the copied segment of source string
   1369  * @returns #FALSE if not enough memory
   1370  */
   1371 dbus_bool_t
   1372 _dbus_string_copy_len (const DBusString *source,
   1373                        int               start,
   1374                        int               len,
   1375                        DBusString       *dest,
   1376                        int               insert_at)
   1377 {
   1378   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
   1379   _dbus_assert (len >= 0);
   1380   _dbus_assert (start <= real_source->len);
   1381   _dbus_assert (len <= real_source->len - start);
   1382 
   1383   return copy (real_source, start, len,
   1384                real_dest,
   1385                insert_at);
   1386 }
   1387 
   1388 /**
   1389  * Replaces a segment of dest string with a segment of source string.
   1390  *
   1391  * @param source the source string
   1392  * @param start where to start copying the source string
   1393  * @param len length of segment to copy
   1394  * @param dest the destination string
   1395  * @param replace_at start of segment of dest string to replace
   1396  * @param replace_len length of segment of dest string to replace
   1397  * @returns #FALSE if not enough memory
   1398  *
   1399  */
   1400 dbus_bool_t
   1401 _dbus_string_replace_len (const DBusString *source,
   1402                           int               start,
   1403                           int               len,
   1404                           DBusString       *dest,
   1405                           int               replace_at,
   1406                           int               replace_len)
   1407 {
   1408   DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
   1409   _dbus_assert (len >= 0);
   1410   _dbus_assert (start <= real_source->len);
   1411   _dbus_assert (len <= real_source->len - start);
   1412   _dbus_assert (replace_at >= 0);
   1413   _dbus_assert (replace_at <= real_dest->len);
   1414   _dbus_assert (replace_len <= real_dest->len - replace_at);
   1415 
   1416   if (len == replace_len)
   1417     {
   1418       memmove (real_dest->str + replace_at,
   1419                real_source->str + start, len);
   1420     }
   1421   else if (len < replace_len)
   1422     {
   1423       memmove (real_dest->str + replace_at,
   1424                real_source->str + start, len);
   1425       delete (real_dest, replace_at + len,
   1426               replace_len - len);
   1427     }
   1428   else
   1429     {
   1430       int diff;
   1431 
   1432       _dbus_assert (len > replace_len);
   1433 
   1434       diff = len - replace_len;
   1435 
   1436       /* First of all we check if destination string can be enlarged as
   1437        * required, then we overwrite previous bytes
   1438        */
   1439 
   1440       if (!copy (real_source, start + replace_len, diff,
   1441                  real_dest, replace_at + replace_len))
   1442         return FALSE;
   1443 
   1444       memmove (real_dest->str + replace_at,
   1445                real_source->str + start, replace_len);
   1446     }
   1447 
   1448   return TRUE;
   1449 }
   1450 
   1451 /**
   1452  * Looks for the first occurance of a byte, deletes that byte,
   1453  * and moves everything after the byte to the beginning of a
   1454  * separate string.  Both strings must be initialized, valid
   1455  * strings.
   1456  *
   1457  * @param source the source string
   1458  * @param byte the byte to remove and split the string at
   1459  * @param tail the split off string
   1460  * @returns #FALSE if not enough memory or if byte could not be found
   1461  *
   1462  */
   1463 dbus_bool_t
   1464 _dbus_string_split_on_byte (DBusString        *source,
   1465                             unsigned char      byte,
   1466                             DBusString        *tail)
   1467 {
   1468   int byte_position;
   1469   char byte_string[2] = "";
   1470   int head_length;
   1471   int tail_length;
   1472 
   1473   byte_string[0] = (char) byte;
   1474 
   1475   if (!_dbus_string_find (source, 0, byte_string, &byte_position))
   1476     return FALSE;
   1477 
   1478   head_length = byte_position;
   1479   tail_length = _dbus_string_get_length (source) - head_length - 1;
   1480 
   1481   if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
   1482                               tail, 0))
   1483     return FALSE;
   1484 
   1485   /* remove the trailing delimiter byte from the head now.
   1486    */
   1487   if (!_dbus_string_set_length (source, head_length))
   1488     return FALSE;
   1489 
   1490   return TRUE;
   1491 }
   1492 
   1493 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
   1494  * Pennington, and Tom Tromey are the authors and authorized relicense.
   1495  */
   1496 
   1497 /** computes length and mask of a unicode character
   1498  * @param Char the char
   1499  * @param Mask the mask variable to assign to
   1500  * @param Len the length variable to assign to
   1501  */
   1502 #define UTF8_COMPUTE(Char, Mask, Len)					      \
   1503   if (Char < 128)							      \
   1504     {									      \
   1505       Len = 1;								      \
   1506       Mask = 0x7f;							      \
   1507     }									      \
   1508   else if ((Char & 0xe0) == 0xc0)					      \
   1509     {									      \
   1510       Len = 2;								      \
   1511       Mask = 0x1f;							      \
   1512     }									      \
   1513   else if ((Char & 0xf0) == 0xe0)					      \
   1514     {									      \
   1515       Len = 3;								      \
   1516       Mask = 0x0f;							      \
   1517     }									      \
   1518   else if ((Char & 0xf8) == 0xf0)					      \
   1519     {									      \
   1520       Len = 4;								      \
   1521       Mask = 0x07;							      \
   1522     }									      \
   1523   else if ((Char & 0xfc) == 0xf8)					      \
   1524     {									      \
   1525       Len = 5;								      \
   1526       Mask = 0x03;							      \
   1527     }									      \
   1528   else if ((Char & 0xfe) == 0xfc)					      \
   1529     {									      \
   1530       Len = 6;								      \
   1531       Mask = 0x01;							      \
   1532     }									      \
   1533   else                                                                        \
   1534     {                                                                         \
   1535       Len = 0;                                                               \
   1536       Mask = 0;                                                               \
   1537     }
   1538 
   1539 /**
   1540  * computes length of a unicode character in UTF-8
   1541  * @param Char the char
   1542  */
   1543 #define UTF8_LENGTH(Char)              \
   1544   ((Char) < 0x80 ? 1 :                 \
   1545    ((Char) < 0x800 ? 2 :               \
   1546     ((Char) < 0x10000 ? 3 :            \
   1547      ((Char) < 0x200000 ? 4 :          \
   1548       ((Char) < 0x4000000 ? 5 : 6)))))
   1549 
   1550 /**
   1551  * Gets a UTF-8 value.
   1552  *
   1553  * @param Result variable for extracted unicode char.
   1554  * @param Chars the bytes to decode
   1555  * @param Count counter variable
   1556  * @param Mask mask for this char
   1557  * @param Len length for this char in bytes
   1558  */
   1559 #define UTF8_GET(Result, Chars, Count, Mask, Len)			      \
   1560   (Result) = (Chars)[0] & (Mask);					      \
   1561   for ((Count) = 1; (Count) < (Len); ++(Count))				      \
   1562     {									      \
   1563       if (((Chars)[(Count)] & 0xc0) != 0x80)				      \
   1564 	{								      \
   1565 	  (Result) = -1;						      \
   1566 	  break;							      \
   1567 	}								      \
   1568       (Result) <<= 6;							      \
   1569       (Result) |= ((Chars)[(Count)] & 0x3f);				      \
   1570     }
   1571 
   1572 /**
   1573  * Check whether a Unicode (5.2) char is in a valid range.
   1574  *
   1575  * The first check comes from the Unicode guarantee to never encode
   1576  * a point above 0x0010ffff, since UTF-16 couldn't represent it.
   1577  *
   1578  * The second check covers surrogate pairs (category Cs).
   1579  *
   1580  * The last two checks cover "Noncharacter": defined as:
   1581  *   "A code point that is permanently reserved for
   1582  *    internal use, and that should never be interchanged. In
   1583  *    Unicode 3.1, these consist of the values U+nFFFE and U+nFFFF
   1584  *    (where n is from 0 to 10_16) and the values U+FDD0..U+FDEF."
   1585  *
   1586  * @param Char the character
   1587  */
   1588 #define UNICODE_VALID(Char)                   \
   1589     ((Char) < 0x110000 &&                     \
   1590      (((Char) & 0xFFFFF800) != 0xD800) &&     \
   1591      ((Char) < 0xFDD0 || (Char) > 0xFDEF) &&  \
   1592      ((Char) & 0xFFFE) != 0xFFFE)
   1593 
   1594 /**
   1595  * Finds the given substring in the string,
   1596  * returning #TRUE and filling in the byte index
   1597  * where the substring was found, if it was found.
   1598  * Returns #FALSE if the substring wasn't found.
   1599  * Sets *start to the length of the string if the substring
   1600  * is not found.
   1601  *
   1602  * @param str the string
   1603  * @param start where to start looking
   1604  * @param substr the substring
   1605  * @param found return location for where it was found, or #NULL
   1606  * @returns #TRUE if found
   1607  */
   1608 dbus_bool_t
   1609 _dbus_string_find (const DBusString *str,
   1610                    int               start,
   1611                    const char       *substr,
   1612                    int              *found)
   1613 {
   1614   return _dbus_string_find_to (str, start,
   1615                                ((const DBusRealString*)str)->len,
   1616                                substr, found);
   1617 }
   1618 
   1619 /**
   1620  * Finds end of line ("\r\n" or "\n") in the string,
   1621  * returning #TRUE and filling in the byte index
   1622  * where the eol string was found, if it was found.
   1623  * Returns #FALSE if eol wasn't found.
   1624  *
   1625  * @param str the string
   1626  * @param start where to start looking
   1627  * @param found return location for where eol was found or string length otherwise
   1628  * @param found_len return length of found eol string or zero otherwise
   1629  * @returns #TRUE if found
   1630  */
   1631 dbus_bool_t
   1632 _dbus_string_find_eol (const DBusString *str,
   1633                        int               start,
   1634                        int              *found,
   1635                        int              *found_len)
   1636 {
   1637   int i;
   1638 
   1639   DBUS_CONST_STRING_PREAMBLE (str);
   1640   _dbus_assert (start <= real->len);
   1641   _dbus_assert (start >= 0);
   1642 
   1643   i = start;
   1644   while (i < real->len)
   1645     {
   1646       if (real->str[i] == '\r')
   1647         {
   1648           if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
   1649             {
   1650               if (found)
   1651                 *found = i;
   1652               if (found_len)
   1653                 *found_len = 2;
   1654               return TRUE;
   1655             }
   1656           else /* only "\r" */
   1657             {
   1658               if (found)
   1659                 *found = i;
   1660               if (found_len)
   1661                 *found_len = 1;
   1662               return TRUE;
   1663             }
   1664         }
   1665       else if (real->str[i] == '\n')  /* only "\n" */
   1666         {
   1667           if (found)
   1668             *found = i;
   1669           if (found_len)
   1670             *found_len = 1;
   1671           return TRUE;
   1672         }
   1673       ++i;
   1674     }
   1675 
   1676   if (found)
   1677     *found = real->len;
   1678 
   1679   if (found_len)
   1680     *found_len = 0;
   1681 
   1682   return FALSE;
   1683 }
   1684 
   1685 /**
   1686  * Finds the given substring in the string,
   1687  * up to a certain position,
   1688  * returning #TRUE and filling in the byte index
   1689  * where the substring was found, if it was found.
   1690  * Returns #FALSE if the substring wasn't found.
   1691  * Sets *start to the length of the string if the substring
   1692  * is not found.
   1693  *
   1694  * @param str the string
   1695  * @param start where to start looking
   1696  * @param end where to stop looking
   1697  * @param substr the substring
   1698  * @param found return location for where it was found, or #NULL
   1699  * @returns #TRUE if found
   1700  */
   1701 dbus_bool_t
   1702 _dbus_string_find_to (const DBusString *str,
   1703 		      int               start,
   1704 		      int               end,
   1705 		      const char       *substr,
   1706 		      int              *found)
   1707 {
   1708   int i;
   1709   DBUS_CONST_STRING_PREAMBLE (str);
   1710   _dbus_assert (substr != NULL);
   1711   _dbus_assert (start <= real->len);
   1712   _dbus_assert (start >= 0);
   1713   _dbus_assert (substr != NULL);
   1714   _dbus_assert (end <= real->len);
   1715   _dbus_assert (start <= end);
   1716 
   1717   /* we always "find" an empty string */
   1718   if (*substr == '\0')
   1719     {
   1720       if (found)
   1721         *found = start;
   1722       return TRUE;
   1723     }
   1724 
   1725   i = start;
   1726   while (i < end)
   1727     {
   1728       if (real->str[i] == substr[0])
   1729         {
   1730           int j = i + 1;
   1731 
   1732           while (j < end)
   1733             {
   1734               if (substr[j - i] == '\0')
   1735                 break;
   1736               else if (real->str[j] != substr[j - i])
   1737                 break;
   1738 
   1739               ++j;
   1740             }
   1741 
   1742           if (substr[j - i] == '\0')
   1743             {
   1744               if (found)
   1745                 *found = i;
   1746               return TRUE;
   1747             }
   1748         }
   1749 
   1750       ++i;
   1751     }
   1752 
   1753   if (found)
   1754     *found = end;
   1755 
   1756   return FALSE;
   1757 }
   1758 
   1759 /**
   1760  * Finds a blank (space or tab) in the string. Returns #TRUE
   1761  * if found, #FALSE otherwise. If a blank is not found sets
   1762  * *found to the length of the string.
   1763  *
   1764  * @param str the string
   1765  * @param start byte index to start looking
   1766  * @param found place to store the location of the first blank
   1767  * @returns #TRUE if a blank was found
   1768  */
   1769 dbus_bool_t
   1770 _dbus_string_find_blank (const DBusString *str,
   1771                          int               start,
   1772                          int              *found)
   1773 {
   1774   int i;
   1775   DBUS_CONST_STRING_PREAMBLE (str);
   1776   _dbus_assert (start <= real->len);
   1777   _dbus_assert (start >= 0);
   1778 
   1779   i = start;
   1780   while (i < real->len)
   1781     {
   1782       if (real->str[i] == ' ' ||
   1783           real->str[i] == '\t')
   1784         {
   1785           if (found)
   1786             *found = i;
   1787           return TRUE;
   1788         }
   1789 
   1790       ++i;
   1791     }
   1792 
   1793   if (found)
   1794     *found = real->len;
   1795 
   1796   return FALSE;
   1797 }
   1798 
   1799 /**
   1800  * Skips blanks from start, storing the first non-blank in *end
   1801  * (blank is space or tab).
   1802  *
   1803  * @param str the string
   1804  * @param start where to start
   1805  * @param end where to store the first non-blank byte index
   1806  */
   1807 void
   1808 _dbus_string_skip_blank (const DBusString *str,
   1809                          int               start,
   1810                          int              *end)
   1811 {
   1812   int i;
   1813   DBUS_CONST_STRING_PREAMBLE (str);
   1814   _dbus_assert (start <= real->len);
   1815   _dbus_assert (start >= 0);
   1816 
   1817   i = start;
   1818   while (i < real->len)
   1819     {
   1820       if (!DBUS_IS_ASCII_BLANK (real->str[i]))
   1821         break;
   1822 
   1823       ++i;
   1824     }
   1825 
   1826   _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
   1827 
   1828   if (end)
   1829     *end = i;
   1830 }
   1831 
   1832 
   1833 /**
   1834  * Skips whitespace from start, storing the first non-whitespace in *end.
   1835  * (whitespace is space, tab, newline, CR).
   1836  *
   1837  * @param str the string
   1838  * @param start where to start
   1839  * @param end where to store the first non-whitespace byte index
   1840  */
   1841 void
   1842 _dbus_string_skip_white (const DBusString *str,
   1843                          int               start,
   1844                          int              *end)
   1845 {
   1846   int i;
   1847   DBUS_CONST_STRING_PREAMBLE (str);
   1848   _dbus_assert (start <= real->len);
   1849   _dbus_assert (start >= 0);
   1850 
   1851   i = start;
   1852   while (i < real->len)
   1853     {
   1854       if (!DBUS_IS_ASCII_WHITE (real->str[i]))
   1855         break;
   1856 
   1857       ++i;
   1858     }
   1859 
   1860   _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
   1861 
   1862   if (end)
   1863     *end = i;
   1864 }
   1865 
   1866 /**
   1867  * Skips whitespace from end, storing the start index of the trailing
   1868  * whitespace in *start. (whitespace is space, tab, newline, CR).
   1869  *
   1870  * @param str the string
   1871  * @param end where to start scanning backward
   1872  * @param start where to store the start of whitespace chars
   1873  */
   1874 void
   1875 _dbus_string_skip_white_reverse (const DBusString *str,
   1876                                  int               end,
   1877                                  int              *start)
   1878 {
   1879   int i;
   1880   DBUS_CONST_STRING_PREAMBLE (str);
   1881   _dbus_assert (end <= real->len);
   1882   _dbus_assert (end >= 0);
   1883 
   1884   i = end;
   1885   while (i > 0)
   1886     {
   1887       if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
   1888         break;
   1889       --i;
   1890     }
   1891 
   1892   _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
   1893 
   1894   if (start)
   1895     *start = i;
   1896 }
   1897 
   1898 /**
   1899  * Assigns a newline-terminated or \\r\\n-terminated line from the front
   1900  * of the string to the given dest string. The dest string's previous
   1901  * contents are deleted. If the source string contains no newline,
   1902  * moves the entire source string to the dest string.
   1903  *
   1904  * @todo owen correctly notes that this is a stupid function (it was
   1905  * written purely for test code,
   1906  * e.g. dbus-message-builder.c). Probably should be enforced as test
   1907  * code only with ifdef DBUS_BUILD_TESTS
   1908  *
   1909  * @param source the source string
   1910  * @param dest the destination string (contents are replaced)
   1911  * @returns #FALSE if no memory, or source has length 0
   1912  */
   1913 dbus_bool_t
   1914 _dbus_string_pop_line (DBusString *source,
   1915                        DBusString *dest)
   1916 {
   1917   int eol, eol_len;
   1918 
   1919   _dbus_string_set_length (dest, 0);
   1920 
   1921   eol = 0;
   1922   eol_len = 0;
   1923   if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
   1924     {
   1925       _dbus_assert (eol == _dbus_string_get_length (source));
   1926       if (eol == 0)
   1927         {
   1928           /* If there's no newline and source has zero length, we're done */
   1929           return FALSE;
   1930         }
   1931       /* otherwise, the last line of the file has no eol characters */
   1932     }
   1933 
   1934   /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
   1935    * since find_eol returned TRUE
   1936    */
   1937 
   1938   if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
   1939     return FALSE;
   1940 
   1941   /* remove line ending */
   1942   if (!_dbus_string_set_length (dest, eol))
   1943     {
   1944       _dbus_assert_not_reached ("out of memory when shortening a string");
   1945       return FALSE;
   1946     }
   1947 
   1948   return TRUE;
   1949 }
   1950 
   1951 #ifdef DBUS_BUILD_TESTS
   1952 /**
   1953  * Deletes up to and including the first blank space
   1954  * in the string.
   1955  *
   1956  * @param str the string
   1957  */
   1958 void
   1959 _dbus_string_delete_first_word (DBusString *str)
   1960 {
   1961   int i;
   1962 
   1963   if (_dbus_string_find_blank (str, 0, &i))
   1964     _dbus_string_skip_blank (str, i, &i);
   1965 
   1966   _dbus_string_delete (str, 0, i);
   1967 }
   1968 #endif
   1969 
   1970 #ifdef DBUS_BUILD_TESTS
   1971 /**
   1972  * Deletes any leading blanks in the string
   1973  *
   1974  * @param str the string
   1975  */
   1976 void
   1977 _dbus_string_delete_leading_blanks (DBusString *str)
   1978 {
   1979   int i;
   1980 
   1981   _dbus_string_skip_blank (str, 0, &i);
   1982 
   1983   if (i > 0)
   1984     _dbus_string_delete (str, 0, i);
   1985 }
   1986 #endif
   1987 
   1988 /**
   1989  * Deletes leading and trailing whitespace
   1990  *
   1991  * @param str the string
   1992  */
   1993 void
   1994 _dbus_string_chop_white(DBusString *str)
   1995 {
   1996   int i;
   1997 
   1998   _dbus_string_skip_white (str, 0, &i);
   1999 
   2000   if (i > 0)
   2001     _dbus_string_delete (str, 0, i);
   2002 
   2003   _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
   2004 
   2005   _dbus_string_set_length (str, i);
   2006 }
   2007 
   2008 /**
   2009  * Tests two DBusString for equality.
   2010  *
   2011  * @todo memcmp is probably faster
   2012  *
   2013  * @param a first string
   2014  * @param b second string
   2015  * @returns #TRUE if equal
   2016  */
   2017 dbus_bool_t
   2018 _dbus_string_equal (const DBusString *a,
   2019                     const DBusString *b)
   2020 {
   2021   const unsigned char *ap;
   2022   const unsigned char *bp;
   2023   const unsigned char *a_end;
   2024   const DBusRealString *real_a = (const DBusRealString*) a;
   2025   const DBusRealString *real_b = (const DBusRealString*) b;
   2026   DBUS_GENERIC_STRING_PREAMBLE (real_a);
   2027   DBUS_GENERIC_STRING_PREAMBLE (real_b);
   2028 
   2029   if (real_a->len != real_b->len)
   2030     return FALSE;
   2031 
   2032   ap = real_a->str;
   2033   bp = real_b->str;
   2034   a_end = real_a->str + real_a->len;
   2035   while (ap != a_end)
   2036     {
   2037       if (*ap != *bp)
   2038         return FALSE;
   2039 
   2040       ++ap;
   2041       ++bp;
   2042     }
   2043 
   2044   return TRUE;
   2045 }
   2046 
   2047 /**
   2048  * Tests two DBusString for equality up to the given length.
   2049  * The strings may be shorter than the given length.
   2050  *
   2051  * @todo write a unit test
   2052  *
   2053  * @todo memcmp is probably faster
   2054  *
   2055  * @param a first string
   2056  * @param b second string
   2057  * @param len the maximum length to look at
   2058  * @returns #TRUE if equal for the given number of bytes
   2059  */
   2060 dbus_bool_t
   2061 _dbus_string_equal_len (const DBusString *a,
   2062                         const DBusString *b,
   2063                         int               len)
   2064 {
   2065   const unsigned char *ap;
   2066   const unsigned char *bp;
   2067   const unsigned char *a_end;
   2068   const DBusRealString *real_a = (const DBusRealString*) a;
   2069   const DBusRealString *real_b = (const DBusRealString*) b;
   2070   DBUS_GENERIC_STRING_PREAMBLE (real_a);
   2071   DBUS_GENERIC_STRING_PREAMBLE (real_b);
   2072 
   2073   if (real_a->len != real_b->len &&
   2074       (real_a->len < len || real_b->len < len))
   2075     return FALSE;
   2076 
   2077   ap = real_a->str;
   2078   bp = real_b->str;
   2079   a_end = real_a->str + MIN (real_a->len, len);
   2080   while (ap != a_end)
   2081     {
   2082       if (*ap != *bp)
   2083         return FALSE;
   2084 
   2085       ++ap;
   2086       ++bp;
   2087     }
   2088 
   2089   return TRUE;
   2090 }
   2091 
   2092 /**
   2093  * Tests two sub-parts of two DBusString for equality.  The specified
   2094  * range of the first string must exist; the specified start position
   2095  * of the second string must exist.
   2096  *
   2097  * @todo write a unit test
   2098  *
   2099  * @todo memcmp is probably faster
   2100  *
   2101  * @param a first string
   2102  * @param a_start where to start substring in first string
   2103  * @param a_len length of substring in first string
   2104  * @param b second string
   2105  * @param b_start where to start substring in second string
   2106  * @returns #TRUE if the two substrings are equal
   2107  */
   2108 dbus_bool_t
   2109 _dbus_string_equal_substring (const DBusString  *a,
   2110                               int                a_start,
   2111                               int                a_len,
   2112                               const DBusString  *b,
   2113                               int                b_start)
   2114 {
   2115   const unsigned char *ap;
   2116   const unsigned char *bp;
   2117   const unsigned char *a_end;
   2118   const DBusRealString *real_a = (const DBusRealString*) a;
   2119   const DBusRealString *real_b = (const DBusRealString*) b;
   2120   DBUS_GENERIC_STRING_PREAMBLE (real_a);
   2121   DBUS_GENERIC_STRING_PREAMBLE (real_b);
   2122   _dbus_assert (a_start >= 0);
   2123   _dbus_assert (a_len >= 0);
   2124   _dbus_assert (a_start <= real_a->len);
   2125   _dbus_assert (a_len <= real_a->len - a_start);
   2126   _dbus_assert (b_start >= 0);
   2127   _dbus_assert (b_start <= real_b->len);
   2128 
   2129   if (a_len > real_b->len - b_start)
   2130     return FALSE;
   2131 
   2132   ap = real_a->str + a_start;
   2133   bp = real_b->str + b_start;
   2134   a_end = ap + a_len;
   2135   while (ap != a_end)
   2136     {
   2137       if (*ap != *bp)
   2138         return FALSE;
   2139 
   2140       ++ap;
   2141       ++bp;
   2142     }
   2143 
   2144   _dbus_assert (bp <= (real_b->str + real_b->len));
   2145 
   2146   return TRUE;
   2147 }
   2148 
   2149 /**
   2150  * Checks whether a string is equal to a C string.
   2151  *
   2152  * @param a the string
   2153  * @param c_str the C string
   2154  * @returns #TRUE if equal
   2155  */
   2156 dbus_bool_t
   2157 _dbus_string_equal_c_str (const DBusString *a,
   2158                           const char       *c_str)
   2159 {
   2160   const unsigned char *ap;
   2161   const unsigned char *bp;
   2162   const unsigned char *a_end;
   2163   const DBusRealString *real_a = (const DBusRealString*) a;
   2164   DBUS_GENERIC_STRING_PREAMBLE (real_a);
   2165   _dbus_assert (c_str != NULL);
   2166 
   2167   ap = real_a->str;
   2168   bp = (const unsigned char*) c_str;
   2169   a_end = real_a->str + real_a->len;
   2170   while (ap != a_end && *bp)
   2171     {
   2172       if (*ap != *bp)
   2173         return FALSE;
   2174 
   2175       ++ap;
   2176       ++bp;
   2177     }
   2178 
   2179   if (ap != a_end || *bp)
   2180     return FALSE;
   2181 
   2182   return TRUE;
   2183 }
   2184 
   2185 /**
   2186  * Checks whether a string starts with the given C string.
   2187  *
   2188  * @param a the string
   2189  * @param c_str the C string
   2190  * @returns #TRUE if string starts with it
   2191  */
   2192 dbus_bool_t
   2193 _dbus_string_starts_with_c_str (const DBusString *a,
   2194                                 const char       *c_str)
   2195 {
   2196   const unsigned char *ap;
   2197   const unsigned char *bp;
   2198   const unsigned char *a_end;
   2199   const DBusRealString *real_a = (const DBusRealString*) a;
   2200   DBUS_GENERIC_STRING_PREAMBLE (real_a);
   2201   _dbus_assert (c_str != NULL);
   2202 
   2203   ap = real_a->str;
   2204   bp = (const unsigned char*) c_str;
   2205   a_end = real_a->str + real_a->len;
   2206   while (ap != a_end && *bp)
   2207     {
   2208       if (*ap != *bp)
   2209         return FALSE;
   2210 
   2211       ++ap;
   2212       ++bp;
   2213     }
   2214 
   2215   if (*bp == '\0')
   2216     return TRUE;
   2217   else
   2218     return FALSE;
   2219 }
   2220 
   2221 /**
   2222  * Appends a two-character hex digit to a string, where the hex digit
   2223  * has the value of the given byte.
   2224  *
   2225  * @param str the string
   2226  * @param byte the byte
   2227  * @returns #FALSE if no memory
   2228  */
   2229 dbus_bool_t
   2230 _dbus_string_append_byte_as_hex (DBusString *str,
   2231                                  int         byte)
   2232 {
   2233   const char hexdigits[16] = {
   2234     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
   2235     'a', 'b', 'c', 'd', 'e', 'f'
   2236   };
   2237 
   2238   if (!_dbus_string_append_byte (str,
   2239                                  hexdigits[(byte >> 4)]))
   2240     return FALSE;
   2241 
   2242   if (!_dbus_string_append_byte (str,
   2243                                  hexdigits[(byte & 0x0f)]))
   2244     {
   2245       _dbus_string_set_length (str,
   2246                                _dbus_string_get_length (str) - 1);
   2247       return FALSE;
   2248     }
   2249 
   2250   return TRUE;
   2251 }
   2252 
   2253 /**
   2254  * Encodes a string in hex, the way MD5 and SHA-1 are usually
   2255  * encoded. (Each byte is two hex digits.)
   2256  *
   2257  * @param source the string to encode
   2258  * @param start byte index to start encoding
   2259  * @param dest string where encoded data should be placed
   2260  * @param insert_at where to place encoded data
   2261  * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
   2262  */
   2263 dbus_bool_t
   2264 _dbus_string_hex_encode (const DBusString *source,
   2265                          int               start,
   2266                          DBusString       *dest,
   2267                          int               insert_at)
   2268 {
   2269   DBusString result;
   2270   const unsigned char *p;
   2271   const unsigned char *end;
   2272   dbus_bool_t retval;
   2273 
   2274   _dbus_assert (start <= _dbus_string_get_length (source));
   2275 
   2276   if (!_dbus_string_init (&result))
   2277     return FALSE;
   2278 
   2279   retval = FALSE;
   2280 
   2281   p = (const unsigned char*) _dbus_string_get_const_data (source);
   2282   end = p + _dbus_string_get_length (source);
   2283   p += start;
   2284 
   2285   while (p != end)
   2286     {
   2287       if (!_dbus_string_append_byte_as_hex (&result, *p))
   2288         goto out;
   2289 
   2290       ++p;
   2291     }
   2292 
   2293   if (!_dbus_string_move (&result, 0, dest, insert_at))
   2294     goto out;
   2295 
   2296   retval = TRUE;
   2297 
   2298  out:
   2299   _dbus_string_free (&result);
   2300   return retval;
   2301 }
   2302 
   2303 /**
   2304  * Decodes a string from hex encoding.
   2305  *
   2306  * @param source the string to decode
   2307  * @param start byte index to start decode
   2308  * @param end_return return location of the end of the hex data, or #NULL
   2309  * @param dest string where decoded data should be placed
   2310  * @param insert_at where to place decoded data
   2311  * @returns #TRUE if decoding was successful, #FALSE if no memory.
   2312  */
   2313 dbus_bool_t
   2314 _dbus_string_hex_decode (const DBusString *source,
   2315                          int               start,
   2316 			 int              *end_return,
   2317                          DBusString       *dest,
   2318                          int               insert_at)
   2319 {
   2320   DBusString result;
   2321   const unsigned char *p;
   2322   const unsigned char *end;
   2323   dbus_bool_t retval;
   2324   dbus_bool_t high_bits;
   2325 
   2326   _dbus_assert (start <= _dbus_string_get_length (source));
   2327 
   2328   if (!_dbus_string_init (&result))
   2329     return FALSE;
   2330 
   2331   retval = FALSE;
   2332 
   2333   high_bits = TRUE;
   2334   p = (const unsigned char*) _dbus_string_get_const_data (source);
   2335   end = p + _dbus_string_get_length (source);
   2336   p += start;
   2337 
   2338   while (p != end)
   2339     {
   2340       unsigned int val;
   2341 
   2342       switch (*p)
   2343         {
   2344         case '0':
   2345           val = 0;
   2346           break;
   2347         case '1':
   2348           val = 1;
   2349           break;
   2350         case '2':
   2351           val = 2;
   2352           break;
   2353         case '3':
   2354           val = 3;
   2355           break;
   2356         case '4':
   2357           val = 4;
   2358           break;
   2359         case '5':
   2360           val = 5;
   2361           break;
   2362         case '6':
   2363           val = 6;
   2364           break;
   2365         case '7':
   2366           val = 7;
   2367           break;
   2368         case '8':
   2369           val = 8;
   2370           break;
   2371         case '9':
   2372           val = 9;
   2373           break;
   2374         case 'a':
   2375         case 'A':
   2376           val = 10;
   2377           break;
   2378         case 'b':
   2379         case 'B':
   2380           val = 11;
   2381           break;
   2382         case 'c':
   2383         case 'C':
   2384           val = 12;
   2385           break;
   2386         case 'd':
   2387         case 'D':
   2388           val = 13;
   2389           break;
   2390         case 'e':
   2391         case 'E':
   2392           val = 14;
   2393           break;
   2394         case 'f':
   2395         case 'F':
   2396           val = 15;
   2397           break;
   2398         default:
   2399           goto done;
   2400         }
   2401 
   2402       if (high_bits)
   2403         {
   2404           if (!_dbus_string_append_byte (&result,
   2405                                          val << 4))
   2406 	    goto out;
   2407         }
   2408       else
   2409         {
   2410           int len;
   2411           unsigned char b;
   2412 
   2413           len = _dbus_string_get_length (&result);
   2414 
   2415           b = _dbus_string_get_byte (&result, len - 1);
   2416 
   2417           b |= val;
   2418 
   2419           _dbus_string_set_byte (&result, len - 1, b);
   2420         }
   2421 
   2422       high_bits = !high_bits;
   2423 
   2424       ++p;
   2425     }
   2426 
   2427  done:
   2428   if (!_dbus_string_move (&result, 0, dest, insert_at))
   2429     goto out;
   2430 
   2431   if (end_return)
   2432     *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
   2433 
   2434   retval = TRUE;
   2435 
   2436  out:
   2437   _dbus_string_free (&result);
   2438   return retval;
   2439 }
   2440 
   2441 /**
   2442  * Checks that the given range of the string is valid ASCII with no
   2443  * nul bytes. If the given range is not entirely contained in the
   2444  * string, returns #FALSE.
   2445  *
   2446  * @todo this is inconsistent with most of DBusString in that
   2447  * it allows a start,len range that extends past the string end.
   2448  *
   2449  * @param str the string
   2450  * @param start first byte index to check
   2451  * @param len number of bytes to check
   2452  * @returns #TRUE if the byte range exists and is all valid ASCII
   2453  */
   2454 dbus_bool_t
   2455 _dbus_string_validate_ascii (const DBusString *str,
   2456                              int               start,
   2457                              int               len)
   2458 {
   2459   const unsigned char *s;
   2460   const unsigned char *end;
   2461   DBUS_CONST_STRING_PREAMBLE (str);
   2462   _dbus_assert (start >= 0);
   2463   _dbus_assert (start <= real->len);
   2464   _dbus_assert (len >= 0);
   2465 
   2466   if (len > real->len - start)
   2467     return FALSE;
   2468 
   2469   s = real->str + start;
   2470   end = s + len;
   2471   while (s != end)
   2472     {
   2473       if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
   2474         return FALSE;
   2475 
   2476       ++s;
   2477     }
   2478 
   2479   return TRUE;
   2480 }
   2481 
   2482 /**
   2483  * Converts the given range of the string to lower case.
   2484  *
   2485  * @param str the string
   2486  * @param start first byte index to convert
   2487  * @param len number of bytes to convert
   2488  */
   2489 void
   2490 _dbus_string_tolower_ascii (const DBusString *str,
   2491                             int               start,
   2492                             int               len)
   2493 {
   2494   unsigned char *s;
   2495   unsigned char *end;
   2496   DBUS_STRING_PREAMBLE (str);
   2497   _dbus_assert (start >= 0);
   2498   _dbus_assert (start <= real->len);
   2499   _dbus_assert (len >= 0);
   2500   _dbus_assert (len <= real->len - start);
   2501 
   2502   s = real->str + start;
   2503   end = s + len;
   2504 
   2505   while (s != end)
   2506     {
   2507       if (*s >= 'A' && *s <= 'Z')
   2508           *s += 'a' - 'A';
   2509       ++s;
   2510     }
   2511 }
   2512 
   2513 /**
   2514  * Converts the given range of the string to upper case.
   2515  *
   2516  * @param str the string
   2517  * @param start first byte index to convert
   2518  * @param len number of bytes to convert
   2519  */
   2520 void
   2521 _dbus_string_toupper_ascii (const DBusString *str,
   2522                             int               start,
   2523                             int               len)
   2524 {
   2525   unsigned char *s;
   2526   unsigned char *end;
   2527   DBUS_STRING_PREAMBLE (str);
   2528   _dbus_assert (start >= 0);
   2529   _dbus_assert (start <= real->len);
   2530   _dbus_assert (len >= 0);
   2531   _dbus_assert (len <= real->len - start);
   2532 
   2533   s = real->str + start;
   2534   end = s + len;
   2535 
   2536   while (s != end)
   2537     {
   2538       if (*s >= 'a' && *s <= 'z')
   2539           *s += 'A' - 'a';
   2540       ++s;
   2541     }
   2542 }
   2543 
   2544 /**
   2545  * Checks that the given range of the string is valid UTF-8. If the
   2546  * given range is not entirely contained in the string, returns
   2547  * #FALSE. If the string contains any nul bytes in the given range,
   2548  * returns #FALSE. If the start and start+len are not on character
   2549  * boundaries, returns #FALSE.
   2550  *
   2551  * @todo this is inconsistent with most of DBusString in that
   2552  * it allows a start,len range that extends past the string end.
   2553  *
   2554  * @param str the string
   2555  * @param start first byte index to check
   2556  * @param len number of bytes to check
   2557  * @returns #TRUE if the byte range exists and is all valid UTF-8
   2558  */
   2559 dbus_bool_t
   2560 _dbus_string_validate_utf8  (const DBusString *str,
   2561                              int               start,
   2562                              int               len)
   2563 {
   2564   const unsigned char *p;
   2565   const unsigned char *end;
   2566   DBUS_CONST_STRING_PREAMBLE (str);
   2567   _dbus_assert (start >= 0);
   2568   _dbus_assert (start <= real->len);
   2569   _dbus_assert (len >= 0);
   2570 
   2571   /* we are doing _DBUS_UNLIKELY() here which might be
   2572    * dubious in a generic library like GLib, but in D-Bus
   2573    * we know we're validating messages and that it would
   2574    * only be evil/broken apps that would have invalid
   2575    * UTF-8. Also, this function seems to be a performance
   2576    * bottleneck in profiles.
   2577    */
   2578 
   2579   if (_DBUS_UNLIKELY (len > real->len - start))
   2580     return FALSE;
   2581 
   2582   p = real->str + start;
   2583   end = p + len;
   2584 
   2585   while (p < end)
   2586     {
   2587       int i, mask, char_len;
   2588       dbus_unichar_t result;
   2589 
   2590       /* nul bytes considered invalid */
   2591       if (*p == '\0')
   2592         break;
   2593 
   2594       /* Special-case ASCII; this makes us go a lot faster in
   2595        * D-Bus profiles where we are typically validating
   2596        * function names and such. We have to know that
   2597        * all following checks will pass for ASCII though,
   2598        * comments follow ...
   2599        */
   2600       if (*p < 128)
   2601         {
   2602           ++p;
   2603           continue;
   2604         }
   2605 
   2606       UTF8_COMPUTE (*p, mask, char_len);
   2607 
   2608       if (_DBUS_UNLIKELY (char_len == 0))  /* ASCII: char_len == 1 */
   2609         break;
   2610 
   2611       /* check that the expected number of bytes exists in the remaining length */
   2612       if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
   2613         break;
   2614 
   2615       UTF8_GET (result, p, i, mask, char_len);
   2616 
   2617       /* Check for overlong UTF-8 */
   2618       if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
   2619         break;
   2620 #if 0
   2621       /* The UNICODE_VALID check below will catch this */
   2622       if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
   2623         break;
   2624 #endif
   2625 
   2626       if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
   2627         break;
   2628 
   2629       /* UNICODE_VALID should have caught it */
   2630       _dbus_assert (result != (dbus_unichar_t)-1);
   2631 
   2632       p += char_len;
   2633     }
   2634 
   2635   /* See that we covered the entire length if a length was
   2636    * passed in
   2637    */
   2638   if (_DBUS_UNLIKELY (p != end))
   2639     return FALSE;
   2640   else
   2641     return TRUE;
   2642 }
   2643 
   2644 /**
   2645  * Checks that the given range of the string is all nul bytes. If the
   2646  * given range is not entirely contained in the string, returns
   2647  * #FALSE.
   2648  *
   2649  * @todo this is inconsistent with most of DBusString in that
   2650  * it allows a start,len range that extends past the string end.
   2651  *
   2652  * @param str the string
   2653  * @param start first byte index to check
   2654  * @param len number of bytes to check
   2655  * @returns #TRUE if the byte range exists and is all nul bytes
   2656  */
   2657 dbus_bool_t
   2658 _dbus_string_validate_nul (const DBusString *str,
   2659                            int               start,
   2660                            int               len)
   2661 {
   2662   const unsigned char *s;
   2663   const unsigned char *end;
   2664   DBUS_CONST_STRING_PREAMBLE (str);
   2665   _dbus_assert (start >= 0);
   2666   _dbus_assert (len >= 0);
   2667   _dbus_assert (start <= real->len);
   2668 
   2669   if (len > real->len - start)
   2670     return FALSE;
   2671 
   2672   s = real->str + start;
   2673   end = s + len;
   2674   while (s != end)
   2675     {
   2676       if (_DBUS_UNLIKELY (*s != '\0'))
   2677         return FALSE;
   2678       ++s;
   2679     }
   2680 
   2681   return TRUE;
   2682 }
   2683 
   2684 /**
   2685  * Clears all allocated bytes in the string to zero.
   2686  *
   2687  * @param str the string
   2688  */
   2689 void
   2690 _dbus_string_zero (DBusString *str)
   2691 {
   2692   DBUS_STRING_PREAMBLE (str);
   2693 
   2694   memset (real->str - real->align_offset, '\0', real->allocated);
   2695 }
   2696 /** @} */
   2697 
   2698 /* tests are in dbus-string-util.c */
   2699