Coverage report for bus/signals.c.gcov

        -:    0:Source:signals.c
        -:    0:Graph:signals.gcno
        -:    0:Data:signals.gcda
        -:    0:Runs:10114
        -:    0:Programs:2
        -:    1:/* -*- mode: C; c-file-style: "gnu" -*- */
        -:    2:/* signals.c  Bus signal connection implementation
        -:    3: *
        -:    4: * Copyright (C) 2003, 2005  Red Hat, Inc.
        -:    5: *
        -:    6: * Licensed under the Academic Free License version 2.1
        -:    7: *
        -:    8: * This program is free software; you can redistribute it and/or modify
        -:    9: * it under the terms of the GNU General Public License as published by
        -:   10: * the Free Software Foundation; either version 2 of the License, or
        -:   11: * (at your option) any later version.
        -:   12: *
        -:   13: * This program is distributed in the hope that it will be useful,
        -:   14: * but WITHOUT ANY WARRANTY; without even the implied warranty of
        -:   15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        -:   16: * GNU General Public License for more details.
        -:   17: *
        -:   18: * You should have received a copy of the GNU General Public License
        -:   19: * along with this program; if not, write to the Free Software
        -:   20: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        -:   21: *
        -:   22: */
        -:   23:#include "signals.h"
        -:   24:#include "services.h"
        -:   25:#include "utils.h"
        -:   26:#include <dbus/dbus-marshal-validate.h>
        -:   27:
        -:   28:struct BusMatchRule
        -:   29:{
        -:   30:  int refcount;       /**< reference count */
        -:   31:
        -:   32:  DBusConnection *matches_go_to; /**< Owner of the rule */
        -:   33:
        -:   34:  unsigned int flags; /**< BusMatchFlags */
        -:   35:
        -:   36:  int   message_type;
        -:   37:  char *interface;
        -:   38:  char *member;
        -:   39:  char *sender;
        -:   40:  char *destination;
        -:   41:  char *path;
        -:   42:
        -:   43:  char **args;
        -:   44:  int args_len;
        -:   45:};
        -:   46:
        -:   47:BusMatchRule*
        -:   48:bus_match_rule_new (DBusConnection *matches_go_to)
function bus_match_rule_new called 45754 returned 100% blocks executed 100%
    45754:   49:{
        -:   50:  BusMatchRule *rule;
        -:   51:
    45754:   52:  rule = dbus_new0 (BusMatchRule, 1);
call    0 returned 100%
    45754:   53:  if (rule == NULL)
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
     1709:   54:    return NULL;
        -:   55:
    44045:   56:  rule->refcount = 1;
    44045:   57:  rule->matches_go_to = matches_go_to;
        -:   58:
        -:   59:#ifndef DBUS_BUILD_TESTS
        -:   60:  _dbus_assert (rule->matches_go_to != NULL);
        -:   61:#endif
        -:   62:  
    44045:   63:  return rule;
        -:   64:}
        -:   65:
        -:   66:BusMatchRule *
        -:   67:bus_match_rule_ref (BusMatchRule *rule)
function bus_match_rule_ref called 3308 returned 100% blocks executed 100%
     3308:   68:{
     3308:   69:  _dbus_assert (rule->refcount > 0);
call    0 returned 100%
        -:   70:
     3308:   71:  rule->refcount += 1;
        -:   72:
     3308:   73:  return rule;
        -:   74:}
        -:   75:
        -:   76:void
        -:   77:bus_match_rule_unref (BusMatchRule *rule)
function bus_match_rule_unref called 47353 returned 100% blocks executed 100%
    47353:   78:{
    47353:   79:  _dbus_assert (rule->refcount > 0);
call    0 returned 100%
        -:   80:
    47353:   81:  rule->refcount -= 1;
    47353:   82:  if (rule->refcount == 0)
branch  0 taken 93% (fallthrough)
branch  1 taken 7%
        -:   83:    {
    44045:   84:      dbus_free (rule->interface);
call    0 returned 100%
    44045:   85:      dbus_free (rule->member);
call    0 returned 100%
    44045:   86:      dbus_free (rule->sender);
call    0 returned 100%
    44045:   87:      dbus_free (rule->destination);
call    0 returned 100%
    44045:   88:      dbus_free (rule->path);
call    0 returned 100%
        -:   89:
        -:   90:      /* can't use dbus_free_string_array() since there
        -:   91:       * are embedded NULL
        -:   92:       */
    44045:   93:      if (rule->args)
branch  0 taken 29% (fallthrough)
branch  1 taken 71%
        -:   94:        {
        -:   95:          int i;
        -:   96:
    12750:   97:          i = 0;
   262462:   98:          while (i < rule->args_len)
branch  0 taken 95%
branch  1 taken 5% (fallthrough)
        -:   99:            {
   236962:  100:              if (rule->args[i])
branch  0 taken 5% (fallthrough)
branch  1 taken 95%
    12772:  101:                dbus_free (rule->args[i]);
call    0 returned 100%
   236962:  102:              ++i;
        -:  103:            }
        -:  104:
    12750:  105:          dbus_free (rule->args);
call    0 returned 100%
        -:  106:        }
        -:  107:      
    44045:  108:      dbus_free (rule);
call    0 returned 100%
        -:  109:    }
    47353:  110:}
        -:  111:
        -:  112:#ifdef DBUS_ENABLE_VERBOSE_MODE
        -:  113:/* Note this function does not do escaping, so it's only
        -:  114: * good for debug spew at the moment
        -:  115: */
        -:  116:static char*
        -:  117:match_rule_to_string (BusMatchRule *rule)
function match_rule_to_string called 78724 returned 100% blocks executed 28%
    78724:  118:{
        -:  119:  DBusString str;
        -:  120:  char *ret;
        -:  121:  
    78724:  122:  if (!_dbus_string_init (&str))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  123:    {
        -:  124:      char *s;
      270:  125:      while ((s = _dbus_strdup ("nomem")) == NULL)
call    0 returned 100%
branch  1 taken 47%
branch  2 taken 53% (fallthrough)
        -:  126:        ; /* only OK for debug spew... */
      144:  127:      return s;
        -:  128:    }
        -:  129:  
    78580:  130:  if (rule->flags & BUS_MATCH_MESSAGE_TYPE)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  131:    {
        -:  132:      /* FIXME make type readable */
    #####:  133:      if (!_dbus_string_append_printf (&str, "type='%d'", rule->message_type))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  134:        goto nomem;
        -:  135:    }
        -:  136:
    78580:  137:  if (rule->flags & BUS_MATCH_INTERFACE)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  138:    {
    #####:  139:      if (_dbus_string_get_length (&str) > 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  140:        {
    #####:  141:          if (!_dbus_string_append (&str, ","))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  142:            goto nomem;
        -:  143:        }
        -:  144:      
    #####:  145:      if (!_dbus_string_append_printf (&str, "interface='%s'", rule->interface))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  146:        goto nomem;
        -:  147:    }
        -:  148:
    78580:  149:  if (rule->flags & BUS_MATCH_MEMBER)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  150:    {
    #####:  151:      if (_dbus_string_get_length (&str) > 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  152:        {
    #####:  153:          if (!_dbus_string_append (&str, ","))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  154:            goto nomem;
        -:  155:        }
        -:  156:      
    #####:  157:      if (!_dbus_string_append_printf (&str, "member='%s'", rule->member))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  158:        goto nomem;
        -:  159:    }
        -:  160:
    78580:  161:  if (rule->flags & BUS_MATCH_PATH)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  162:    {
    #####:  163:      if (_dbus_string_get_length (&str) > 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  164:        {
    #####:  165:          if (!_dbus_string_append (&str, ","))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  166:            goto nomem;
        -:  167:        }
        -:  168:      
    #####:  169:      if (!_dbus_string_append_printf (&str, "path='%s'", rule->path))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  170:        goto nomem;
        -:  171:    }
        -:  172:
    78580:  173:  if (rule->flags & BUS_MATCH_SENDER)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  174:    {
    #####:  175:      if (_dbus_string_get_length (&str) > 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  176:        {
    #####:  177:          if (!_dbus_string_append (&str, ","))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  178:            goto nomem;
        -:  179:        }
        -:  180:      
    #####:  181:      if (!_dbus_string_append_printf (&str, "sender='%s'", rule->sender))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  182:        goto nomem;
        -:  183:    }
        -:  184:
    78580:  185:  if (rule->flags & BUS_MATCH_DESTINATION)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  186:    {
    #####:  187:      if (_dbus_string_get_length (&str) > 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  188:        {
    #####:  189:          if (!_dbus_string_append (&str, ","))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  190:            goto nomem;
        -:  191:        }
        -:  192:      
    #####:  193:      if (!_dbus_string_append_printf (&str, "destination='%s'", rule->destination))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  194:        goto nomem;
        -:  195:    }
        -:  196:
    78580:  197:  if (rule->flags & BUS_MATCH_ARGS)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  198:    {
        -:  199:      int i;
        -:  200:      
    #####:  201:      _dbus_assert (rule->args != NULL);
call    0 never executed
        -:  202:
    #####:  203:      i = 0;
    #####:  204:      while (i < rule->args_len)
branch  0 never executed
branch  1 never executed
        -:  205:        {
    #####:  206:          if (rule->args[i] != NULL)
branch  0 never executed
branch  1 never executed
        -:  207:            {
    #####:  208:              if (_dbus_string_get_length (&str) > 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  209:                {
    #####:  210:                  if (!_dbus_string_append (&str, ","))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####:  211:                    goto nomem;
        -:  212:                }
        -:  213:              
    #####:  214:              if (!_dbus_string_append_printf (&str,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  215:                                               "arg%d='%s'",
        -:  216:                                               i,
        -:  217:                                               rule->args[i]))
    #####:  218:                goto nomem;
        -:  219:            }
        -:  220:          
    #####:  221:          ++i;
        -:  222:        }
        -:  223:    }
        -:  224:  
    78580:  225:  if (!_dbus_string_steal_data (&str, &ret))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      118:  226:    goto nomem;
        -:  227:
    78462:  228:  _dbus_string_free (&str);
call    0 returned 100%
    78462:  229:  return ret;
        -:  230:  
      118:  231: nomem:
      118:  232:  _dbus_string_free (&str);
call    0 returned 100%
        -:  233:  {
        -:  234:    char *s;
      225:  235:    while ((s = _dbus_strdup ("nomem")) == NULL)
call    0 returned 100%
branch  1 taken 48%
branch  2 taken 52% (fallthrough)
        -:  236:      ;  /* only OK for debug spew... */
      118:  237:    return s;
        -:  238:  }
        -:  239:}
        -:  240:#endif /* DBUS_ENABLE_VERBOSE_MODE */
        -:  241:
        -:  242:dbus_bool_t
        -:  243:bus_match_rule_set_message_type (BusMatchRule *rule,
        -:  244:                                 int           type)
function bus_match_rule_set_message_type called 5536 returned 100% blocks executed 100%
     5536:  245:{
     5536:  246:  rule->flags |= BUS_MATCH_MESSAGE_TYPE;
        -:  247:
     5536:  248:  rule->message_type = type;
        -:  249:
     5536:  250:  return TRUE;
        -:  251:}
        -:  252:
        -:  253:dbus_bool_t
        -:  254:bus_match_rule_set_interface (BusMatchRule *rule,
        -:  255:                              const char   *interface)
