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
00293
00294
00295 static DBusValidity
00296 validate_body_helper (DBusTypeReader *reader,
00297 int byte_order,
00298 dbus_bool_t walk_reader_to_end,
00299 int total_depth,
00300 const unsigned char *p,
00301 const unsigned char *end,
00302 const unsigned char **new_p)
00303 {
00304 int current_type;
00305
00306
00307
00308
00309
00310
00311 if (total_depth > (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH * 2))
00312 {
00313 return DBUS_INVALID_NESTED_TOO_DEEPLY;
00314 }
00315
00316 while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
00317 {
00318 const unsigned char *a;
00319 int alignment;
00320
00321 #if 0
00322 _dbus_verbose (" validating value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00323 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00324 (int) (end - p));
00325 #endif
00326
00327
00328 if (p == end)
00329 return DBUS_INVALID_NOT_ENOUGH_DATA;
00330
00331 switch (current_type)
00332 {
00333 case DBUS_TYPE_BYTE:
00334 ++p;
00335 break;
00336
00337 case DBUS_TYPE_BOOLEAN:
00338 case DBUS_TYPE_INT16:
00339 case DBUS_TYPE_UINT16:
00340 case DBUS_TYPE_INT32:
00341 case DBUS_TYPE_UINT32:
00342 case DBUS_TYPE_INT64:
00343 case DBUS_TYPE_UINT64:
00344 case DBUS_TYPE_DOUBLE:
00345 alignment = _dbus_type_get_alignment (current_type);
00346 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00347 if (a >= end)
00348 return DBUS_INVALID_NOT_ENOUGH_DATA;
00349 while (p != a)
00350 {
00351 if (*p != '\0')
00352 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00353 ++p;
00354 }
00355
00356 if (current_type == DBUS_TYPE_BOOLEAN)
00357 {
00358 dbus_uint32_t v = _dbus_unpack_uint32 (byte_order,
00359 p);
00360 if (!(v == 0 || v == 1))
00361 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00362 }
00363
00364 p += alignment;
00365 break;
00366
00367 case DBUS_TYPE_ARRAY:
00368 case DBUS_TYPE_STRING:
00369 case DBUS_TYPE_OBJECT_PATH:
00370 {
00371 dbus_uint32_t claimed_len;
00372
00373 a = _DBUS_ALIGN_ADDRESS (p, 4);
00374 if (a + 4 > end)
00375 return DBUS_INVALID_NOT_ENOUGH_DATA;
00376 while (p != a)
00377 {
00378 if (*p != '\0')
00379 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00380 ++p;
00381 }
00382
00383 claimed_len = _dbus_unpack_uint32 (byte_order, p);
00384 p += 4;
00385
00386
00387 _dbus_assert (p <= end);
00388
00389 if (current_type == DBUS_TYPE_ARRAY)
00390 {
00391 int array_elem_type = _dbus_type_reader_get_element_type (reader);
00392 alignment = _dbus_type_get_alignment (array_elem_type);
00393 p = _DBUS_ALIGN_ADDRESS (p, alignment);
00394 }
00395
00396 if (claimed_len > (unsigned long) (end - p))
00397 return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
00398
00399 if (current_type == DBUS_TYPE_OBJECT_PATH)
00400 {
00401 DBusString str;
00402 _dbus_string_init_const_len (&str, p, claimed_len);
00403 if (!_dbus_validate_path (&str, 0,
00404 _dbus_string_get_length (&str)))
00405 return DBUS_INVALID_BAD_PATH;
00406
00407 p += claimed_len;
00408 }
00409 else if (current_type == DBUS_TYPE_STRING)
00410 {
00411 DBusString str;
00412 _dbus_string_init_const_len (&str, p, claimed_len);
00413 if (!_dbus_string_validate_utf8 (&str, 0,
00414 _dbus_string_get_length (&str)))
00415 return DBUS_INVALID_BAD_UTF8_IN_STRING;
00416
00417 p += claimed_len;
00418 }
00419 else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
00420 {
00421 DBusTypeReader sub;
00422 DBusValidity validity;
00423 const unsigned char *array_end;
00424
00425 if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
00426 return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
00427
00428
00429
00430
00431
00432 _dbus_type_reader_recurse (reader, &sub);
00433
00434 array_end = p + claimed_len;
00435
00436 while (p < array_end)
00437 {
00438
00439
00440
00441
00442
00443 validity = validate_body_helper (&sub, byte_order, FALSE,
00444 total_depth + 1,
00445 p, end, &p);
00446 if (validity != DBUS_VALID)
00447 return validity;
00448 }
00449
00450 if (p != array_end)
00451 return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
00452 }
00453
00454
00455 if (current_type != DBUS_TYPE_ARRAY)
00456 {
00457 if (p == end)
00458 return DBUS_INVALID_NOT_ENOUGH_DATA;
00459
00460 if (*p != '\0')
00461 return DBUS_INVALID_STRING_MISSING_NUL;
00462 ++p;
00463 }
00464 }
00465 break;
00466
00467 case DBUS_TYPE_SIGNATURE:
00468 {
00469 dbus_uint32_t claimed_len;
00470 DBusString str;
00471 DBusValidity validity;
00472
00473 claimed_len = *p;
00474 ++p;
00475
00476
00477 if (claimed_len + 1 > (unsigned long) (end - p))
00478 return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00479
00480 _dbus_string_init_const_len (&str, p, claimed_len);
00481 validity =
00482 _dbus_validate_signature_with_reason (&str, 0,
00483 _dbus_string_get_length (&str));
00484
00485 if (validity != DBUS_VALID)
00486 return validity;
00487
00488 p += claimed_len;
00489
00490 _dbus_assert (p < end);
00491 if (*p != DBUS_TYPE_INVALID)
00492 return DBUS_INVALID_SIGNATURE_MISSING_NUL;
00493
00494 ++p;
00495
00496 _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
00497 }
00498 break;
00499
00500 case DBUS_TYPE_VARIANT:
00501 {
00502
00503
00504
00505
00506
00507
00508
00509 dbus_uint32_t claimed_len;
00510 DBusString sig;
00511 DBusTypeReader sub;
00512 DBusValidity validity;
00513 int contained_alignment;
00514 int contained_type;
00515 DBusValidity reason;
00516
00517 claimed_len = *p;
00518 ++p;
00519
00520
00521 if (claimed_len + 1 > (unsigned long) (end - p))
00522 return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00523
00524 _dbus_string_init_const_len (&sig, p, claimed_len);
00525 reason = _dbus_validate_signature_with_reason (&sig, 0,
00526 _dbus_string_get_length (&sig));
00527 if (!(reason == DBUS_VALID))
00528 {
00529 if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
00530 return reason;
00531 else
00532 return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
00533 }
00534
00535 p += claimed_len;
00536
00537 if (*p != DBUS_TYPE_INVALID)
00538 return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
00539 ++p;
00540
00541 contained_type = _dbus_first_type_in_signature (&sig, 0);
00542 if (contained_type == DBUS_TYPE_INVALID)
00543 return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
00544
00545 contained_alignment = _dbus_type_get_alignment (contained_type);
00546
00547 a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00548 if (a > end)
00549 return DBUS_INVALID_NOT_ENOUGH_DATA;
00550 while (p != a)
00551 {
00552 if (*p != '\0')
00553 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00554 ++p;
00555 }
00556
00557 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00558
00559 _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
00560
00561 validity = validate_body_helper (&sub, byte_order, FALSE,
00562 total_depth + 1,
00563 p, end, &p);
00564 if (validity != DBUS_VALID)
00565 return validity;
00566
00567 if (_dbus_type_reader_next (&sub))
00568 return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
00569
00570 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
00571 }
00572 break;
00573
00574 case DBUS_TYPE_DICT_ENTRY:
00575 case DBUS_TYPE_STRUCT:
00576 {
00577 DBusTypeReader sub;
00578 DBusValidity validity;
00579
00580 a = _DBUS_ALIGN_ADDRESS (p, 8);
00581 if (a > end)
00582 return DBUS_INVALID_NOT_ENOUGH_DATA;
00583 while (p != a)
00584 {
00585 if (*p != '\0')
00586 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00587 ++p;
00588 }
00589
00590 _dbus_type_reader_recurse (reader, &sub);
00591
00592 validity = validate_body_helper (&sub, byte_order, TRUE,
00593 total_depth + 1,
00594 p, end, &p);
00595 if (validity != DBUS_VALID)
00596 return validity;
00597 }
00598 break;
00599
00600 default:
00601 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00602 break;
00603 }
00604
00605 #if 0
00606 _dbus_verbose (" validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00607 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00608 (int) (end - p));
00609 #endif
00610
00611 if (p > end)
00612 {
00613 _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
00614 p, end, (int) (end - p));
00615 return DBUS_INVALID_NOT_ENOUGH_DATA;
00616 }
00617
00618 if (walk_reader_to_end)
00619 _dbus_type_reader_next (reader);
00620 else
00621 break;
00622 }
00623
00624 if (new_p)
00625 *new_p = p;
00626
00627 return DBUS_VALID;
00628 }
00629
00650 DBusValidity
00651 _dbus_validate_body_with_reason (const DBusString *expected_signature,
00652 int expected_signature_start,
00653 int byte_order,
00654 int *bytes_remaining,
00655 const DBusString *value_str,
00656 int value_pos,
00657 int len)
00658 {
00659 DBusTypeReader reader;
00660 const unsigned char *p;
00661 const unsigned char *end;
00662 DBusValidity validity;
00663
00664 _dbus_assert (len >= 0);
00665 _dbus_assert (value_pos >= 0);
00666 _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
00667
00668 _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
00669 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
00670 expected_signature_start,
00671 0));
00672
00673 _dbus_type_reader_init_types_only (&reader,
00674 expected_signature, expected_signature_start);
00675
00676 p = _dbus_string_get_const_data_len (value_str, value_pos, len);
00677 end = p + len;
00678
00679 validity = validate_body_helper (&reader, byte_order, TRUE, 0, p, end, &p);
00680 if (validity != DBUS_VALID)
00681 return validity;
00682
00683 if (bytes_remaining)
00684 {
00685 *bytes_remaining = end - p;
00686 return DBUS_VALID;
00687 }
00688 else if (p < end)
00689 return DBUS_INVALID_TOO_MUCH_DATA;
00690 else
00691 {
00692 _dbus_assert (p == end);
00693 return DBUS_VALID;
00694 }
00695 }
00696
00701 #define VALID_INITIAL_NAME_CHARACTER(c) \
00702 ( ((c) >= 'A' && (c) <= 'Z') || \
00703 ((c) >= 'a' && (c) <= 'z') || \
00704 ((c) == '_') )
00705
00710 #define VALID_NAME_CHARACTER(c) \
00711 ( ((c) >= '0' && (c) <= '9') || \
00712 ((c) >= 'A' && (c) <= 'Z') || \
00713 ((c) >= 'a' && (c) <= 'z') || \
00714 ((c) == '_') )
00715
00732 dbus_bool_t
00733 _dbus_validate_path (const DBusString *str,
00734 int start,
00735 int len)
00736 {
00737 const unsigned char *s;
00738 const unsigned char *end;
00739 const unsigned char *last_slash;
00740
00741 _dbus_assert (start >= 0);
00742 _dbus_assert (len >= 0);
00743 _dbus_assert (start <= _dbus_string_get_length (str));
00744
00745 if (len > _dbus_string_get_length (str) - start)
00746 return FALSE;
00747
00748 if (len == 0)
00749 return FALSE;
00750
00751 s = _dbus_string_get_const_data (str) + start;
00752 end = s + len;
00753
00754 if (*s != '/')
00755 return FALSE;
00756 last_slash = s;
00757 ++s;
00758
00759 while (s != end)
00760 {
00761 if (*s == '/')
00762 {
00763 if ((s - last_slash) < 2)
00764 return FALSE;
00765
00766 last_slash = s;
00767 }
00768 else
00769 {
00770 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00771 return FALSE;
00772 }
00773
00774 ++s;
00775 }
00776
00777 if ((end - last_slash) < 2 &&
00778 len > 1)
00779 return FALSE;
00780
00781 return TRUE;
00782 }
00783
00797 dbus_bool_t
00798 _dbus_validate_interface (const DBusString *str,
00799 int start,
00800 int len)
00801 {
00802 const unsigned char *s;
00803 const unsigned char *end;
00804 const unsigned char *iface;
00805 const unsigned char *last_dot;
00806
00807 _dbus_assert (start >= 0);
00808 _dbus_assert (len >= 0);
00809 _dbus_assert (start <= _dbus_string_get_length (str));
00810
00811 if (len > _dbus_string_get_length (str) - start)
00812 return FALSE;
00813
00814 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00815 return FALSE;
00816
00817 if (len == 0)
00818 return FALSE;
00819
00820 last_dot = NULL;
00821 iface = _dbus_string_get_const_data (str) + start;
00822 end = iface + len;
00823 s = iface;
00824
00825
00826
00827
00828 if (_DBUS_UNLIKELY (*s == '.'))
00829 return FALSE;
00830 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00831 return FALSE;
00832 else
00833 ++s;
00834
00835 while (s != end)
00836 {
00837 if (*s == '.')
00838 {
00839 if (_DBUS_UNLIKELY ((s + 1) == end))
00840 return FALSE;
00841 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
00842 return FALSE;
00843 last_dot = s;
00844 ++s;
00845 }
00846 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00847 {
00848 return FALSE;
00849 }
00850
00851 ++s;
00852 }
00853
00854 if (_DBUS_UNLIKELY (last_dot == NULL))
00855 return FALSE;
00856
00857 return TRUE;
00858 }
00859
00873 dbus_bool_t
00874 _dbus_validate_member (const DBusString *str,
00875 int start,
00876 int len)
00877 {
00878 const unsigned char *s;
00879 const unsigned char *end;
00880 const unsigned char *member;
00881
00882 _dbus_assert (start >= 0);
00883 _dbus_assert (len >= 0);
00884 _dbus_assert (start <= _dbus_string_get_length (str));
00885
00886 if (len > _dbus_string_get_length (str) - start)
00887 return FALSE;
00888
00889 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00890 return FALSE;
00891
00892 if (len == 0)
00893 return FALSE;
00894
00895 member = _dbus_string_get_const_data (str) + start;
00896 end = member + len;
00897 s = member;
00898
00899
00900
00901
00902
00903 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00904 return FALSE;
00905 else
00906 ++s;
00907
00908 while (s != end)
00909 {
00910 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00911 {
00912 return FALSE;
00913 }
00914
00915 ++s;
00916 }
00917
00918 return TRUE;
00919 }
00920
00934 dbus_bool_t
00935 _dbus_validate_error_name (const DBusString *str,
00936 int start,
00937 int len)
00938 {
00939
00940 return _dbus_validate_interface (str, start, len);
00941 }
00942
00947 #define VALID_INITIAL_BUS_NAME_CHARACTER(c) \
00948 ( ((c) >= 'A' && (c) <= 'Z') || \
00949 ((c) >= 'a' && (c) <= 'z') || \
00950 ((c) == '_') || ((c) == '-'))
00951
00956 #define VALID_BUS_NAME_CHARACTER(c) \
00957 ( ((c) >= '0' && (c) <= '9') || \
00958 ((c) >= 'A' && (c) <= 'Z') || \
00959 ((c) >= 'a' && (c) <= 'z') || \
00960 ((c) == '_') || ((c) == '-'))
00961
00975 dbus_bool_t
00976 _dbus_validate_bus_name (const DBusString *str,
00977 int start,
00978 int len)
00979 {
00980 const unsigned char *s;
00981 const unsigned char *end;
00982 const unsigned char *iface;
00983 const unsigned char *last_dot;
00984
00985 _dbus_assert (start >= 0);
00986 _dbus_assert (len >= 0);
00987 _dbus_assert (start <= _dbus_string_get_length (str));
00988
00989 if (len > _dbus_string_get_length (str) - start)
00990 return FALSE;
00991
00992 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00993 return FALSE;
00994
00995 if (len == 0)
00996 return FALSE;
00997
00998 last_dot = NULL;
00999 iface = _dbus_string_get_const_data (str) + start;
01000 end = iface + len;
01001 s = iface;
01002
01003
01004
01005
01006 if (*s == ':')
01007 {
01008
01009 ++s;
01010 while (s != end)
01011 {
01012 if (*s == '.')
01013 {
01014 if (_DBUS_UNLIKELY ((s + 1) == end))
01015 return FALSE;
01016 if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
01017 return FALSE;
01018 ++s;
01019 }
01020 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01021 {
01022 return FALSE;
01023 }
01024
01025 ++s;
01026 }
01027
01028 return TRUE;
01029 }
01030 else if (_DBUS_UNLIKELY (*s == '.'))
01031 return FALSE;
01032 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s)))
01033 return FALSE;
01034 else
01035 ++s;
01036
01037 while (s != end)
01038 {
01039 if (*s == '.')
01040 {
01041 if (_DBUS_UNLIKELY ((s + 1) == end))
01042 return FALSE;
01043 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
01044 return FALSE;
01045 last_dot = s;
01046 ++s;
01047 }
01048 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01049 {
01050 return FALSE;
01051 }
01052
01053 ++s;
01054 }
01055
01056 if (_DBUS_UNLIKELY (last_dot == NULL))
01057 return FALSE;
01058
01059 return TRUE;
01060 }
01061
01074 dbus_bool_t
01075 _dbus_validate_signature (const DBusString *str,
01076 int start,
01077 int len)
01078 {
01079 _dbus_assert (start >= 0);
01080 _dbus_assert (start <= _dbus_string_get_length (str));
01081 _dbus_assert (len >= 0);
01082
01083 if (len > _dbus_string_get_length (str) - start)
01084 return FALSE;
01085
01086 return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
01087 }
01088
01090 DEFINE_DBUS_NAME_CHECK(path)
01092 DEFINE_DBUS_NAME_CHECK(interface)
01094 DEFINE_DBUS_NAME_CHECK(member)
01096 DEFINE_DBUS_NAME_CHECK(error_name)
01098 DEFINE_DBUS_NAME_CHECK(bus_name)
01100 DEFINE_DBUS_NAME_CHECK(signature)
01101
01104