Coverage report for dbus/dbus-address.c.gcov

        -:    0:Source:dbus-address.c
        -:    0:Graph:.libs/dbus-address.gcno
        -:    0:Data:.libs/dbus-address.gcda
        -:    0:Runs:11814
        -:    0:Programs:5
        -:    1:/* -*- mode: C; c-file-style: "gnu" -*- */
        -:    2:/* dbus-address.c  Server address parser.
        -:    3: *
        -:    4: * Copyright (C) 2003  CodeFactory AB
        -:    5: * Copyright (C) 2004,2005  Red Hat, Inc.
        -:    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        -:   22: *
        -:   23: */
        -:   24:
        -:   25:#include <config.h>
        -:   26:#include "dbus-address.h"
        -:   27:#include "dbus-internals.h"
        -:   28:#include "dbus-list.h"
        -:   29:#include "dbus-string.h"
        -:   30:#include "dbus-protocol.h"
        -:   31:
        -:   32:/**
        -:   33: * @defgroup DBusAddressInternals Address parsing
        -:   34: * @ingroup  DBusInternals
        -:   35: * @brief Implementation of parsing addresses of D-BUS servers.
        -:   36: *
        -:   37: * @{
        -:   38: */
        -:   39:
        -:   40:/**
        -:   41: * Internals of DBusAddressEntry 
        -:   42: */
        -:   43:struct DBusAddressEntry
        -:   44:{
        -:   45:  DBusString method; /**< The address type (unix, tcp, etc.) */
        -:   46:
        -:   47:  DBusList *keys;    /**< List of keys */
        -:   48:  DBusList *values;  /**< List of values */
        -:   49:};
        -:   50:
        -:   51:/** @} */ /* End of internals */
        -:   52:
        -:   53:static void
        -:   54:dbus_address_entry_free (DBusAddressEntry *entry)
function dbus_address_entry_free called 7932 returned 100% blocks executed 100%
     7932:   55:{
        -:   56:  DBusList *link;
        -:   57:  
     7932:   58:  _dbus_string_free (&entry->method);
call    0 returned 100%
        -:   59:
     7932:   60:  link = _dbus_list_get_first_link (&entry->keys);
call    0 returned 100%
    25537:   61:  while (link != NULL)
branch  0 taken 55%
branch  1 taken 45% (fallthrough)
        -:   62:    {
     9673:   63:      _dbus_string_free (link->data);
call    0 returned 100%
     9673:   64:      dbus_free (link->data);
call    0 returned 100%
        -:   65:      
     9673:   66:      link = _dbus_list_get_next_link (&entry->keys, link);
branch  0 taken 19% (fallthrough)
branch  1 taken 81%
        -:   67:    }
     7932:   68:  _dbus_list_clear (&entry->keys);
call    0 returned 100%
        -:   69:  
     7932:   70:  link = _dbus_list_get_first_link (&entry->values);
call    0 returned 100%
    25531:   71:  while (link != NULL)
branch  0 taken 55%
branch  1 taken 45% (fallthrough)
        -:   72:    {
     9667:   73:      _dbus_string_free (link->data);
call    0 returned 100%
     9667:   74:      dbus_free (link->data);
call    0 returned 100%
        -:   75:      
     9667:   76:      link = _dbus_list_get_next_link (&entry->values, link);
branch  0 taken 19% (fallthrough)
branch  1 taken 81%
        -:   77:    }
     7932:   78:  _dbus_list_clear (&entry->values);
call    0 returned 100%
        -:   79:  
     7932:   80:  dbus_free (entry);
call    0 returned 100%
     7932:   81:}
        -:   82:
        -:   83:/**
        -:   84: * @defgroup DBusAddress Address parsing
        -:   85: * @ingroup  DBus
        -:   86: * @brief Parsing addresses of D-BUS servers.
        -:   87: *
        -:   88: * @{
        -:   89: */
        -:   90:
        -:   91:/**
        -:   92: * Frees a #NULL-terminated array of address entries.
        -:   93: *
        -:   94: * @param entries the array.
        -:   95: */
        -:   96:void
        -:   97:dbus_address_entries_free (DBusAddressEntry **entries)
function dbus_address_entries_free called 6864 returned 100% blocks executed 100%
     6864:   98:{
        -:   99:  int i;
        -:  100:  
    14661:  101:  for (i = 0; entries[i] != NULL; i++)
branch  0 taken 53%
branch  1 taken 47% (fallthrough)
     7797:  102:    dbus_address_entry_free (entries[i]);
call    0 returned 100%
     6864:  103:  dbus_free (entries);
call    0 returned 100%
     6864:  104:}
        -:  105:
        -:  106:static DBusAddressEntry *
        -:  107:create_entry (void)