function bus_match_rule_set_interface called 3829 returned 100% blocks executed 100%
     3829:  256:{
        -:  257:  char *new;
        -:  258:
     3829:  259:  _dbus_assert (interface != NULL);
call    0 returned 100%
        -:  260:
     3829:  261:  new = _dbus_strdup (interface);
call    0 returned 100%
     3829:  262:  if (new == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        9:  263:    return FALSE;
        -:  264:
     3820:  265:  rule->flags |= BUS_MATCH_INTERFACE;
     3820:  266:  dbus_free (rule->interface);
call    0 returned 100%
     3820:  267:  rule->interface = new;
        -:  268:
     3820:  269:  return TRUE;
        -:  270:}
        -:  271:
        -:  272:dbus_bool_t
        -:  273:bus_match_rule_set_member (BusMatchRule *rule,
        -:  274:                           const char   *member)
function bus_match_rule_set_member called 2565 returned 100% blocks executed 100%
     2565:  275:{
        -:  276:  char *new;
        -:  277:
     2565:  278:  _dbus_assert (member != NULL);
call    0 returned 100%
        -:  279:
     2565:  280:  new = _dbus_strdup (member);
call    0 returned 100%
     2565:  281:  if (new == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        6:  282:    return FALSE;
        -:  283:
     2559:  284:  rule->flags |= BUS_MATCH_MEMBER;
     2559:  285:  dbus_free (rule->member);
call    0 returned 100%
     2559:  286:  rule->member = new;
        -:  287:
     2559:  288:  return TRUE;
        -:  289:}
        -:  290:
        -:  291:dbus_bool_t
        -:  292:bus_match_rule_set_sender (BusMatchRule *rule,
        -:  293:                           const char   *sender)
function bus_match_rule_set_sender called 2559 returned 100% blocks executed 100%
     2559:  294:{
        -:  295:  char *new;
        -:  296:
     2559:  297:  _dbus_assert (sender != NULL);
call    0 returned 100%
        -:  298:
     2559:  299:  new = _dbus_strdup (sender);
call    0 returned 100%
     2559:  300:  if (new == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        6:  301:    return FALSE;
        -:  302:
     2553:  303:  rule->flags |= BUS_MATCH_SENDER;
     2553:  304:  dbus_free (rule->sender);
call    0 returned 100%
     2553:  305:  rule->sender = new;
        -:  306:
     2553:  307:  return TRUE;
        -:  308:}
        -:  309:
        -:  310:dbus_bool_t
        -:  311:bus_match_rule_set_destination (BusMatchRule *rule,
        -:  312:                                const char   *destination)
function bus_match_rule_set_destination called 2535 returned 100% blocks executed 100%
     2535:  313:{
        -:  314:  char *new;
        -:  315:
     2535:  316:  _dbus_assert (destination != NULL);
call    0 returned 100%
        -:  317:
     2535:  318:  new = _dbus_strdup (destination);
call    0 returned 100%
     2535:  319:  if (new == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        6:  320:    return FALSE;
        -:  321:
     2529:  322:  rule->flags |= BUS_MATCH_DESTINATION;
     2529:  323:  dbus_free (rule->destination);
call    0 returned 100%
     2529:  324:  rule->destination = new;
        -:  325:
     2529:  326:  return TRUE;
        -:  327:}
        -:  328:
        -:  329:dbus_bool_t
        -:  330:bus_match_rule_set_path (BusMatchRule *rule,
        -:  331:                         const char   *path)
function bus_match_rule_set_path called 3820 returned 100% blocks executed 100%
     3820:  332:{
        -:  333:  char *new;
        -:  334:
     3820:  335:  _dbus_assert (path != NULL);
call    0 returned 100%
        -:  336:
     3820:  337:  new = _dbus_strdup (path);
call    0 returned 100%
     3820:  338:  if (new == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        9:  339:    return FALSE;
        -:  340:
     3811:  341:  rule->flags |= BUS_MATCH_PATH;
     3811:  342:  dbus_free (rule->path);
call    0 returned 100%
     3811:  343:  rule->path = new;
        -:  344:
     3811:  345:  return TRUE;
        -:  346:}
        -:  347:
        -:  348:dbus_bool_t
        -:  349:bus_match_rule_set_arg (BusMatchRule *rule,
        -:  350:                        int           arg,
        -:  351:                        const char   *value)
function bus_match_rule_set_arg called 12820 returned 100% blocks executed 100%
    12820:  352:{
        -:  353:  char *new;
        -:  354:
    12820:  355:  _dbus_assert (value != NULL);
call    0 returned 100%
        -:  356:
    12820:  357:  new = _dbus_strdup (value);
call    0 returned 100%
    12820:  358:  if (new == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
       24:  359:    return FALSE;
        -:  360:
        -:  361:  /* args_len is the number of args not including null termination
        -:  362:   * in the char**
        -:  363:   */
    12796:  364:  if (arg >= rule->args_len)
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
        -:  365:    {
        -:  366:      char **new_args;
        -:  367:      int new_args_len;
        -:  368:      int i;
        -:  369:
    12794:  370:      new_args_len = arg + 1;
        -:  371:
        -:  372:      /* add another + 1 here for null termination */
    12794:  373:      new_args = dbus_realloc (rule->args,
call    0 returned 100%
        -:  374:                               sizeof(rule->args[0]) * (new_args_len + 1));
    12794:  375:      if (new_args == NULL)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -:  376:        {
       24:  377:          dbus_free (new);
call    0 returned 100%
       24:  378:          return FALSE;
        -:  379:        }
        -:  380:
        -:  381:      /* NULL the new slots */
    12770:  382:      i = rule->args_len;
   275272:  383:      while (i <= new_args_len) /* <= for null termination */
branch  0 taken 95%
branch  1 taken 5% (fallthrough)
        -:  384:        {
   249732:  385:          new_args[i] = NULL;
   249732:  386:          ++i;
        -:  387:        }
        -:  388:      
    12770:  389:      rule->args = new_args;
    12770:  390:      rule->args_len = new_args_len;
        -:  391:    }
        -:  392:
    12772:  393:  rule->flags |= BUS_MATCH_ARGS;
        -:  394:
    12772:  395:  dbus_free (rule->args[arg]);
call    0 returned 100%
    12772:  396:  rule->args[arg] = new;
        -:  397:
        -:  398:  /* NULL termination didn't get busted */
    12772:  399:  _dbus_assert (rule->args[rule->args_len] == NULL);
call    0 returned 100%
        -:  400:
    12772:  401:  return TRUE;
        -:  402:}
        -:  403:
        -:  404:#define ISWHITE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
        -:  405:
        -:  406:static dbus_bool_t
        -:  407:find_key (const DBusString *str,
        -:  408:          int               start,
        -:  409:          DBusString       *key,
        -:  410:          int              *value_pos,
        -:  411:          DBusError        *error)
function find_key called 62169 returned 100% blocks executed 95%
    62169:  412:{
        -:  413:  const char *p;
        -:  414:  const char *s;
        -:  415:  const char *key_start;
        -:  416:  const char *key_end;
        -:  417:
    62169:  418:  _DBUS_ASSERT_ERROR_IS_CLEAR (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%
        -:  419:  
    62169:  420:  s = _dbus_string_get_const_data (str);
call    0 returned 100%
        -:  421:
    62169:  422:  p = s + start;
        -:  423:
   149375:  424:  while (*p && ISWHITE (*p))
branch  0 taken 98% (fallthrough)
branch  1 taken 2%
branch  2 taken 24%
branch  3 taken 76% (fallthrough)
branch  4 taken 7%
branch  5 taken 93% (fallthrough)
branch  6 taken 0%
branch  7 taken 100% (fallthrough)
branch  8 taken 0%
branch  9 taken 100% (fallthrough)
    25037:  425:    ++p;
        -:  426:
    62169:  427:  key_start = p;
        -:  428:
   453751:  429:  while (*p && *p != '=' && !ISWHITE (*p))
branch  0 taken 99% (fallthrough)
branch  1 taken 1%
branch  2 taken 85% (fallthrough)
branch  3 taken 15%
branch  4 taken 100% (fallthrough)
branch  5 taken 0%
branch  6 taken 100% (fallthrough)
branch  7 taken 0%
branch  8 taken 100% (fallthrough)
branch  9 taken 0%
branch 10 taken 100%
branch 11 taken 0% (fallthrough)
   329413:  430:    ++p;
        -:  431:
    62169:  432:  key_end = p;
        -:  433:
   124338:  434:  while (*p && ISWHITE (*p))
branch  0 taken 95% (fallthrough)
branch  1 taken 5%
branch  2 taken 0%
branch  3 taken 100% (fallthrough)
branch  4 taken 0%
branch  5 taken 100% (fallthrough)
branch  6 taken 0%
branch  7 taken 100% (fallthrough)
branch  8 taken 0%
branch  9 taken 100% (fallthrough)
    #####:  435:    ++p;
        -:  436:  
    62169:  437:  if (key_start == key_end)
branch  0 taken 3% (fallthrough)
branch  1 taken 97%
        -:  438:    {
        -:  439:      /* Empty match rules or trailing whitespace are OK */
     1660:  440:      *value_pos = p - s;
     1660:  441:      return TRUE;
        -:  442:    }
        -:  443:
    60509:  444:  if (*p != '=')
branch  0 taken 3% (fallthrough)
branch  1 taken 97%
        -:  445:    {
     1674:  446:      dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  447:                      "Match rule has a key with no subsequent '=' character");
     1674:  448:      return FALSE;
        -:  449:    }
    58835:  450:  ++p;
        -:  451:  
    58835:  452:  if (!_dbus_string_append_len (key, key_start, key_end - key_start))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  453:    {
      114:  454:      BUS_SET_OOM (error);
call    0 returned 100%
      114:  455:      return FALSE;
        -:  456:    }
        -:  457:
    58721:  458:  *value_pos = p - s;
        -:  459:  
    58721:  460:  return TRUE;
        -:  461:}
        -:  462:
        -:  463:static dbus_bool_t
        -:  464:find_value (const DBusString *str,
        -:  465:            int               start,
        -:  466:            const char       *key,
        -:  467:            DBusString       *value,
        -:  468:            int              *value_end,
        -:  469:            DBusError        *error)
function find_value called 58607 returned 100% blocks executed 57%
    58607:  470:{
        -:  471:  const char *p;
        -:  472:  const char *s;
        -:  473:  char quote_char;
        -:  474:  int orig_len;
        -:  475:
    58607:  476:  _DBUS_ASSERT_ERROR_IS_CLEAR (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%
        -:  477:  
    58607:  478:  orig_len = _dbus_string_get_length (value);
call    0 returned 100%
        -:  479:  
    58607:  480:  s = _dbus_string_get_const_data (str);
call    0 returned 100%
        -:  481:
    58607:  482:  p = s + start;
        -:  483:
    58607:  484:  quote_char = '\0';
        -:  485:
   655195:  486:  while (*p)
branch  0 taken 94%
branch  1 taken 6% (fallthrough)
        -:  487:    {
   562084:  488:      if (quote_char == '\0')
branch  0 taken 16% (fallthrough)
branch  1 taken 84%
        -:  489:        {
    88136:  490:          switch (*p)
branch  0 taken 0%
branch  1 taken 74%
branch  2 taken 26%
branch  3 taken 0%
branch  4 taken 0%
        -:  491:            {
        -:  492:            case '\0':
    #####:  493:              goto done;
        -:  494:
        -:  495:            case '\'':
    64858:  496:              quote_char = '\'';
    64858:  497:              goto next;
        -:  498:              
        -:  499:            case ',':
    23278:  500:              ++p;
    23278:  501:              goto done;
        -:  502:
        -:  503:            case '\\':
    #####:  504:              quote_char = '\\';
    #####:  505:              goto next;
        -:  506:              
        -:  507:            default:
    #####:  508:              if (!_dbus_string_append_byte (value, *p))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  509:                {
    #####:  510:                  BUS_SET_OOM (error);
call    0 never executed
    #####:  511:                  goto failed;
        -:  512:                }
        -:  513:            }
        -:  514:        }
   473948:  515:      else if (quote_char == '\\')
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  516:        {
        -:  517:          /* \ only counts as an escape if escaping a quote mark */
    #####:  518:          if (*p != '\'')
branch  0 never executed
branch  1 never executed
        -:  519:            {
    #####:  520:              if (!_dbus_string_append_byte (value, '\\'))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  521:                {
    #####:  522:                  BUS_SET_OOM (error);
call    0 never executed
    #####:  523:                  goto failed;
        -:  524:                }
        -:  525:            }
        -:  526:
    #####:  527:          if (!_dbus_string_append_byte (value, *p))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  528:            {
    #####:  529:              BUS_SET_OOM (error);
call    0 never executed
    #####:  530:              goto failed;
        -:  531:            }
        -:  532:          
    #####:  533:          quote_char = '\0';
        -:  534:        }
        -:  535:      else
        -:  536:        {
   473948:  537:          _dbus_assert (quote_char == '\'');
call    0 returned 100%
        -:  538:
   473948:  539:          if (*p == '\'')
branch  0 taken 14% (fallthrough)
branch  1 taken 86%
        -:  540:            {
    64033:  541:              quote_char = '\0';
        -:  542:            }
        -:  543:          else
        -:  544:            {
   409915:  545:              if (!_dbus_string_append_byte (value, *p))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  546:                {
      825:  547:                  BUS_SET_OOM (error);
call    0 returned 100%
      825:  548:                  goto failed;
        -:  549:                }
        -:  550:            }
        -:  551:        }
        -:  552:
   537981:  553:    next:
   537981:  554:      ++p;
        -:  555:    }
        -:  556:
    57782:  557: done:
        -:  558:
    57782:  559:  if (quote_char == '\\')
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  560:    {
    #####:  561:      if (!_dbus_string_append_byte (value, '\\'))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -:  562:        {
    #####:  563:          BUS_SET_OOM (error);
call    0 never executed
    #####:  564:          goto failed;
        -:  565:        }
        -:  566:    }
    57782:  567:  else if (quote_char == '\'')
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  568:    {
    #####:  569:      dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  570:                      "Unbalanced quotation marks in match rule");
    #####:  571:      goto failed;
        -:  572:    }
        -:  573:  else
    57782:  574:    _dbus_assert (quote_char == '\0');
call    0 returned 100%
        -:  575:
        -:  576:  /* Zero-length values are allowed */
        -:  577:  
    57782:  578:  *value_end = p - s;
        -:  579:  
    57782:  580:  return TRUE;
        -:  581:
      825:  582: failed:
      825:  583:  _DBUS_ASSERT_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%
      825:  584:  _dbus_string_set_length (value, orig_len);
call    0 returned 100%
      825:  585:  return FALSE;
        -:  586:}
        -:  587:
        -:  588:/* duplicates aren't allowed so the real legitimate max is only 6 or
        -:  589: * so. Leaving extra so we don't have to bother to update it.
        -:  590: * FIXME this is sort of busted now with arg matching, but we let
        -:  591: * you match on up to 10 args for now
        -:  592: */
        -:  593:#define MAX_RULE_TOKENS 16
        -:  594:
        -:  595:/* this is slightly too high level to be termed a "token"
        -:  596: * but let's not be pedantic.
        -:  597: */
        -:  598:typedef struct
        -:  599:{
        -:  600:  char *key;
        -:  601:  char *value;
        -:  602:} RuleToken;
        -:  603:
        -:  604:static dbus_bool_t
        -:  605:tokenize_rule (const DBusString *rule_text,
        -:  606:               RuleToken         tokens[MAX_RULE_TOKENS],
        -:  607:               DBusError        *error) 
function tokenize_rule called 44045 returned 100% blocks executed 100%
    44045:  608:{
        -:  609:  int i;
        -:  610:  int pos;
        -:  611:  DBusString key;
        -:  612:  DBusString value;
        -:  613:  dbus_bool_t retval;
        -:  614:
    44045:  615:  retval = FALSE;
        -:  616:  
    44045:  617:  if (!_dbus_string_init (&key))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  618:    {
       79:  619:      BUS_SET_OOM (error);
call    0 returned 100%
       79:  620:      return FALSE;
        -:  621:    }
        -:  622:
    43966:  623:  if (!_dbus_string_init (&value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  624:    {
       79:  625:      _dbus_string_free (&key);
call    0 returned 100%
       79:  626:      BUS_SET_OOM (error);
call    0 returned 100%
       79:  627:      return FALSE;
        -:  628:    }
        -:  629:
    43887:  630:  i = 0;
    43887:  631:  pos = 0;
   147102:  632:  while (i < MAX_RULE_TOKENS &&
branch  0 taken 100% (fallthrough)
branch  1 taken 0%
call    2 returned 100%
branch  3 taken 60%
branch  4 taken 40% (fallthrough)
        -:  633:         pos < _dbus_string_get_length (rule_text))
        -:  634:    {
    62169:  635:      _dbus_assert (tokens[i].key == NULL);
call    0 returned 100%
    62169:  636:      _dbus_assert (tokens[i].value == NULL);
call    0 returned 100%
        -:  637:
    62169:  638:      if (!find_key (rule_text, pos, &key, &pos, error))
call    0 returned 100%
branch  1 taken 3% (fallthrough)
branch  2 taken 97%
     1788:  639:        goto out;
        -:  640:
    60381:  641:      if (_dbus_string_get_length (&key) == 0)
call    0 returned 100%
branch  1 taken 97% (fallthrough)
branch  2 taken 3%
     1660:  642:        goto next;
        -:  643:      
    58721:  644:      if (!_dbus_string_steal_data (&key, &tokens[i].key))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  645:        {
      114:  646:          BUS_SET_OOM (error);
call    0 returned 100%
      114:  647:          goto out;
        -:  648:        }
        -:  649:
    58607:  650:      if (!find_value (rule_text, pos, tokens[i].key, &value, &pos, error))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
      825:  651:        goto out;
        -:  652:
    57782:  653:      if (!_dbus_string_steal_data (&value, &tokens[i].value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  654:        {
      114:  655:          BUS_SET_OOM (error);
call    0 returned 100%
      114:  656:          goto out;
        -:  657:        }
        -:  658:
    59328:  659:    next:
    59328:  660:      ++i;
        -:  661:    }
        -:  662:
    41046:  663:  retval = TRUE;
        -:  664:  
    43887:  665: out:
    43887:  666:  if (!retval)
branch  0 taken 6% (fallthrough)
branch  1 taken 94%
        -:  667:    {
     2841:  668:      i = 0;
     8118:  669:      while (tokens[i].key || tokens[i].value)
branch  0 taken 46%
branch  1 taken 54% (fallthrough)
branch  2 taken 0%
branch  3 taken 100% (fallthrough)
        -:  670:        {
     2436:  671:          dbus_free (tokens[i].key);
call    0 returned 100%
     2436:  672:          dbus_free (tokens[i].value);
call    0 returned 100%
     2436:  673:          tokens[i].key = NULL;
     2436:  674:          tokens[i].value = NULL;
     2436:  675:          ++i;
        -:  676:        }
        -:  677:    }
        -:  678:  
    43887:  679:  _dbus_string_free (&key);
call    0 returned 100%
    43887:  680:  _dbus_string_free (&value);
call    0 returned 100%
        -:  681:  
    43887:  682:  return retval;
        -:  683:}
        -:  684:
        -:  685:static dbus_bool_t
        -:  686:bus_match_rule_parse_arg_match (BusMatchRule     *rule,
        -:  687:                                const char       *key,
        -:  688:                                const DBusString *value,
        -:  689:                                DBusError        *error)
function bus_match_rule_parse_arg_match called 27281 returned 100% blocks executed 97%
    27281:  690:{
        -:  691:  DBusString key_str;
        -:  692:  unsigned long arg;
        -:  693:  int end;
        -:  694:
        -:  695:  /* For now, arg0='foo' always implies that 'foo' is a
        -:  696:   * DBUS_TYPE_STRING. Someday we could add an arg0type='int32' thing
        -:  697:   * if we wanted, which would specify another type, in which case
        -:  698:   * arg0='5' would have the 5 parsed as an int rather than string.
        -:  699:   */
        -:  700:  
        -:  701:  /* First we need to parse arg0 = 0, arg27 = 27 */
        -:  702:
    27281:  703:  _dbus_string_init_const (&key_str, key);
call    0 returned 100%
        -:  704:
    27281:  705:  if (_dbus_string_get_length (&key_str) < 4)
call    0 returned 100%
branch  1 taken 6% (fallthrough)
branch  2 taken 94%
        -:  706:    {
     1624:  707:      dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  708:                      "Key '%s' in match rule starts with 'arg' but lacks an arg number. Should be 'arg0' or 'arg7' for example.\n", key);
     1624:  709:      goto failed;
        -:  710:    }
        -:  711:
    25657:  712:  if (!_dbus_string_parse_uint (&key_str, 3, &arg, &end) ||
call    0 returned 100%
branch  1 taken 87% (fallthrough)
branch  2 taken 13%
call    3 returned 100%
branch  4 taken 7% (fallthrough)
branch  5 taken 93%
        -:  713:      end != _dbus_string_get_length (&key_str))
        -:  714:    {
     4872:  715:      dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  716:                      "Key '%s' in match rule starts with 'arg' but could not parse arg number. Should be 'arg0' or 'arg7' for example.\n", key);
     4872:  717:      goto failed;
        -:  718:    }
        -:  719:
        -:  720:  /* If we didn't check this we could allocate a huge amount of RAM */
    20785:  721:  if (arg > DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER)
branch  0 taken 16% (fallthrough)
branch  1 taken 84%
        -:  722:    {
     3256:  723:      dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  724:                      "Key '%s' in match rule has arg number %lu but the maximum is %d.\n", key, (unsigned long) arg, DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER);
     3256:  725:      goto failed;
        -:  726:    }
        -:  727:  
    17529:  728:  if ((rule->flags & BUS_MATCH_ARGS) &&
branch  0 taken 27% (fallthrough)
branch  1 taken 73%
branch  2 taken 99% (fallthrough)
branch  3 taken 1%
branch  4 taken 99% (fallthrough)
branch  5 taken 1%
        -:  729:      rule->args_len > (int) arg &&
        -:  730:      rule->args[arg] != NULL)
        -:  731:    {
     4709:  732:      dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  733:                      "Key '%s' specified twice in match rule\n", key);
     4709:  734:      goto failed;
        -:  735:    }
        -:  736:  
    12820:  737:  if (!bus_match_rule_set_arg (rule, arg,
call    0 returned 100%
call    1 returned 100%
branch  2 taken 1% (fallthrough)
branch  3 taken 99%
        -:  738:                               _dbus_string_get_const_data (value)))
        -:  739:    {
       48:  740:      BUS_SET_OOM (error);
call    0 returned 100%
       48:  741:      goto failed;
        -:  742:    }
        -:  743:
    12772:  744:  return TRUE;
        -:  745:
    14509:  746: failed:
    14509:  747:  _DBUS_ASSERT_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%
    14509:  748:  return FALSE;
        -:  749:}
        -:  750:
        -:  751:/*
        -:  752: * The format is comma-separated with strings quoted with single quotes
        -:  753: * as for the shell (to escape a literal single quote, use '\'').
        -:  754: *
        -:  755: * type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='Foo',
        -:  756: * path='/bar/foo',destination=':452345.34'
        -:  757: *
        -:  758: */
        -:  759:BusMatchRule*
        -:  760:bus_match_rule_parse (DBusConnection   *matches_go_to,
        -:  761:                      const DBusString *rule_text,
        -:  762:                      DBusError        *error)
function bus_match_rule_parse called 45754 returned 100% blocks executed 81%
    45754:  763:{
        -:  764:  BusMatchRule *rule;
        -:  765:  RuleToken tokens[MAX_RULE_TOKENS+1]; /* NULL termination + 1 */
        -:  766:  int i;
        -:  767:  
    45754:  768:  _DBUS_ASSERT_ERROR_IS_CLEAR (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%
        -:  769:
    45754:  770:  if (_dbus_string_get_length (rule_text) > DBUS_MAXIMUM_MATCH_RULE_LENGTH)
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  771:    {
    #####:  772:      dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
call    0 never executed
call    1 never executed
        -:  773:                      "Match rule text is %d bytes, maximum is %d",
        -:  774:                      _dbus_string_get_length (rule_text),
        -:  775:                      DBUS_MAXIMUM_MATCH_RULE_LENGTH);
    #####:  776:      return NULL;
        -:  777:    }
        -:  778:  
    45754:  779:  memset (tokens, '\0', sizeof (tokens));
call    0 returned 100%
        -:  780:  
    45754:  781:  rule = bus_match_rule_new (matches_go_to);
call    0 returned 100%
    45754:  782:  if (rule == NULL)
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
        -:  783:    {
     1709:  784:      BUS_SET_OOM (error);
call    0 returned 100%
     1709:  785:      goto failed;
        -:  786:    }
        -:  787:  
    44045:  788:  if (!tokenize_rule (rule_text, tokens, error))
call    0 returned 100%
branch  1 taken 7% (fallthrough)
branch  2 taken 93%
     2999:  789:    goto failed;
        -:  790:  
    41046:  791:  i = 0;
   115672:  792:  while (tokens[i].key != NULL)
branch  0 taken 75%
branch  1 taken 25% (fallthrough)
        -:  793:    {
        -:  794:      DBusString tmp_str;
        -:  795:      int len;
    56090:  796:      const char *key = tokens[i].key;
    56090:  797:      const char *value = tokens[i].value;
        -:  798:      
    56090:  799:      _dbus_string_init_const (&tmp_str, value);
call    0 returned 100%
    56090:  800:      len = _dbus_string_get_length (&tmp_str);
call    0 returned 100%
        -:  801:
    56090:  802:      if (strcmp (key, "type") == 0)
call    0 returned 100%
branch  1 taken 16% (fallthrough)
branch  2 taken 84%
        -:  803:        {
        -:  804:          int t;
        -:  805:
     8710:  806:          if (rule->flags & BUS_MATCH_MESSAGE_TYPE)
branch  0 taken 18% (fallthrough)
branch  1 taken 82%
        -:  807:            {
     1573:  808:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  809:                              "Key %s specified twice in match rule\n", key);
     1573:  810:              goto failed;
        -:  811:            }
        -:  812:          
     7137:  813:          t = dbus_message_type_from_string (value);
call    0 returned 100%
        -:  814:          
     7137:  815:          if (t == DBUS_MESSAGE_TYPE_INVALID)
branch  0 taken 22% (fallthrough)
branch  1 taken 78%
        -:  816:            {
     1601:  817:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  818:                              "Invalid message type (%s) in match rule\n", value);
     1601:  819:              goto failed;
        -:  820:            }
        -:  821:
     5536:  822:          if (!bus_match_rule_set_message_type (rule, t))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  823:            {
    #####:  824:              BUS_SET_OOM (error);
call    0 never executed
    #####:  825:              goto failed;
        -:  826:            }
        -:  827:        }
    47380:  828:      else if (strcmp (key, "sender") == 0)
call    0 returned 100%
branch  1 taken 5% (fallthrough)
branch  2 taken 95%
        -:  829:        {
     2559:  830:          if (rule->flags & BUS_MATCH_SENDER)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  831:            {
    #####:  832:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  833:                              "Key %s specified twice in match rule\n", key);
    #####:  834:              goto failed;
        -:  835:            }
        -:  836:
     2559:  837:          if (!_dbus_validate_bus_name (&tmp_str, 0, len))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  838:            {
    #####:  839:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  840:                              "Sender name '%s' is invalid\n", value);
    #####:  841:              goto failed;
        -:  842:            }
        -:  843:
     2559:  844:          if (!bus_match_rule_set_sender (rule, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  845:            {
        6:  846:              BUS_SET_OOM (error);
call    0 returned 100%
        6:  847:              goto failed;
        -:  848:            }
        -:  849:        }
    44821:  850:      else if (strcmp (key, "interface") == 0)
call    0 returned 100%
branch  1 taken 12% (fallthrough)
branch  2 taken 88%
        -:  851:        {
     5426:  852:          if (rule->flags & BUS_MATCH_INTERFACE)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  853:            {
    #####:  854:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  855:                              "Key %s specified twice in match rule\n", key);
    #####:  856:              goto failed;
        -:  857:            }
        -:  858:
     5426:  859:          if (!_dbus_validate_interface (&tmp_str, 0, len))
call    0 returned 100%
branch  1 taken 29% (fallthrough)
branch  2 taken 71%
        -:  860:            {
     1597:  861:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  862:                              "Interface name '%s' is invalid\n", value);
     1597:  863:              goto failed;
        -:  864:            }
        -:  865:
     3829:  866:          if (!bus_match_rule_set_interface (rule, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  867:            {
        9:  868:              BUS_SET_OOM (error);
call    0 returned 100%
        9:  869:              goto failed;
        -:  870:            }
        -:  871:        }
    39395:  872:      else if (strcmp (key, "member") == 0)
call    0 returned 100%
branch  1 taken 7% (fallthrough)
branch  2 taken 93%
        -:  873:        {
     2565:  874:          if (rule->flags & BUS_MATCH_MEMBER)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  875:            {
    #####:  876:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  877:                              "Key %s specified twice in match rule\n", key);
    #####:  878:              goto failed;
        -:  879:            }
        -:  880:
     2565:  881:          if (!_dbus_validate_member (&tmp_str, 0, len))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  882:            {
    #####:  883:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  884:                              "Member name '%s' is invalid\n", value);
    #####:  885:              goto failed;
        -:  886:            }
        -:  887:
     2565:  888:          if (!bus_match_rule_set_member (rule, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  889:            {
        6:  890:              BUS_SET_OOM (error);
call    0 returned 100%
        6:  891:              goto failed;
        -:  892:            }
        -:  893:        }
    36830:  894:      else if (strcmp (key, "path") == 0)
call    0 returned 100%
branch  1 taken 10% (fallthrough)
branch  2 taken 90%
        -:  895:        {
     3820:  896:          if (rule->flags & BUS_MATCH_PATH)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  897:            {
    #####:  898:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  899:                              "Key %s specified twice in match rule\n", key);
    #####:  900:              goto failed;
        -:  901:            }
        -:  902:
     3820:  903:          if (!_dbus_validate_path (&tmp_str, 0, len))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  904:            {
    #####:  905:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  906:                              "Path '%s' is invalid\n", value);
    #####:  907:              goto failed;
        -:  908:            }
        -:  909:
     3820:  910:          if (!bus_match_rule_set_path (rule, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  911:            {
        9:  912:              BUS_SET_OOM (error);
call    0 returned 100%
        9:  913:              goto failed;
        -:  914:            }
        -:  915:        }
    33010:  916:      else if (strcmp (key, "destination") == 0)
call    0 returned 100%
branch  1 taken 8% (fallthrough)
branch  2 taken 92%
        -:  917:        {
     2535:  918:          if (rule->flags & BUS_MATCH_DESTINATION)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -:  919:            {
    #####:  920:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  921:                              "Key %s specified twice in match rule\n", key);
    #####:  922:              goto failed;
        -:  923:            }
        -:  924:
     2535:  925:          if (!_dbus_validate_bus_name (&tmp_str, 0, len))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -:  926:            {
    #####:  927:              dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 never executed
        -:  928:                              "Destination name '%s' is invalid\n", value);
    #####:  929:              goto failed;
        -:  930:            }
        -:  931:
     2535:  932:          if (!bus_match_rule_set_destination (rule, value))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -:  933:            {
        6:  934:              BUS_SET_OOM (error);
call    0 returned 100%
        6:  935:              goto failed;
        -:  936:            }
        -:  937:        }
    30475:  938:      else if (strncmp (key, "arg", 3) == 0)
call    0 returned 100%
branch  1 taken 90% (fallthrough)
branch  2 taken 10%
        -:  939:        {
    27281:  940:          if (!bus_match_rule_parse_arg_match (rule, key, &tmp_str, error))
call    0 returned 100%
branch  1 taken 53% (fallthrough)
branch  2 taken 47%
    14509:  941:            goto failed;
        -:  942:        }
        -:  943:      else
        -:  944:        {
     3194:  945:          dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID,
call    0 returned 100%
        -:  946:                          "Unknown key \"%s\" in match rule",
        -:  947:                          key);
     3194:  948:          goto failed;
        -:  949:        }
        -:  950:
    33580:  951:      ++i;
        -:  952:    }
        -:  953:  
        -:  954:
    18536:  955:  goto out;
        -:  956:  
    27218:  957: failed:
    27218:  958:  _DBUS_ASSERT_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%
    27218:  959:  if (rule)
branch  0 taken 94% (fallthrough)
branch  1 taken 6%
        -:  960:    {
    25509:  961:      bus_match_rule_unref (rule);
call    0 returned 100%
    25509:  962:      rule = NULL;
        -:  963:    }
        -:  964:
    45754:  965: out:
        -:  966:  
    45754:  967:  i = 0;
   147679:  968:  while (tokens[i].key || tokens[i].value)
branch  0 taken 55%
branch  1 taken 45% (fallthrough)
branch  2 taken 0%
branch  3 taken 100% (fallthrough)
        -:  969:    {
    56171:  970:      _dbus_assert (i < MAX_RULE_TOKENS);
call    0 returned 100%
    56171:  971:      dbus_free (tokens[i].key);
call    0 returned 100%
    56171:  972:      dbus_free (tokens[i].value);
call    0 returned 100%
    56171:  973:      ++i;
        -:  974:    }
        -:  975:  
    45754:  976:  return rule;
        -:  977:}
        -:  978:
        -:  979:struct BusMatchmaker
        -:  980:{
        -:  981:  int refcount;
        -:  982:
        -:  983:  DBusList *all_rules;
        -:  984:};
        -:  985:
        -:  986:BusMatchmaker*
        -:  987:bus_matchmaker_new (void)
function bus_matchmaker_new called 4 returned 100% blocks executed 80%
        4:  988:{
        -:  989:  BusMatchmaker *matchmaker;
        -:  990:
        4:  991:  matchmaker = dbus_new0 (BusMatchmaker, 1);
call    0 returned 100%
        4:  992:  if (matchmaker == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####:  993:    return NULL;
        -:  994:
        4:  995:  matchmaker->refcount = 1;
        -:  996:  
        4:  997:  return matchmaker;
        -:  998:}
        -:  999:
        -: 1000:BusMatchmaker *
        -: 1001:bus_matchmaker_ref (BusMatchmaker *matchmaker)
function bus_matchmaker_ref called 1 returned 100% blocks executed 100%
        1: 1002:{
        1: 1003:  _dbus_assert (matchmaker->refcount > 0);
call    0 returned 100%
        -: 1004:
        1: 1005:  matchmaker->refcount += 1;
        -: 1006:
        1: 1007:  return matchmaker;
        -: 1008:}
        -: 1009:
        -: 1010:void
        -: 1011:bus_matchmaker_unref (BusMatchmaker *matchmaker)
function bus_matchmaker_unref called 5 returned 100% blocks executed 75%
        5: 1012:{
        5: 1013:  _dbus_assert (matchmaker->refcount > 0);
call    0 returned 100%
        -: 1014:
        5: 1015:  matchmaker->refcount -= 1;
        5: 1016:  if (matchmaker->refcount == 0)
branch  0 taken 80% (fallthrough)
branch  1 taken 20%
        -: 1017:    {
        8: 1018:      while (matchmaker->all_rules != NULL)
branch  0 taken 0%
branch  1 taken 100% (fallthrough)
        -: 1019:        {
        -: 1020:          BusMatchRule *rule;
        -: 1021:
    #####: 1022:          rule = matchmaker->all_rules->data;
    #####: 1023:          bus_match_rule_unref (rule);
call    0 never executed
    #####: 1024:          _dbus_list_remove_link (&matchmaker->all_rules,
call    0 never executed
        -: 1025:                                  matchmaker->all_rules);
        -: 1026:        }
        -: 1027:
        4: 1028:      dbus_free (matchmaker);
call    0 returned 100%
        -: 1029:    }
        5: 1030:}
        -: 1031:
        -: 1032:/* The rule can't be modified after it's added. */
        -: 1033:dbus_bool_t
        -: 1034:bus_matchmaker_add_rule (BusMatchmaker   *matchmaker,
        -: 1035:                         BusMatchRule    *rule)
function bus_matchmaker_add_rule called 3316 returned 100% blocks executed 100%
     3316: 1036:{
     3316: 1037:  _dbus_assert (bus_connection_is_active (rule->matches_go_to));
call    0 returned 100%
call    1 returned 100%
        -: 1038:
     3316: 1039:  if (!_dbus_list_append (&matchmaker->all_rules, rule))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        4: 1040:    return FALSE;
        -: 1041:
     3312: 1042:  if (!bus_connection_add_match_rule (rule->matches_go_to, rule))
call    0 returned 100%
branch  1 taken 1% (fallthrough)
branch  2 taken 99%
        -: 1043:    {
        4: 1044:      _dbus_list_remove_last (&matchmaker->all_rules, rule);
call    0 returned 100%
        4: 1045:      return FALSE;
        -: 1046:    }
        -: 1047:  
     3308: 1048:  bus_match_rule_ref (rule);
call    0 returned 100%
        -: 1049:
        -: 1050:#ifdef DBUS_ENABLE_VERBOSE_MODE
        -: 1051:  {
     3308: 1052:    char *s = match_rule_to_string (rule);
call    0 returned 100%
        -: 1053:
     3308: 1054:    _dbus_verbose ("Added match rule %s to connection %p\n",
call    0 returned 100%
        -: 1055:                   s, rule->matches_go_to);
     3308: 1056:    dbus_free (s);
call    0 returned 100%
        -: 1057:  }
        -: 1058:#endif
        -: 1059:  
     3308: 1060:  return TRUE;
        -: 1061:}
        -: 1062:
        -: 1063:static dbus_bool_t
        -: 1064:match_rule_equal (BusMatchRule *a,
        -: 1065:                  BusMatchRule *b)
function match_rule_equal called 144 returned 100% blocks executed 83%
      144: 1066:{
      144: 1067:  if (a->flags != b->flags)
branch  0 taken 83% (fallthrough)
branch  1 taken 17%
      120: 1068:    return FALSE;
        -: 1069:
       24: 1070:  if ((a->flags & BUS_MATCH_MESSAGE_TYPE) &&
branch  0 taken 92% (fallthrough)
branch  1 taken 8%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
        -: 1071:      a->message_type != b->message_type)
    #####: 1072:    return FALSE;
        -: 1073:
       24: 1074:  if ((a->flags & BUS_MATCH_MEMBER) &&
branch  0 taken 8% (fallthrough)
branch  1 taken 92%
call    2 returned 100%
branch  3 taken 0% (fallthrough)
branch  4 taken 100%
        -: 1075:      strcmp (a->member, b->member) != 0)
    #####: 1076:    return FALSE;
        -: 1077:
       24: 1078:  if ((a->flags & BUS_MATCH_PATH) &&
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
call    2 returned 100%
branch  3 taken 0% (fallthrough)
branch  4 taken 100%
        -: 1079:      strcmp (a->path, b->path) != 0)
    #####: 1080:    return FALSE;
        -: 1081:  
       24: 1082:  if ((a->flags & BUS_MATCH_INTERFACE) &&
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
call    2 returned 100%
branch  3 taken 0% (fallthrough)
branch  4 taken 100%
        -: 1083:      strcmp (a->interface, b->interface) != 0)
    #####: 1084:    return FALSE;
        -: 1085:
       24: 1086:  if ((a->flags & BUS_MATCH_SENDER) &&
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
call    2 returned 100%
branch  3 taken 0% (fallthrough)
branch  4 taken 100%
        -: 1087:      strcmp (a->sender, b->sender) != 0)
    #####: 1088:    return FALSE;
        -: 1089:
       24: 1090:  if ((a->flags & BUS_MATCH_DESTINATION) &&
branch  0 taken 4% (fallthrough)
branch  1 taken 96%
call    2 returned 100%
branch  3 taken 0% (fallthrough)
branch  4 taken 100%
        -: 1091:      strcmp (a->destination, b->destination) != 0)
    #####: 1092:    return FALSE;
        -: 1093:
       24: 1094:  if (a->flags & BUS_MATCH_ARGS)
branch  0 taken 71% (fallthrough)
branch  1 taken 29%
        -: 1095:    {
        -: 1096:      int i;
        -: 1097:      
       17: 1098:      if (a->args_len != b->args_len)
branch  0 taken 59% (fallthrough)
branch  1 taken 41%
       10: 1099:        return FALSE;
        -: 1100:      
        7: 1101:      i = 0;
       26: 1102:      while (i < a->args_len)
branch  0 taken 74%
branch  1 taken 26% (fallthrough)
        -: 1103:        {
       14: 1104:          if ((a->args[i] != NULL) != (b->args[i] != NULL))
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####: 1105:            return FALSE;
        -: 1106:
       14: 1107:          if (a->args[i] != NULL)
branch  0 taken 57% (fallthrough)
branch  1 taken 43%
        -: 1108:            {
        8: 1109:              _dbus_assert (b->args[i] != NULL);
call    0 returned 100%
        8: 1110:              if (strcmp (a->args[i], b->args[i]) != 0)
call    0 returned 100%
branch  1 taken 25% (fallthrough)
branch  2 taken 75%
        2: 1111:                return FALSE;
        -: 1112:            }
        -: 1113:          
       12: 1114:          ++i;
        -: 1115:        }
        -: 1116:    }
        -: 1117:  
       12: 1118:  return TRUE;
        -: 1119:}
        -: 1120:
        -: 1121:static void
        -: 1122:bus_matchmaker_remove_rule_link (BusMatchmaker   *matchmaker,
        -: 1123:                                 DBusList        *link)
function bus_matchmaker_remove_rule_link called 3256 returned 100% blocks executed 100%
     3256: 1124:{
     3256: 1125:  BusMatchRule *rule = link->data;
        -: 1126:  
     3256: 1127:  bus_connection_remove_match_rule (rule->matches_go_to, rule);
call    0 returned 100%
     3256: 1128:  _dbus_list_remove_link (&matchmaker->all_rules, link);
call    0 returned 100%
        -: 1129:
        -: 1130:#ifdef DBUS_ENABLE_VERBOSE_MODE
        -: 1131:  {
     3256: 1132:    char *s = match_rule_to_string (rule);
call    0 returned 100%
        -: 1133:
     3256: 1134:    _dbus_verbose ("Removed match rule %s for connection %p\n",
call    0 returned 100%
        -: 1135:                   s, rule->matches_go_to);
     3256: 1136:    dbus_free (s);
call    0 returned 100%
        -: 1137:  }
        -: 1138:#endif
        -: 1139:  
     3256: 1140:  bus_match_rule_unref (rule);  
call    0 returned 100%
     3256: 1141:}
        -: 1142:
        -: 1143:void
        -: 1144:bus_matchmaker_remove_rule (BusMatchmaker   *matchmaker,
        -: 1145:                            BusMatchRule    *rule)
function bus_matchmaker_remove_rule called 52 returned 100% blocks executed 100%
       52: 1146:{
       52: 1147:  bus_connection_remove_match_rule (rule->matches_go_to, rule);
call    0 returned 100%
       52: 1148:  _dbus_list_remove (&matchmaker->all_rules, rule);
call    0 returned 100%
        -: 1149:
        -: 1150:#ifdef DBUS_ENABLE_VERBOSE_MODE
        -: 1151:  {
       52: 1152:    char *s = match_rule_to_string (rule);
call    0 returned 100%
        -: 1153:
       52: 1154:    _dbus_verbose ("Removed match rule %s for connection %p\n",
call    0 returned 100%
        -: 1155:                   s, rule->matches_go_to);
       52: 1156:    dbus_free (s);
call    0 returned 100%
        -: 1157:  }
        -: 1158:#endif
        -: 1159:  
       52: 1160:  bus_match_rule_unref (rule);
call    0 returned 100%
       52: 1161:}
        -: 1162:
        -: 1163:/* Remove a single rule which is equal to the given rule by value */
        -: 1164:dbus_bool_t
        -: 1165:bus_matchmaker_remove_rule_by_value (BusMatchmaker   *matchmaker,
        -: 1166:                                     BusMatchRule    *value,
        -: 1167:                                     DBusError       *error)
function bus_matchmaker_remove_rule_by_value called 0 returned 0% blocks executed 0%
    #####: 1168:{
        -: 1169:  /* FIXME this is an unoptimized linear scan */
        -: 1170:
        -: 1171:  DBusList *link;
        -: 1172:
        -: 1173:  /* we traverse backward because bus_connection_remove_match_rule()
        -: 1174:   * removes the most-recently-added rule
        -: 1175:   */
    #####: 1176:  link = _dbus_list_get_last_link (&matchmaker->all_rules);
call    0 never executed
    #####: 1177:  while (link != NULL)
branch  0 never executed
branch  1 never executed
        -: 1178:    {
        -: 1179:      BusMatchRule *rule;
        -: 1180:      DBusList *prev;
        -: 1181:
    #####: 1182:      rule = link->data;
    #####: 1183:      prev = _dbus_list_get_prev_link (&matchmaker->all_rules, link);
branch  0 never executed
branch  1 never executed
        -: 1184:
    #####: 1185:      if (match_rule_equal (rule, value))
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1186:        {
    #####: 1187:          bus_matchmaker_remove_rule_link (matchmaker, link);
call    0 never executed
    #####: 1188:          break;
        -: 1189:        }
        -: 1190:
    #####: 1191:      link = prev;
        -: 1192:    }
        -: 1193:
    #####: 1194:  if (link == NULL)
branch  0 never executed
branch  1 never executed
        -: 1195:    {
    #####: 1196:      dbus_set_error (error, DBUS_ERROR_MATCH_RULE_NOT_FOUND,
call    0 never executed
        -: 1197:                      "The given match rule wasn't found and can't be removed");
    #####: 1198:      return FALSE;
        -: 1199:    }
        -: 1200:
    #####: 1201:  return TRUE;
        -: 1202:}
        -: 1203:
        -: 1204:void
        -: 1205:bus_matchmaker_disconnected (BusMatchmaker   *matchmaker,
        -: 1206:                             DBusConnection  *disconnected)
function bus_matchmaker_disconnected called 3256 returned 100% blocks executed 56%
     3256: 1207:{
        -: 1208:  DBusList *link;
        -: 1209:
        -: 1210:  /* FIXME
        -: 1211:   *
        -: 1212:   * This scans all match rules on the bus. We could avoid that
        -: 1213:   * for the rules belonging to the connection, since we keep
        -: 1214:   * a list of those; but for the rules that just refer to
        -: 1215:   * the connection we'd need to do something more elaborate.
        -: 1216:   * 
        -: 1217:   */
        -: 1218:  
     3256: 1219:  _dbus_assert (bus_connection_is_active (disconnected));
call    0 returned 100%
call    1 returned 100%
        -: 1220:
     3256: 1221:  link = _dbus_list_get_first_link (&matchmaker->all_rules);
call    0 returned 100%
    15055: 1222:  while (link != NULL)
branch  0 taken 72%
branch  1 taken 28% (fallthrough)
        -: 1223:    {
        -: 1224:      BusMatchRule *rule;
        -: 1225:      DBusList *next;
        -: 1226:
     8543: 1227:      rule = link->data;
     8543: 1228:      next = _dbus_list_get_next_link (&matchmaker->all_rules, link);
branch  0 taken 62% (fallthrough)
branch  1 taken 38%
        -: 1229:
     8543: 1230:      if (rule->matches_go_to == disconnected)
branch  0 taken 38% (fallthrough)
branch  1 taken 62%
        -: 1231:        {
     3256: 1232:          bus_matchmaker_remove_rule_link (matchmaker, link);
call    0 returned 100%
        -: 1233:        }
     5287: 1234:      else if (((rule->flags & BUS_MATCH_SENDER) && *rule->sender == ':') ||
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
branch  2 never executed
branch  3 never executed
branch  4 taken 0% (fallthrough)
branch  5 taken 100%
branch  6 never executed
branch  7 never executed
        -: 1235:               ((rule->flags & BUS_MATCH_DESTINATION) && *rule->destination == ':'))
        -: 1236:        {
        -: 1237:          /* The rule matches to/from a base service, see if it's the
        -: 1238:           * one being disconnected, since we know this service name
        -: 1239:           * will never be recycled.
        -: 1240:           */
        -: 1241:          const char *name;
        -: 1242:
    #####: 1243:          name = bus_connection_get_name (disconnected);
call    0 never executed
    #####: 1244:          _dbus_assert (name != NULL); /* because we're an active connection */
call    0 never executed
        -: 1245:
    #####: 1246:          if (((rule->flags & BUS_MATCH_SENDER) &&
branch  0 never executed
branch  1 never executed
call    2 never executed
branch  3 never executed
branch  4 never executed
branch  5 never executed
branch  6 never executed
call    7 never executed
branch  8 never executed
branch  9 never executed
        -: 1247:               strcmp (rule->sender, name) == 0) ||
        -: 1248:              ((rule->flags & BUS_MATCH_DESTINATION) &&
        -: 1249:               strcmp (rule->destination, name) == 0))
        -: 1250:            {
    #####: 1251:              bus_matchmaker_remove_rule_link (matchmaker, link);
call    0 never executed
        -: 1252:            }
        -: 1253:        }
        -: 1254:
     8543: 1255:      link = next;
        -: 1256:    }
     3256: 1257:}
        -: 1258:
        -: 1259:static dbus_bool_t
        -: 1260:connection_is_primary_owner (DBusConnection *connection,
        -: 1261:                             const char     *service_name)
function connection_is_primary_owner called 0 returned 0% blocks executed 0%
    #####: 1262:{
        -: 1263:  BusService *service;
        -: 1264:  DBusString str;
        -: 1265:  BusRegistry *registry;
        -: 1266:
    #####: 1267:  _dbus_assert (connection != NULL);
call    0 never executed
        -: 1268:  
    #####: 1269:  registry = bus_connection_get_registry (connection);
call    0 never executed
        -: 1270:
    #####: 1271:  _dbus_string_init_const (&str, service_name);
call    0 never executed
    #####: 1272:  service = bus_registry_lookup (registry, &str);
call    0 never executed
        -: 1273:
    #####: 1274:  if (service == NULL)
branch  0 never executed
branch  1 never executed
    #####: 1275:    return FALSE; /* Service doesn't exist so connection can't own it. */
        -: 1276:
    #####: 1277:  return bus_service_get_primary_owners_connection (service) == connection;
call    0 never executed
        -: 1278:}
        -: 1279:
        -: 1280:static dbus_bool_t
        -: 1281:match_rule_matches (BusMatchRule    *rule,
        -: 1282:                    DBusConnection  *sender,
        -: 1283:                    DBusConnection  *addressed_recipient,
        -: 1284:                    DBusMessage     *message)
function match_rule_matches called 72128 returned 100% blocks executed 49%
    72128: 1285:{
        -: 1286:  /* All features of the match rule are AND'd together,
        -: 1287:   * so FALSE if any of them don't match.
        -: 1288:   */
        -: 1289:
        -: 1290:  /* sender/addressed_recipient of #NULL may mean bus driver,
        -: 1291:   * or for addressed_recipient may mean a message with no
        -: 1292:   * specific recipient (i.e. a signal)
        -: 1293:   */
        -: 1294:  
    72128: 1295:  if (rule->flags & BUS_MATCH_MESSAGE_TYPE)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -: 1296:    {
        8: 1297:      _dbus_assert (rule->message_type != DBUS_MESSAGE_TYPE_INVALID);
call    0 returned 100%
        -: 1298:
        8: 1299:      if (rule->message_type != dbus_message_get_type (message))
call    0 returned 100%
branch  1 taken 38% (fallthrough)
branch  2 taken 63%
        3: 1300:        return FALSE;
        -: 1301:    }
        -: 1302:
    72125: 1303:  if (rule->flags & BUS_MATCH_INTERFACE)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1304:    {
        -: 1305:      const char *iface;
        -: 1306:
    #####: 1307:      _dbus_assert (rule->interface != NULL);
call    0 never executed
        -: 1308:
    #####: 1309:      iface = dbus_message_get_interface (message);
call    0 never executed
    #####: 1310:      if (iface == NULL)
branch  0 never executed
branch  1 never executed
    #####: 1311:        return FALSE;
        -: 1312:
    #####: 1313:      if (strcmp (iface, rule->interface) != 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####: 1314:        return FALSE;
        -: 1315:    }
        -: 1316:
    72125: 1317:  if (rule->flags & BUS_MATCH_MEMBER)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -: 1318:    {
        -: 1319:      const char *member;
        -: 1320:
        5: 1321:      _dbus_assert (rule->member != NULL);
call    0 returned 100%
        -: 1322:
        5: 1323:      member = dbus_message_get_member (message);
call    0 returned 100%
        5: 1324:      if (member == NULL)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
    #####: 1325:        return FALSE;
        -: 1326:
        5: 1327:      if (strcmp (member, rule->member) != 0)
call    0 returned 100%
branch  1 taken 20% (fallthrough)
branch  2 taken 80%
        1: 1328:        return FALSE;
        -: 1329:    }
        -: 1330:
    72124: 1331:  if (rule->flags & BUS_MATCH_SENDER)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1332:    {
    #####: 1333:      _dbus_assert (rule->sender != NULL);
call    0 never executed
        -: 1334:
    #####: 1335:      if (sender == NULL)
branch  0 never executed
branch  1 never executed
        -: 1336:        {
    #####: 1337:          if (strcmp (rule->sender,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1338:                      DBUS_SERVICE_DBUS) != 0)
    #####: 1339:            return FALSE;
        -: 1340:        }
        -: 1341:      else
        -: 1342:        {
    #####: 1343:          if (!connection_is_primary_owner (sender, rule->sender))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####: 1344:            return FALSE;
        -: 1345:        }
        -: 1346:    }
        -: 1347:
    72124: 1348:  if (rule->flags & BUS_MATCH_DESTINATION)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1349:    {
        -: 1350:      const char *destination;
        -: 1351:
    #####: 1352:      _dbus_assert (rule->destination != NULL);
call    0 never executed
        -: 1353:
    #####: 1354:      destination = dbus_message_get_destination (message);
call    0 never executed
    #####: 1355:      if (destination == NULL)
branch  0 never executed
branch  1 never executed
    #####: 1356:        return FALSE;
        -: 1357:
    #####: 1358:      if (addressed_recipient == NULL)
branch  0 never executed
branch  1 never executed
        -: 1359:        {          
    #####: 1360:          if (strcmp (rule->destination,
call    0 never executed
branch  1 never executed
branch  2 never executed
        -: 1361:                      DBUS_SERVICE_DBUS) != 0)
    #####: 1362:            return FALSE;
        -: 1363:        }
        -: 1364:      else
        -: 1365:        {
    #####: 1366:          if (!connection_is_primary_owner (addressed_recipient, rule->destination))
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####: 1367:            return FALSE;
        -: 1368:        }
        -: 1369:    }
        -: 1370:
    72124: 1371:  if (rule->flags & BUS_MATCH_PATH)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1372:    {
        -: 1373:      const char *path;
        -: 1374:
    #####: 1375:      _dbus_assert (rule->path != NULL);
call    0 never executed
        -: 1376:
    #####: 1377:      path = dbus_message_get_path (message);
call    0 never executed
    #####: 1378:      if (path == NULL)
branch  0 never executed
branch  1 never executed
    #####: 1379:        return FALSE;
        -: 1380:
    #####: 1381:      if (strcmp (path, rule->path) != 0)
call    0 never executed
branch  1 never executed
branch  2 never executed
    #####: 1382:        return FALSE;
        -: 1383:    }
        -: 1384:
    72124: 1385:  if (rule->flags & BUS_MATCH_ARGS)
