From 9c3d566e95c9080f6040c64531b0ccae22bd5d74 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 15 Jan 2005 07:15:38 +0000 Subject: 2005-01-15 Havoc Pennington * Land the new message args API and type system. This patch is huge, but the public API change is not really large. The set of D-BUS types has changed somewhat, and the arg "getters" are more geared toward language bindings; they don't make a copy, etc. There are also some known issues. See these emails for details on this huge patch: http://lists.freedesktop.org/archives/dbus/2004-December/001836.html http://lists.freedesktop.org/archives/dbus/2005-January/001922.html * dbus/dbus-marshal-*: all the new stuff * dbus/dbus-message.c: basically rewritten * dbus/dbus-memory.c (check_guards): with "guards" enabled, init freed blocks to be all non-nul bytes so using freed memory is less likely to work right * dbus/dbus-internals.c (_dbus_test_oom_handling): add DBUS_FAIL_MALLOC=N environment variable, so you can do DBUS_FAIL_MALLOC=0 to skip the out-of-memory checking, or DBUS_FAIL_MALLOC=10 to make it really, really, really slow and thorough. * qt/message.cpp: port to the new message args API (operator<<): use str.utf8() rather than str.unicode() (pretty sure this is right from the Qt docs?) * glib/dbus-gvalue.c: port to the new message args API * bus/dispatch.c, bus/driver.c: port to the new message args API * dbus/dbus-string.c (_dbus_string_init_const_len): initialize the "locked" flag to TRUE and align_offset to 0; I guess we never looked at these anyhow, but seems cleaner. * dbus/dbus-string.h (_DBUS_STRING_ALLOCATION_PADDING): move allocation padding macro to this header; use it to implement (_DBUS_STRING_STATIC): ability to declare a static string. * dbus/dbus-message.c (_dbus_message_has_type_interface_member): change to return TRUE if the interface is not set. * dbus/dbus-string.[hc]: move the D-BUS specific validation stuff to dbus-marshal-validate.[hc] * dbus/dbus-marshal-basic.c (_dbus_type_to_string): move here from dbus-internals.c * dbus/Makefile.am: cut over from dbus-marshal.[hc] to dbus-marshal-*.[hc] * dbus/dbus-object-tree.c (_dbus_decompose_path): move this function here from dbus-marshal.c --- dbus/dbus-marshal-validate.h | 128 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) (limited to 'dbus/dbus-marshal-validate.h') diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h index 86cbf7ea..8f4e7ef6 100644 --- a/dbus/dbus-marshal-validate.h +++ b/dbus/dbus-marshal-validate.h @@ -31,5 +31,133 @@ #error "config.h not included here" #endif +/** + * This is primarily used in unit testing, so we can verify that each + * invalid message is invalid for the expected reasons. Thus we really + * want a distinct enum value for every codepath leaving the validator + * functions. Enum values are specified manually for ease of debugging + * (so you can see the enum value given a printf) + */ +typedef enum +{ + DBUS_VALID = 0, + DBUS_INVALID_UNKNOWN_TYPECODE = 1, + DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE = 2, + DBUS_INVALID_SIGNATURE_TOO_LONG = 3, + DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION = 4, + DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION = 5, + DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED = 6, + DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED = 7, + DBUS_INVALID_STRUCT_HAS_NO_FIELDS = 8, + DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL = 9, + DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE = 10, + DBUS_INVALID_NOT_ENOUGH_DATA = 11, + DBUS_INVALID_TOO_MUCH_DATA = 12, + DBUS_INVALID_BAD_BYTE_ORDER = 13, + DBUS_INVALID_BAD_PROTOCOL_VERSION = 14, + DBUS_INVALID_BAD_MESSAGE_TYPE = 15, + DBUS_INVALID_BAD_SERIAL = 16, + DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH = 17, + DBUS_INVALID_INSANE_BODY_LENGTH = 18, + DBUS_INVALID_MESSAGE_TOO_LONG = 19, + DBUS_INVALID_HEADER_FIELD_CODE = 20, + DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE = 21, + DBUS_INVALID_USES_LOCAL_INTERFACE = 22, + DBUS_INVALID_USES_LOCAL_PATH = 23, + DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE = 24, + DBUS_INVALID_BAD_DESTINATION = 25, + DBUS_INVALID_BAD_INTERFACE = 26, + DBUS_INVALID_BAD_MEMBER = 27, + DBUS_INVALID_BAD_ERROR_NAME = 28, + DBUS_INVALID_BAD_SENDER = 29, + DBUS_INVALID_MISSING_PATH = 30, + DBUS_INVALID_MISSING_INTERFACE = 31, + DBUS_INVALID_MISSING_MEMBER = 32, + DBUS_INVALID_MISSING_ERROR_NAME = 33, + DBUS_INVALID_MISSING_REPLY_SERIAL = 34, + DBUS_INVALID_STRING_LENGTH_OUT_OF_BOUNDS = 35, + DBUS_INVALID_ARRAY_LENGTH_OUT_OF_BOUNDS = 36, + DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM = 37, + DBUS_INVALID_BAD_PATH = 38, + DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 39, + DBUS_INVALID_BAD_SIGNATURE = 40, + DBUS_INVALID_BAD_UTF8_IN_STRING = 41, + DBUS_INVALID_ARRAY_LENGTH_INCORRECT = 42, + DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS = 43, + DBUS_INVALID_VARIANT_SIGNATURE_BAD = 44, + DBUS_INVALID_VARIANT_SIGNATURE_EMPTY = 45, + DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES = 46, + DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL = 47, + DBUS_INVALID_STRING_MISSING_NUL = 48, + DBUS_INVALID_SIGNATURE_MISSING_NUL = 49, +} DBusValidity; + +DBusValidity _dbus_validate_signature_with_reason (const DBusString *type_str, + int type_pos, + int len); +DBusValidity _dbus_validate_body_with_reason (const DBusString *expected_signature, + int expected_signature_start, + int byte_order, + int *bytes_remaining, + const DBusString *value_str, + int value_pos, + int len); + +dbus_bool_t _dbus_validate_path (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_interface (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_member (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_error_name (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_service (const DBusString *str, + int start, + int len); +dbus_bool_t _dbus_validate_signature (const DBusString *str, + int start, + int len); + +#ifdef DBUS_DISABLE_CHECKS + +/* Be sure they don't exist, since we don't want to use them outside of checks + * and so we want the compile failure. + */ +#define DECLARE_DBUS_NAME_CHECK(what) +#define DEFINE_DBUS_NAME_CHECK(what) + +#else /* !DBUS_DISABLE_CHECKS */ + +/* A name check is used in _dbus_return_if_fail(), it's not suitable + * for validating untrusted data. use _dbus_validate_##what for that. + */ +#define DECLARE_DBUS_NAME_CHECK(what) \ +dbus_bool_t _dbus_check_is_valid_##what (const char *name) + +#define DEFINE_DBUS_NAME_CHECK(what) \ +dbus_bool_t \ +_dbus_check_is_valid_##what (const char *name) \ +{ \ + DBusString str; \ + \ + if (name == NULL) \ + return FALSE; \ + \ + _dbus_string_init_const (&str, name); \ + return _dbus_validate_##what (&str, 0, \ + _dbus_string_get_length (&str)); \ +} +#endif /* !DBUS_DISABLE_CHECKS */ + +DECLARE_DBUS_NAME_CHECK(path); +DECLARE_DBUS_NAME_CHECK(interface); +DECLARE_DBUS_NAME_CHECK(member); +DECLARE_DBUS_NAME_CHECK(error_name); +DECLARE_DBUS_NAME_CHECK(service); +DECLARE_DBUS_NAME_CHECK(signature); #endif /* DBUS_MARSHAL_VALIDATE_H */ -- cgit