function create_entry called 7944 returned 100% blocks executed 100%
     7944:  108:{
        -:  109:  DBusAddressEntry *entry;
        -:  110:
     7944:  111:  entry = dbus_new0 (DBusAddressEntry, 1);
call    0 returned 100%
        -:  112:
     7944:  113:  if (entry == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        6:  114:    return NULL;
        -:  115:
     7938:  116:  if (!_dbus_string_init (&entry->method))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  117:    {
        6:  118:      dbus_free (entry);
call    0 returned 100%
        6:  119:      return NULL;
        -:  120:    }
        -:  121:
     7932:  122:  return entry;
        -:  123:}
        -:  124:
        -:  125:/**
        -:  126: * Returns the method string of an address entry.
        -:  127: *
        -:  128: * @param entry the entry.
        -:  129: * @returns a string describing the method. This string
        -:  130: * must not be freed.
        -:  131: */
        -:  132:const char *
        -:  133:dbus_address_entry_get_method (DBusAddressEntry *entry)
function dbus_address_entry_get_method called 6863 returned 100% blocks executed 100%
     6863:  134:{
     6863:  135:  return _dbus_string_get_const_data (&entry->method);
call    0 returned 100%
        -:  136:}
        -:  137:
        -:  138:/**
        -:  139: * Returns a value from a key of an entry.
        -:  140: *
        -:  141: * @param entry the entry.
        -:  142: * @param key the key.
        -:  143: * @returns the key value. This string must not be freed.
        -:  144: */
        -:  145:const char *
        -:  146:dbus_address_entry_get_value (DBusAddressEntry *entry,
        -:  147:			      const char       *key)
function dbus_address_entry_get_value called 27859 returned 100% blocks executed 100%
    27859:  148:{
        -:  149:  DBusList *values, *keys;
        -:  150:
    27859:  151:  keys = _dbus_list_get_first_link (&entry->keys);
call    0 returned 100%
    27859:  152:  values = _dbus_list_get_first_link (&entry->values);
call    0 returned 100%
        -:  153:
    78570:  154:  while (keys != NULL)
branch  0 taken 62%
branch  1 taken 38% (fallthrough)
        -:  155:    {
    31580:  156:      _dbus_assert (values != NULL);
call    0 returned 100%
        -:  157:
    31580:  158:      if (_dbus_string_equal_c_str (keys->data, key))
call    0 returned 100%
branch  1 taken 28% (fallthrough)
branch  2 taken 72%
     8728:  159:        return _dbus_string_get_const_data (values->data);
call    0 returned 100%
        -:  160:
    22852:  161:      keys = _dbus_list_get_next_link (&entry->keys, keys);
branch  0 taken 16% (fallthrough)
branch  1 taken 84%
    22852:  162:      values = _dbus_list_get_next_link (&entry->values, values);
branch  0 taken 16% (fallthrough)
branch  1 taken 84%
        -:  163:    }
        -:  164:  
    19131:  165:  return NULL;
        -:  166:}
        -:  167:
        -:  168:#define _DBUS_ADDRESS_OPTIONALLY_ESCAPED_BYTE(b)        \
        -:  169:         (((b) >= 'a' && (b) <= 'z') ||                 \
        -:  170:          ((b) >= 'A' && (b) <= 'Z') ||                 \
        -:  171:          ((b) >= '0' && (b) <= '9') ||                 \
        -:  172:          (b) == '-' ||                                 \
        -:  173:          (b) == '_' ||                                 \
        -:  174:          (b) == '/' ||                                 \
        -:  175:          (b) == '\\' ||                                \
        -:  176:          (b) == '.')
        -:  177:
        -:  178:/**
        -:  179: * Appends an escaped version of one string to another string,
        -:  180: * using the D-BUS address escaping mechanism
        -:  181: *
        -:  182: * @param escaped the string to append to
        -:  183: * @param unescaped the string to escape
        -:  184: * @returns #FALSE if no memory
        -:  185: */
        -:  186:dbus_bool_t
        -:  187:_dbus_address_append_escaped (DBusString       *escaped,
        -:  188:                              const DBusString *unescaped)
function _dbus_address_append_escaped called 32 returned 100% blocks executed 87%
       32:  189:{
        -:  190:  const char *p;
        -:  191:  const char *end;
        -:  192:  dbus_bool_t ret;
        -:  193:  int orig_len;
        -:  194:
       32:  195:  ret = FALSE;
        -:  196:
       32:  197:  orig_len = _dbus_string_get_length (escaped);
call    0 returned 100%
       32:  198:  p = _dbus_string_get_const_data (unescaped);
call    0 returned 100%
       32:  199:  end = p + _dbus_string_get_length (unescaped);
call    0 returned 100%
      267:  200:  while (p != end)
branch  0 taken 86%
branch  1 taken 14% (fallthrough)
        -:  201:    {
      399:  202:      if (_DBUS_ADDRESS_OPTIONALLY_ESCAPED_BYTE (*p))
branch  0 taken 77% (fallthrough)
branch  1 taken 23%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 40% (fallthrough)
branch  5 taken 60%
branch  6 taken 5% (fallthrough)
branch  7 taken 95%
branch  8 taken 17% (fallthrough)
branch  9 taken 83%
branch 10 taken 20% (fallthrough)
branch 11 taken 80%
branch 12 taken 76% (fallthrough)
branch 13 taken 24%
branch 14 taken 95% (fallthrough)
branch 15 taken 5%
branch 16 taken 50% (fallthrough)
branch 17 taken 50%
branch 18 taken 100% (fallthrough)
branch 19 taken 0%
branch 20 taken 22% (fallthrough)
branch 21 taken 78%
        -:  203:        {
      196:  204:          if (!_dbus_string_append_byte (escaped, *p))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  205:            goto out;
        -:  206:        }
        -:  207:      else
        -:  208:        {
        7:  209:          if (!_dbus_string_append_byte (escaped, '%'))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  210:            goto out;
        7:  211:          if (!_dbus_string_append_byte_as_hex (escaped, *p))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  212:            goto out;
        -:  213:        }
        -:  214:      
      203:  215:      ++p;
        -:  216:    }
        -:  217:
       32:  218:  ret = TRUE;
        -:  219:  
       32:  220: out:
       32:  221:  if (!ret)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  222:    _dbus_string_set_length (escaped, orig_len);
call    0 never executed
       32:  223:  return ret;
        -:  224:}
        -:  225:
        -:  226:static dbus_bool_t
        -:  227:append_unescaped_value (DBusString       *unescaped,
        -:  228:                        const DBusString *escaped,
        -:  229:                        int               escaped_start,
        -:  230:                        int               escaped_len,
        -:  231:                        DBusError        *error)
function append_unescaped_value called 9773 returned 100% blocks executed 96%
     9773:  232:{
        -:  233:  const char *p;
        -:  234:  const char *end;
        -:  235:  dbus_bool_t ret;
        -:  236:  
     9773:  237:  ret = FALSE;
        -:  238:
     9773:  239:  p = _dbus_string_get_const_data (escaped) + escaped_start;
call    0 returned 100%
     9773:  240:  end = p + escaped_len;
   173596:  241:  while (p != end)
branch  0 taken 94%
branch  1 taken 6% (fallthrough)
        -:  242:    {
   308170:  243:      if (_DBUS_ADDRESS_OPTIONALLY_ESCAPED_BYTE (*p))
branch  0 taken 64% (fallthrough)
branch  1 taken 36%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
branch  4 taken 5% (fallthrough)
branch  5 taken 95%
branch  6 taken 1% (fallthrough)
branch  7 taken 99%
branch  8 taken 82% (fallthrough)
branch  9 taken 18%
branch 10 taken 1% (fallthrough)
branch 11 taken 99%
branch 12 taken 19% (fallthrough)
branch 13 taken 81%
branch 14 taken 99% (fallthrough)
branch 15 taken 1%
branch 16 taken 1% (fallthrough)
branch 17 taken 99%
branch 18 taken 100% (fallthrough)
branch 19 taken 0%
branch 20 taken 18% (fallthrough)
branch 21 taken 82%
        -:  244:        {
   154109:  245:          if (!_dbus_string_append_byte (unescaped, *p))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
       66:  246:            goto out;
        -:  247:        }
       18:  248:      else if (*p == '%')
branch  0 taken 83% (fallthrough)
branch  1 taken 17%
        -:  249:        {
        -:  250:          /* Efficiency is king */
        -:  251:          char buf[3];
        -:  252:          DBusString hex;
        -:  253:          int hex_end;
        -:  254:          
       15:  255:          ++p;
        -:  256:
       15:  257:          if ((p + 2) > end)
branch  0 taken 33% (fallthrough)
branch  1 taken 67%
        -:  258:            {
        5:  259:              dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
call    0 returned 100%
        -:  260:                              "In D-BUS address, percent character was not followed by two hex digits");
        5:  261:              goto out;
        -:  262:            }
        -:  263:            
       10:  264:          buf[0] = *p;
       10:  265:          ++p;
       10:  266:          buf[1] = *p;
       10:  267:          buf[2] = '\0';
        -:  268:
       10:  269:          _dbus_string_init_const (&hex, buf);
call    0 returned 100%
        -:  270:
       10:  271:          if (!_dbus_string_hex_decode (&hex, 0, &hex_end,
call    0 returned 100%
call    1 returned 100%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
        -:  272:                                        unescaped,
        -:  273:                                        _dbus_string_get_length (unescaped)))
    #####:  274:            goto out;
        -:  275:
       10:  276:          if (hex_end != 2)
branch  0 taken 30% (fallthrough)
branch  1 taken 70%
        -:  277:            {
        3:  278:              dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
call    0 returned 100%
        -:  279:                              "In D-BUS address, percent character was followed by characters other than hex digits");
        3:  280:              goto out;
        -:  281:            }
        -:  282:        }
        -:  283:      else
        -:  284:        {
        -:  285:          /* Error, should have been escaped */
        3:  286:          dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
call    0 returned 100%
        -:  287:                          "In D-BUS address, character '%c' should have been escaped\n",
        -:  288:                          *p);
        3:  289:          goto out;
        -:  290:        }
        -:  291:      
   154050:  292:      ++p;
        -:  293:    }
        -:  294:
     9696:  295:  ret = TRUE;
        -:  296:  
     9773:  297: out:
     9773:  298:  if (!ret && error && !dbus_error_is_set (error))
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
call    4 returned 100%
branch  5 taken 86% (fallthrough)
branch  6 taken 14%
       66:  299:    _DBUS_SET_OOM (error);
