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 "dbus-internals.h"
00025 #include "dbus-marshal-validate.h"
00026 #include "dbus-marshal-recursive.h"
00027 #include "dbus-marshal-basic.h"
00028 #include "dbus-signature.h"
00029 #include "dbus-string.h"
00030
00053 DBusValidity
00054 _dbus_validate_signature_with_reason (const DBusString *type_str,
00055 int type_pos,
00056 int len)
00057 {
00058 const unsigned char *p;
00059 const unsigned char *end;
00060 int last;
00061 int struct_depth;
00062 int array_depth;
00063 int dict_entry_depth;
00064 DBusValidity result;
00065
00066 int element_count;
00067 DBusList *element_count_stack;
00068
00069 result = DBUS_VALID;
00070 element_count_stack = NULL;
00071
00072 if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0)))
00073 {
00074 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00075 goto out;
00076 }
00077
00078 _dbus_assert (type_str != NULL);
00079 _dbus_assert (type_pos < _DBUS_INT32_MAX - len);
00080 _dbus_assert (len >= 0);
00081 _dbus_assert (type_pos >= 0);
00082
00083 if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH)
00084 {
00085 result = DBUS_INVALID_SIGNATURE_TOO_LONG;
00086 goto out;
00087 }
00088
00089 p = _dbus_string_get_const_data_len (type_str, type_pos, 0);
00090
00091 end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0);
00092 struct_depth = 0;
00093 array_depth = 0;
00094 dict_entry_depth = 0;
00095 last = DBUS_TYPE_INVALID;
00096
00097 while (p != end)
00098 {
00099 switch (*p)
00100 {
00101 case DBUS_TYPE_BYTE:
00102 case DBUS_TYPE_BOOLEAN:
00103 case DBUS_TYPE_INT16:
00104 case DBUS_TYPE_UINT16:
00105 case DBUS_TYPE_INT32:
00106 case DBUS_TYPE_UINT32:
00107 case DBUS_TYPE_INT64:
00108 case DBUS_TYPE_UINT64:
00109 case DBUS_TYPE_DOUBLE:
00110 case DBUS_TYPE_STRING:
00111 case DBUS_TYPE_OBJECT_PATH:
00112 case DBUS_TYPE_SIGNATURE:
00113 case DBUS_TYPE_VARIANT:
00114 break;
00115
00116 case DBUS_TYPE_ARRAY:
00117 array_depth += 1;
00118 if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
00119 {
00120 result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
00121 goto out;
00122 }
00123 break;
00124
00125 case DBUS_STRUCT_BEGIN_CHAR:
00126 struct_depth += 1;
00127
00128 if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
00129 {
00130 result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
00131 goto out;
00132 }
00133
00134 if (!_dbus_list_append (&element_count_stack,
00135 _DBUS_INT_TO_POINTER (0)))
00136 {
00137 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00138 goto out;
00139 }
00140
00141 break;
00142
00143 case DBUS_STRUCT_END_CHAR:
00144 if (struct_depth == 0)
00145 {
00146 result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
00147 goto out;
00148 }
00149
00150 if (last == DBUS_STRUCT_BEGIN_CHAR)
00151 {
00152 result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
00153 goto out;
00154 }
00155
00156 _dbus_list_pop_last (&element_count_stack);
00157
00158 struct_depth -= 1;
00159 break;
00160
00161 case DBUS_DICT_ENTRY_BEGIN_CHAR:
00162 if (last != DBUS_TYPE_ARRAY)
00163 {
00164 result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY;
00165 goto out;
00166 }
00167
00168 dict_entry_depth += 1;
00169
00170 if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
00171 {
00172 result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
00173 goto out;
00174 }
00175
00176 if (!_dbus_list_append (&element_count_stack,
00177 _DBUS_INT_TO_POINTER (0)))
00178 {
00179 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00180 goto out;
00181 }
00182
00183 break;
00184
00185 case DBUS_DICT_ENTRY_END_CHAR:
00186 if (dict_entry_depth == 0)
00187 {
00188 result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
00189 goto out;
00190 }
00191
00192 dict_entry_depth -= 1;
00193
00194 element_count =
00195 _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
00196
00197 if (element_count != 2)
00198 {
00199 if (element_count == 0)
00200 result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
00201 else if (element_count == 1)
00202 result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD;
00203 else
00204 result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS;
00205
00206 goto out;
00207 }
00208 break;
00209
00210 case DBUS_TYPE_STRUCT:
00211 case DBUS_TYPE_DICT_ENTRY:
00212 default:
00213 result = DBUS_INVALID_UNKNOWN_TYPECODE;
00214 goto out;
00215 }
00216
00217 if (*p != DBUS_TYPE_ARRAY &&
00218 *p != DBUS_DICT_ENTRY_BEGIN_CHAR &&
00219 *p != DBUS_STRUCT_BEGIN_CHAR)
00220 {
00221 element_count =
00222 _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
00223
00224 ++element_count;
00225
00226 if (!_dbus_list_append (&element_count_stack,
00227 _DBUS_INT_TO_POINTER (element_count)))
00228 {
00229 result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
00230 goto out;
00231 }
00232 }
00233
00234 if (array_depth > 0)
00235 {
00236 if (*p == DBUS_TYPE_ARRAY && p != end)
00237 {
00238 const char *p1;
00239 p1 = p + 1;
00240 if (*p1 == DBUS_STRUCT_END_CHAR ||
00241 *p1 == DBUS_DICT_ENTRY_END_CHAR)
00242 {
00243 result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
00244 goto out;
00245 }
00246 }
00247 else
00248 {
00249 array_depth = 0;
00250 }
00251 }
00252
00253 if (last == DBUS_DICT_ENTRY_BEGIN_CHAR &&
00254 !dbus_type_is_basic (*p))
00255 {
00256 result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
00257 goto out;
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_INT64:
00331 case DBUS_TYPE_UINT64:
00332 case DBUS_TYPE_DOUBLE:
00333 alignment = _dbus_type_get_alignment (current_type);
00334 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00335 if (a >= end)
00336 return DBUS_INVALID_NOT_ENOUGH_DATA;
00337 while (p != a)
00338 {
00339 if (*p != '\0')
00340 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00341 ++p;
00342 }
00343
00344 if (current_type == DBUS_TYPE_BOOLEAN)
00345 {
00346 dbus_uint32_t v = _dbus_unpack_uint32 (byte_order,
00347 p);
00348 if (!(v == 0 || v == 1))
00349 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00350 }
00351
00352 p += alignment;
00353 break;
00354
00355 case DBUS_TYPE_ARRAY:
00356 case DBUS_TYPE_STRING:
00357 case DBUS_TYPE_OBJECT_PATH:
00358 {
00359 dbus_uint32_t claimed_len;
00360
00361 a = _DBUS_ALIGN_ADDRESS (p, 4);
00362 if (a + 4 > end)
00363 return DBUS_INVALID_NOT_ENOUGH_DATA;
00364 while (p != a)
00365 {
00366 if (*p != '\0')
00367 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00368 ++p;
00369 }
00370
00371 claimed_len = _dbus_unpack_uint32 (byte_order, p);
00372 p += 4;
00373
00374
00375 _dbus_assert (p <= end);
00376
00377 if (current_type == DBUS_TYPE_ARRAY)
00378 {
00379 int array_elem_type = _dbus_type_reader_get_element_type (reader);
00380 alignment = _dbus_type_get_alignment (array_elem_type);
00381 p = _DBUS_ALIGN_ADDRESS (p, alignment);
00382 }
00383
00384 if (claimed_len > (unsigned long) (end - p))
00385 return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
00386
00387 if (current_type == DBUS_TYPE_OBJECT_PATH)
00388 {
00389 DBusString str;
00390 _dbus_string_init_const_len (&str, p, claimed_len);
00391 if (!_dbus_validate_path (&str, 0,
00392 _dbus_string_get_length (&str)))
00393 return DBUS_INVALID_BAD_PATH;
00394
00395 p += claimed_len;
00396 }
00397 else if (current_type == DBUS_TYPE_STRING)
00398 {
00399 DBusString str;
00400 _dbus_string_init_const_len (&str, p, claimed_len);
00401 if (!_dbus_string_validate_utf8 (&str, 0,
00402 _dbus_string_get_length (&str)))
00403 return DBUS_INVALID_BAD_UTF8_IN_STRING;
00404
00405 p += claimed_len;
00406 }
00407 else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
00408 {
00409 DBusTypeReader sub;
00410 DBusValidity validity;
00411 const unsigned char *array_end;
00412
00413 if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
00414 return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
00415
00416
00417
00418
00419
00420 _dbus_type_reader_recurse (reader, &sub);
00421
00422 array_end = p + claimed_len;
00423
00424 while (p < array_end)
00425 {
00426
00427
00428
00429
00430
00431 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00432 if (validity != DBUS_VALID)
00433 return validity;
00434 }
00435
00436 if (p != array_end)
00437 return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
00438 }
00439
00440
00441 if (current_type != DBUS_TYPE_ARRAY)
00442 {
00443 if (p == end)
00444 return DBUS_INVALID_NOT_ENOUGH_DATA;
00445
00446 if (*p != '\0')
00447 return DBUS_INVALID_STRING_MISSING_NUL;
00448 ++p;
00449 }
00450 }
00451 break;
00452
00453 case DBUS_TYPE_SIGNATURE:
00454 {
00455 dbus_uint32_t claimed_len;
00456 DBusString str;
00457 DBusValidity validity;
00458
00459 claimed_len = *p;
00460 ++p;
00461
00462
00463 if (claimed_len + 1 > (unsigned long) (end - p))
00464 return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00465
00466 _dbus_string_init_const_len (&str, p, claimed_len);
00467 validity =
00468 _dbus_validate_signature_with_reason (&str, 0,
00469 _dbus_string_get_length (&str));
00470
00471 if (validity != DBUS_VALID)
00472 return validity;
00473
00474 p += claimed_len;
00475
00476 _dbus_assert (p < end);
00477 if (*p != DBUS_TYPE_INVALID)
00478 return DBUS_INVALID_SIGNATURE_MISSING_NUL;
00479
00480 ++p;
00481
00482 _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
00483 }
00484 break;
00485
00486 case DBUS_TYPE_VARIANT:
00487 {
00488
00489
00490
00491
00492
00493
00494
00495 dbus_uint32_t claimed_len;
00496 DBusString sig;
00497 DBusTypeReader sub;
00498 DBusValidity validity;
00499 int contained_alignment;
00500 int contained_type;
00501 DBusValidity reason;
00502
00503 claimed_len = *p;
00504 ++p;
00505
00506
00507 if (claimed_len + 1 > (unsigned long) (end - p))
00508 return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00509
00510 _dbus_string_init_const_len (&sig, p, claimed_len);
00511 reason = _dbus_validate_signature_with_reason (&sig, 0,
00512 _dbus_string_get_length (&sig));
00513 if (!(reason == DBUS_VALID))
00514 {
00515 if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
00516 return reason;
00517 else
00518 return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
00519 }
00520
00521 p += claimed_len;
00522
00523 if (*p != DBUS_TYPE_INVALID)
00524 return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
00525 ++p;
00526
00527 contained_type = _dbus_first_type_in_signature (&sig, 0);
00528 if (contained_type == DBUS_TYPE_INVALID)
00529 return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
00530
00531 contained_alignment = _dbus_type_get_alignment (contained_type);
00532
00533 a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00534 if (a > end)
00535 return DBUS_INVALID_NOT_ENOUGH_DATA;
00536 while (p != a)
00537 {
00538 if (*p != '\0')
00539 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00540 ++p;
00541 }
00542
00543 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00544
00545 _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
00546
00547 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00548 if (validity != DBUS_VALID)
00549 return validity;
00550
00551 if (_dbus_type_reader_next (&sub))
00552 return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
00553
00554 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
00555 }
00556 break;
00557
00558 case DBUS_TYPE_DICT_ENTRY:
00559 case DBUS_TYPE_STRUCT:
00560 {
00561 DBusTypeReader sub;
00562 DBusValidity validity;
00563
00564 a = _DBUS_ALIGN_ADDRESS (p, 8);
00565 if (a > end)
00566 return DBUS_INVALID_NOT_ENOUGH_DATA;
00567 while (p != a)
00568 {
00569 if (*p != '\0')
00570 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00571 ++p;
00572 }
00573
00574 _dbus_type_reader_recurse (reader, &sub);
00575
00576 validity = validate_body_helper (&sub, byte_order, TRUE, p, end, &p);
00577 if (validity != DBUS_VALID)
00578 return validity;
00579 }
00580 break;
00581
00582 default:
00583 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00584 break;
00585 }
00586
00587 #if 0
00588 _dbus_verbose (" validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00589 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00590 (int) (end - p));
00591 #endif
00592
00593 if (p > end)
00594 {
00595 _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
00596 p, end, (int) (end - p));
00597 return DBUS_INVALID_NOT_ENOUGH_DATA;
00598 }
00599
00600 if (walk_reader_to_end)
00601 _dbus_type_reader_next (reader);
00602 else
00603 break;
00604 }
00605
00606 if (new_p)
00607 *new_p = p;
00608
00609 return DBUS_VALID;
00610 }
00611
00632 DBusValidity
00633 _dbus_validate_body_with_reason (const DBusString *expected_signature,
00634 int expected_signature_start,
00635 int byte_order,
00636 int *bytes_remaining,
00637 const DBusString *value_str,
00638 int value_pos,
00639 int len)
00640 {
00641 DBusTypeReader reader;
00642 const unsigned char *p;
00643 const unsigned char *end;
00644 DBusValidity validity;
00645
00646 _dbus_assert (len >= 0);
00647 _dbus_assert (value_pos >= 0);
00648 _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
00649
00650 _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
00651 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
00652 expected_signature_start,
00653 0));
00654
00655 _dbus_type_reader_init_types_only (&reader,
00656 expected_signature, expected_signature_start);
00657
00658 p = _dbus_string_get_const_data_len (value_str, value_pos, len);
00659 end = p + len;
00660
00661 validity = validate_body_helper (&reader, byte_order, TRUE, p, end, &p);
00662 if (validity != DBUS_VALID)
00663 return validity;
00664
00665 if (bytes_remaining)
00666 {
00667 *bytes_remaining = end - p;
00668 return DBUS_VALID;
00669 }
00670 else if (p < end)
00671 return DBUS_INVALID_TOO_MUCH_DATA;
00672 else
00673 {
00674 _dbus_assert (p == end);
00675 return DBUS_VALID;
00676 }
00677 }
00678
00683 #define VALID_INITIAL_NAME_CHARACTER(c) \
00684 ( ((c) >= 'A' && (c) <= 'Z') || \
00685 ((c) >= 'a' && (c) <= 'z') || \
00686 ((c) == '_') )
00687
00692 #define VALID_NAME_CHARACTER(c) \
00693 ( ((c) >= '0' && (c) <= '9') || \
00694 ((c) >= 'A' && (c) <= 'Z') || \
00695 ((c) >= 'a' && (c) <= 'z') || \
00696 ((c) == '_') )
00697
00714 dbus_bool_t
00715 _dbus_validate_path (const DBusString *str,
00716 int start,
00717 int len)
00718 {
00719 const unsigned char *s;
00720 const unsigned char *end;
00721 const unsigned char *last_slash;
00722
00723 _dbus_assert (start >= 0);
00724 _dbus_assert (len >= 0);
00725 _dbus_assert (start <= _dbus_string_get_length (str));
00726
00727 if (len > _dbus_string_get_length (str) - start)
00728 return FALSE;
00729
00730 if (len == 0)
00731 return FALSE;
00732
00733 s = _dbus_string_get_const_data (str) + start;
00734 end = s + len;
00735
00736 if (*s != '/')
00737 return FALSE;
00738 last_slash = s;
00739 ++s;
00740
00741 while (s != end)
00742 {
00743 if (*s == '/')
00744 {
00745 if ((s - last_slash) < 2)
00746 return FALSE;
00747
00748 last_slash = s;
00749 }
00750 else
00751 {
00752 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00753 return FALSE;
00754 }
00755
00756 ++s;
00757 }
00758
00759 if ((end - last_slash) < 2 &&
00760 len > 1)
00761 return FALSE;
00762
00763 return TRUE;
00764 }
00765
00779 dbus_bool_t
00780 _dbus_validate_interface (const DBusString *str,
00781 int start,
00782 int len)
00783 {
00784 const unsigned char *s;
00785 const unsigned char *end;
00786 const unsigned char *iface;
00787 const unsigned char *last_dot;
00788
00789 _dbus_assert (start >= 0);
00790 _dbus_assert (len >= 0);
00791 _dbus_assert (start <= _dbus_string_get_length (str));
00792
00793 if (len > _dbus_string_get_length (str) - start)
00794 return FALSE;
00795
00796 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00797 return FALSE;
00798
00799 if (len == 0)
00800 return FALSE;
00801
00802 last_dot = NULL;
00803 iface = _dbus_string_get_const_data (str) + start;
00804 end = iface + len;
00805 s = iface;
00806
00807
00808
00809
00810 if (_DBUS_UNLIKELY (*s == '.'))
00811 return FALSE;
00812 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00813 return FALSE;
00814 else
00815 ++s;
00816
00817 while (s != end)
00818 {
00819 if (*s == '.')
00820 {
00821 if (_DBUS_UNLIKELY ((s + 1) == end))
00822 return FALSE;
00823 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
00824 return FALSE;
00825 last_dot = s;
00826 ++s;
00827 }
00828 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00829 {
00830 return FALSE;
00831 }
00832
00833 ++s;
00834 }
00835
00836 if (_DBUS_UNLIKELY (last_dot == NULL))
00837 return FALSE;
00838
00839 return TRUE;
00840 }
00841
00855 dbus_bool_t
00856 _dbus_validate_member (const DBusString *str,
00857 int start,
00858 int len)
00859 {
00860 const unsigned char *s;
00861 const unsigned char *end;
00862 const unsigned char *member;
00863
00864 _dbus_assert (start >= 0);
00865 _dbus_assert (len >= 0);
00866 _dbus_assert (start <= _dbus_string_get_length (str));
00867
00868 if (len > _dbus_string_get_length (str) - start)
00869 return FALSE;
00870
00871 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00872 return FALSE;
00873
00874 if (len == 0)
00875 return FALSE;
00876
00877 member = _dbus_string_get_const_data (str) + start;
00878 end = member + len;
00879 s = member;
00880
00881
00882
00883
00884
00885 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00886 return FALSE;
00887 else
00888 ++s;
00889
00890 while (s != end)
00891 {
00892 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00893 {
00894 return FALSE;
00895 }
00896
00897 ++s;
00898 }
00899
00900 return TRUE;
00901 }
00902
00916 dbus_bool_t
00917 _dbus_validate_error_name (const DBusString *str,
00918 int start,
00919 int len)
00920 {
00921
00922 return _dbus_validate_interface (str, start, len);
00923 }
00924
00925
00926 static dbus_bool_t
00927 _dbus_validate_unique_name (const DBusString *str,
00928 int start,
00929 int len)
00930 {
00931 const unsigned char *s;
00932 const unsigned char *end;
00933 const unsigned char *name;
00934
00935 _dbus_assert (start >= 0);
00936 _dbus_assert (len >= 0);
00937 _dbus_assert (start <= _dbus_string_get_length (str));
00938
00939 if (len > _dbus_string_get_length (str) - start)
00940 return FALSE;
00941
00942 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00943 return FALSE;
00944
00945 _dbus_assert (len > 0);
00946
00947 name = _dbus_string_get_const_data (str) + start;
00948 end = name + len;
00949 _dbus_assert (*name == ':');
00950 s = name + 1;
00951
00952 while (s != end)
00953 {
00954 if (*s == '.')
00955 {
00956 if (_DBUS_UNLIKELY ((s + 1) == end))
00957 return FALSE;
00958 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*(s + 1))))
00959 return FALSE;
00960 ++s;
00961 }
00962 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00963 {
00964 return FALSE;
00965 }
00966
00967 ++s;
00968 }
00969
00970 return TRUE;
00971 }
00972
00986 dbus_bool_t
00987 _dbus_validate_bus_name (const DBusString *str,
00988 int start,
00989 int len)
00990 {
00991 if (_DBUS_UNLIKELY (len == 0))
00992 return FALSE;
00993 if (_dbus_string_get_byte (str, start) == ':')
00994 return _dbus_validate_unique_name (str, start, len);
00995 else
00996 return _dbus_validate_interface (str, start, len);
00997 }
00998
01011 dbus_bool_t
01012 _dbus_validate_signature (const DBusString *str,
01013 int start,
01014 int len)
01015 {
01016 _dbus_assert (start >= 0);
01017 _dbus_assert (start <= _dbus_string_get_length (str));
01018 _dbus_assert (len >= 0);
01019
01020 if (len > _dbus_string_get_length (str) - start)
01021 return FALSE;
01022
01023 return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
01024 }
01025
01027 DEFINE_DBUS_NAME_CHECK(path);
01029 DEFINE_DBUS_NAME_CHECK(interface);
01031 DEFINE_DBUS_NAME_CHECK(member);
01033 DEFINE_DBUS_NAME_CHECK(error_name);
01035 DEFINE_DBUS_NAME_CHECK(bus_name);
01037 DEFINE_DBUS_NAME_CHECK(signature);
01038
01041