branch  0 taken 1% (fallthrough)
branch  1 taken 99%
        -: 1386:    {
        -: 1387:      int i;
        -: 1388:      DBusMessageIter iter;
        -: 1389:      
       13: 1390:      _dbus_assert (rule->args != NULL);
call    0 returned 100%
        -: 1391:
       13: 1392:      dbus_message_iter_init (message, &iter);
call    0 returned 100%
        -: 1393:      
       13: 1394:      i = 0;
       40: 1395:      while (i < rule->args_len)
branch  0 taken 85%
branch  1 taken 15% (fallthrough)
        -: 1396:        {
        -: 1397:          int current_type;
        -: 1398:          const char *expected_arg;
        -: 1399:
       23: 1400:          expected_arg = rule->args[i];
        -: 1401:          
       23: 1402:          current_type = dbus_message_iter_get_arg_type (&iter);
call    0 returned 100%
        -: 1403:
       23: 1404:          if (expected_arg != NULL)
branch  0 taken 70% (fallthrough)
branch  1 taken 30%
        -: 1405:            {
        -: 1406:              const char *actual_arg;
        -: 1407:              
       16: 1408:              if (current_type != DBUS_TYPE_STRING)
branch  0 taken 44% (fallthrough)
branch  1 taken 56%
        7: 1409:                return FALSE;
        -: 1410:
        9: 1411:              actual_arg = NULL;
        9: 1412:              dbus_message_iter_get_basic (&iter, &actual_arg);
call    0 returned 100%
        9: 1413:              _dbus_assert (actual_arg != NULL);
call    0 returned 100%
        -: 1414:
        9: 1415:              if (strcmp (expected_arg, actual_arg) != 0)
call    0 returned 100%
branch  1 taken 22% (fallthrough)
branch  2 taken 78%
        2: 1416:                return FALSE;
        -: 1417:            }
        -: 1418:          
       14: 1419:          if (current_type != DBUS_TYPE_INVALID)
branch  0 taken 93% (fallthrough)
branch  1 taken 7%
       13: 1420:            dbus_message_iter_next (&iter);
call    0 returned 100%
        -: 1421:
       14: 1422:          ++i;
        -: 1423:        }
        -: 1424:    }
        -: 1425:  
    72115: 1426:  return TRUE;
        -: 1427:}
        -: 1428:
        -: 1429:dbus_bool_t
        -: 1430:bus_matchmaker_get_recipients (BusMatchmaker   *matchmaker,
        -: 1431:                               BusConnections  *connections,
        -: 1432:                               DBusConnection  *sender,
        -: 1433:                               DBusConnection  *addressed_recipient,
        -: 1434:                               DBusMessage     *message,
        -: 1435:                               DBusList       **recipients_p)
