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