dbus-marshal-validate: Check brackets in signature nest correctly
[platform/upstream/dbus.git] / dbus / dbus-message-util.c
index 5266b01..ebf00e2 100644 (file)
  * @{
  */
 
+/**
+ * Gets the number of unix fds attached to this message.
+ *
+ * @param message the message
+ * @returns the number of file descriptors
+ */
+unsigned int
+_dbus_message_get_n_unix_fds (DBusMessage *message)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+  return message->n_unix_fds;
+#else
+  return 0;
+#endif
+}
+
 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
 /**
  * Reads arguments from a message iterator given a variable argument
@@ -132,7 +148,7 @@ check_memleaks (void)
 
   if (_dbus_get_malloc_blocks_outstanding () != 0)
     {
-      _dbus_warn ("%d dbus_malloc blocks were not freed in %s\n",
+      _dbus_warn ("%d dbus_malloc blocks were not freed in %s",
                   _dbus_get_malloc_blocks_outstanding (), __FILE__);
       _dbus_assert_not_reached ("memleaks");
     }
@@ -182,6 +198,13 @@ _dbus_check_fdleaks_enter (void)
           if (fd == dirfd (d))
             continue;
 
+          if (fd >= FD_SETSIZE)
+            {
+              _dbus_verbose ("FD %d unexpectedly large; cannot track whether "
+                             "it is leaked\n", fd);
+              continue;
+            }
+
           FD_SET (fd, &fds->set);
         }
 
@@ -227,10 +250,17 @@ _dbus_check_fdleaks_leave (DBusInitialFDs *fds)
           if (fd == dirfd (d))
             continue;
 
+          if (fd >= FD_SETSIZE)
+            {
+              _dbus_verbose ("FD %d unexpectedly large; cannot track whether "
+                             "it is leaked\n", fd);
+              continue;
+            }
+
           if (FD_ISSET (fd, &fds->set))
             continue;
 
-          _dbus_warn ("file descriptor %i leaked in %s.\n", fd, __FILE__);
+          _dbus_warn ("file descriptor %i leaked in %s.", fd, __FILE__);
           _dbus_assert_not_reached ("fdleaks");
         }
 
@@ -254,7 +284,7 @@ check_have_valid_message (DBusMessageLoader *loader)
 
   if (_dbus_message_loader_get_is_corrupted (loader))
     {
-      _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d\n",
+      _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d",
                   loader->corruption_reason);
       goto failed;
     }
@@ -262,13 +292,13 @@ check_have_valid_message (DBusMessageLoader *loader)
   message = _dbus_message_loader_pop_message (loader);
   if (message == NULL)
     {
-      _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
+      _dbus_warn ("didn't load message that was expected to be valid (message not popped)");
       goto failed;
     }
 
   if (_dbus_string_get_length (&loader->data) > 0)
     {
-      _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
+      _dbus_warn ("had leftover bytes from expected-to-be-valid single message");
       goto failed;
     }
 
@@ -303,7 +333,7 @@ check_invalid_message (DBusMessageLoader *loader,
 
   if (!_dbus_message_loader_get_is_corrupted (loader))
     {
-      _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
+      _dbus_warn ("loader not corrupted on message that was expected to be invalid");
       goto failed;
     }
 
@@ -312,7 +342,7 @@ check_invalid_message (DBusMessageLoader *loader,
   if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON &&
       loader->corruption_reason != expected_validity)
     {
-      _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead\n",
+      _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead",
                   expected_validity, loader->corruption_reason);
       goto failed;
     }
@@ -334,7 +364,7 @@ check_incomplete_message (DBusMessageLoader *loader)
 
   if (_dbus_message_loader_get_is_corrupted (loader))
     {
-      _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d\n",
+      _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d",
                   loader->corruption_reason);
       goto failed;
     }
@@ -342,7 +372,7 @@ check_incomplete_message (DBusMessageLoader *loader)
   message = _dbus_message_loader_pop_message (loader);
   if (message != NULL)
     {
-      _dbus_warn ("loaded message that was expected to be incomplete\n");
+      _dbus_warn ("loaded message that was expected to be incomplete");
       goto failed;
     }
 
@@ -400,7 +430,7 @@ dbus_internal_do_not_use_load_message_file (const DBusString    *filename,
   _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
   if (!_dbus_file_get_contents (data, filename, &error))
     {
-      _dbus_warn ("Could not load message file %s: %s\n",
+      _dbus_warn ("Could not load message file %s: %s",
                   _dbus_string_get_const_data (filename),
                   error.message);
       dbus_error_free (&error);
@@ -432,7 +462,7 @@ dbus_internal_do_not_use_try_message_file (const DBusString    *filename,
   retval = FALSE;
 
   if (!_dbus_string_init (&data))
-    _dbus_assert_not_reached ("could not allocate string\n");
+    _dbus_assert_not_reached ("could not allocate string");
 
   if (!dbus_internal_do_not_use_load_message_file (filename, &data))
     goto failed;
@@ -447,7 +477,7 @@ dbus_internal_do_not_use_try_message_file (const DBusString    *filename,
         _dbus_verbose_bytes_of_string (&data, 0,
                                        _dbus_string_get_length (&data));
 
-      _dbus_warn ("Failed message loader test on %s\n",
+      _dbus_warn ("Failed message loader test on %s",
                   _dbus_string_get_const_data (filename));
     }
 
@@ -479,20 +509,22 @@ dbus_internal_do_not_use_try_message_data (const DBusString    *data,
   /* Write the data one byte at a time */
 
   loader = _dbus_message_loader_new ();