function bus_matchmaker_get_recipients called 29069 returned 100% blocks executed 100%
    29069: 1436:{
        -: 1437:  /* FIXME for now this is a wholly unoptimized linear search */
        -: 1438:  /* Guessing the important optimization is to skip the signal-related
        -: 1439:   * match lists when processing method call and exception messages.
        -: 1440:   * So separate match rule lists for signals?
        -: 1441:   */
        -: 1442:  
        -: 1443:  DBusList *link;
        -: 1444:
    29069: 1445:  _dbus_assert (*recipients_p == NULL);
call    0 returned 100%
        -: 1446:
        -: 1447:  /* This avoids sending same message to the same connection twice.
        -: 1448:   * Purpose of the stamp instead of a bool is to avoid iterating over
        -: 1449:   * all connections resetting the bool each time.
        -: 1450:   */
    29069: 1451:  bus_connections_increment_stamp (connections);
call    0 returned 100%
        -: 1452:
        -: 1453:  /* addressed_recipient is already receiving the message, don't add to list.
        -: 1454:   * NULL addressed_recipient means either bus driver, or this is a signal
        -: 1455:   * and thus lacks a specific addressed_recipient.
        -: 1456:   */
    29069: 1457:  if (addressed_recipient != NULL)
branch  0 taken 5% (fallthrough)
branch  1 taken 95%
     1553: 1458:    bus_connection_mark_stamp (addressed_recipient);
call    0 returned 100%
        -: 1459:
    29069: 1460:  link = _dbus_list_get_first_link (&matchmaker->all_rules);
call    0 returned 100%
   130106: 1461:  while (link != NULL)
branch  0 taken 71%
branch  1 taken 29% (fallthrough)
        -: 1462:    {
        -: 1463:      BusMatchRule *rule;
        -: 1464:
    72108: 1465:      rule = link->data;
        -: 1466:
        -: 1467:#ifdef DBUS_ENABLE_VERBOSE_MODE
        -: 1468:      {
    72108: 1469:        char *s = match_rule_to_string (rule);
call    0 returned 100%
        -: 1470:        
    72108: 1471:        _dbus_verbose ("Checking whether message matches rule %s for connection %p\n",
call    0 returned 100%
        -: 1472:                       s, rule->matches_go_to);
    72108: 1473:        dbus_free (s);
call    0 returned 100%
        -: 1474:      }
        -: 1475:#endif
        -: 1476:      
    72108: 1477:      if (match_rule_matches (rule,
call    0 returned 100%
branch  1 taken 100% (fallthrough)
branch  2 taken 0%
        -: 1478:                              sender, addressed_recipient, message))
        -: 1479:        {
    72108: 1480:          _dbus_verbose ("Rule matched\n");
call    0 returned 100%
        -: 1481:          
        -: 1482:          /* Append to the list if we haven't already */
    72108: 1483:          if (bus_connection_mark_stamp (rule->matches_go_to))
call    0 returned 100%
branch  1 taken 99% (fallthrough)
branch  2 taken 1%
        -: 1484:            {
    72105: 1485:              if (!_dbus_list_append (recipients_p, rule->matches_go_to))
call    0 returned 100%
branch  1 taken 99% (fallthrough)
branch  2 taken 1%
      140: 1486:                goto nomem;
        -: 1487:            }
        -: 1488:#ifdef DBUS_ENABLE_VERBOSE_MODE
        -: 1489:          else
        -: 1490:            {
        3: 1491:              _dbus_verbose ("Connection already receiving this message, so not adding again\n");
call    0 returned 100%
        -: 1492:            }
        -: 1493:#endif /* DBUS_ENABLE_VERBOSE_MODE */
        -: 1494:        }
        -: 1495:
    71968: 1496:      link = _dbus_list_get_next_link (&matchmaker->all_rules, link);
branch  0 taken 60% (fallthrough)
branch  1 taken 40%
        -: 1497:    }
        -: 1498:
    28929: 1499:  return TRUE;
        -: 1500:
      140: 1501: nomem:
      140: 1502:  _dbus_list_clear (recipients_p);
call    0 returned 100%
      140: 1503:  return FALSE;
        -: 1504:}
        -: 1505:
        -: 1506:#ifdef DBUS_BUILD_TESTS
        -: 1507:#include "test.h"
        -: 1508:#include <stdlib.h>
        -: 1509:
        -: 1510:static BusMatchRule*
        -: 1511:check_parse (dbus_bool_t should_succeed,
        -: 1512:             const char *text)
