summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-marshal-validate-util.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-01-27 01:50:01 +0000
committerHavoc Pennington <hp@redhat.com>2005-01-27 01:50:01 +0000
commit382d5ad0b4adf0070948fc2da623bc52894a7788 (patch)
tree9f0c9f2a8d342cc267442a0f375c5fbc19356774 /dbus/dbus-marshal-validate-util.c
parentddc4a0f79a84780e4b8ba19655ce40b5ca5dea7c (diff)
2005-01-26 Havoc Pennington <hp@redhat.com>
* dbus/dbus-marshal-validate-util.c: break this out (and fix build, apparently - nobody noticed?)
Diffstat (limited to 'dbus/dbus-marshal-validate-util.c')
-rw-r--r--dbus/dbus-marshal-validate-util.c575
1 files changed, 575 insertions, 0 deletions
diff --git a/dbus/dbus-marshal-validate-util.c b/dbus/dbus-marshal-validate-util.c
new file mode 100644
index 00000000..6915c054
--- /dev/null
+++ b/dbus/dbus-marshal-validate-util.c
@@ -0,0 +1,575 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-marshal-validate-util.c Would be in dbus-marshal-validate.c, but only used by tests/bus
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+#ifdef DBUS_BUILD_TESTS
+#include "dbus-internals.h"
+#include "dbus-marshal-validate.h"
+#include "dbus-marshal-recursive.h"
+
+#include "dbus-test.h"
+#include <stdio.h>
+
+typedef struct
+{
+ const char *data;
+ DBusValidity expected;
+} ValidityTest;
+
+static void
+run_validity_tests (const ValidityTest *tests,
+ int n_tests,
+ DBusValidity (* func) (const DBusString*,int,int))
+{
+ int i;
+
+ for (i = 0; i < n_tests; i++)
+ {
+ DBusString str;
+ DBusValidity v;
+
+ _dbus_string_init_const (&str, tests[i].data);
+
+ v = (*func) (&str, 0, _dbus_string_get_length (&str));
+
+ if (v != tests[i].expected)
+ {
+ _dbus_warn ("Improper validation result %d for '%s'\n",
+ v, tests[i].data);
+ _dbus_assert_not_reached ("test failed");
+ }
+
+ ++i;
+ }
+}
+
+static const ValidityTest signature_tests[] = {
+ { "", DBUS_VALID },
+ { "i", DBUS_VALID },
+ { "ai", DBUS_VALID },
+ { "(i)", DBUS_VALID },
+ { "q", DBUS_INVALID_UNKNOWN_TYPECODE },
+ { "a", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
+ { "aaaaaa", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
+ { "ii(ii)a", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
+ { "ia", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
+ /* DBUS_INVALID_SIGNATURE_TOO_LONG, */ /* too hard to test this way */
+ { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION },
+ { "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((ii))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))",
+ DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION },
+ { ")", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED },
+ { "i)", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED },
+ { "a)", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED },
+ { "(", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
+ { "(i", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
+ { "(iiiii", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
+ { "(ai", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
+ { "()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
+ { "(())", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
+ { "a()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
+ { "i()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
+ { "()i", DBUS_INVALID_STRUCT_HAS_NO_FIELDS }
+};
+
+dbus_bool_t
+_dbus_marshal_validate_test (void)
+{
+ DBusString str;
+ int i;
+
+ const char *valid_paths[] = {
+ "/",
+ "/foo/bar",
+ "/foo",
+ "/foo/bar/baz"
+ };
+ const char *invalid_paths[] = {
+ "bar",
+ "bar/baz",
+ "/foo/bar/",
+ "/foo/"
+ "foo/",
+ "boo//blah",
+ "//",
+ "///",
+ "foo///blah/",
+ "Hello World",
+ "",
+ " ",
+ "foo bar"
+ };
+
+ const char *valid_interfaces[] = {
+ "org.freedesktop.Foo",
+ "Bar.Baz",
+ "Blah.Blah.Blah.Blah.Blah",
+ "a.b",
+ "a.b.c.d.e.f.g",
+ "a0.b1.c2.d3.e4.f5.g6",
+ "abc123.foo27"
+ };
+ const char *invalid_interfaces[] = {
+ ".",
+ "",
+ "..",
+ ".Foo.Bar",
+ "..Foo.Bar",
+ "Foo.Bar.",
+ "Foo.Bar..",
+ "Foo",
+ "9foo.bar.baz",
+ "foo.bar..baz",
+ "foo.bar...baz",
+ "foo.bar.b..blah",
+ ":",
+ ":0-1",
+ "10",
+ ":11.34324",
+ "0.0.0",
+ "0..0",
+ "foo.Bar.%",
+ "foo.Bar!!",
+ "!Foo.bar.bz",
+ "foo.$.blah",
+ "",
+ " ",
+ "foo bar"
+ };
+
+ const char *valid_unique_names[] = {
+ ":0",
+ ":a",
+ ":",
+ ":.a",
+ ":.1",
+ ":0.1",
+ ":000.2222",
+ ":.blah",
+ ":abce.freedesktop.blah"
+ };
+ const char *invalid_unique_names[] = {
+ ":-",
+ ":!",
+ ":0-10",
+ ":blah.",
+ ":blah.",
+ ":blah..org",
+ ":blah.org..",
+ ":..blah.org",
+ "",
+ " ",
+ "foo bar"
+ };
+
+ const char *valid_members[] = {
+ "Hello",
+ "Bar",
+ "foobar",
+ "_foobar",
+ "foo89"
+ };
+
+ const char *invalid_members[] = {
+ "9Hello",
+ "10",
+ "1",
+ "foo-bar",
+ "blah.org",
+ ".blah",
+ "blah.",
+ "Hello.",
+ "!foo",
+ "",
+ " ",
+ "foo bar"
+ };
+
+ const char *valid_signatures[] = {
+ "",
+ "sss",
+ "i",
+ "b"
+ };
+
+ const char *invalid_signatures[] = {
+ " ",
+ "not a valid signature",
+ "123",
+ ".",
+ "("
+ };
+
+ /* Signature with reason */
+
+ run_validity_tests (signature_tests, _DBUS_N_ELEMENTS (signature_tests),
+ _dbus_validate_signature_with_reason);
+
+ /* Path validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
+ {
+ _dbus_string_init_const (&str, valid_paths[i]);
+
+ if (!_dbus_validate_path (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
+ _dbus_assert_not_reached ("invalid path");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
+ {
+ _dbus_string_init_const (&str, invalid_paths[i]);
+
+ if (_dbus_validate_path (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
+ _dbus_assert_not_reached ("valid path");
+ }
+
+ ++i;
+ }
+
+ /* Interface validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
+ {
+ _dbus_string_init_const (&str, valid_interfaces[i]);
+
+ if (!_dbus_validate_interface (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]);
+ _dbus_assert_not_reached ("invalid interface");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
+ {
+ _dbus_string_init_const (&str, invalid_interfaces[i]);
+
+ if (_dbus_validate_interface (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]);
+ _dbus_assert_not_reached ("valid interface");
+ }
+
+ ++i;
+ }
+
+ /* Bus name validation (check that valid interfaces are valid bus names,
+ * and invalid interfaces are invalid services except if they start with ':')
+ */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
+ {
+ _dbus_string_init_const (&str, valid_interfaces[i]);
+
+ if (!_dbus_validate_bus_name (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_interfaces[i]);
+ _dbus_assert_not_reached ("invalid bus name");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
+ {
+ if (invalid_interfaces[i][0] != ':')
+ {
+ _dbus_string_init_const (&str, invalid_interfaces[i]);
+
+ if (_dbus_validate_bus_name (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_interfaces[i]);
+ _dbus_assert_not_reached ("valid bus name");
+ }
+ }
+
+ ++i;
+ }
+
+ /* unique name validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_unique_names))
+ {
+ _dbus_string_init_const (&str, valid_unique_names[i]);
+
+ if (!_dbus_validate_bus_name (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_unique_names[i]);
+ _dbus_assert_not_reached ("invalid unique name");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_unique_names))
+ {
+ _dbus_string_init_const (&str, invalid_unique_names[i]);
+
+ if (_dbus_validate_bus_name (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_unique_names[i]);
+ _dbus_assert_not_reached ("valid unique name");
+ }
+
+ ++i;
+ }
+
+
+ /* Error name validation (currently identical to interfaces)
+ */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
+ {
+ _dbus_string_init_const (&str, valid_interfaces[i]);
+
+ if (!_dbus_validate_error_name (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]);
+ _dbus_assert_not_reached ("invalid error name");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
+ {
+ if (invalid_interfaces[i][0] != ':')
+ {
+ _dbus_string_init_const (&str, invalid_interfaces[i]);
+
+ if (_dbus_validate_error_name (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]);
+ _dbus_assert_not_reached ("valid error name");
+ }
+ }
+
+ ++i;
+ }
+
+ /* Member validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_members))
+ {
+ _dbus_string_init_const (&str, valid_members[i]);
+
+ if (!_dbus_validate_member (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]);
+ _dbus_assert_not_reached ("invalid member");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_members))
+ {
+ _dbus_string_init_const (&str, invalid_members[i]);
+
+ if (_dbus_validate_member (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]);
+ _dbus_assert_not_reached ("valid member");
+ }
+
+ ++i;
+ }
+
+ /* Signature validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_signatures))
+ {
+ _dbus_string_init_const (&str, valid_signatures[i]);
+
+ if (!_dbus_validate_signature (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]);
+ _dbus_assert_not_reached ("invalid signature");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures))
+ {
+ _dbus_string_init_const (&str, invalid_signatures[i]);
+
+ if (_dbus_validate_signature (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]);
+ _dbus_assert_not_reached ("valid signature");
+ }
+
+ ++i;
+ }
+
+ /* Validate claimed length longer than real length */
+ _dbus_string_init_const (&str, "abc.efg");
+ if (_dbus_validate_bus_name (&str, 0, 8))
+ _dbus_assert_not_reached ("validated too-long string");
+ if (_dbus_validate_interface (&str, 0, 8))
+ _dbus_assert_not_reached ("validated too-long string");
+ if (_dbus_validate_error_name (&str, 0, 8))
+ _dbus_assert_not_reached ("validated too-long string");
+
+ _dbus_string_init_const (&str, "abc");
+ if (_dbus_validate_member (&str, 0, 4))
+ _dbus_assert_not_reached ("validated too-long string");
+
+ _dbus_string_init_const (&str, "sss");
+ if (_dbus_validate_signature (&str, 0, 4))
+ _dbus_assert_not_reached ("validated too-long signature");
+
+ /* Validate string exceeding max name length */
+ if (!_dbus_string_init (&str))
+ _dbus_assert_not_reached ("no memory");
+
+ while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
+ if (!_dbus_string_append (&str, "abc.def"))
+ _dbus_assert_not_reached ("no memory");
+
+ if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
+ _dbus_assert_not_reached ("validated overmax string");
+ if (_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str)))
+ _dbus_assert_not_reached ("validated overmax string");
+ if (_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str)))
+ _dbus_assert_not_reached ("validated overmax string");
+
+ /* overlong member */
+ _dbus_string_set_length (&str, 0);
+ while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
+ if (!_dbus_string_append (&str, "abc"))
+ _dbus_assert_not_reached ("no memory");
+
+ if (_dbus_validate_member (&str, 0, _dbus_string_get_length (&str)))
+ _dbus_assert_not_reached ("validated overmax string");
+
+ /* overlong unique name */
+ _dbus_string_set_length (&str, 0);
+ _dbus_string_append (&str, ":");
+ while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
+ if (!_dbus_string_append (&str, "abc"))
+ _dbus_assert_not_reached ("no memory");
+
+ if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
+ _dbus_assert_not_reached ("validated overmax string");
+
+ _dbus_string_free (&str);
+
+ /* Body validation; test basic validation of valid bodies for both endian */
+
+ {
+ int sequence;
+ DBusString signature;
+ DBusString body;
+
+ if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
+ _dbus_assert_not_reached ("oom");
+
+ sequence = 0;
+ while (dbus_internal_do_not_use_generate_bodies (sequence,
+ DBUS_LITTLE_ENDIAN,
+ &signature, &body))
+ {
+ DBusValidity validity;
+
+ validity = _dbus_validate_body_with_reason (&signature, 0,
+ DBUS_LITTLE_ENDIAN,
+ NULL, &body, 0,
+ _dbus_string_get_length (&body));
+ if (validity != DBUS_VALID)
+ {
+ _dbus_warn ("invalid code %d expected valid on sequence %d little endian\n",
+ validity, sequence);
+ _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature));
+ _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body));
+ _dbus_assert_not_reached ("test failed");
+ }
+
+ _dbus_string_set_length (&signature, 0);
+ _dbus_string_set_length (&body, 0);
+ ++sequence;
+ }
+
+ sequence = 0;
+ while (dbus_internal_do_not_use_generate_bodies (sequence,
+ DBUS_BIG_ENDIAN,
+ &signature, &body))
+ {
+ DBusValidity validity;
+
+ validity = _dbus_validate_body_with_reason (&signature, 0,
+ DBUS_BIG_ENDIAN,
+ NULL, &body, 0,
+ _dbus_string_get_length (&body));
+ if (validity != DBUS_VALID)
+ {
+ _dbus_warn ("invalid code %d expected valid on sequence %d big endian\n",
+ validity, sequence);
+ _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature));
+ _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body));
+ _dbus_assert_not_reached ("test failed");
+ }
+
+ _dbus_string_set_length (&signature, 0);
+ _dbus_string_set_length (&body, 0);
+ ++sequence;
+ }
+
+ _dbus_string_free (&signature);
+ _dbus_string_free (&body);
+ }
+
+ return TRUE;
+}
+
+#endif /* DBUS_BUILD_TESTS */