+  if (loader == NULL)
+    goto failed;
 
   /* check some trivial loader functions */
   _dbus_message_loader_ref (loader);
   _dbus_message_loader_unref (loader);
-  _dbus_message_loader_get_max_message_size (loader);
 
   len = _dbus_string_get_length (data);
   for (i = 0; i < len; i++)
     {
       DBusString *buffer;
 
-      _dbus_message_loader_get_buffer (loader, &buffer);
-      _dbus_string_append_byte (buffer,
-                                _dbus_string_get_byte (data, i));
+      _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
+      if (!_dbus_string_append_byte (buffer,
+                                     _dbus_string_get_byte (data, i)))
+        goto failed;
       _dbus_message_loader_return_buffer (loader, buffer);
     }
 
@@ -505,13 +537,16 @@ dbus_internal_do_not_use_try_message_data (const DBusString    *data,
   /* Write the data all at once */
 
   loader = _dbus_message_loader_new ();
+  if (loader == NULL)
+    goto failed;
 
   {
     DBusString *buffer;
 
-    _dbus_message_loader_get_buffer (loader, &buffer);
-    _dbus_string_copy (data, 0, buffer,
-                       _dbus_string_get_length (buffer));
+    _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
+    if (!_dbus_string_copy (data, 0, buffer,
+                            _dbus_string_get_length (buffer)))
+        goto failed;
     _dbus_message_loader_return_buffer (loader, buffer);
   }
 
@@ -524,18 +559,26 @@ dbus_internal_do_not_use_try_message_data (const DBusString    *data,
   /* Write the data 2 bytes at a time */
 
   loader = _dbus_message_loader_new ();
+  if (loader == NULL)
+    goto failed;
 
   len = _dbus_string_get_length (data);
   for (i = 0; i < len; i += 2)
     {
       DBusString *buffer;
 
-      _dbus_message_loader_get_buffer (loader, &buffer);
-      _dbus_string_append_byte (buffer,
-                                _dbus_string_get_byte (data, i));
+      _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
+      if (!_dbus_string_append_byte (buffer,
+                                     _dbus_string_get_byte (data, i)))
+        goto failed;
+
       if ((i+1) < len)
-        _dbus_string_append_byte (buffer,
-                                  _dbus_string_get_byte (data, i+1));
+        {
+          if (!_dbus_string_append_byte (buffer,
+                                         _dbus_string_get_byte (data, i+1)))
+            goto failed;
+        }
+
       _dbus_message_loader_return_buffer (loader, buffer);
     }
 
@@ -572,7 +615,7 @@ process_test_subdir (const DBusString          *test_base_dir,
   dir = NULL;
 
   if (!_dbus_string_init (&test_directory))
-    _dbus_assert_not_reached ("didn't allocate test_directory\n");
+    _dbus_assert_not_reached ("didn't allocate test_directory");
 
   _dbus_string_init_const (&filename, subdir);
 
@@ -585,12 +628,12 @@ process_test_subdir (const DBusString          *test_base_dir,
 
   _dbus_string_free (&filename);
   if (!_dbus_string_init (&filename))
-    _dbus_assert_not_reached ("didn't allocate filename string\n");
+    _dbus_assert_not_reached ("didn't allocate filename string");
 
   dir = _dbus_directory_open (&test_directory, &error);
   if (dir == NULL)
     {
-      _dbus_warn ("Could not open %s: %s\n",
+      _dbus_warn ("Could not open %s: %s",
                   _dbus_string_get_const_data (&test_directory),
                   error.message);
       dbus_error_free (&error);
@@ -644,7 +687,7 @@ process_test_subdir (const DBusString          *test_base_dir,
 
   if (dbus_error_is_set (&error))
     {
-      _dbus_warn ("Could not get next file in %s: %s\n",
+      _dbus_warn ("Could not get next file in %s: %s",
                   _dbus_string_get_const_data (&test_directory),
                   error.message);
       dbus_error_free (&error);
@@ -875,7 +918,7 @@ verify_test_message (DBusMessage *message)
                                    &our_string_array, &our_string_array_len,
                                   0))
     {
-      _dbus_warn ("error: %s - %s\n", error.name,
+      _dbus_warn ("error: %s - %s", error.name,
                   (error.message != NULL) ? error.message : "no message");
       _dbus_assert_not_reached ("Could not get arguments");
     }
@@ -1006,7 +1049,7 @@ verify_test_message_args_ignored (DBusMessage *message)
   if (!dbus_message_iter_get_args (&iter, &error,
                                    DBUS_TYPE_INVALID))
     {
-      _dbus_warn ("error: %s - %s\n", error.name,
+      _dbus_warn ("error: %s - %s", error.name,
                      (error.message != NULL) ? error.message : "no message");
     }
   else
@@ -1021,7 +1064,7 @@ verify_test_message_args_ignored (DBusMessage *message)
                                    DBUS_TYPE_UINT32, &our_uint,
                                    DBUS_TYPE_INVALID))
     {
-      _dbus_warn ("error: %s - %s\n", error.name,
+      _dbus_warn ("error: %s - %s", error.name,
                      (error.message != NULL) ? error.message : "no message");
     }
   else
@@ -1045,8 +1088,10 @@ verify_test_message_memleak (DBusMessage *message)
   int our_string_array_len1;
   char **our_string_array2;
   int our_string_array_len2;
+#ifdef HAVE_UNIX_FD_PASSING
   int our_unix_fd1;
   int our_unix_fd2;
+#endif
   DBusInitialFDs *initial_fds;
 
   initial_fds = _dbus_check_fdleaks_enter ();
@@ -1075,7 +1120,7 @@ verify_test_message_memleak (DBusMessage *message)
     }
   else
     {
-      _dbus_warn ("error: parse with wrong signature: 'uashuu'.\n");
+      _dbus_warn ("error: parse with wrong signature: 'uashuu'.");
     }
 
   /* parse with wrong signature: "uashuashu" */
@@ -1109,7 +1154,7 @@ verify_test_message_memleak (DBusMessage *message)
     }
   else
     {
-      _dbus_warn ("error: parse with wrong signature: 'uashuashu'.\n");
+      _dbus_warn ("error: parse with wrong signature: 'uashuashu'.");
     }
 
   /* parse with correct signature: "uashuash" */
@@ -1130,7 +1175,7 @@ verify_test_message_memleak (DBusMessage *message)
 #endif
                                    DBUS_TYPE_INVALID))
     {
-      _dbus_warn ("error: %s - %s\n", error.name,
+      _dbus_warn ("error: %s - %s", error.name,
                   (error.message != NULL) ? error.message : "no message");
       _dbus_assert_not_reached ("Could not get arguments");
     }
@@ -1206,6 +1251,16 @@ _dbus_message_test (const char *test_data_dir)
   char **decomposed;
   DBusInitialFDs *initial_fds;
   dbus_bool_t ok;
+  char basic_types[] = DBUS_TYPE_BYTE_AS_STRING \
+                       DBUS_TYPE_BOOLEAN_AS_STRING \
+                       DBUS_TYPE_INT16_AS_STRING \
+                       DBUS_TYPE_INT32_AS_STRING \
+                       DBUS_TYPE_INT64_AS_STRING \
+                       DBUS_TYPE_UINT16_AS_STRING \
+                       DBUS_TYPE_UINT32_AS_STRING \
+                       DBUS_TYPE_UINT64_AS_STRING \
+                       DBUS_TYPE_DOUBLE_AS_STRING \
+                       DBUS_TYPE_STRING_AS_STRING;
 
   initial_fds = _dbus_check_fdleaks_enter ();
 
@@ -1486,7 +1541,7 @@ _dbus_message_test (const char *test_data_dir)
     {
       DBusString *buffer;
 
-      _dbus_message_loader_get_buffer (loader, &buffer);
+      _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
       _dbus_string_append_byte (buffer, data[i]);
       _dbus_message_loader_return_buffer (loader, buffer);
     }
@@ -1497,7 +1552,7 @@ _dbus_message_test (const char *test_data_dir)
     {
       DBusString *buffer;
 
-      _dbus_message_loader_get_buffer (loader, &buffer);
+      _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
       _dbus_string_append_byte (buffer, data[i]);
       _dbus_message_loader_return_buffer (loader, buffer);
     }
@@ -1596,6 +1651,56 @@ _dbus_message_test (const char *test_data_dir)
   _dbus_check_fdleaks_leave (initial_fds);
   initial_fds = _dbus_check_fdleaks_enter ();
 
+  /* Test enumeration of array elements */
+  for (i = strlen (basic_types) - 1; i > 0; i--)
+    {
+      DBusBasicValue val;
+      int some;
+      char* signature = _dbus_strdup ("?");
+
+      signature[0] = basic_types[i];
+      s = "SomeThingToSay";
+      memset (&val, '\0', sizeof (val));
+
+      message = dbus_message_new_method_call ("de.ende.test",
+        "/de/ende/test", "de.ende.Test", "ArtistName");
+      _dbus_assert (message != NULL);
+      dbus_message_iter_init_append (message, &iter);
+      dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+                                        signature, &array_iter);
+      for (some = 0; some < 3; some++)
+        {
+          if (basic_types[i] == DBUS_TYPE_STRING)
+            dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &s);
+          else
+            dbus_message_iter_append_basic (&array_iter, basic_types[i], &val);
+        }
+      dbus_message_iter_close_container (&iter, &array_iter);
+      dbus_message_iter_init (message, &iter);
+      _dbus_assert (dbus_message_iter_get_element_count (&iter) == some);
+      dbus_message_unref (message);
+      dbus_free (signature);
+    }
+  /* Array of structs */
+  message = dbus_message_new_method_call ("de.ende.test",
+      "/de/ende/test", "de.ende.Test", "ArtistName");
+  _dbus_assert (message != NULL);
+  dbus_message_iter_init_append (message, &iter);
+  dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+                                    DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+                                    DBUS_TYPE_STRING_AS_STRING
+                                    DBUS_STRUCT_END_CHAR_AS_STRING, &array_iter);
+  dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT,
+                                    NULL, &struct_iter);
+  s = "SpamAndEggs";
+  dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s);
+  dbus_message_iter_close_container (&array_iter, &struct_iter);
+  dbus_message_iter_close_container (&iter, &array_iter);
+  dbus_message_iter_init (message, &iter);
+  _dbus_assert (dbus_message_iter_get_element_count (&iter) == 1);
+  dbus_message_unref (message);
+  check_memleaks ();
+
   /* Check that we can abandon a container */
   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
                                          "/org/freedesktop/TestPath",
@@ -1687,7 +1792,7 @@ _dbus_message_test (const char *test_data_dir)
         if (!dbus_internal_do_not_use_try_message_data (&mdata.data,
                                                         mdata.expected_validity))
           {
-            _dbus_warn ("expected validity %d and did not get it\n",
+            _dbus_warn ("expected validity %d and did not get it",
                         mdata.expected_validity);
             _dbus_assert_not_reached ("message data failed");
           }