function check_parse called 42426 returned 100% blocks executed 70%
    42426: 1513:{
        -: 1514:  BusMatchRule *rule;
        -: 1515:  DBusString str;
        -: 1516:  DBusError error;
        -: 1517:
    42426: 1518:  dbus_error_init (&error);
call    0 returned 100%
        -: 1519:
    42426: 1520:  _dbus_string_init_const (&str, text);
call    0 returned 100%
        -: 1521:  
    42426: 1522:  rule = bus_match_rule_parse (NULL, &str, &error);
call    0 returned 100%
    42426: 1523:  if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
call    0 returned 100%
branch  1 taken 8% (fallthrough)
branch  2 taken 92%
        -: 1524:    {
     3286: 1525:      dbus_error_free (&error);
call    0 returned 100%
     3286: 1526:      return NULL;
        -: 1527:    }
        -: 1528:
    39140: 1529:  if (should_succeed && rule == NULL)
branch  0 taken 39% (fallthrough)
branch  1 taken 61%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
        -: 1530:    {
    #####: 1531:      _dbus_warn ("Failed to parse: %s: %s: \"%s\"\n",
call    0 never executed
call    1 never executed
        -: 1532:                  error.name, error.message,
        -: 1533:                  _dbus_string_get_const_data (&str));
    #####: 1534:      exit (1);
call    0 never executed
        -: 1535:    }
        -: 1536:
    39140: 1537:  if (!should_succeed && rule != NULL)