call    0 returned 100%
        -:  300:
     9773:  301:  _dbus_assert (ret || error == NULL || dbus_error_is_set (error));
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
call    4 returned 100%
branch  5 taken 100% (fallthrough)
branch  6 taken 0%
call    7 returned 100%
        -:  302:  
     9773:  303:  return ret;
        -:  304:}
        -:  305:
        -:  306:/**
        -:  307: * Parses an address string of the form:
        -:  308: *
        -:  309: * method:key=value,key=value;method:key=value
        -:  310: *
        -:  311: * See the D-BUS specification for complete docs on the format.
        -:  312: * 
        -:  313: * @param address the address.
        -:  314: * @param entry return location to an array of entries.
        -:  315: * @param array_len return location for array length.
        -:  316: * @param error address where an error can be returned.
        -:  317: * @returns #TRUE on success, #FALSE otherwise.
        -:  318: */
        -:  319:dbus_bool_t
        -:  320:dbus_parse_address (const char         *address,
        -:  321:		    DBusAddressEntry ***entry,
        -:  322:		    int                *array_len,
        -:  323:                    DBusError          *error)
function dbus_parse_address called 7010 returned 100% blocks executed 98%
     7010:  324:{
        -:  325:  DBusString str;
        -:  326:  int pos, end_pos, len, i;
        -:  327:  DBusList *entries, *link;
        -:  328:  DBusAddressEntry **entry_array;
        -:  329:
     7010:  330:  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
call    5 returned 100%
        -:  331:  
     7010:  332:  _dbus_string_init_const (&str, address);
call    0 returned 100%
        -:  333:
     7010:  334:  entries = NULL;
     7010:  335:  pos = 0;
     7010:  336:  len = _dbus_string_get_length (&str);
call    0 returned 100%
        -:  337:  
    21824:  338:  while (pos < len)
branch  0 taken 54%
branch  1 taken 46% (fallthrough)
        -:  339:    {
        -:  340:      DBusAddressEntry *entry;
        -:  341:
        -:  342:      int found_pos;
        -:  343:
     7944:  344:      entry = create_entry ();
call    0 returned 100%
     7944:  345:      if (!entry)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  346:	{
       12:  347:	  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        -:  348:
       12:  349:	  goto error;
        -:  350:	}
        -:  351:      
        -:  352:      /* Append the entry */
     7932:  353:      if (!_dbus_list_append (&entries, entry))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  354:	{
        6:  355:	  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        6:  356:	  dbus_address_entry_free (entry);
call    0 returned 100%
        6:  357:	  goto error;
        -:  358:	}
        -:  359:      
        -:  360:      /* Look for a semi-colon */
     7926:  361:      if (!_dbus_string_find (&str, pos, ";", &end_pos))
call    0 returned 100%
branch  1 taken 88% (fallthrough)
branch  2 taken 12%
     6991:  362:	end_pos = len;
        -:  363:      
        -:  364:      /* Look for the colon : */
     7926:  365:      if (!_dbus_string_find_to (&str, pos, end_pos, ":", &found_pos))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  366:	{
        2:  367:	  dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Address does not contain a colon");
call    0 returned 100%
        2:  368:	  goto error;
        -:  369:	}
        -:  370:
     7924:  371:      if (!_dbus_string_copy_len (&str, pos, found_pos - pos, &entry->method, 0))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  372:	{
        6:  373:	  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        6:  374:	  goto error;
        -:  375:	}
        -:  376:	  
     7918:  377:      pos = found_pos + 1;
        -:  378:
    25503:  379:      while (pos < end_pos)
branch  0 taken 56%
branch  1 taken 44% (fallthrough)
        -:  380:	{
        -:  381:	  int comma_pos, equals_pos;
        -:  382:
     9781:  383:	  if (!_dbus_string_find_to (&str, pos, end_pos, ",", &comma_pos))
call    0 returned 100%
branch  1 taken 81% (fallthrough)
branch  2 taken 19%
     7916:  384:	    comma_pos = end_pos;
        -:  385:	  
     9781:  386:	  if (!_dbus_string_find_to (&str, pos, comma_pos, "=", &equals_pos) ||
call    0 returned 100%
branch  1 taken 99% (fallthrough)
branch  2 taken 1%
branch  3 taken 99% (fallthrough)
branch  4 taken 1%
branch  5 taken 1% (fallthrough)
branch  6 taken 99%
        -:  387:	      equals_pos == pos || equals_pos + 1 == comma_pos)
        -:  388:	    {
        6:  389:	      dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
call    0 returned 100%
        -:  390:                              "'=' character not found or has no value following it");
        6:  391:              goto error;
        -:  392:	    }
        -:  393:	  else
        -:  394:	    {
        -:  395:	      DBusString *key;
        -:  396:	      DBusString *value;
        -:  397:
     9775:  398:	      key = dbus_new0 (DBusString, 1);
call    0 returned 100%
        -:  399:
     9775:  400:	      if (!key)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  401:		{
        6:  402:		  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);		  
call    0 returned 100%
        6:  403:		  goto error;
        -:  404:		}
        -:  405:
     9769:  406:	      value = dbus_new0 (DBusString, 1);
call    0 returned 100%
     9769:  407:	      if (!value)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  408:		{
        6:  409:		  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        6:  410:		  dbus_free (key);
call    0 returned 100%
        6:  411:		  goto error;
        -:  412:		}
        -:  413:	      
     9763:  414:	      if (!_dbus_string_init (key))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  415:		{
        6:  416:		  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        6:  417:		  dbus_free (key);
call    0 returned 100%
        6:  418:		  dbus_free (value);
call    0 returned 100%
        -:  419:		  
        6:  420:		  goto error;
        -:  421:		}
        -:  422:	      
     9757:  423:	      if (!_dbus_string_init (value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  424:		{
        6:  425:		  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        6:  426:		  _dbus_string_free (key);
call    0 returned 100%
        -:  427:
        6:  428:		  dbus_free (key);
call    0 returned 100%
        6:  429:		  dbus_free (value);		  
call    0 returned 100%
        6:  430:		  goto error;
        -:  431:		}
        -:  432:
     9751:  433:	      if (!_dbus_string_copy_len (&str, pos, equals_pos - pos, key, 0))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  434:		{
        6:  435:		  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        6:  436:		  _dbus_string_free (key);
call    0 returned 100%
        6:  437:		  _dbus_string_free (value);
call    0 returned 100%
        -:  438:
        6:  439:		  dbus_free (key);
call    0 returned 100%
        6:  440:		  dbus_free (value);		  
call    0 returned 100%
        6:  441:		  goto error;
        -:  442:		}
        -:  443:
     9745:  444:	      if (!append_unescaped_value (value, &str, equals_pos + 1,
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  445:                                           comma_pos - equals_pos - 1, error))
        -:  446:		{
       66:  447:                  _dbus_assert (error == NULL || dbus_error_is_set (error));
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
call    2 returned 100%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
call    5 returned 100%
       66:  448:		  _dbus_string_free (key);
call    0 returned 100%
       66:  449:		  _dbus_string_free (value);
call    0 returned 100%
        -:  450:
       66:  451:		  dbus_free (key);
call    0 returned 100%
       66:  452:		  dbus_free (value);		  
call    0 returned 100%
       66:  453:		  goto error;
        -:  454:		}
        -:  455:
     9679:  456:	      if (!_dbus_list_append (&entry->keys, key))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  457:		{
        6:  458:		  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);		  
call    0 returned 100%
        6:  459:		  _dbus_string_free (key);
call    0 returned 100%
        6:  460:		  _dbus_string_free (value);
call    0 returned 100%
        -:  461:
        6:  462:		  dbus_free (key);
call    0 returned 100%
        6:  463:		  dbus_free (value);		  
call    0 returned 100%
        6:  464:		  goto error;
        -:  465:		}
        -:  466:
     9673:  467:	      if (!_dbus_list_append (&entry->values, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  468:		{
        6:  469:		  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);		  
call    0 returned 100%
        6:  470:		  _dbus_string_free (value);
call    0 returned 100%
        -:  471:
        6:  472:		  dbus_free (value);
call    0 returned 100%
        6:  473:		  goto error;		  
        -:  474:		}
        -:  475:	    }
        -:  476:
     9667:  477:	  pos = comma_pos + 1;
        -:  478:	}
        -:  479:
     7804:  480:      pos = end_pos + 1;
        -:  481:    }
        -:  482:
     6870:  483:  *array_len = _dbus_list_get_length (&entries);
call    0 returned 100%
        -:  484:  
     6870:  485:  entry_array = dbus_new (DBusAddressEntry *, *array_len + 1);
call    0 returned 100%
        -:  486:
     6870:  487:  if (!entry_array)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  488:    {
        6:  489:      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
call    0 returned 100%
        -:  490:      
        6:  491:      goto error;
        -:  492:    }
        -:  493:  
     6864:  494:  entry_array [*array_len] = NULL;
        -:  495:
     6864:  496:  link = _dbus_list_get_first_link (&entries);
call    0 returned 100%
     6864:  497:  i = 0;
    21525:  498:  while (link != NULL)
branch  0 taken 53%
branch  1 taken 47% (fallthrough)
        -:  499:    {
     7797:  500:      entry_array[i] = link->data;
     7797:  501:      i++;
     7797:  502:      link = _dbus_list_get_next_link (&entries, link);
branch  0 taken 12% (fallthrough)
branch  1 taken 88%
        -:  503:    }
        -:  504:
     6864:  505:  _dbus_list_clear (&entries);
call    0 returned 100%
     6864:  506:  *entry = entry_array;
        -:  507:
     6864:  508:  return TRUE;
        -:  509:
      146:  510: error:
        -:  511:  
      146:  512:  link = _dbus_list_get_first_link (&entries);
call    0 returned 100%
      421:  513:  while (link != NULL)
branch  0 taken 47%
branch  1 taken 53% (fallthrough)
        -:  514:    {
      129:  515:      dbus_address_entry_free (link->data);
call    0 returned 100%
      129:  516:      link = _dbus_list_get_next_link (&entries, link);
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  517:    }
        -:  518:
      146:  519:  _dbus_list_clear (&entries);
call    0 returned 100%
        -:  520:  
      146:  521:  return FALSE;
        -:  522:  
        -:  523:}
        -:  524:
        -:  525:/**
        -:  526: * Escapes the given string as a value in a key=value pair
        -:  527: * for a D-BUS address.
        -:  528: *
        -:  529: * @param value the unescaped value
        -:  530: * @returns newly-allocated escaped value or #NULL if no memory
        -:  531: */
        -:  532:char*
        -:  533:dbus_address_escape_value (const char *value)
