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