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