function dbus_address_escape_value called 17 returned 100% blocks executed 83%
       17:  534:{
        -:  535:  DBusString escaped;
        -:  536:  DBusString unescaped;
        -:  537:  char *ret;
        -:  538:
       17:  539:  ret = NULL;
        -:  540:
       17:  541:  _dbus_string_init_const (&unescaped, value);
call    0 returned 100%
        -:  542:  
       17:  543:  if (!_dbus_string_init (&escaped))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  544:    return NULL;
        -:  545:
       17:  546:  if (!_dbus_address_append_escaped (&escaped, &unescaped))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  547:    goto out;
        -:  548:  
       17:  549:  if (!_dbus_string_steal_data (&escaped, &ret))
call    0 returned 100%
       17:  550:    goto out;
        -:  551:
       17:  552: out:
       17:  553:  _dbus_string_free (&escaped);
call    0 returned 100%
       17:  554:  return ret;
        -:  555:}
        -:  556:
        -:  557:/**
        -:  558: * Unescapes the given string as a value in a key=value pair
        -:  559: * for a D-BUS address.
        -:  560: *
        -:  561: * @param value the escaped value
        -:  562: * @param error error to set if the unescaping fails
        -:  563: * @returns newly-allocated unescaped value or #NULL if no memory
        -:  564: */
        -:  565:char*
        -:  566:dbus_address_unescape_value (const char *value,
        -:  567:                             DBusError  *error)
