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
00378 if (!_dbus_type_is_valid (array_elem_type))
00379 {
00380 return DBUS_INVALID_UNKNOWN_TYPECODE;
00381 }
00382
00383 alignment = _dbus_type_get_alignment (array_elem_type);
00384
00385 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00386
00387
00388 if (a > end)
00389 return DBUS_INVALID_NOT_ENOUGH_DATA;
00390
00391 while (p != a)
00392 {
00393 if (*p != '\0')
00394 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00395 ++p;
00396 }
00397 }
00398
00399 if (claimed_len > (unsigned long) (end - p))
00400 return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
00401
00402 if (current_type == DBUS_TYPE_OBJECT_PATH)
00403 {
00404 DBusString str;
00405 _dbus_string_init_const_len (&str, p, claimed_len);
00406 if (!_dbus_validate_path (&str, 0,
00407 _dbus_string_get_length (&str)))
00408 return DBUS_INVALID_BAD_PATH;
00409
00410 p += claimed_len;
00411 }
00412 else if (current_type == DBUS_TYPE_STRING)
00413 {
00414 DBusString str;
00415 _dbus_string_init_const_len (&str, p, claimed_len);
00416 if (!_dbus_string_validate_utf8 (&str, 0,
00417 _dbus_string_get_length (&str)))
00418 return DBUS_INVALID_BAD_UTF8_IN_STRING;
00419
00420 p += claimed_len;
00421 }
00422 else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
00423 {
00424 DBusTypeReader sub;
00425 DBusValidity validity;
00426 const unsigned char *array_end;
00427 int array_elem_type;
00428
00429 if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
00430 return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
00431
00432
00433
00434
00435
00436 _dbus_type_reader_recurse (reader, &sub);
00437
00438 array_end = p + claimed_len;
00439
00440 array_elem_type = _dbus_type_reader_get_element_type (reader);
00441
00442
00443
00444
00445 if (dbus_type_is_fixed (array_elem_type))
00446 {
00447
00448
00449
00450 if (array_elem_type == DBUS_TYPE_BOOLEAN)
00451 {
00452 dbus_uint32_t v;
00453 alignment = _dbus_type_get_alignment (array_elem_type);
00454
00455 while (p < array_end)
00456 {
00457 v = _dbus_unpack_uint32 (byte_order, p);
00458
00459 if (!(v == 0 || v == 1))
00460 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00461
00462 p += alignment;
00463 }
00464 }
00465
00466 else
00467 {
00468 p = array_end;
00469 }
00470 }
00471
00472 else
00473 {
00474 while (p < array_end)
00475 {
00476 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00477 if (validity != DBUS_VALID)
00478 return validity;
00479 }
00480 }
00481
00482 if (p != array_end)
00483 return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
00484 }
00485
00486
00487 if (current_type != DBUS_TYPE_ARRAY)
00488 {
00489 if (p == end)
00490 return DBUS_INVALID_NOT_ENOUGH_DATA;
00491
00492 if (*p != '\0')
00493 return DBUS_INVALID_STRING_MISSING_NUL;
00494 ++p;
00495 }
00496 }
00497 break;
00498
00499 case DBUS_TYPE_SIGNATURE:
00500 {
00501 dbus_uint32_t claimed_len;
00502 DBusString str;
00503 DBusValidity validity;
00504
00505 claimed_len = *p;
00506 ++p;
00507
00508
00509 if (claimed_len + 1 > (unsigned long) (end - p))
00510 return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00511
00512 _dbus_string_init_const_len (&str, p, claimed_len);
00513 validity =
00514 _dbus_validate_signature_with_reason (&str, 0,
00515 _dbus_string_get_length (&str));
00516
00517 if (validity != DBUS_VALID)
00518 return validity;
00519
00520 p += claimed_len;
00521
00522 _dbus_assert (p < end);
00523 if (*p != DBUS_TYPE_INVALID)
00524 return DBUS_INVALID_SIGNATURE_MISSING_NUL;
00525
00526 ++p;
00527
00528 _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
00529 }
00530 break;
00531
00532 case DBUS_TYPE_VARIANT:
00533 {
00534
00535
00536
00537
00538
00539
00540
00541 dbus_uint32_t claimed_len;
00542 DBusString sig;
00543 DBusTypeReader sub;
00544 DBusValidity validity;
00545 int contained_alignment;
00546 int contained_type;
00547 DBusValidity reason;
00548
00549 claimed_len = *p;
00550 ++p;
00551
00552
00553 if (claimed_len + 1 > (unsigned long) (end - p))
00554 return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00555
00556 _dbus_string_init_const_len (&sig, p, claimed_len);
00557 reason = _dbus_validate_signature_with_reason (&sig, 0,
00558 _dbus_string_get_length (&sig));
00559 if (!(reason == DBUS_VALID))
00560 {
00561 if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
00562 return reason;
00563 else
00564 return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
00565 }
00566
00567 p += claimed_len;
00568
00569 if (*p != DBUS_TYPE_INVALID)
00570 return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
00571 ++p;
00572
00573 contained_type = _dbus_first_type_in_signature (&sig, 0);
00574 if (contained_type == DBUS_TYPE_INVALID)
00575 return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
00576
00577 contained_alignment = _dbus_type_get_alignment (contained_type);
00578
00579 a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00580 if (a > end)
00581 return DBUS_INVALID_NOT_ENOUGH_DATA;
00582 while (p != a)
00583 {
00584 if (*p != '\0')
00585 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00586 ++p;
00587 }
00588
00589 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00590
00591 _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
00592
00593 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00594 if (validity != DBUS_VALID)
00595 return validity;
00596
00597 if (_dbus_type_reader_next (&sub))
00598 return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
00599
00600 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
00601 }
00602 break;
00603
00604 case DBUS_TYPE_DICT_ENTRY:
00605 case DBUS_TYPE_STRUCT:
00606 {
00607 DBusTypeReader sub;
00608 DBusValidity validity;
00609
00610 a = _DBUS_ALIGN_ADDRESS (p, 8);
00611 if (a > end)
00612 return DBUS_INVALID_NOT_ENOUGH_DATA;
00613 while (p != a)
00614 {
00615 if (*p != '\0')
00616 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00617 ++p;
00618 }
00619
00620 _dbus_type_reader_recurse (reader, &sub);
00621
00622 validity = validate_body_helper (&sub, byte_order, TRUE, p, end, &p);
00623 if (validity != DBUS_VALID)
00624 return validity;
00625 }
00626 break;
00627
00628 default:
00629 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00630 break;
00631 }
00632
00633 #if 0
00634 _dbus_verbose (" validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00635 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00636 (int) (end - p));
00637 #endif
00638
00639 if (p > end)
00640 {
00641 _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
00642 p, end, (int) (end - p));
00643 return DBUS_INVALID_NOT_ENOUGH_DATA;
00644 }
00645
00646 if (walk_reader_to_end)
00647 _dbus_type_reader_next (reader);
00648 else
00649 break;
00650 }
00651
00652 if (new_p)
00653 *new_p = p;
00654
00655 return DBUS_VALID;
00656 }
00657
00678 DBusValidity
00679 _dbus_validate_body_with_reason (const DBusString *expected_signature,
00680 int expected_signature_start,
00681 int byte_order,
00682 int *bytes_remaining,
00683 const DBusString *value_str,
00684 int value_pos,
00685 int len)
00686 {
00687 DBusTypeReader reader;
00688 const unsigned char *p;
00689 const unsigned char *end;
00690 DBusValidity validity;
00691
00692 _dbus_assert (len >= 0);
00693 _dbus_assert (value_pos >= 0);
00694 _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
00695
00696 _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
00697 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
00698 expected_signature_start,
00699 0));
00700
00701 _dbus_type_reader_init_types_only (&reader,
00702 expected_signature, expected_signature_start);
00703
00704 p = _dbus_string_get_const_data_len (value_str, value_pos, len);
00705 end = p + len;
00706
00707 validity = validate_body_helper (&reader, byte_order, TRUE, p, end, &p);
00708 if (validity != DBUS_VALID)
00709 return validity;
00710
00711 if (bytes_remaining)
00712 {
00713 *bytes_remaining = end - p;
00714 return DBUS_VALID;
00715 }
00716 else if (p < end)
00717 return DBUS_INVALID_TOO_MUCH_DATA;
00718 else
00719 {
00720 _dbus_assert (p == end);
00721 return DBUS_VALID;
00722 }
00723 }
00724
00729 #define VALID_INITIAL_NAME_CHARACTER(c) \
00730 ( ((c) >= 'A' && (c) <= 'Z') || \
00731 ((c) >= 'a' && (c) <= 'z') || \
00732 ((c) == '_') )
00733
00738 #define VALID_NAME_CHARACTER(c) \
00739 ( ((c) >= '0' && (c) <= '9') || \
00740 ((c) >= 'A' && (c) <= 'Z') || \
00741 ((c) >= 'a' && (c) <= 'z') || \
00742 ((c) == '_') )
00743
00760 dbus_bool_t
00761 _dbus_validate_path (const DBusString *str,
00762 int start,
00763 int len)
00764 {
00765 const unsigned char *s;
00766 const unsigned char *end;
00767 const unsigned char *last_slash;
00768
00769 _dbus_assert (start >= 0);
00770 _dbus_assert (len >= 0);
00771 _dbus_assert (start <= _dbus_string_get_length (str));
00772
00773 if (len > _dbus_string_get_length (str) - start)
00774 return FALSE;
00775
00776 if (len == 0)
00777 return FALSE;
00778
00779 s = _dbus_string_get_const_data (str) + start;
00780 end = s + len;
00781
00782 if (*s != '/')
00783 return FALSE;
00784 last_slash = s;
00785 ++s;
00786
00787 while (s != end)
00788 {
00789 if (*s == '/')
00790 {
00791 if ((s - last_slash) < 2)
00792 return FALSE;
00793
00794 last_slash = s;
00795 }
00796 else
00797 {
00798 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00799 return FALSE;
00800 }
00801
00802 ++s;
00803 }
00804
00805 if ((end - last_slash) < 2 &&
00806 len > 1)
00807 return FALSE;
00808
00809 return TRUE;
00810 }
00811
00825 dbus_bool_t
00826 _dbus_validate_interface (const DBusString *str,
00827 int start,
00828 int len)
00829 {
00830 const unsigned char *s;
00831 const unsigned char *end;
00832 const unsigned char *iface;
00833 const unsigned char *last_dot;
00834
00835 _dbus_assert (start >= 0);
00836 _dbus_assert (len >= 0);
00837 _dbus_assert (start <= _dbus_string_get_length (str));
00838
00839 if (len > _dbus_string_get_length (str) - start)
00840 return FALSE;
00841
00842 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00843 return FALSE;
00844
00845 if (len == 0)
00846 return FALSE;
00847
00848 last_dot = NULL;
00849 iface = _dbus_string_get_const_data (str) + start;
00850 end = iface + len;
00851 s = iface;
00852
00853
00854
00855
00856 if (_DBUS_UNLIKELY (*s == '.'))
00857 return FALSE;
00858 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00859 return FALSE;
00860 else
00861 ++s;
00862
00863 while (s != end)
00864 {
00865 if (*s == '.')
00866 {
00867 if (_DBUS_UNLIKELY ((s + 1) == end))
00868 return FALSE;
00869 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
00870 return FALSE;
00871 last_dot = s;
00872 ++s;
00873 }
00874 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00875 {
00876 return FALSE;
00877 }
00878
00879 ++s;
00880 }
00881
00882 if (_DBUS_UNLIKELY (last_dot == NULL))
00883 return FALSE;
00884
00885 return TRUE;
00886 }
00887
00901 dbus_bool_t
00902 _dbus_validate_member (const DBusString *str,
00903 int start,
00904 int len)
00905 {
00906 const unsigned char *s;
00907 const unsigned char *end;
00908 const unsigned char *member;
00909
00910 _dbus_assert (start >= 0);
00911 _dbus_assert (len >= 0);
00912 _dbus_assert (start <= _dbus_string_get_length (str));
00913
00914 if (len > _dbus_string_get_length (str) - start)
00915 return FALSE;
00916
00917 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00918 return FALSE;
00919
00920 if (len == 0)
00921 return FALSE;
00922
00923 member = _dbus_string_get_const_data (str) + start;
00924 end = member + len;
00925 s = member;
00926
00927
00928
00929
00930
00931 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00932 return FALSE;
00933 else
00934 ++s;
00935
00936 while (s != end)
00937 {
00938 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00939 {
00940 return FALSE;
00941 }
00942
00943 ++s;
00944 }
00945
00946 return TRUE;
00947 }
00948
00962 dbus_bool_t
00963 _dbus_validate_error_name (const DBusString *str,
00964 int start,
00965 int len)
00966 {
00967
00968 return _dbus_validate_interface (str, start, len);
00969 }
00970
00975 #define VALID_INITIAL_BUS_NAME_CHARACTER(c) \
00976 ( ((c) >= 'A' && (c) <= 'Z') || \
00977 ((c) >= 'a' && (c) <= 'z') || \
00978 ((c) == '_') || ((c) == '-'))
00979
00984 #define VALID_BUS_NAME_CHARACTER(c) \
00985 ( ((c) >= '0' && (c) <= '9') || \
00986 ((c) >= 'A' && (c) <= 'Z') || \
00987 ((c) >= 'a' && (c) <= 'z') || \
00988 ((c) == '_') || ((c) == '-'))
00989
01003 dbus_bool_t
01004 _dbus_validate_bus_name (const DBusString *str,
01005 int start,
01006 int len)
01007 {
01008 const unsigned char *s;
01009 const unsigned char *end;
01010 const unsigned char *iface;
01011 const unsigned char *last_dot;
01012
01013 _dbus_assert (start >= 0);
01014 _dbus_assert (len >= 0);
01015 _dbus_assert (start <= _dbus_string_get_length (str));
01016
01017 if (len > _dbus_string_get_length (str) - start)
01018 return FALSE;
01019
01020 if (len > DBUS_MAXIMUM_NAME_LENGTH)
01021 return FALSE;
01022
01023 if (len == 0)
01024 return FALSE;
01025
01026 last_dot = NULL;
01027 iface = _dbus_string_get_const_data (str) + start;
01028 end = iface + len;
01029 s = iface;
01030
01031
01032
01033
01034 if (*s == ':')
01035 {
01036
01037 ++s;
01038 while (s != end)
01039 {
01040 if (*s == '.')
01041 {
01042 if (_DBUS_UNLIKELY ((s + 1) == end))
01043 return FALSE;
01044 if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
01045 return FALSE;
01046 ++s;
01047 }
01048 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01049 {
01050 return FALSE;
01051 }
01052
01053 ++s;
01054 }
01055
01056 return TRUE;
01057 }
01058 else if (_DBUS_UNLIKELY (*s == '.'))
01059 return FALSE;
01060 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s)))
01061 return FALSE;
01062 else
01063 ++s;
01064
01065 while (s != end)
01066 {
01067 if (*s == '.')
01068 {
01069 if (_DBUS_UNLIKELY ((s + 1) == end))
01070 return FALSE;
01071 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
01072 return FALSE;
01073 last_dot = s;
01074 ++s;
01075 }
01076 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01077 {
01078 return FALSE;
01079 }
01080
01081 ++s;
01082 }
01083
01084 if (_DBUS_UNLIKELY (last_dot == NULL))
01085 return FALSE;
01086
01087 return TRUE;
01088 }
01089
01102 dbus_bool_t
01103 _dbus_validate_signature (const DBusString *str,
01104 int start,
01105 int len)
01106 {
01107 _dbus_assert (start >= 0);
01108 _dbus_assert (start <= _dbus_string_get_length (str));
01109 _dbus_assert (len >= 0);
01110
01111 if (len > _dbus_string_get_length (str) - start)
01112 return FALSE;
01113
01114 return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
01115 }
01116
01118 DEFINE_DBUS_NAME_CHECK(path)
01120 DEFINE_DBUS_NAME_CHECK(interface)
01122 DEFINE_DBUS_NAME_CHECK(member)
01124 DEFINE_DBUS_NAME_CHECK(error_name)
01126 DEFINE_DBUS_NAME_CHECK(bus_name)
01128 DEFINE_DBUS_NAME_CHECK(signature)
01129
01132