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 {
00255 if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p)))
00256 {
00257 result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
00258 goto out;
00259 }
00260 }
00261
00262 last = *p;
00263 ++p;
00264 }
00265
00266
00267 if (array_depth > 0)
00268 {
00269 result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
00270 goto out;
00271 }
00272
00273 if (struct_depth > 0)
00274 {
00275 result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
00276 goto out;
00277 }
00278
00279 if (dict_entry_depth > 0)
00280 {
00281 result = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
00282 goto out;
00283 }
00284
00285 _dbus_assert (last != DBUS_TYPE_ARRAY);
00286 _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR);
00287 _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR);
00288
00289 result = DBUS_VALID;
00290
00291 out:
00292 _dbus_list_clear (&element_count_stack);
00293 return result;
00294 }
00295
00296 static DBusValidity
00297 validate_body_helper (DBusTypeReader *reader,
00298 int byte_order,
00299 dbus_bool_t walk_reader_to_end,
00300 const unsigned char *p,
00301 const unsigned char *end,
00302 const unsigned char **new_p)
00303 {
00304 int current_type;
00305
00306 while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
00307 {
00308 const unsigned char *a;
00309 int alignment;
00310
00311 #if 0
00312 _dbus_verbose (" validating value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00313 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00314 (int) (end - p));
00315 #endif
00316
00317
00318 if (p == end)
00319 return DBUS_INVALID_NOT_ENOUGH_DATA;
00320
00321 switch (current_type)
00322 {
00323 case DBUS_TYPE_BYTE:
00324 ++p;
00325 break;
00326
00327 case DBUS_TYPE_BOOLEAN:
00328 case DBUS_TYPE_INT16:
00329 case DBUS_TYPE_UINT16:
00330 case DBUS_TYPE_INT32:
00331 case DBUS_TYPE_UINT32:
00332 case DBUS_TYPE_INT64:
00333 case DBUS_TYPE_UINT64:
00334 case DBUS_TYPE_DOUBLE:
00335 alignment = _dbus_type_get_alignment (current_type);
00336 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00337 if (a >= end)
00338 return DBUS_INVALID_NOT_ENOUGH_DATA;
00339 while (p != a)
00340 {
00341 if (*p != '\0')
00342 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00343 ++p;
00344 }
00345
00346 if (current_type == DBUS_TYPE_BOOLEAN)
00347 {
00348 dbus_uint32_t v = _dbus_unpack_uint32 (byte_order,
00349 p);
00350 if (!(v == 0 || v == 1))
00351 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00352 }
00353
00354 p += alignment;
00355 break;
00356
00357 case DBUS_TYPE_ARRAY:
00358 case DBUS_TYPE_STRING:
00359 case DBUS_TYPE_OBJECT_PATH:
00360 {
00361 dbus_uint32_t claimed_len;
00362
00363 a = _DBUS_ALIGN_ADDRESS (p, 4);
00364 if (a + 4 > end)
00365 return DBUS_INVALID_NOT_ENOUGH_DATA;
00366 while (p != a)
00367 {
00368 if (*p != '\0')
00369 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00370 ++p;
00371 }
00372
00373 claimed_len = _dbus_unpack_uint32 (byte_order, p);
00374 p += 4;
00375
00376
00377 _dbus_assert (p <= end);
00378
00379 if (current_type == DBUS_TYPE_ARRAY)
00380 {
00381 int array_elem_type = _dbus_type_reader_get_element_type (reader);
00382 alignment = _dbus_type_get_alignment (array_elem_type);
00383 p = _DBUS_ALIGN_ADDRESS (p, alignment);
00384 }
00385
00386 if (claimed_len > (unsigned long) (end - p))
00387 return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
00388
00389 if (current_type == DBUS_TYPE_OBJECT_PATH)
00390 {
00391 DBusString str;
00392 _dbus_string_init_const_len (&str, p, claimed_len);
00393 if (!_dbus_validate_path (&str, 0,
00394 _dbus_string_get_length (&str)))
00395 return DBUS_INVALID_BAD_PATH;
00396
00397 p += claimed_len;
00398 }
00399 else if (current_type == DBUS_TYPE_STRING)
00400 {
00401 DBusString str;
00402 _dbus_string_init_const_len (&str, p, claimed_len);
00403 if (!_dbus_string_validate_utf8 (&str, 0,
00404 _dbus_string_get_length (&str)))
00405 return DBUS_INVALID_BAD_UTF8_IN_STRING;
00406
00407 p += claimed_len;
00408 }
00409 else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
00410 {
00411 DBusTypeReader sub;
00412 DBusValidity validity;
00413 const unsigned char *array_end;
00414
00415 if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
00416 return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
00417
00418
00419
00420
00421
00422 _dbus_type_reader_recurse (reader, &sub);
00423
00424 array_end = p + claimed_len;
00425
00426 while (p < array_end)
00427 {
00428
00429
00430
00431
00432
00433 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00434 if (validity != DBUS_VALID)
00435 return validity;
00436 }
00437
00438 if (p != array_end)
00439 return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
00440 }
00441
00442
00443 if (current_type != DBUS_TYPE_ARRAY)
00444 {
00445 if (p == end)
00446 return DBUS_INVALID_NOT_ENOUGH_DATA;
00447
00448 if (*p != '\0')
00449 return DBUS_INVALID_STRING_MISSING_NUL;
00450 ++p;
00451 }
00452 }
00453 break;
00454
00455 case DBUS_TYPE_SIGNATURE:
00456 {
00457 dbus_uint32_t claimed_len;
00458 DBusString str;
00459 DBusValidity validity;
00460
00461 claimed_len = *p;
00462 ++p;
00463
00464
00465 if (claimed_len + 1 > (unsigned long) (end - p))
00466 return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00467
00468 _dbus_string_init_const_len (&str, p, claimed_len);
00469 validity =
00470 _dbus_validate_signature_with_reason (&str, 0,
00471 _dbus_string_get_length (&str));
00472
00473 if (validity != DBUS_VALID)
00474 return validity;
00475
00476 p += claimed_len;
00477
00478 _dbus_assert (p < end);
00479 if (*p != DBUS_TYPE_INVALID)
00480 return DBUS_INVALID_SIGNATURE_MISSING_NUL;
00481
00482 ++p;
00483
00484 _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
00485 }
00486 break;
00487
00488 case DBUS_TYPE_VARIANT:
00489 {
00490
00491
00492
00493
00494
00495
00496
00497 dbus_uint32_t claimed_len;
00498 DBusString sig;
00499 DBusTypeReader sub;
00500 DBusValidity validity;
00501 int contained_alignment;
00502 int contained_type;
00503 DBusValidity reason;
00504
00505 claimed_len = *p;
00506 ++p;
00507
00508
00509 if (claimed_len + 1 > (unsigned long) (end - p))
00510 return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00511
00512 _dbus_string_init_const_len (&sig, p, claimed_len);
00513 reason = _dbus_validate_signature_with_reason (&sig, 0,
00514 _dbus_string_get_length (&sig));
00515 if (!(reason == DBUS_VALID))
00516 {
00517 if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
00518 return reason;
00519 else
00520 return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
00521 }
00522
00523 p += claimed_len;
00524
00525 if (*p != DBUS_TYPE_INVALID)
00526 return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
00527 ++p;
00528
00529 contained_type = _dbus_first_type_in_signature (&sig, 0);
00530 if (contained_type == DBUS_TYPE_INVALID)
00531 return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
00532
00533 contained_alignment = _dbus_type_get_alignment (contained_type);
00534
00535 a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00536 if (a > end)
00537 return DBUS_INVALID_NOT_ENOUGH_DATA;
00538 while (p != a)
00539 {
00540 if (*p != '\0')
00541 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00542 ++p;
00543 }
00544
00545 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00546
00547 _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
00548
00549 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00550 if (validity != DBUS_VALID)
00551 return validity;
00552
00553 if (_dbus_type_reader_next (&sub))
00554 return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
00555
00556 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
00557 }
00558 break;
00559
00560 case DBUS_TYPE_DICT_ENTRY:
00561 case DBUS_TYPE_STRUCT:
00562 {
00563 DBusTypeReader sub;
00564 DBusValidity validity;
00565
00566 a = _DBUS_ALIGN_ADDRESS (p, 8);
00567 if (a > end)
00568 return DBUS_INVALID_NOT_ENOUGH_DATA;
00569 while (p != a)
00570 {
00571 if (*p != '\0')
00572 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00573 ++p;
00574 }
00575
00576 _dbus_type_reader_recurse (reader, &sub);
00577
00578 validity = validate_body_helper (&sub, byte_order, TRUE, p, end, &p);
00579 if (validity != DBUS_VALID)
00580 return validity;
00581 }
00582 break;
00583
00584 default:
00585 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00586 break;
00587 }
00588
00589 #if 0
00590 _dbus_verbose (" validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00591 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00592 (int) (end - p));
00593 #endif
00594
00595 if (p > end)
00596 {
00597 _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
00598 p, end, (int) (end - p));
00599 return DBUS_INVALID_NOT_ENOUGH_DATA;
00600 }
00601
00602 if (walk_reader_to_end)
00603 _dbus_type_reader_next (reader);
00604 else
00605 break;
00606 }
00607
00608 if (new_p)
00609 *new_p = p;
00610
00611 return DBUS_VALID;
00612 }
00613
00634 DBusValidity
00635 _dbus_validate_body_with_reason (const DBusString *expected_signature,
00636 int expected_signature_start,
00637 int byte_order,
00638 int *bytes_remaining,
00639 const DBusString *value_str,
00640 int value_pos,
00641 int len)
00642 {
00643 DBusTypeReader reader;
00644 const unsigned char *p;
00645 const unsigned char *end;
00646 DBusValidity validity;
00647
00648 _dbus_assert (len >= 0);
00649 _dbus_assert (value_pos >= 0);
00650 _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
00651
00652 _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
00653 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
00654 expected_signature_start,
00655 0));
00656
00657 _dbus_type_reader_init_types_only (&reader,
00658 expected_signature, expected_signature_start);
00659
00660 p = _dbus_string_get_const_data_len (value_str, value_pos, len);
00661 end = p + len;
00662
00663 validity = validate_body_helper (&reader, byte_order, TRUE, p, end, &p);
00664 if (validity != DBUS_VALID)
00665 return validity;
00666
00667 if (bytes_remaining)
00668 {
00669 *bytes_remaining = end - p;
00670 return DBUS_VALID;
00671 }
00672 else if (p < end)
00673 return DBUS_INVALID_TOO_MUCH_DATA;
00674 else
00675 {
00676 _dbus_assert (p == end);
00677 return DBUS_VALID;
00678 }
00679 }
00680
00685 #define VALID_INITIAL_NAME_CHARACTER(c) \
00686 ( ((c) >= 'A' && (c) <= 'Z') || \
00687 ((c) >= 'a' && (c) <= 'z') || \
00688 ((c) == '_') )
00689
00694 #define VALID_NAME_CHARACTER(c) \
00695 ( ((c) >= '0' && (c) <= '9') || \
00696 ((c) >= 'A' && (c) <= 'Z') || \
00697 ((c) >= 'a' && (c) <= 'z') || \
00698 ((c) == '_') )
00699
00716 dbus_bool_t
00717 _dbus_validate_path (const DBusString *str,
00718 int start,
00719 int len)
00720 {
00721 const unsigned char *s;
00722 const unsigned char *end;
00723 const unsigned char *last_slash;
00724
00725 _dbus_assert (start >= 0);
00726 _dbus_assert (len >= 0);
00727 _dbus_assert (start <= _dbus_string_get_length (str));
00728
00729 if (len > _dbus_string_get_length (str) - start)
00730 return FALSE;
00731
00732 if (len == 0)
00733 return FALSE;
00734
00735 s = _dbus_string_get_const_data (str) + start;
00736 end = s + len;
00737
00738 if (*s != '/')
00739 return FALSE;
00740 last_slash = s;
00741 ++s;
00742
00743 while (s != end)
00744 {
00745 if (*s == '/')
00746 {
00747 if ((s - last_slash) < 2)
00748 return FALSE;
00749
00750 last_slash = s;
00751 }
00752 else
00753 {
00754 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00755 return FALSE;
00756 }
00757
00758 ++s;
00759 }
00760
00761 if ((end - last_slash) < 2 &&
00762 len > 1)
00763 return FALSE;
00764
00765 return TRUE;
00766 }
00767
00781 dbus_bool_t
00782 _dbus_validate_interface (const DBusString *str,
00783 int start,
00784 int len)
00785 {
00786 const unsigned char *s;
00787 const unsigned char *end;
00788 const unsigned char *iface;
00789 const unsigned char *last_dot;
00790
00791 _dbus_assert (start >= 0);
00792 _dbus_assert (len >= 0);
00793 _dbus_assert (start <= _dbus_string_get_length (str));
00794
00795 if (len > _dbus_string_get_length (str) - start)
00796 return FALSE;
00797
00798 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00799 return FALSE;
00800
00801 if (len == 0)
00802 return FALSE;
00803
00804 last_dot = NULL;
00805 iface = _dbus_string_get_const_data (str) + start;
00806 end = iface + len;
00807 s = iface;
00808
00809
00810
00811
00812 if (_DBUS_UNLIKELY (*s == '.'))
00813 return FALSE;
00814 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00815 return FALSE;
00816 else
00817 ++s;
00818
00819 while (s != end)
00820 {
00821 if (*s == '.')
00822 {
00823 if (_DBUS_UNLIKELY ((s + 1) == end))
00824 return FALSE;
00825 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
00826 return FALSE;
00827 last_dot = s;
00828 ++s;
00829 }
00830 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00831 {
00832 return FALSE;
00833 }
00834
00835 ++s;
00836 }
00837
00838 if (_DBUS_UNLIKELY (last_dot == NULL))
00839 return FALSE;
00840
00841 return TRUE;
00842 }
00843
00857 dbus_bool_t
00858 _dbus_validate_member (const DBusString *str,
00859 int start,
00860 int len)
00861 {
00862 const unsigned char *s;
00863 const unsigned char *end;
00864 const unsigned char *member;
00865
00866 _dbus_assert (start >= 0);
00867 _dbus_assert (len >= 0);
00868 _dbus_assert (start <= _dbus_string_get_length (str));
00869
00870 if (len > _dbus_string_get_length (str) - start)
00871 return FALSE;
00872
00873 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00874 return FALSE;
00875
00876 if (len == 0)
00877 return FALSE;
00878
00879 member = _dbus_string_get_const_data (str) + start;
00880 end = member + len;
00881 s = member;
00882
00883
00884
00885
00886
00887 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00888 return FALSE;
00889 else
00890 ++s;
00891
00892 while (s != end)
00893 {
00894 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00895 {
00896 return FALSE;
00897 }
00898
00899 ++s;
00900 }
00901
00902 return TRUE;
00903 }
00904
00918 dbus_bool_t
00919 _dbus_validate_error_name (const DBusString *str,
00920 int start,
00921 int len)
00922 {
00923
00924 return _dbus_validate_interface (str, start, len);
00925 }
00926
00931 #define VALID_INITIAL_BUS_NAME_CHARACTER(c) \
00932 ( ((c) >= 'A' && (c) <= 'Z') || \
00933 ((c) >= 'a' && (c) <= 'z') || \
00934 ((c) == '_') || ((c) == '-'))
00935
00940 #define VALID_BUS_NAME_CHARACTER(c) \
00941 ( ((c) >= '0' && (c) <= '9') || \
00942 ((c) >= 'A' && (c) <= 'Z') || \
00943 ((c) >= 'a' && (c) <= 'z') || \
00944 ((c) == '_') || ((c) == '-'))
00945
00959 dbus_bool_t
00960 _dbus_validate_bus_name (const DBusString *str,
00961 int start,
00962 int len)
00963 {
00964 const unsigned char *s;
00965 const unsigned char *end;
00966 const unsigned char *iface;
00967 const unsigned char *last_dot;
00968
00969 _dbus_assert (start >= 0);
00970 _dbus_assert (len >= 0);
00971 _dbus_assert (start <= _dbus_string_get_length (str));
00972
00973 if (len > _dbus_string_get_length (str) - start)
00974 return FALSE;
00975
00976 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00977 return FALSE;
00978
00979 if (len == 0)
00980 return FALSE;
00981
00982 last_dot = NULL;
00983 iface = _dbus_string_get_const_data (str) + start;
00984 end = iface + len;
00985 s = iface;
00986
00987
00988
00989
00990 if (*s == ':')
00991 {
00992
00993 ++s;
00994 while (s != end)
00995 {
00996 if (*s == '.')
00997 {
00998 if (_DBUS_UNLIKELY ((s + 1) == end))
00999 return FALSE;
01000 if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
01001 return FALSE;
01002 ++s;
01003 }
01004 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01005 {
01006 return FALSE;
01007 }
01008
01009 ++s;
01010 }
01011
01012 return TRUE;
01013 }
01014 else if (_DBUS_UNLIKELY (*s == '.'))
01015 return FALSE;
01016 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s)))
01017 return FALSE;
01018 else
01019 ++s;
01020
01021 while (s != end)
01022 {
01023 if (*s == '.')
01024 {
01025 if (_DBUS_UNLIKELY ((s + 1) == end))
01026 return FALSE;
01027 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
01028 return FALSE;
01029 last_dot = s;
01030 ++s;
01031 }
01032 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01033 {
01034 return FALSE;
01035 }
01036
01037 ++s;
01038 }
01039
01040 if (_DBUS_UNLIKELY (last_dot == NULL))
01041 return FALSE;
01042
01043 return TRUE;
01044 }
01045
01058 dbus_bool_t
01059 _dbus_validate_signature (const DBusString *str,
01060 int start,
01061 int len)
01062 {
01063 _dbus_assert (start >= 0);
01064 _dbus_assert (start <= _dbus_string_get_length (str));
01065 _dbus_assert (len >= 0);
01066
01067 if (len > _dbus_string_get_length (str) - start)
01068 return FALSE;
01069
01070 return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
01071 }
01072
01074 DEFINE_DBUS_NAME_CHECK(path);
01076 DEFINE_DBUS_NAME_CHECK(interface);
01078 DEFINE_DBUS_NAME_CHECK(member);
01080 DEFINE_DBUS_NAME_CHECK(error_name);
01082 DEFINE_DBUS_NAME_CHECK(bus_name);
01084 DEFINE_DBUS_NAME_CHECK(signature);
01085
01088