function dbus_address_unescape_value called 28 returned 100% blocks executed 88%
       28:  568:{
        -:  569:  DBusString unescaped;
        -:  570:  DBusString escaped;
        -:  571:  char *ret;
        -:  572:  
       28:  573:  ret = NULL;
        -:  574:
       28:  575:  _dbus_string_init_const (&escaped, value);
call    0 returned 100%
        -:  576:  
       28:  577:  if (!_dbus_string_init (&unescaped))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  578:    return NULL;
        -:  579:
       28:  580:  if (!append_unescaped_value (&unescaped, &escaped,
call    0 returned 100%
call    1 returned 100%
branch  2 taken 39% (fallthrough)
branch  3 taken 61%
        -:  581:                               0, _dbus_string_get_length (&escaped),
        -:  582:                               error))
       11:  583:    goto out;
        -:  584:  
       17:  585:  if (!_dbus_string_steal_data (&unescaped, &ret))
call    0 returned 100%
       17:  586:    goto out;
        -:  587:
       28:  588: out:
       28:  589:  if (ret == NULL && error && !dbus_error_is_set (error))
branch  0 taken 39% (fallthrough)
branch  1 taken 61%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
call    4 returned 100%
branch  5 taken 0% (fallthrough)
branch  6 taken 100%
    #####:  590:    _DBUS_SET_OOM (error);
call    0 never executed
        -:  591:
       28:  592:  _dbus_assert (ret != NULL || error == NULL || dbus_error_is_set (error));
branch  0 taken 39% (fallthrough)
branch  1 taken 61%
branch  2 taken 100% (fallthrough)
branch  3 taken 0%
call    4 returned 100%
branch  5 taken 100% (fallthrough)
branch  6 taken 0%
call    7 returned 100%
        -:  593:  
       28:  594:  _dbus_string_free (&unescaped);
call    0 returned 100%
       28:  595:  return ret;
        -:  596:}
        -:  597:
        -:  598:/** @} */ /* End of public API */
        -:  599:
        -:  600:#ifdef DBUS_BUILD_TESTS
        -:  601:#include "dbus-test.h"
        -:  602:#include <stdlib.h>
        -:  603:
        -:  604:typedef struct
        -:  605:{
        -:  606:  const char *escaped;
        -:  607:  const char *unescaped;
        -:  608:} EscapeTest;
        -:  609:
        -:  610:static const EscapeTest escape_tests[] = {
        -:  611:  { "abcde", "abcde" },
        -:  612:  { "", "" },
        -:  613:  { "%20%20", "  " },
        -:  614:  { "%24", "$" },
        -:  615:  { "%25", "%" },
        -:  616:  { "abc%24", "abc$" },
        -:  617:  { "%24abc", "$abc" },
        -:  618:  { "abc%24abc", "abc$abc" },
        -:  619:  { "/", "/" },
        -:  620:  { "-", "-" },
        -:  621:  { "_", "_" },
        -:  622:  { "A", "A" },
        -:  623:  { "I", "I" },
        -:  624:  { "Z", "Z" },
        -:  625:  { "a", "a" },
        -:  626:  { "i", "i" },
        -:  627:  { "z", "z" }
        -:  628:};
        -:  629:
        -:  630:static const char* invalid_escaped_values[] = {
        -:  631:  "%a",
        -:  632:  "%q",
        -:  633:  "%az",
        -:  634:  "%%",
        -:  635:  "%$$",
        -:  636:  "abc%a",
        -:  637:  "%axyz",
        -:  638:  "%",
        -:  639:  "$",
        -:  640:  " ",
        -:  641:  "*"
        -:  642:};
        -:  643:
        -:  644:dbus_bool_t
        -:  645:_dbus_address_test (void)