branch  0 taken 61% (fallthrough)
branch  1 taken 39%
branch  2 taken 0% (fallthrough)
branch  3 taken 100%
        -: 1538:    {
    #####: 1539:      _dbus_warn ("Failed to fail to parse: \"%s\"\n",
call    0 never executed
call    1 never executed
        -: 1540:                  _dbus_string_get_const_data (&str));
    #####: 1541:      exit (1);
call    0 never executed
        -: 1542:    }
        -: 1543:
    39140: 1544:  dbus_error_free (&error);
call    0 returned 100%
        -: 1545:
    39140: 1546:  return rule;
        -: 1547:}
        -: 1548:
        -: 1549:static void
        -: 1550:assert_large_rule (BusMatchRule *rule)
function assert_large_rule called 2516 returned 100% blocks executed 100%
     2516: 1551:{
     2516: 1552:  _dbus_assert (rule->flags & BUS_MATCH_MESSAGE_TYPE);
call    0 returned 100%
     2516: 1553:  _dbus_assert (rule->flags & BUS_MATCH_SENDER);
call    0 returned 100%
     2516: 1554:  _dbus_assert (rule->flags & BUS_MATCH_INTERFACE);
call    0 returned 100%
     2516: 1555:  _dbus_assert (rule->flags & BUS_MATCH_MEMBER);
call    0 returned 100%
     2516: 1556:  _dbus_assert (rule->flags & BUS_MATCH_DESTINATION);
call    0 returned 100%
     2516: 1557:  _dbus_assert (rule->flags & BUS_MATCH_PATH);
call    0 returned 100%
        -: 1558:
     2516: 1559:  _dbus_assert (rule->message_type == DBUS_MESSAGE_TYPE_SIGNAL);
call    0 returned 100%
     2516: 1560:  _dbus_assert (rule->interface != NULL);
call    0 returned 100%
     2516: 1561:  _dbus_assert (rule->member != NULL);
call    0 returned 100%
     2516: 1562:  _dbus_assert (rule->sender != NULL);
call    0 returned 100%
     2516: 1563:  _dbus_assert (rule->destination != NULL);
call    0 returned 100%
     2516: 1564:  _dbus_assert (rule->path != NULL);
call    0 returned 100%
        -: 1565:
     2516: 1566:  _dbus_assert (strcmp (rule->interface, "org.freedesktop.DBusInterface") == 0);
call    0 returned 100%
call    1 returned 100%
     2516: 1567:  _dbus_assert (strcmp (rule->sender, "org.freedesktop.DBusSender") == 0);
call    0 returned 100%
call    1 returned 100%
     2516: 1568:  _dbus_assert (strcmp (rule->member, "Foo") == 0);
call    0 returned 100%
call    1 returned 100%
     2516: 1569:  _dbus_assert (strcmp (rule->path, "/bar/foo") == 0);
call    0 returned 100%
call    1 returned 100%
     2516: 1570:  _dbus_assert (strcmp (rule->destination, ":452345.34") == 0);
call    0 returned 100%
call    1 returned 100%
     2516: 1571:}
        -: 1572:
        -: 1573:static dbus_bool_t
        -: 1574:test_parsing (void *data)
