(linenum→info "unix/slp.c:2238")

dbus/1.0.2/dbus/dbus-message-factory.c

    1: /* -*- mode: C; c-file-style: "gnu" -*- */
    2: /* dbus-message-factory.c Generator of valid and invalid message data for test suite
    3:  *
    4:  * Copyright (C) 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 <config.h>
   24: 
   25: #ifndef DOXYGEN_SHOULD_SKIP_THIS
   26: 
   27: #ifdef DBUS_BUILD_TESTS
   28: #include "dbus-message-factory.h"
   29: #include "dbus-message-private.h"
   30: #include "dbus-test.h"
   31: #include <stdio.h>
   32: 
   33: typedef enum
   34:   {
   35:     CHANGE_TYPE_ADJUST,
   36:     CHANGE_TYPE_ABSOLUTE
   37:   } ChangeType;
   38: 
   39: #define BYTE_ORDER_OFFSET  0
   40: #define TYPE_OFFSET        1
   41: #define BODY_LENGTH_OFFSET 4
   42: #define FIELDS_ARRAY_LENGTH_OFFSET 12
   43: 
   44: static void
   45: iter_recurse (DBusMessageDataIter *iter)
   46: {
   47:   iter->depth += 1;
   48:   _dbus_assert (iter->depth < _DBUS_MESSAGE_DATA_MAX_NESTING);
   49:   _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
   50: }
   51: 
   52: static int
   53: iter_get_sequence (DBusMessageDataIter *iter)
   54: {
   55:   _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
   56:   return iter->sequence_nos[iter->depth];
   57: }
   58: 
   59: static void
   60: iter_set_sequence (DBusMessageDataIter *iter,
   61:                    int                  sequence)
   62: {
   63:   _dbus_assert (sequence >= 0);
   64:   iter->sequence_nos[iter->depth] = sequence;
   65: }
   66: 
   67: static void
   68: iter_unrecurse (DBusMessageDataIter *iter)
   69: {
   70:   iter->depth -= 1;
   71:   _dbus_assert (iter->depth >= 0);
   72: }
   73: 
   74: static void
   75: iter_next (DBusMessageDataIter *iter)
   76: {
   77:   iter->sequence_nos[iter->depth] += 1;
   78: }
   79: 
   80: static dbus_bool_t
   81: iter_first_in_series (DBusMessageDataIter *iter)
   82: {
   83:   int i;
   84: 
   85:   i = iter->depth;
   86:   while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
   87:     {
   88:       if (iter->sequence_nos[i] != 0)
   89:         return FALSE;
   90:       ++i;
   91:     }
   92:   return TRUE;
   93: }
   94: 
   95: typedef dbus_bool_t (* DBusInnerGeneratorFunc)   (DBusMessageDataIter *iter,
   96:                                                   DBusMessage        **message_p);
   97: typedef dbus_bool_t (* DBusMessageGeneratorFunc) (DBusMessageDataIter *iter,
   98:                                                   DBusString          *data,
   99:                                                   DBusValidity        *expected_validity);
  100: 
  101: static void
  102: set_reply_serial (DBusMessage *message)
  103: {
  104:   if (message == NULL)
  105:     _dbus_assert_not_reached ("oom");
  106:   if (!dbus_message_set_reply_serial (message, 100))
  107:     _dbus_assert_not_reached ("oom");
  108: }
  109: 
  110: static dbus_bool_t
  111: generate_trivial_inner (DBusMessageDataIter *iter,
  112:                         DBusMessage        **message_p)
  113: {
  114:   DBusMessage *message;
  115: 
  116:   switch (iter_get_sequence (iter))
  117:     {
  118:     case 0:
  119:       message = dbus_message_new_method_call ("org.freedesktop.TextEditor",
  120:                                               "/foo/bar",
  121:                                               "org.freedesktop.DocumentFactory",
  122:                                               "Create");
  123:       break;
  124:     case 1:
  125:       message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
  126:       set_reply_serial (message);
  127:       break;
  128:     case 2:
  129:       message = dbus_message_new_signal ("/foo/bar",
  130:                                          "org.freedesktop.DocumentFactory",
  131:                                          "Created");
  132:       break;
  133:     case 3:
  134:       message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
  135: 
  136:       if (!dbus_message_set_error_name (message,
  137:                                         "org.freedesktop.TestErrorName"))
  138:         _dbus_assert_not_reached ("oom");
  139:       
  140:       {
  141:         DBusMessageIter iter;
  142:         const char *v_STRING = "This is an error";
  143:         
  144:         dbus_message_iter_init_append (message, &iter);
  145:         if (!dbus_message_iter_append_basic (&iter,
  146:                                              DBUS_TYPE_STRING,
  147:                                              &v_STRING))
  148:           _dbus_assert_not_reached ("oom");
  149:       }
  150:       
  151:       set_reply_serial (message);
  152:       break;
  153:     default:
  154:       return FALSE;
  155:     }
  156:   
  157:   if (message == NULL)
  158:     _dbus_assert_not_reached ("oom");
  159: 
  160:   *message_p = message;
  161:   
  162:   return TRUE;
  163: }
  164: 
  165: static dbus_bool_t
  166: generate_many_bodies_inner (DBusMessageDataIter *iter,
  167:                             DBusMessage        **message_p)
  168: {
  169:   DBusMessage *message;
  170:   DBusString signature;
  171:   DBusString body;
  172: 
  173:   /* Keeping this small makes things go faster */
  174:   message = dbus_message_new_method_call ("o.z.F",
  175:                                           "/",
  176:                                           "o.z.B",
  177:                                           "Nah");
  178:   if (message == NULL)
  179:     _dbus_assert_not_reached ("oom");
  180: 
  181:   set_reply_serial (message);
  182: 
  183:   if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
  184:     _dbus_assert_not_reached ("oom");
  185:   
  186:   if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter),
  187:                                                 message->byte_order,
  188:                                                 &signature, &body))
  189:     {
  190:       const char *v_SIGNATURE;
  191: 
  192:       v_SIGNATURE = _dbus_string_get_const_data (&signature);
  193:       if (!_dbus_header_set_field_basic (&message->header,
  194:                                          DBUS_HEADER_FIELD_SIGNATURE,
  195:                                          DBUS_TYPE_SIGNATURE,
  196:                                          &v_SIGNATURE))
  197:         _dbus_assert_not_reached ("oom");
  198: 
  199:       if (!_dbus_string_move (&body, 0, &message->body, 0))
  200:         _dbus_assert_not_reached ("oom");
  201: 
  202:       _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET,
  203:                                 _dbus_string_get_length (&message->body),
  204:                                 message->byte_order);
  205:       
  206:       *message_p = message;
  207:     }
  208:   else
  209:     {
  210:       dbus_message_unref (message);
  211:       *message_p = NULL;
  212:     }
  213:   
  214:   _dbus_string_free (&signature);
  215:   _dbus_string_free (&body);
  216: 
  217:   return *message_p != NULL;
  218: }
  219: 
  220: static void
  221: generate_from_message (DBusString            *data,
  222:                        DBusValidity          *expected_validity,
  223:                        DBusMessage           *message)
  224: {
  225:   _dbus_message_set_serial (message, 1);
  226:   _dbus_message_lock (message);
  227: 
  228:   *expected_validity = DBUS_VALID;
  229:   
  230:   /* move for efficiency, since we'll nuke the message anyway */
  231:   if (!_dbus_string_move (&message->header.data, 0,
  232:                           data, 0))
  233:     _dbus_assert_not_reached ("oom");
  234: 
  235:   if (!_dbus_string_copy (&message->body, 0,
  236:                           data, _dbus_string_get_length (data)))
  237:     _dbus_assert_not_reached ("oom");
  238: }
  239: 
  240: static dbus_bool_t
  241: generate_outer (DBusMessageDataIter   *iter,
  242:                 DBusString            *data,
  243:                 DBusValidity          *expected_validity,
  244:                 DBusInnerGeneratorFunc func)
  245: {
  246:   DBusMessage *message;
  247: 
  248:   message = NULL;
  249:   if (!(*func)(iter, &message))
  250:     return FALSE;
  251: 
  252:   iter_next (iter);
  253:   
  254:   _dbus_assert (message != NULL);
  255: 
  256:   generate_from_message (data, expected_validity, message);
  257: 
  258:   dbus_message_unref (message);
  259: 
  260:   return TRUE;
  261: }
  262: 
  263: static dbus_bool_t
  264: generate_trivial (DBusMessageDataIter   *iter,
  265:                   DBusString            *data,
  266:                   DBusValidity          *expected_validity)
  267: {
  268:   return generate_outer (iter, data, expected_validity,
  269:                          generate_trivial_inner);
  270: }
  271: 
  272: static dbus_bool_t
  273: generate_many_bodies (DBusMessageDataIter   *iter,
  274:                       DBusString            *data,
  275:                       DBusValidity          *expected_validity)
  276: {
  277:   return generate_outer (iter, data, expected_validity,
  278:                          generate_many_bodies_inner);
  279: }
  280: 
  281: static DBusMessage*
  282: simple_method_call (void)
  283: {
  284:   DBusMessage *message;
  285:   /* Keeping this small makes stuff go faster */
  286:   message = dbus_message_new_method_call ("o.b.Q",
  287:                                           "/f/b",
  288:                                           "o.b.Z",
  289:                                           "Fro");
  290:   if (message == NULL)
  291:     _dbus_assert_not_reached ("oom");
  292:   return message;
  293: }
  294: 
  295: static DBusMessage*
  296: simple_signal (void)
  297: {
  298:   DBusMessage *message;
  299:   message = dbus_message_new_signal ("/f/b",
  300:                                      "o.b.Z",
  301:                                      "Fro");
  302:   if (message == NULL)
  303:     _dbus_assert_not_reached ("oom");
  304:   return message;
  305: }
  306: 
  307: static DBusMessage*
  308: simple_method_return (void)
  309: {
  310:   DBusMessage *message;
  311:   message =  dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
  312:   if (message == NULL)
  313:     _dbus_assert_not_reached ("oom");
  314: 
  315:   set_reply_serial (message);
  316:   
  317:   return message;
  318: }
  319: 
  320: static DBusMessage*
  321: simple_error (void)
  322: {
  323:   DBusMessage *message;
  324:   message =  dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
  325:   if (message == NULL)
  326:     _dbus_assert_not_reached ("oom");
  327: 
  328:   if (!dbus_message_set_error_name (message, "foo.bar"))
  329:     _dbus_assert_not_reached ("oom");
  330:   
  331:   set_reply_serial (message);
  332:   
  333:   return message;
  334: }
  335: 
  336: static dbus_bool_t
  337: generate_special (DBusMessageDataIter   *iter,
  338:                   DBusString            *data,
  339:                   DBusValidity          *expected_validity)
  340: {
  341:   int item_seq;
  342:   DBusMessage *message;
  343:   int pos;
  344:   dbus_int32_t v_INT32;
  345: 
  346:   _dbus_assert (_dbus_string_get_length (data) == 0);
  347:   
  348:   message = NULL;
  349:   pos = -1;
  350:   v_INT32 = 42;
  351:   item_seq = iter_get_sequence (iter);
  352: 
  353:   if (item_seq == 0)
  354:     {
  355:       message = simple_method_call ();
  356:       if (!dbus_message_append_args (message,
  357:                                      DBUS_TYPE_INT32, &v_INT32,
  358:                                      DBUS_TYPE_INT32, &v_INT32,
  359:                                      DBUS_TYPE_INT32, &v_INT32,
  360:                                      DBUS_TYPE_INVALID))
  361:         _dbus_assert_not_reached ("oom");
  362:                                      
  363:       _dbus_header_get_field_raw (&message->header,
  364:                                   DBUS_HEADER_FIELD_SIGNATURE,
  365:                                   NULL, &pos);
  366:       generate_from_message (data, expected_validity, message);
  367:       
  368:       /* set an invalid typecode */
  369:       _dbus_string_set_byte (data, pos + 1, '$');
  370: 
  371:       *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
  372:     }
  373:   else if (item_seq == 1)
  374:     {
  375:       char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2];
  376:       const char *v_STRING;
  377:       int i;
  378:       
  379:       message = simple_method_call ();
  380:       if (!dbus_message_append_args (message,
  381:                                      DBUS_TYPE_INT32, &v_INT32,
  382:                                      DBUS_TYPE_INT32, &v_INT32,
  383:                                      DBUS_TYPE_INT32, &v_INT32,
  384:                                      DBUS_TYPE_INVALID))
  385:         _dbus_assert_not_reached ("oom");
  386: 
  387:       i = 0;
  388:       while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
  389:         {
  390:           long_sig[i] = DBUS_TYPE_ARRAY;
  391:           ++i;
  392:         }
  393:       long_sig[i] = DBUS_TYPE_INVALID;
  394: 
  395:       v_STRING = long_sig;
  396:       if (!_dbus_header_set_field_basic (&message->header,
  397:                                          DBUS_HEADER_FIELD_SIGNATURE,
  398:                                          DBUS_TYPE_SIGNATURE,
  399:                                          &v_STRING))
  400:         _dbus_assert_not_reached ("oom");
  401:       
  402:       _dbus_header_get_field_raw (&message->header,
  403:                                   DBUS_HEADER_FIELD_SIGNATURE,
  404:                                   NULL, &pos);
  405:       generate_from_message (data, expected_validity, message);
  406:       
  407:       *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
  408:     }
  409:   else if (item_seq == 2)
  410:     {
  411:       char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4];
  412:       const char *v_STRING;
  413:       int i;
  414:       
  415:       message = simple_method_call ();
  416:       if (!dbus_message_append_args (message,
  417:                                      DBUS_TYPE_INT32, &v_INT32,
  418:                                      DBUS_TYPE_INT32, &v_INT32,
  419:                                      DBUS_TYPE_INT32, &v_INT32,
  420:                                      DBUS_TYPE_INVALID))
  421:         _dbus_assert_not_reached ("oom");
  422: 
  423:       i = 0;
  424:       while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
  425:         {
  426:           long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
  427:           ++i;
  428:         }
  429: 
  430:       long_sig[i] = DBUS_TYPE_INT32;
  431:       ++i;
  432: 
  433:       while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
  434:         {
  435:           long_sig[i] = DBUS_STRUCT_END_CHAR;
  436:           ++i;
  437:         }
  438:       long_sig[i] = DBUS_TYPE_INVALID;
  439:       
  440:       v_STRING = long_sig;
  441:       if (!_dbus_header_set_field_basic (&message->header,
  442:                                          DBUS_HEADER_FIELD_SIGNATURE,
  443:                                          DBUS_TYPE_SIGNATURE,
  444:                                          &v_STRING))
  445:         _dbus_assert_not_reached ("oom");
  446:       
  447:       _dbus_header_get_field_raw (&message->header,
  448:                                   DBUS_HEADER_FIELD_SIGNATURE,
  449:                                   NULL, &pos);
  450:       generate_from_message (data, expected_validity, message);
  451:       
  452:       *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
  453:     }
  454:   else if (item_seq == 3)
  455:     {
  456:       message = simple_method_call ();
  457:       if (!dbus_message_append_args (message,
  458:                                      DBUS_TYPE_INT32, &v_INT32,
  459:                                      DBUS_TYPE_INT32, &v_INT32,
  460:                                      DBUS_TYPE_INT32, &v_INT32,
  461:                                      DBUS_TYPE_INVALID))
  462:         _dbus_assert_not_reached ("oom");
  463:                                      
  464:       _dbus_header_get_field_raw (&message->header,
  465:                                   DBUS_HEADER_FIELD_SIGNATURE,
  466:                                   NULL, &pos);
  467:       generate_from_message (data, expected_validity, message);
  468:       
  469:       _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
  470:       
  471:       *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
  472:     }
  473:   else if (item_seq == 4)
  474:     {
  475:       message = simple_method_call ();
  476:       if (!dbus_message_append_args (message,
  477:                                      DBUS_TYPE_INT32, &v_INT32,
  478:                                      DBUS_TYPE_INT32, &v_INT32,
  479:                                      DBUS_TYPE_INT32, &v_INT32,
  480:                                      DBUS_TYPE_INVALID))
  481:         _dbus_assert_not_reached ("oom");
  482:                                      
  483:       _dbus_header_get_field_raw (&message->header,
  484:                                   DBUS_HEADER_FIELD_SIGNATURE,
  485:                                   NULL, &pos);
  486:       generate_from_message (data, expected_validity, message);
  487:       
  488:       _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
  489:       
  490:       *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
  491:     }
  492:   else if (item_seq == 5)
  493:     {
  494:       message = simple_method_call ();
  495:       if (!dbus_message_append_args (message,
  496:                                      DBUS_TYPE_INT32, &v_INT32,
  497:                                      DBUS_TYPE_INT32, &v_INT32,
  498:                                      DBUS_TYPE_INT32, &v_INT32,
  499:                                      DBUS_TYPE_INVALID))
  500:         _dbus_assert_not_reached ("oom");
  501:                                      
  502:       _dbus_header_get_field_raw (&message->header,
  503:                                   DBUS_HEADER_FIELD_SIGNATURE,
  504:                                   NULL, &pos);
  505:       generate_from_message (data, expected_validity, message);
  506:       
  507:       _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
  508:       _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
  509:       
  510:       *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
  511:     }
  512:   else if (item_seq == 6)
  513:     {
  514:       message = simple_method_call ();
  515:       generate_from_message (data, expected_validity, message);
  516:       
  517:       _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
  518:       
  519:       *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
  520:     }
  521:   else if (item_seq == 7)
  522:     {
  523:       /* Messages of unknown type are considered valid */
  524:       message = simple_method_call ();
  525:       generate_from_message (data, expected_validity, message);
  526:       
  527:       _dbus_string_set_byte (data, TYPE_OFFSET, 100);
  528:       
  529:       *expected_validity = DBUS_VALID;
  530:     }
  531:   else if (item_seq == 8)
  532:     {
  533:       message = simple_method_call ();
  534:       generate_from_message (data, expected_validity, message);
  535:       
  536:       _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
  537:                                 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
  538:                                 message->byte_order);
  539:       _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
  540:                                 DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
  541:                                 message->byte_order);
  542:       *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
  543:     }
  544:   else if (item_seq == 9)
  545:     {
  546:       const char *v_STRING = "not a valid bus name";
  547:       message = simple_method_call ();
  548: 
  549:       if (!_dbus_header_set_field_basic (&message->header,
  550:                                          DBUS_HEADER_FIELD_SENDER,
  551:                                          DBUS_TYPE_STRING, &v_STRING))
  552:         _dbus_assert_not_reached ("oom");
  553:       
  554:       generate_from_message (data, expected_validity, message);
  555: 
  556:       *expected_validity = DBUS_INVALID_BAD_SENDER;
  557:     }
  558:   else if (item_seq == 10)
  559:     {
  560:       message = simple_method_call ();
  561: 
  562:       if (!dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL))
  563:         _dbus_assert_not_reached ("oom");
  564:       
  565:       generate_from_message (data, expected_validity, message);
  566: 
  567:       *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
  568:     }
  569:   else if (item_seq == 11)
  570:     {
  571:       message = simple_method_call ();
  572: 
  573:       if (!dbus_message_set_path (message, DBUS_PATH_LOCAL))
  574:         _dbus_assert_not_reached ("oom");
  575:       
  576:       generate_from_message (data, expected_validity, message);
  577: 
  578:       *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
  579:     }
  580:   else if (item_seq ==