function _dbus_address_test called 1 returned 100% blocks executed 75%
        1:  646:{
        -:  647:  DBusAddressEntry **entries;
        -:  648:  int len;  
        -:  649:  DBusError error;
        -:  650:  int i;
        -:  651:
        1:  652:  dbus_error_init (&error);
call    0 returned 100%
        -:  653:
        1:  654:  i = 0;
       19:  655:  while (i < _DBUS_N_ELEMENTS (escape_tests))
branch  0 taken 94%
branch  1 taken 6% (fallthrough)
        -:  656:    {
       17:  657:      const EscapeTest *test = &escape_tests[i];
        -:  658:      char *escaped;
        -:  659:      char *unescaped;
        -:  660:
       17:  661:      escaped = dbus_address_escape_value (test->unescaped);
call    0 returned 100%
       17:  662:      if (escaped == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  663:        _dbus_assert_not_reached ("oom");
call    0 never executed
        -:  664:
       17:  665:      if (strcmp (escaped, test->escaped) != 0)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  666:        {
    #####:  667:          _dbus_warn ("Escaped '%s' as '%s' should have been '%s'\n",
call    0 never executed
        -:  668:                      test->unescaped, escaped, test->escaped);
    #####:  669:          exit (1);
call    0 never executed
        -:  670:        }
       17:  671:      dbus_free (escaped);
call    0 returned 100%
        -:  672:
       17:  673:      unescaped = dbus_address_unescape_value (test->escaped, &error);
call    0 returned 100%
       17:  674:      if (unescaped == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  675:        {
    #####:  676:          _dbus_warn ("Failed to unescape '%s': %s\n",
call    0 never executed
        -:  677:                      test->escaped, error.message);
    #####:  678:          dbus_error_free (&error);
call    0 never executed
    #####:  679:          exit (1);
call    0 never executed
        -:  680:        }
        -:  681:
       17:  682:      if (strcmp (unescaped, test->unescaped) != 0)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  683:        {
    #####:  684:          _dbus_warn ("Unescaped '%s' as '%s' should have been '%s'\n",
call    0 never executed
        -:  685:                      test->escaped, unescaped, test->unescaped);
    #####:  686:          exit (1);
call    0 never executed
        -:  687:        }
       17:  688:      dbus_free (unescaped);
call    0 returned 100%
        -:  689:      
       17:  690:      ++i;
        -:  691:    }
        -:  692:
        1:  693:  i = 0;
       13:  694:  while (i < _DBUS_N_ELEMENTS (invalid_escaped_values))
