00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-internals.h"
00026 #include "dbus-marshal-validate.h"
00027 #include "dbus-marshal-recursive.h"
00028 #include "dbus-marshal-basic.h"
00029 #include "dbus-signature.h"
00030 #include "dbus-string.h"
00031
00050 DBusValidity
00051 _dbus_validate_signature_with_reason (const DBusString *type_str,
00052 int type_pos,
00053 int len)
00054 {
00055 const unsigned char *p;
00056 const unsigned char *end;
00057 int last;
00058 int struct_depth;
00059 int array_depth;
00060 int dict_entry_depth;
00061 DBusValidity result;
00062
00063 int element_count;
00064 DBusList *element_count_stack;
00065
00066 result = DBUS_VALID;
00067 element_count_stack = NULL;
00068
00069 if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0)))
00070 {
00071 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00072 goto out;
00073 }
00074
00075 _dbus_assert (type_str != NULL);
00076 _dbus_assert (type_pos < _DBUS_INT32_MAX - len);
00077 _dbus_assert (len >= 0);
00078 _dbus_assert (type_pos >= 0);
00079
00080 if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH)
00081 {
00082 result = DBUS_INVALID_SIGNATURE_TOO_LONG;
00083 goto out;
00084 }
00085
00086 p = _dbus_string_get_const_data_len (type_str, type_pos, 0);
00087
00088 end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0);
00089 struct_depth = 0;
00090 array_depth = 0;
00091 dict_entry_depth = 0;
00092 last = DBUS_TYPE_INVALID;
00093
00094 while (p != end)
00095 {
00096 switch (*p)
00097 {
00098 case DBUS_TYPE_BYTE:
00099 case DBUS_TYPE_BOOLEAN:
00100 case DBUS_TYPE_INT16:
00101 case DBUS_TYPE_UINT16:
00102 case DBUS_TYPE_INT32:
00103 case DBUS_TYPE_UINT32:
00104 case DBUS_TYPE_UNIX_FD:
00105 case DBUS_TYPE_INT64:
00106 case DBUS_TYPE_UINT64:
00107 case DBUS_TYPE_DOUBLE:
00108 case DBUS_TYPE_STRING:
00109 case DBUS_TYPE_OBJECT_PATH:
00110 case DBUS_TYPE_SIGNATURE:
00111 case DBUS_TYPE_VARIANT:
00112 break;
00113
00114 case DBUS_TYPE_ARRAY:
00115 array_depth += 1;
00116 if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
00117 {
00118 result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
00119 goto out;
00120 }
00121 break;
00122
00123 case DBUS_STRUCT_BEGIN_CHAR:
00124 struct_depth += 1;
00125
00126 if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
00127 {
00128 result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
00129 goto out;
00130 }
00131
00132 if (!_dbus_list_append (&element_count_stack,
00133 _DBUS_INT_TO_POINTER (0)))
00134 {
00135 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00136 goto out;
00137 }
00138
00139 break;
00140
00141 case DBUS_STRUCT_END_CHAR:
00142 if (struct_depth == 0)
00143 {
00144 result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
00145 goto out;
00146 }
00147
00148 if (last == DBUS_STRUCT_BEGIN_CHAR)
00149 {
00150 result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
00151 goto out;
00152 }
00153
00154 _dbus_list_pop_last (&element_count_stack);
00155
00156 struct_depth -= 1;
00157 break;
00158
00159 case DBUS_DICT_ENTRY_BEGIN_CHAR:
00160 if (last != DBUS_TYPE_ARRAY)
00161 {
00162 result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY;
00163 goto out;
00164 }
00165
00166 dict_entry_depth += 1;
00167
00168 if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
00169 {
00170 result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
00171 goto out;
00172 }
00173
00174 if (!_dbus_list_append (&element_count_stack,
00175 _DBUS_INT_TO_POINTER (0)))
00176 {
00177 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00178 goto out;
00179 }
00180
00181 break;
00182
00183 case DBUS_DICT_ENTRY_END_CHAR:
00184 if (dict_entry_depth == 0)
00185 {
00186 result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
00187 goto out;
00188 }
00189
00190 dict_entry_depth -= 1;
00191
00192 element_count =
00193 _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
00194
00195 if (element_count != 2)
00196 {
00197 if (element_count == 0)
00198 result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
00199 else if (element_count == 1)
00200 result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD;
00201 else
00202 result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS;
00203
00204 goto out;
00205 }
00206 break;
00207
00208 case DBUS_TYPE_STRUCT:
00209 case DBUS_TYPE_DICT_ENTRY:
00210 default:
00211 result = DBUS_INVALID_UNKNOWN_TYPECODE;
00212 goto out;
00213 }
00214
00215 if (*p != DBUS_TYPE_ARRAY &&
00216 *p != DBUS_DICT_ENTRY_BEGIN_CHAR &&
00217 *p != DBUS_STRUCT_BEGIN_CHAR)
00218 {
00219 element_count =
00220 _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
00221
00222 ++element_count;
00223
00224 if (!_dbus_list_append (&element_count_stack,
00225 _DBUS_INT_TO_POINTER (element_count)))
00226 {
00227 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00228 goto out;
00229 }
00230 }
00231
00232 if (array_depth > 0)
00233 {
00234 if (*p == DBUS_TYPE_ARRAY && p != end)
00235 {
00236 const char *p1;
00237 p1 = p + 1;
00238 if (*p1 == DBUS_STRUCT_END_CHAR ||
00239 *p1 == DBUS_DICT_ENTRY_END_CHAR)
00240 {
00241 result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
00242 goto out;
00243 }
00244 }
00245 else
00246 {
00247 array_depth = 0;
00248 }
00249 }
00250
00251 if (last == DBUS_DICT_ENTRY_BEGIN_CHAR)
00252 {
00253 if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p)))
00254 {
00255 result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
00256 goto out;
00257 }
00258 }
00259
00260 last = *p;
00261 ++p;
00262 }
00263
00264
00265 if (array_depth > 0)
00266 {
00267 result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
00268 goto out;
00269 }
00270
00271 if (struct_depth > 0)
00272 {
00273 result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
00274 goto out;
00275 }
00276
00277 if (dict_entry_depth > 0)
00278 {
00279 result = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
00280 goto out;
00281 }
00282
00283 _dbus_assert (last != DBUS_TYPE_ARRAY);
00284 _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR);
00285 _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR);
00286
00287 result = DBUS_VALID;
00288
00289 out:
00290 _dbus_list_clear (&element_count_stack);
00291 return result;
00292 }
00293
00294 static DBusValidity
00295 validate_body_helper (DBusTypeReader *reader,
00296 int byte_order,
00297 dbus_bool_t walk_reader_to_end,
00298 const unsigned char *p,
00299 const unsigned char *end,
00300 const unsigned char **new_p)
00301 {
00302 int current_type;
00303
00304 while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
00305 {
00306 const unsigned char *a;
00307 int alignment;
00308
00309 #if 0
00310 _dbus_verbose (" validating value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00311 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00312 (int) (end - p));
00313 #endif
00314
00315
00316 if (p == end)
00317 return DBUS_INVALID_NOT_ENOUGH_DATA;
00318
00319 switch (current_type)
00320 {
00321 case DBUS_TYPE_BYTE:
00322 ++p;
00323 break;
00324
00325 case DBUS_TYPE_BOOLEAN:
00326 case DBUS_TYPE_INT16:
00327 case DBUS_TYPE_UINT16:
00328 case DBUS_TYPE_INT32:
00329 case DBUS_TYPE_UINT32:
00330 case DBUS_TYPE_UNIX_FD:
00331 case DBUS_TYPE_INT64:
00332 case DBUS_TYPE_UINT64:
00333 case DBUS_TYPE_DOUBLE:
00334 alignment = _dbus_type_get_alignment (current_type);
00335 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00336 if (a >= end)
00337 return DBUS_INVALID_NOT_ENOUGH_DATA;
00338 while (p != a)
00339 {
00340 if (*p != '\0')
00341 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00342 ++p;
00343 }
00344
00345 if (current_type == DBUS_TYPE_BOOLEAN)
00346 {
00347 dbus_uint32_t v = _dbus_unpack_uint32 (byte_order,
00348 p);
00349 if (!(v == 0 || v == 1))
00350 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00351 }
00352
00353 p += alignment;
00354 break;
00355
00356 case DBUS_TYPE_ARRAY:
00357 case DBUS_TYPE_STRING:
00358 case DBUS_TYPE_OBJECT_PATH:
00359 {
00360 dbus_uint32_t claimed_len;
00361
00362 a = _DBUS_ALIGN_ADDRESS (p, 4);
00363 if (a + 4 > end)
00364 return DBUS_INVALID_NOT_ENOUGH_DATA;
00365 while (p != a)
00366 {
00367 if (*p != '\0')
00368 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00369 ++p;
00370 }
00371
00372 claimed_len = _dbus_unpack_uint32 (byte_order, p);
00373 p += 4;
00374
00375
00376 _dbus_assert (p <= end);
00377
00378 if (current_type == DBUS_TYPE_ARRAY)
00379 {
00380 int array_elem_type = _dbus_type_reader_get_element_type (reader);
00381
00382 if (!_dbus_type_is_valid (array_elem_type))
00383 {
00384 return DBUS_INVALID_UNKNOWN_TYPECODE;
00385 }
00386
00387 alignment = _dbus_type_get_alignment (array_elem_type);
00388
00389 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00390
00391
00392 if (a > end)
00393 return DBUS_INVALID_NOT_ENOUGH_DATA;
00394
00395 while (p != a)
00396 {
00397 if (*p != '\0')
00398 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00399 ++p;
00400 }
00401 }
00402
00403 if (claimed_len > (unsigned long) (end - p))
00404 return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
00405
00406 if (current_type == DBUS_TYPE_OBJECT_PATH)
00407 {
00408 DBusString str;
00409 _dbus_string_init_const_len (&str, p, claimed_len);
00410 if (!_dbus_validate_path (&str, 0,
00411 _dbus_string_get_length (&str)))
00412 return DBUS_INVALID_BAD_PATH;
00413
00414 p += claimed_len;
00415 }
00416 else if (current_type == DBUS_TYPE_STRING)
00417 {
00418 DBusString str;
00419 _dbus_string_init_const_len (&str, p, claimed_len);
00420 if (!_dbus_string_validate_utf8 (&str, 0,
00421 _dbus_string_get_length (&str)))
00422 return DBUS_INVALID_BAD_UTF8_IN_STRING;
00423
00424 p += claimed_len;
00425 }
00426 else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
00427 {
00428 DBusTypeReader sub;
00429 DBusValidity validity;
00430 const unsigned char *array_end;
00431 int array_elem_type;
00432
00433 if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
00434 return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
00435
00436
00437
00438
00439
00440 _dbus_type_reader_recurse (reader, &sub);
00441
00442 array_end = p + claimed_len;
00443
00444 array_elem_type = _dbus_type_reader_get_element_type (reader);
00445
00446
00447
00448
00449 if (dbus_type_is_fixed (array_elem_type))
00450 {
00451
00452
00453
00454 if (array_elem_type == DBUS_TYPE_BOOLEAN)
00455 {
00456 dbus_uint32_t v;
00457 alignment = _dbus_type_get_alignment (array_elem_type);
00458
00459 while (p < array_end)
00460 {
00461 v = _dbus_unpack_uint32 (byte_order, p);
00462
00463 if (!(v == 0 || v == 1))
00464 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00465
00466 p += alignment;
00467 }
00468 }
00469
00470 else
00471 {
00472 p = array_end;
00473 }
00474 }
00475
00476 else
00477 {
00478 while (p < array_end)
00479 {
00480 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00481 if (validity != DBUS_VALID)
00482 return validity;
00483 }
00484 }
00485
00486 if (p != array_end)
00487 return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
00488 }
00489
00490
00491 if (current_type != DBUS_TYPE_ARRAY)
00492 {
00493 if (p == end)
00494 return DBUS_INVALID_NOT_ENOUGH_DATA;
00495
00496 if (*p != '\0')
00497 return DBUS_INVALID_STRING_MISSING_NUL;
00498 ++p;
00499 }
00500 }
00501 break;
00502
00503 case DBUS_TYPE_SIGNATURE:
00504 {
00505 dbus_uint32_t claimed_len;
00506 DBusString str;
00507 DBusValidity validity;
00508
00509 claimed_len = *p;
00510 ++p;
00511
00512
00513 if (claimed_len + 1 > (unsigned long) (end - p))
00514 return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00515
00516 _dbus_string_init_const_len (&str, p, claimed_len);
00517 validity =
00518 _dbus_validate_signature_with_reason (&str, 0,
00519 _dbus_string_get_length (&str));
00520
00521 if (validity != DBUS_VALID)
00522 return validity;
00523
00524 p += claimed_len;
00525
00526 _dbus_assert (p < end);
00527 if (*p != DBUS_TYPE_INVALID)
00528 return DBUS_INVALID_SIGNATURE_MISSING_NUL;
00529
00530 ++p;
00531
00532 _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
00533 }
00534 break;
00535
00536 case DBUS_TYPE_VARIANT:
00537 {
00538
00539
00540
00541
00542
00543
00544
00545 dbus_uint32_t claimed_len;
00546 DBusString sig;
00547 DBusTypeReader sub;
00548 DBusValidity validity;
00549 int contained_alignment;
00550 int contained_type;
00551 DBusValidity reason;
00552
00553 claimed_len = *p;
00554 ++p;
00555
00556
00557 if (claimed_len + 1 > (unsigned long) (end - p))
00558 return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00559
00560 _dbus_string_init_const_len (&sig, p, claimed_len);
00561 reason = _dbus_validate_signature_with_reason (&sig, 0,
00562 _dbus_string_get_length (&sig));
00563 if (!(reason == DBUS_VALID))
00564 {
00565 if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
00566 return reason;
00567 else
00568 return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
00569 }
00570
00571 p += claimed_len;
00572
00573 if (*p != DBUS_TYPE_INVALID)
00574 return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
00575 ++p;
00576
00577 contained_type = _dbus_first_type_in_signature (&sig, 0);
00578 if (contained_type == DBUS_TYPE_INVALID)
00579 return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
00580
00581 contained_alignment = _dbus_type_get_alignment (contained_type);
00582
00583 a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00584 if (a > end)
00585 return DBUS_INVALID_NOT_ENOUGH_DATA;
00586 while (p != a)
00587 {
00588 if (*p != '\0')
00589 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00590 ++p;
00591 }
00592
00593 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00594
00595 _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
00596
00597 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00598 if (validity != DBUS_VALID)
00599 return validity;
00600
00601 if (_dbus_type_reader_next (&sub))
00602 return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
00603
00604 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
00605 }
00606 break;
00607
00608 case DBUS_TYPE_DICT_ENTRY:
00609 case DBUS_TYPE_STRUCT:
00610 {
00611 DBusTypeReader sub;
00612 DBusValidity validity;
00613
00614 a = _DBUS_ALIGN_ADDRESS (p, 8);
00615 if (a > end)
00616 return DBUS_INVALID_NOT_ENOUGH_DATA;
00617 while (p != a)
00618 {
00619 if (*p != '\0')
00620 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00621 ++p;
00622 }
00623
00624 _dbus_type_reader_recurse (reader, &sub);
00625
00626 validity = validate_body_helper (&sub, byte_order, TRUE, p, end, &p);
00627 if (validity != DBUS_VALID)
00628 return validity;
00629 }
00630 break;
00631
00632 default:
00633 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00634 break;
00635 }
00636
00637 #if 0
00638 _dbus_verbose (" validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00639 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00640 (int) (end - p));
00641 #endif
00642
00643 if (p > end)
00644 {
00645 _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
00646 p, end, (int) (end - p));
00647 return DBUS_INVALID_NOT_ENOUGH_DATA;
00648 }
00649
00650 if (walk_reader_to_end)
00651 _dbus_type_reader_next (reader);
00652 else
00653 break;
00654 }
00655
00656 if (new_p)
00657 *new_p = p;
00658
00659 return DBUS_VALID;
00660 }
00661
00682 DBusValidity
00683 _dbus_validate_body_with_reason (const DBusString *expected_signature,
00684 int expected_signature_start,
00685 int byte_order,
00686 int *bytes_remaining,
00687 const DBusString *value_str,
00688 int value_pos,
00689 int len)
00690 {
00691 DBusTypeReader reader;
00692 const unsigned char *p;
00693 const unsigned char *end;
00694 DBusValidity validity;
00695
00696 _dbus_assert (len >= 0);
00697 _dbus_assert (value_pos >= 0);
00698 _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
00699
00700 _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
00701 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
00702 expected_signature_start,
00703 0));
00704
00705 _dbus_type_reader_init_types_only (&reader,
00706 expected_signature, expected_signature_start);
00707
00708 p = _dbus_string_get_const_data_len (value_str, value_pos, len);
00709 end = p + len;
00710
00711 validity = validate_body_helper (&reader, byte_order, TRUE, p, end, &p);
00712 if (validity != DBUS_VALID)
00713 return validity;
00714
00715 if (bytes_remaining)
00716 {
00717 *bytes_remaining = end - p;
00718 return DBUS_VALID;
00719 }
00720 else if (p < end)
00721 return DBUS_INVALID_TOO_MUCH_DATA;
00722 else
00723 {
00724 _dbus_assert (p == end);
00725 return DBUS_VALID;
00726 }
00727 }
00728
00733 #define VALID_INITIAL_NAME_CHARACTER(c) \
00734 ( ((c) >= 'A' && (c) <= 'Z') || \
00735 ((c) >= 'a' && (c) <= 'z') || \
00736 ((c) == '_') )
00737
00742 #define VALID_NAME_CHARACTER(c) \
00743 ( ((c) >= '0' && (c) <= '9') || \
00744 ((c) >= 'A' && (c) <= 'Z') || \
00745 ((c) >= 'a' && (c) <= 'z') || \
00746 ((c) == '_') )
00747
00764 dbus_bool_t
00765 _dbus_validate_path (const DBusString *str,
00766 int start,
00767 int len)
00768 {
00769 const unsigned char *s;
00770 const unsigned char *end;
00771 const unsigned char *last_slash;
00772
00773 _dbus_assert (start >= 0);
00774 _dbus_assert (len >= 0);
00775 _dbus_assert (start <= _dbus_string_get_length (str));
00776
00777 if (len > _dbus_string_get_length (str) - start)
00778 return FALSE;
00779
00780 if (len == 0)
00781 return FALSE;
00782
00783 s = _dbus_string_get_const_data (str) + start;
00784 end = s + len;
00785
00786 if (*s != '/')
00787 return FALSE;
00788 last_slash = s;
00789 ++s;
00790
00791 while (s != end)
00792 {
00793 if (*s == '/')
00794 {
00795 if ((s - last_slash) < 2)
00796 return FALSE;
00797
00798 last_slash = s;
00799 }
00800 else
00801 {
00802 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00803 return FALSE;
00804 }
00805
00806 ++s;
00807 }
00808
00809 if ((end - last_slash) < 2 &&
00810 len > 1)
00811 return FALSE;
00812
00813 return TRUE;
00814 }
00815
00816 const char *
00817 _dbus_validity_to_error_message (DBusValidity validity)
00818 {
00819 switch (validity)
00820 {
00821 case DBUS_VALIDITY_UNKNOWN_OOM_ERROR: return "Out of memory";
00822 case DBUS_INVALID_FOR_UNKNOWN_REASON: return "Unknown reason";
00823 case DBUS_VALID_BUT_INCOMPLETE: return "Valid but incomplete";
00824 case DBUS_VALIDITY_UNKNOWN: return "Validity unknown";
00825 case DBUS_VALID: return "Valid";
00826 case DBUS_INVALID_UNKNOWN_TYPECODE: return "Unknown typecode";
00827 case DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE: return "Missing array element type";
00828 case DBUS_INVALID_SIGNATURE_TOO_LONG: return "Signature is too long";
00829 case DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION: return "Exceeded maximum array recursion";
00830 case DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION: return "Exceeded maximum struct recursion";
00831 case DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED: return "Struct ended but not started";
00832 case DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED: return "Struct started but not ended";
00833 case DBUS_INVALID_STRUCT_HAS_NO_FIELDS: return "Struct has no fields";
00834 case DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL: return "Alignment padding not null";
00835 case DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE: return "Boolean is not zero or one";
00836 case DBUS_INVALID_NOT_ENOUGH_DATA: return "Not enough data";
00837 case DBUS_INVALID_TOO_MUCH_DATA: return "Too much data";
00838 case DBUS_INVALID_BAD_BYTE_ORDER: return "Bad byte order";
00839 case DBUS_INVALID_BAD_PROTOCOL_VERSION: return "Bad protocol version";
00840 case DBUS_INVALID_BAD_MESSAGE_TYPE: return "Bad message type";
00841 case DBUS_INVALID_BAD_SERIAL: return "Bad serial";
00842 case DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH: return "Insane fields array length";
00843 case DBUS_INVALID_INSANE_BODY_LENGTH: return "Insane body length";
00844 case DBUS_INVALID_MESSAGE_TOO_LONG: return "Message too long";
00845 case DBUS_INVALID_HEADER_FIELD_CODE: return "Header field code";
00846 case DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE: return "Header field has wrong type";
00847 case DBUS_INVALID_USES_LOCAL_INTERFACE: return "Uses local interface";
00848 case DBUS_INVALID_USES_LOCAL_PATH: return "Uses local path";
00849 case DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE: return "Header field appears twice";
00850 case DBUS_INVALID_BAD_DESTINATION: return "Bad destination";
00851 case DBUS_INVALID_BAD_INTERFACE: return "Bad interface";
00852 case DBUS_INVALID_BAD_MEMBER: return "Bad member";
00853 case DBUS_INVALID_BAD_ERROR_NAME: return "Bad error name";
00854 case DBUS_INVALID_BAD_SENDER: return "Bad sender";
00855 case DBUS_INVALID_MISSING_PATH: return "Missing path";
00856 case DBUS_INVALID_MISSING_INTERFACE: return "Missing interface";
00857 case DBUS_INVALID_MISSING_MEMBER: return "Missing member";
00858 case DBUS_INVALID_MISSING_ERROR_NAME: return "Missing error name";
00859 case DBUS_INVALID_MISSING_REPLY_SERIAL: return "Missing reply serial";
00860 case DBUS_INVALID_LENGTH_OUT_OF_BOUNDS: return "Length out of bounds";
00861 case DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM: return "Array length exceeds maximum";
00862 case DBUS_INVALID_BAD_PATH: return "Bad path";
00863 case DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Signature length out of bounds";
00864 case DBUS_INVALID_BAD_UTF8_IN_STRING: return "Bad utf8 in string";
00865 case DBUS_INVALID_ARRAY_LENGTH_INCORRECT: return "Array length incorrect";
00866 case DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Variant signature length out of bounds";
00867 case DBUS_INVALID_VARIANT_SIGNATURE_BAD: return "Variant signature bad";
00868 case DBUS_INVALID_VARIANT_SIGNATURE_EMPTY: return "Variant signature empty";
00869 case DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES: return "Variant signature specifies multiple values";
00870 case DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL: return "Variant signature missing nul";
00871 case DBUS_INVALID_STRING_MISSING_NUL: return "String missing nul";
00872 case DBUS_INVALID_SIGNATURE_MISSING_NUL: return "Signature missing nul";
00873 case DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION: return "Exceeded maximum dict entry recursion";
00874 case DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED: return "Dict entry ended but not started";
00875 case DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED: return "Dict entry started but not ended";
00876 case DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS: return "Dict entry has no fields";
00877 case DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD: return "Dict entry has only one field";
00878 case DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS: return "Dict entry has too many fields";
00879 case DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY: return "Dict entry not inside array";
00880 case DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE: return "Dict key must be basic type";
00881
00882 default:
00883 return "Invalid";
00884 }
00885 }
00886
00900 dbus_bool_t
00901 _dbus_validate_interface (const DBusString *str,
00902 int start,
00903 int len)
00904 {
00905 const unsigned char *s;
00906 const unsigned char *end;
00907 const unsigned char *iface;
00908 const unsigned char *last_dot;
00909
00910 _dbus_assert (start >= 0);
00911 _dbus_assert (len >= 0);
00912 _dbus_assert (start <= _dbus_string_get_length (str));
00913
00914 if (len > _dbus_string_get_length (str) - start)
00915 return FALSE;
00916
00917 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00918 return FALSE;
00919
00920 if (len == 0)
00921 return FALSE;
00922
00923 last_dot = NULL;
00924 iface = _dbus_string_get_const_data (str) + start;
00925 end = iface + len;
00926 s = iface;
00927
00928
00929
00930
00931 if (_DBUS_UNLIKELY (*s == '.'))
00932 return FALSE;
00933 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00934 return FALSE;
00935 else
00936 ++s;
00937
00938 while (s != end)
00939 {
00940 if (*s == '.')
00941 {
00942 if (_DBUS_UNLIKELY ((s + 1) == end))
00943 return FALSE;
00944 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
00945 return FALSE;
00946 last_dot = s;
00947 ++s;
00948 }
00949 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00950 {
00951 return FALSE;
00952 }
00953
00954 ++s;
00955 }
00956
00957 if (_DBUS_UNLIKELY (last_dot == NULL))
00958 return FALSE;
00959
00960 return TRUE;
00961 }
00962
00976 dbus_bool_t
00977 _dbus_validate_member (const DBusString *str,
00978 int start,
00979 int len)
00980 {
00981 const unsigned char *s;
00982 const unsigned char *end;
00983 const unsigned char *member;
00984
00985 _dbus_assert (start >= 0);
00986 _dbus_assert (len >= 0);
00987 _dbus_assert (start <= _dbus_string_get_length (str));
00988
00989 if (len > _dbus_string_get_length (str) - start)
00990 return FALSE;
00991
00992 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00993 return FALSE;
00994
00995 if (len == 0)
00996 return FALSE;
00997
00998 member = _dbus_string_get_const_data (str) + start;
00999 end = member + len;
01000 s = member;
01001
01002
01003
01004
01005
01006 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
01007 return FALSE;
01008 else
01009 ++s;
01010
01011 while (s != end)
01012 {
01013 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
01014 {
01015 return FALSE;
01016 }
01017
01018 ++s;
01019 }
01020
01021 return TRUE;
01022 }
01023
01037 dbus_bool_t
01038 _dbus_validate_error_name (const DBusString *str,
01039 int start,
01040 int len)
01041 {
01042
01043 return _dbus_validate_interface (str, start, len);
01044 }
01045
01050 #define VALID_INITIAL_BUS_NAME_CHARACTER(c) \
01051 ( ((c) >= 'A' && (c) <= 'Z') || \
01052 ((c) >= 'a' && (c) <= 'z') || \
01053 ((c) == '_') || ((c) == '-'))
01054
01059 #define VALID_BUS_NAME_CHARACTER(c) \
01060 ( ((c) >= '0' && (c) <= '9') || \
01061 ((c) >= 'A' && (c) <= 'Z') || \
01062 ((c) >= 'a' && (c) <= 'z') || \
01063 ((c) == '_') || ((c) == '-'))
01064
01078 dbus_bool_t
01079 _dbus_validate_bus_name (const DBusString *str,
01080 int start,
01081 int len)
01082 {
01083 const unsigned char *s;
01084 const unsigned char *end;
01085 const unsigned char *iface;
01086 const unsigned char *last_dot;
01087
01088 _dbus_assert (start >= 0);
01089 _dbus_assert (len >= 0);
01090 _dbus_assert (start <= _dbus_string_get_length (str));
01091
01092 if (len > _dbus_string_get_length (str) - start)
01093 return FALSE;
01094
01095 if (len > DBUS_MAXIMUM_NAME_LENGTH)
01096 return FALSE;
01097
01098 if (len == 0)
01099 return FALSE;
01100
01101 last_dot = NULL;
01102 iface = _dbus_string_get_const_data (str) + start;
01103 end = iface + len;
01104 s = iface;
01105
01106
01107
01108
01109 if (*s == ':')
01110 {
01111
01112 ++s;
01113 while (s != end)
01114 {
01115 if (*s == '.')
01116 {
01117 if (_DBUS_UNLIKELY ((s + 1) == end))
01118 return FALSE;
01119 if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
01120 return FALSE;
01121 ++s;
01122 }
01123 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01124 {
01125 return FALSE;
01126 }
01127
01128 ++s;
01129 }
01130
01131 return TRUE;
01132 }
01133 else if (_DBUS_UNLIKELY (*s == '.'))
01134 return FALSE;
01135 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s)))
01136 return FALSE;
01137 else
01138 ++s;
01139
01140 while (s != end)
01141 {
01142 if (*s == '.')
01143 {
01144 if (_DBUS_UNLIKELY ((s + 1) == end))
01145 return FALSE;
01146 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
01147 return FALSE;
01148 last_dot = s;
01149 ++s;
01150 }
01151 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01152 {
01153 return FALSE;
01154 }
01155
01156 ++s;
01157 }
01158
01159 if (_DBUS_UNLIKELY (last_dot == NULL))
01160 return FALSE;
01161
01162 return TRUE;
01163 }
01164
01177 dbus_bool_t
01178 _dbus_validate_signature (const DBusString *str,
01179 int start,
01180 int len)
01181 {
01182 _dbus_assert (start >= 0);
01183 _dbus_assert (start <= _dbus_string_get_length (str));
01184 _dbus_assert (len >= 0);
01185
01186 if (len > _dbus_string_get_length (str) - start)
01187 return FALSE;
01188
01189 return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
01190 }
01191
01193 DEFINE_DBUS_NAME_CHECK(path)
01195 DEFINE_DBUS_NAME_CHECK(interface)
01197 DEFINE_DBUS_NAME_CHECK(member)
01199 DEFINE_DBUS_NAME_CHECK(error_name)
01201 DEFINE_DBUS_NAME_CHECK(bus_name)
01203 DEFINE_DBUS_NAME_CHECK(signature)
01204
01207