X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-marshal-validate.c;h=9187a3e9854220f1b1e014dc4abf6ef93e7c3d91;hb=3ccb027c907f9ee2890028e83b60296204bbf478;hp=35998cbb21a5be3d26d6e4ef9d7d03c3938c50bb;hpb=e61f13cf328d131ddbd8b49842fcd0f49847dbff;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index 35998cb..9187a3e 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -17,10 +17,11 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +#include #include "dbus-internals.h" #include "dbus-marshal-validate.h" #include "dbus-marshal-recursive.h" @@ -100,6 +101,7 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, case DBUS_TYPE_UINT16: case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: + case DBUS_TYPE_UNIX_FD: case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: @@ -246,14 +248,15 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, } } - if (last == DBUS_DICT_ENTRY_BEGIN_CHAR && - _dbus_type_is_valid (*p) && - !dbus_type_is_basic (*p)) + if (last == DBUS_DICT_ENTRY_BEGIN_CHAR) { - result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; - goto out; + if (!(dbus_type_is_valid (*p) && dbus_type_is_basic (*p))) + { + result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; + goto out; + } } - + last = *p; ++p; } @@ -288,16 +291,30 @@ out: return result; } +/* note: this function is also used to validate the header's values, + * since the header is a valid body with a particular signature. + */ static DBusValidity validate_body_helper (DBusTypeReader *reader, int byte_order, dbus_bool_t walk_reader_to_end, + int total_depth, const unsigned char *p, const unsigned char *end, const unsigned char **new_p) { int current_type; + /* The spec allows arrays and structs to each nest 32, for total + * nesting of 2*32. We want to impose the same limit on "dynamic" + * value nesting (not visible in the signature) which is introduced + * by DBUS_TYPE_VARIANT. + */ + if (total_depth > (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH * 2)) + { + return DBUS_INVALID_NESTED_TOO_DEEPLY; + } + while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID) { const unsigned char *a; @@ -318,12 +335,13 @@ validate_body_helper (DBusTypeReader *reader, case DBUS_TYPE_BYTE: ++p; break; - + case DBUS_TYPE_BOOLEAN: case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: + case DBUS_TYPE_UNIX_FD: case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: @@ -375,7 +393,7 @@ validate_body_helper (DBusTypeReader *reader, { int array_elem_type = _dbus_type_reader_get_element_type (reader); - if (!_dbus_type_is_valid (array_elem_type)) + if (!dbus_type_is_valid (array_elem_type)) { return DBUS_INVALID_UNKNOWN_TYPECODE; } @@ -473,7 +491,9 @@ validate_body_helper (DBusTypeReader *reader, { while (p < array_end) { - validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p); + validity = validate_body_helper (&sub, byte_order, FALSE, + total_depth + 1, + p, end, &p); if (validity != DBUS_VALID) return validity; } @@ -590,7 +610,9 @@ validate_body_helper (DBusTypeReader *reader, _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID); - validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p); + validity = validate_body_helper (&sub, byte_order, FALSE, + total_depth + 1, + p, end, &p); if (validity != DBUS_VALID) return validity; @@ -619,7 +641,9 @@ validate_body_helper (DBusTypeReader *reader, _dbus_type_reader_recurse (reader, &sub); - validity = validate_body_helper (&sub, byte_order, TRUE, p, end, &p); + validity = validate_body_helper (&sub, byte_order, TRUE, + total_depth + 1, + p, end, &p); if (validity != DBUS_VALID) return validity; } @@ -704,7 +728,7 @@ _dbus_validate_body_with_reason (const DBusString *expected_signature, p = _dbus_string_get_const_data_len (value_str, value_pos, len); end = p + len; - validity = validate_body_helper (&reader, byte_order, TRUE, p, end, &p); + validity = validate_body_helper (&reader, byte_order, TRUE, 0, p, end, &p); if (validity != DBUS_VALID) return validity; @@ -809,6 +833,77 @@ _dbus_validate_path (const DBusString *str, return TRUE; } +const char * +_dbus_validity_to_error_message (DBusValidity validity) +{ + switch (validity) + { + case DBUS_VALIDITY_UNKNOWN_OOM_ERROR: return "Out of memory"; + case DBUS_INVALID_FOR_UNKNOWN_REASON: return "Unknown reason"; + case DBUS_VALID_BUT_INCOMPLETE: return "Valid but incomplete"; + case DBUS_VALIDITY_UNKNOWN: return "Validity unknown"; + case DBUS_VALID: return "Valid"; + case DBUS_INVALID_UNKNOWN_TYPECODE: return "Unknown typecode"; + case DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE: return "Missing array element type"; + case DBUS_INVALID_SIGNATURE_TOO_LONG: return "Signature is too long"; + case DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION: return "Exceeded maximum array recursion"; + case DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION: return "Exceeded maximum struct recursion"; + case DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED: return "Struct ended but not started"; + case DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED: return "Struct started but not ended"; + case DBUS_INVALID_STRUCT_HAS_NO_FIELDS: return "Struct has no fields"; + case DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL: return "Alignment padding not null"; + case DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE: return "Boolean is not zero or one"; + case DBUS_INVALID_NOT_ENOUGH_DATA: return "Not enough data"; + case DBUS_INVALID_TOO_MUCH_DATA: return "Too much data"; + case DBUS_INVALID_BAD_BYTE_ORDER: return "Bad byte order"; + case DBUS_INVALID_BAD_PROTOCOL_VERSION: return "Bad protocol version"; + case DBUS_INVALID_BAD_MESSAGE_TYPE: return "Bad message type"; + case DBUS_INVALID_BAD_SERIAL: return "Bad serial"; + case DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH: return "Insane fields array length"; + case DBUS_INVALID_INSANE_BODY_LENGTH: return "Insane body length"; + case DBUS_INVALID_MESSAGE_TOO_LONG: return "Message too long"; + case DBUS_INVALID_HEADER_FIELD_CODE: return "Header field code"; + case DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE: return "Header field has wrong type"; + case DBUS_INVALID_USES_LOCAL_INTERFACE: return "Uses local interface"; + case DBUS_INVALID_USES_LOCAL_PATH: return "Uses local path"; + case DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE: return "Header field appears twice"; + case DBUS_INVALID_BAD_DESTINATION: return "Bad destination"; + case DBUS_INVALID_BAD_INTERFACE: return "Bad interface"; + case DBUS_INVALID_BAD_MEMBER: return "Bad member"; + case DBUS_INVALID_BAD_ERROR_NAME: return "Bad error name"; + case DBUS_INVALID_BAD_SENDER: return "Bad sender"; + case DBUS_INVALID_MISSING_PATH: return "Missing path"; + case DBUS_INVALID_MISSING_INTERFACE: return "Missing interface"; + case DBUS_INVALID_MISSING_MEMBER: return "Missing member"; + case DBUS_INVALID_MISSING_ERROR_NAME: return "Missing error name"; + case DBUS_INVALID_MISSING_REPLY_SERIAL: return "Missing reply serial"; + case DBUS_INVALID_LENGTH_OUT_OF_BOUNDS: return "Length out of bounds"; + case DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM: return "Array length exceeds maximum"; + case DBUS_INVALID_BAD_PATH: return "Bad path"; + case DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Signature length out of bounds"; + case DBUS_INVALID_BAD_UTF8_IN_STRING: return "Bad utf8 in string"; + case DBUS_INVALID_ARRAY_LENGTH_INCORRECT: return "Array length incorrect"; + case DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Variant signature length out of bounds"; + case DBUS_INVALID_VARIANT_SIGNATURE_BAD: return "Variant signature bad"; + case DBUS_INVALID_VARIANT_SIGNATURE_EMPTY: return "Variant signature empty"; + case DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES: return "Variant signature specifies multiple values"; + case DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL: return "Variant signature missing nul"; + case DBUS_INVALID_STRING_MISSING_NUL: return "String missing nul"; + case DBUS_INVALID_SIGNATURE_MISSING_NUL: return "Signature missing nul"; + case DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION: return "Exceeded maximum dict entry recursion"; + case DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED: return "Dict entry ended but not started"; + case DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED: return "Dict entry started but not ended"; + case DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS: return "Dict entry has no fields"; + case DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD: return "Dict entry has only one field"; + case DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS: return "Dict entry has too many fields"; + case DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY: return "Dict entry not inside array"; + case DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE: return "Dict key must be basic type"; + case DBUS_INVALID_NESTED_TOO_DEEPLY: return "Variants cannot be used to create a hugely recursive tree of values"; + default: + return "Invalid"; + } +} + /** * Checks that the given range of the string is a valid interface name * in the D-Bus protocol. This includes a length restriction and an @@ -987,23 +1082,11 @@ _dbus_validate_error_name (const DBusString *str, ((c) >= 'a' && (c) <= 'z') || \ ((c) == '_') || ((c) == '-')) -/** - * Checks that the given range of the string is a valid bus name in - * the D-Bus protocol. This includes a length restriction, etc., see - * the specification. - * - * @todo this is inconsistent with most of DBusString in that - * it allows a start,len range that extends past the string end. - * - * @param str the string - * @param start first byte index to check - * @param len number of bytes to check - * @returns #TRUE if the byte range exists and is a valid name - */ -dbus_bool_t -_dbus_validate_bus_name (const DBusString *str, - int start, - int len) +static dbus_bool_t +_dbus_validate_bus_name_full (const DBusString *str, + int start, + int len, + dbus_bool_t is_namespace) { const unsigned char *s; const unsigned char *end; @@ -1081,13 +1164,55 @@ _dbus_validate_bus_name (const DBusString *str, ++s; } - if (_DBUS_UNLIKELY (last_dot == NULL)) + if (!is_namespace && _DBUS_UNLIKELY (last_dot == NULL)) return FALSE; return TRUE; } /** + * Checks that the given range of the string is a valid bus name in + * the D-Bus protocol. This includes a length restriction, etc., see + * the specification. + * + * @todo this is inconsistent with most of DBusString in that + * it allows a start,len range that extends past the string end. + * + * @param str the string + * @param start first byte index to check + * @param len number of bytes to check + * @returns #TRUE if the byte range exists and is a valid name + */ +dbus_bool_t +_dbus_validate_bus_name (const DBusString *str, + int start, + int len) +{ + return _dbus_validate_bus_name_full (str, start, len, FALSE); +} + +/** + * Checks that the given range of the string is a prefix of a valid bus name in + * the D-Bus protocol. Unlike _dbus_validate_bus_name(), this accepts strings + * with only one period-separated component. + * + * @todo this is inconsistent with most of DBusString in that + * it allows a start,len range that extends past the string end. + * + * @param str the string + * @param start first byte index to check + * @param len number of bytes to check + * @returns #TRUE if the byte range exists and is a valid name + */ +dbus_bool_t +_dbus_validate_bus_namespace (const DBusString *str, + int start, + int len) +{ + return _dbus_validate_bus_name_full (str, start, len, TRUE); +} + +/** * Checks that the given range of the string is a valid message type * signature in the D-Bus protocol. * @@ -1126,6 +1251,8 @@ DEFINE_DBUS_NAME_CHECK(error_name) DEFINE_DBUS_NAME_CHECK(bus_name) /** define _dbus_check_is_valid_signature() */ DEFINE_DBUS_NAME_CHECK(signature) +/** define _dbus_check_is_valid_utf8() */ +DEFINE_DBUS_NAME_CHECK(utf8) /** @} */