branch  0 taken 92%
branch  1 taken 8% (fallthrough)
        -:  695:    {
        -:  696:      char *unescaped;
        -:  697:
       11:  698:      unescaped = dbus_address_unescape_value (invalid_escaped_values[i],
call    0 returned 100%
        -:  699:                                               &error);
       11:  700:      if (unescaped != NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  701:        {
    #####:  702:          _dbus_warn ("Should not have successfully unescaped '%s' to '%s'\n",
call    0 never executed
        -:  703:                      invalid_escaped_values[i], unescaped);
    #####:  704:          dbus_free (unescaped);
call    0 never executed
    #####:  705:          exit (1);
call    0 never executed
        -:  706:        }
        -:  707:
       11:  708:      _dbus_assert (dbus_error_is_set (&error));
call    0 returned 100%
call    1 returned 100%
       11:  709:      dbus_error_free (&error);
call    0 returned 100%
        -:  710:
       11:  711:      ++i;
        -:  712:    }
        -:  713:  
        1:  714:  if (!dbus_parse_address ("unix:path=/tmp/foo;debug:name=test,sliff=sloff;",
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  715:			   &entries, &len, &error))
    #####:  716:    _dbus_assert_not_reached ("could not parse address");
call    0 never executed
        1:  717:  _dbus_assert (len == 2);