function test_parsing called 1690 returned 100% blocks executed 100%
     1690: 1575:{
        -: 1576:  BusMatchRule *rule;
        -: 1577:
     1690: 1578:  rule = check_parse (TRUE, "type='signal',sender='org.freedesktop.DBusSender',interface='org.freedesktop.DBusInterface',member='Foo',path='/bar/foo',destination=':452345.34'");
call    0 returned 100%
     1690: 1579:  if (rule != NULL)
branch  0 taken 81% (fallthrough)
branch  1 taken 19%
        -: 1580:    {
     1366: 1581:      assert_large_rule (rule);
call    0 returned 100%
     1366: 1582:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1583:    }
        -: 1584:
        -: 1585:  /* With extra whitespace and useless quotes */
     1690: 1586:  rule = check_parse (TRUE, "    type='signal',  \tsender='org.freedes''ktop.DBusSender',   interface='org.freedesktop.DBusInterface''''', \tmember='Foo',path='/bar/foo',destination=':452345.34'''''");
call    0 returned 100%
     1690: 1587:  if (rule != NULL)
branch  0 taken 68% (fallthrough)
branch  1 taken 32%
        -: 1588:    {
     1150: 1589:      assert_large_rule (rule);
call    0 returned 100%
     1150: 1590:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1591:    }
        -: 1592:
        -: 1593:
        -: 1594:  /* A simple signal connection */
     1690: 1595:  rule = check_parse (TRUE, "type='signal',path='/foo',interface='org.Bar'");
call    0 returned 100%
     1690: 1596:  if (rule != NULL)
branch  0 taken 75% (fallthrough)
branch  1 taken 25%
        -: 1597:    {
     1273: 1598:      _dbus_assert (rule->flags & BUS_MATCH_MESSAGE_TYPE);
call    0 returned 100%
     1273: 1599:      _dbus_assert (rule->flags & BUS_MATCH_INTERFACE);
call    0 returned 100%
     1273: 1600:      _dbus_assert (rule->flags & BUS_MATCH_PATH);
call    0 returned 100%
        -: 1601:
     1273: 1602:      _dbus_assert (rule->message_type == DBUS_MESSAGE_TYPE_SIGNAL);
call    0 returned 100%
     1273: 1603:      _dbus_assert (rule->interface != NULL);
call    0 returned 100%
     1273: 1604:      _dbus_assert (rule->path != NULL);
call    0 returned 100%
        -: 1605:
     1273: 1606:      _dbus_assert (strcmp (rule->interface, "org.Bar") == 0);
call    0 returned 100%
call    1 returned 100%
     1273: 1607:      _dbus_assert (strcmp (rule->path, "/foo") == 0);
call    0 returned 100%
call    1 returned 100%
        -: 1608:  
     1273: 1609:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1610:    }
        -: 1611:
        -: 1612:  /* argN */
     1690: 1613:  rule = check_parse (TRUE, "arg0='foo'");
call    0 returned 100%
     1690: 1614:  if (rule != NULL)
branch  0 taken 88% (fallthrough)
branch  1 taken 12%
        -: 1615:    {
     1487: 1616:      _dbus_assert (rule->flags == BUS_MATCH_ARGS);
call    0 returned 100%
     1487: 1617:      _dbus_assert (rule->args != NULL);
call    0 returned 100%
     1487: 1618:      _dbus_assert (rule->args_len == 1);
call    0 returned 100%
     1487: 1619:      _dbus_assert (rule->args[0] != NULL);
call    0 returned 100%
     1487: 1620:      _dbus_assert (rule->args[1] == NULL);
call    0 returned 100%
     1487: 1621:      _dbus_assert (strcmp (rule->args[0], "foo") == 0);
call    0 returned 100%
call    1 returned 100%
        -: 1622:
     1487: 1623:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1624:    }
        -: 1625:  
     1690: 1626:  rule = check_parse (TRUE, "arg1='foo'");
call    0 returned 100%
     1690: 1627:  if (rule != NULL)
branch  0 taken 95% (fallthrough)
branch  1 taken 5%
        -: 1628:    {
     1604: 1629:      _dbus_assert (rule->flags == BUS_MATCH_ARGS);
call    0 returned 100%
     1604: 1630:      _dbus_assert (rule->args != NULL);
call    0 returned 100%
     1604: 1631:      _dbus_assert (rule->args_len == 2);
call    0 returned 100%
     1604: 1632:      _dbus_assert (rule->args[0] == NULL);
call    0 returned 100%
     1604: 1633:      _dbus_assert (rule->args[1] != NULL);
call    0 returned 100%
     1604: 1634:      _dbus_assert (rule->args[2] == NULL);
call    0 returned 100%
     1604: 1635:      _dbus_assert (strcmp (rule->args[1], "foo") == 0);
call    0 returned 100%
call    1 returned 100%
        -: 1636:
     1604: 1637:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1638:    }
        -: 1639:
     1690: 1640:  rule = check_parse (TRUE, "arg2='foo'");
call    0 returned 100%
     1690: 1641:  if (rule != NULL)
branch  0 taken 96% (fallthrough)
branch  1 taken 4%
        -: 1642:    {
     1624: 1643:      _dbus_assert (rule->flags == BUS_MATCH_ARGS);
call    0 returned 100%
     1624: 1644:      _dbus_assert (rule->args != NULL);
call    0 returned 100%
     1624: 1645:      _dbus_assert (rule->args_len == 3);
call    0 returned 100%
     1624: 1646:      _dbus_assert (rule->args[0] == NULL);
call    0 returned 100%
     1624: 1647:      _dbus_assert (rule->args[1] == NULL);
call    0 returned 100%
     1624: 1648:      _dbus_assert (rule->args[2] != NULL);
call    0 returned 100%
     1624: 1649:      _dbus_assert (rule->args[3] == NULL);
call    0 returned 100%
     1624: 1650:      _dbus_assert (strcmp (rule->args[2], "foo") == 0);
call    0 returned 100%
call    1 returned 100%
        -: 1651:
     1624: 1652:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1653:    }
        -: 1654:  
     1690: 1655:  rule = check_parse (TRUE, "arg40='foo'");
call    0 returned 100%
     1690: 1656:  if (rule != NULL)
branch  0 taken 96% (fallthrough)
branch  1 taken 4%
        -: 1657:    {
     1624: 1658:      _dbus_assert (rule->flags == BUS_MATCH_ARGS);
call    0 returned 100%
     1624: 1659:      _dbus_assert (rule->args != NULL);
call    0 returned 100%
     1624: 1660:      _dbus_assert (rule->args_len == 41);
call    0 returned 100%
     1624: 1661:      _dbus_assert (rule->args[0] == NULL);
call    0 returned 100%
     1624: 1662:      _dbus_assert (rule->args[1] == NULL);
call    0 returned 100%
     1624: 1663:      _dbus_assert (rule->args[40] != NULL);
call    0 returned 100%
     1624: 1664:      _dbus_assert (rule->args[41] == NULL);
call    0 returned 100%
     1624: 1665:      _dbus_assert (strcmp (rule->args[40], "foo") == 0);
call    0 returned 100%
call    1 returned 100%
        -: 1666:
     1624: 1667:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1668:    }
        -: 1669:  
     1690: 1670:  rule = check_parse (TRUE, "arg63='foo'");
call    0 returned 100%
     1690: 1671:  if (rule != NULL)
branch  0 taken 96% (fallthrough)
branch  1 taken 4%
        -: 1672:    {
     1624: 1673:      _dbus_assert (rule->flags == BUS_MATCH_ARGS);
call    0 returned 100%
     1624: 1674:      _dbus_assert (rule->args != NULL);
call    0 returned 100%
     1624: 1675:      _dbus_assert (rule->args_len == 64);
call    0 returned 100%
     1624: 1676:      _dbus_assert (rule->args[0] == NULL);
call    0 returned 100%
     1624: 1677:      _dbus_assert (rule->args[1] == NULL);
call    0 returned 100%
     1624: 1678:      _dbus_assert (rule->args[63] != NULL);
call    0 returned 100%
     1624: 1679:      _dbus_assert (rule->args[64] == NULL);
call    0 returned 100%
     1624: 1680:      _dbus_assert (strcmp (rule->args[63], "foo") == 0);
call    0 returned 100%
call    1 returned 100%
        -: 1681:
     1624: 1682:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1683:    }
        -: 1684:  
        -: 1685:  /* Too-large argN */
     1690: 1686:  rule = check_parse (FALSE, "arg300='foo'");
call    0 returned 100%
     1690: 1687:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1688:  rule = check_parse (FALSE, "arg64='foo'");
call    0 returned 100%
     1690: 1689:  _dbus_assert (rule == NULL);
call    0 returned 100%
        -: 1690:
        -: 1691:  /* No N in argN */
     1690: 1692:  rule = check_parse (FALSE, "arg='foo'");
call    0 returned 100%
     1690: 1693:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1694:  rule = check_parse (FALSE, "argv='foo'");
call    0 returned 100%
     1690: 1695:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1696:  rule = check_parse (FALSE, "arg3junk='foo'");
call    0 returned 100%
     1690: 1697:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1698:  rule = check_parse (FALSE, "argument='foo'");
call    0 returned 100%
     1690: 1699:  _dbus_assert (rule == NULL);
call    0 returned 100%
        -: 1700:  
        -: 1701:  /* Reject duplicates */
     1690: 1702:  rule = check_parse (FALSE, "type='signal',type='method_call'");
call    0 returned 100%
     1690: 1703:  _dbus_assert (rule == NULL);
call    0 returned 100%
        -: 1704:
        -: 1705:  /* Duplicates with the argN code */
     1690: 1706:  rule = check_parse (FALSE, "arg0='foo',arg0='bar'");
call    0 returned 100%
     1690: 1707:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1708:  rule = check_parse (FALSE, "arg3='foo',arg3='bar'");
call    0 returned 100%
     1690: 1709:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1710:  rule = check_parse (FALSE, "arg30='foo',arg30='bar'");
call    0 returned 100%
     1690: 1711:  _dbus_assert (rule == NULL);
call    0 returned 100%
        -: 1712:  
        -: 1713:  /* Reject broken keys */
     1690: 1714:  rule = check_parse (FALSE, "blah='signal'");
call    0 returned 100%
     1690: 1715:  _dbus_assert (rule == NULL);
call    0 returned 100%
        -: 1716:
        -: 1717:  /* Reject broken values */
     1690: 1718:  rule = check_parse (FALSE, "type='chouin'");
call    0 returned 100%
     1690: 1719:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1720:  rule = check_parse (FALSE, "interface='abc@def++'");
call    0 returned 100%
     1690: 1721:  _dbus_assert (rule == NULL);
call    0 returned 100%
     1690: 1722:  rule = check_parse (FALSE, "service='youpi'");
call    0 returned 100%
     1690: 1723:  _dbus_assert (rule == NULL);
call    0 returned 100%
        -: 1724:
        -: 1725:  /* Allow empty rule */
     1690: 1726:  rule = check_parse (TRUE, "");
call    0 returned 100%
     1690: 1727:  if (rule != NULL)
branch  0 taken 97% (fallthrough)
branch  1 taken 3%
        -: 1728:    {
     1632: 1729:      _dbus_assert (rule->flags == 0);
call    0 returned 100%
        -: 1730:      
     1632: 1731:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1732:    }
        -: 1733:
        -: 1734:  /* All-whitespace rule is the same as empty */
     1690: 1735:  rule = check_parse (TRUE, "    \t");
call    0 returned 100%
     1690: 1736:  if (rule != NULL)
branch  0 taken 98% (fallthrough)
branch  1 taken 2%
        -: 1737:    {
     1660: 1738:      _dbus_assert (rule->flags == 0);
call    0 returned 100%
        -: 1739:      
     1660: 1740:      bus_match_rule_unref (rule);
call    0 returned 100%
        -: 1741:    }
        -: 1742:
        -: 1743:  /* But with non-whitespace chars and no =value, it's not OK */
     1690: 1744:  rule = check_parse (FALSE, "type");
call    0 returned 100%
     1690: 1745:  _dbus_assert (rule == NULL);
call    0 returned 100%
        -: 1746:  
     1690: 1747:  return TRUE;
        -: 1748:}
        -: 1749:
        -: 1750:static struct {
        -: 1751:  const char *first;
        -: 1752:  const char *second;
        -: 1753:} equality_tests[] = {
        -: 1754:  { "type='signal'", "type='signal'" },
        -: 1755:  { "type='signal',interface='foo.bar'", "interface='foo.bar',type='signal'" },
        -: 1756:  { "type='signal',member='bar'", "member='bar',type='signal'" },
        -: 1757:  { "type='method_call',sender=':1.0'", "sender=':1.0',type='method_call'" },
        -: 1758:  { "type='method_call',destination=':1.0'", "destination=':1.0',type='method_call'" },
        -: 1759:  { "type='method_call',path='/foo/bar'", "path='/foo/bar',type='method_call'" },
        -: 1760:  { "type='method_call',arg0='blah'", "arg0='blah',type='method_call'" },
        -: 1761:  { "type='method_call',arg0='boo'", "arg0='boo',type='method_call'" },
        -: 1762:  { "type='method_call',arg0='blah',arg1='baz'", "arg0='blah',arg1='baz',type='method_call'" },
        -: 1763:  { "type='method_call',arg3='foosh'", "arg3='foosh',type='method_call'" },
        -: 1764:  { "arg3='fool'", "arg3='fool'" },
        -: 1765:  { "member='food'", "member='food'" }
        -: 1766:};
        -: 1767:
        -: 1768:static void
        -: 1769:test_equality (void)
