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