call    0 returned 100%
        1:  718:  _dbus_assert (strcmp (dbus_address_entry_get_value (entries[0], "path"), "/tmp/foo") == 0);
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
        1:  719:  _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "name"), "test") == 0);
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
        1:  720:  _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "sliff"), "sloff") == 0);
call    0 returned 100%
call    1 returned 100%
call    2 returned 100%
        -:  721:  
        1:  722:  dbus_address_entries_free (entries);
call    0 returned 100%
        -:  723:
        -:  724:  /* Different possible errors */
        1:  725:  if (dbus_parse_address ("foo", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  726:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  727:  else
        1:  728:    dbus_error_free (&error);
call    0 returned 100%
        -:  729:  
        1:  730:  if (dbus_parse_address ("foo:bar", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  731:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  732:  else
        1:  733:    dbus_error_free (&error);
call    0 returned 100%
        -:  734:  
        1:  735:  if (dbus_parse_address ("foo:bar,baz", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  736:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  737:  else
        1:  738:    dbus_error_free (&error);
call    0 returned 100%
        -:  739:  
        1:  740:  if (dbus_parse_address ("foo:bar=foo,baz", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  741:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  742:  else
        1:  743:    dbus_error_free (&error);
call    0 returned 100%
        -:  744:  
        1:  745:  if (dbus_parse_address ("foo:bar=foo;baz", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  746:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  747:  else
        1:  748:    dbus_error_free (&error);
call    0 returned 100%
        -:  749:  
        1:  750:  if (dbus_parse_address ("foo:=foo", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  751:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  752:  else
        1:  753:    dbus_error_free (&error);
call    0 returned 100%
        -:  754:  
        1:  755:  if (dbus_parse_address ("foo:foo=", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  756:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  757:  else
        1:  758:    dbus_error_free (&error);
call    0 returned 100%
        -:  759:
        1:  760:  if (dbus_parse_address ("foo:foo,bar=baz", &entries, &len, &error))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####:  761:    _dbus_assert_not_reached ("Parsed incorrect address.");
call    0 never executed
        -:  762:  else
        1:  763:    dbus_error_free (&error);
call    0 returned 100%
        -:  764:
        1:  765:  return TRUE;
        -:  766:}
        -:  767:
        -:  768:#endif