function test_equality called 1 returned 100% blocks executed 83%
        1: 1770:{
        -: 1771:  int i;
        -: 1772:  
        1: 1773:  i = 0;
       14: 1774:  while (i < _DBUS_N_ELEMENTS (equality_tests))
branch  0 taken 92%
branch  1 taken 8% (fallthrough)
        -: 1775:    {
        -: 1776:      BusMatchRule *first;
        -: 1777:      BusMatchRule *second;
        -: 1778:      int j;
        -: 1779:      
       12: 1780:      first = check_parse (TRUE, equality_tests[i].first);
call    0 returned 100%
       12: 1781:      _dbus_assert (first != NULL);
call    0 returned 100%
       12: 1782:      second = check_parse (TRUE, equality_tests[i].second);
call    0 returned 100%
       12: 1783:      _dbus_assert (second != NULL);
call    0 returned 100%
        -: 1784:
       12: 1785:      if (!match_rule_equal (first, second))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1786:        {
    #####: 1787:          _dbus_warn ("rule %s and %s should have been equal\n",
call    0 never executed
        -: 1788:                      equality_tests[i].first,
        -: 1789:                      equality_tests[i].second);
    #####: 1790:          exit (1);
call    0 never executed
        -: 1791:        }
        -: 1792:
       12: 1793:      bus_match_rule_unref (second);
call    0 returned 100%
        -: 1794:
        -: 1795:      /* Check that the rule is not equal to any of the
        -: 1796:       * others besides its pair match
        -: 1797:       */
       12: 1798:      j = 0;
      168: 1799:      while (j < _DBUS_N_ELEMENTS (equality_tests))
branch  0 taken 92%
branch  1 taken 8% (fallthrough)
        -: 1800:        {
      144: 1801:          if (i != j)
branch  0 taken 92% (fallthrough)
branch  1 taken 8%
        -: 1802:            {
      132: 1803:              second = check_parse (TRUE, equality_tests[j].second);
call    0 returned 100%
        -: 1804:
      132: 1805:              if (match_rule_equal (first, second))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1806:                {
    #####: 1807:                  _dbus_warn ("rule %s and %s should not have been equal\n",
call    0 never executed
        -: 1808:                              equality_tests[i].first,
        -: 1809:                              equality_tests[j].second);
    #####: 1810:                  exit (1);
call    0 never executed
        -: 1811:                }
        -: 1812:              
      132: 1813:              bus_match_rule_unref (second);
call    0 returned 100%
        -: 1814:            }
        -: 1815:          
      144: 1816:          ++j;
        -: 1817:        }
        -: 1818:
       12: 1819:      bus_match_rule_unref (first);
call    0 returned 100%
        -: 1820:
       12: 1821:      ++i;
        -: 1822:    }
        1: 1823:}
        -: 1824:
        -: 1825:static const char*
        -: 1826:should_match_message_1[] = {
        -: 1827:  "type='signal'",
        -: 1828:  "member='Frobated'",
        -: 1829:  "arg0='foobar'",
        -: 1830:  "type='signal',member='Frobated'",
        -: 1831:  "type='signal',member='Frobated',arg0='foobar'",
        -: 1832:  "member='Frobated',arg0='foobar'",
        -: 1833:  "type='signal',arg0='foobar'",
        -: 1834:  NULL
        -: 1835:};
        -: 1836:
        -: 1837:static const char*
        -: 1838:should_not_match_message_1[] = {
        -: 1839:  "type='method_call'",
        -: 1840:  "type='error'",
        -: 1841:  "type='method_return'",
        -: 1842:  "type='signal',member='Oopsed'",
        -: 1843:  "arg0='blah'",
        -: 1844:  "arg1='foobar'",
        -: 1845:  "arg2='foobar'",
        -: 1846:  "arg3='foobar'",
        -: 1847:  "arg0='3'",
        -: 1848:  "arg1='3'",
        -: 1849:  "arg0='foobar',arg1='abcdef'",
        -: 1850:  "arg0='foobar',arg1='abcdef',arg2='abcdefghi',arg3='abcdefghi',arg4='abcdefghi'",
        -: 1851:  "arg0='foobar',arg1='abcdef',arg4='abcdefghi',arg3='abcdefghi',arg2='abcdefghi'",
        -: 1852:  NULL
        -: 1853:};
        -: 1854:
        -: 1855:static void
        -: 1856:check_matches (dbus_bool_t  expected_to_match,
        -: 1857:               int          number,
        -: 1858:               DBusMessage *message,
        -: 1859:               const char  *rule_text)
function check_matches called 20 returned 100% blocks executed 55%
       20: 1860:{
        -: 1861:  BusMatchRule *rule;
        -: 1862:  dbus_bool_t matched;
        -: 1863:
       20: 1864:  rule = check_parse (TRUE, rule_text);
call    0 returned 100%
       20: 1865:  _dbus_assert (rule != NULL);
call    0 returned 100%
        -: 1866:
        -: 1867:  /* We can't test sender/destination rules since we pass NULL here */
       20: 1868:  matched = match_rule_matches (rule, NULL, NULL, message);
call    0 returned 100%
        -: 1869:
       20: 1870:  if (matched != expected_to_match)
branch  0 taken 0% (fallthrough)
branch  1 taken 100%
        -: 1871:    {
    #####: 1872:      _dbus_warn ("Expected rule %s to %s message %d, failed\n",
branch  0 never executed
branch  1 never executed
call    2 never executed
        -: 1873:                  rule_text, expected_to_match ?
        -: 1874:                  "match" : "not match", number);
    #####: 1875:      exit (1);
call    0 never executed
        -: 1876:    }
        -: 1877:
       20: 1878:  bus_match_rule_unref (rule);
call    0 returned 100%
       20: 1879:}
        -: 1880:
        -: 1881:static void
        -: 1882:check_matching (DBusMessage *message,
        -: 1883:                int          number,
        -: 1884:                const char **should_match,
        -: 1885:                const char **should_not_match)
function check_matching called 1 returned 100% blocks executed 100%
        1: 1886:{
        -: 1887:  int i;
        -: 1888:
        1: 1889:  i = 0;
        9: 1890:  while (should_match[i] != NULL)
branch  0 taken 88%
branch  1 taken 13% (fallthrough)
        -: 1891:    {
        7: 1892:      check_matches (TRUE, number, message, should_match[i]);
call    0 returned 100%
        7: 1893:      ++i;
        -: 1894:    }
        -: 1895:
        1: 1896:  i = 0;
       15: 1897:  while (should_not_match[i] != NULL)
branch  0 taken 93%
branch  1 taken 7% (fallthrough)
        -: 1898:    {
       13: 1899:      check_matches (FALSE, number, message, should_not_match[i]);
call    0 returned 100%
       13: 1900:      ++i;
        -: 1901:    }
        1: 1902:}
        -: 1903:
        -: 1904:static void
        -: 1905:test_matching (void)
function test_matching called 1 returned 100% blocks executed 82%
        1: 1906:{
        -: 1907:  DBusMessage *message1;
        -: 1908:  const char *v_STRING;
        -: 1909:  dbus_int32_t v_INT32;
        -: 1910:
        1: 1911:  message1 = dbus_message_new (DBUS_MESSAGE_TYPE_SIGNAL);
call    0 returned 100%
        1: 1912:  _dbus_assert (message1 != NULL);
call    0 returned 100%
        1: 1913:  if (!dbus_message_set_member (message1, "Frobated"))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 1914:    _dbus_assert_not_reached ("oom");
call    0 never executed
        -: 1915:
        1: 1916:  v_STRING = "foobar";
        1: 1917:  v_INT32 = 3;
        1: 1918:  if (!dbus_message_append_args (message1,
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
        -: 1919:                                 DBUS_TYPE_STRING, &v_STRING,
        -: 1920:                                 DBUS_TYPE_INT32, &v_INT32,
        -: 1921:                                 NULL))
    #####: 1922:    _dbus_assert_not_reached ("oom");
call    0 never executed
        -: 1923:  
        1: 1924:  check_matching (message1, 1,
call    0 returned 100%
        -: 1925:                  should_match_message_1,
        -: 1926:                  should_not_match_message_1);
        -: 1927:  
        1: 1928:  dbus_message_unref (message1);
call    0 returned 100%
        1: 1929:}
        -: 1930:
        -: 1931:dbus_bool_t
        -: 1932:bus_signals_test (const DBusString *test_data_dir)
function bus_signals_test called 1 returned 100% blocks executed 90%
        1: 1933:{
        -: 1934:  BusMatchmaker *matchmaker;
        -: 1935:
        1: 1936:  matchmaker = bus_matchmaker_new ();
call    0 returned 100%
        1: 1937:  bus_matchmaker_ref (matchmaker);
call    0 returned 100%
        1: 1938:  bus_matchmaker_unref (matchmaker);
call    0 returned 100%
        1: 1939:  bus_matchmaker_unref (matchmaker);
call    0 returned 100%
        -: 1940:
        1: 1941:  if (!_dbus_test_oom_handling ("parsing match rules", test_parsing, NULL))
call    0 returned 100%
branch  1 taken 0% (fallthrough)
branch  2 taken 100%
    #####: 1942:    _dbus_assert_not_reached ("Parsing match rules test failed");
call    0 never executed
        -: 1943:
        1: 1944:  test_equality ();
call    0 returned 100%
        -: 1945:
        1: 1946:  test_matching ();
call    0 returned 100%
        -: 1947:  
        1: 1948:  return TRUE;
        -: 1949:}
        -: 1950:
        -: 1951:#endif /* DBUS_BUILD_TESTS */
        -: 1952: