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
00379 if (!_dbus_type_is_valid (array_elem_type))
00380 {
00381 return DBUS_INVALID_UNKNOWN_TYPECODE;
00382 }
00383
00384 alignment = _dbus_type_get_alignment (array_elem_type);
00385
00386 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00387
00388
00389 if (a > end)
00390 return DBUS_INVALID_NOT_ENOUGH_DATA;
00391
00392 while (p != a)
00393 {
00394 if (*p != '\0')
00395 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00396 ++p;
00397 }
00398 }
00399
00400 if (claimed_len > (unsigned long) (end - p))
00401 return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
00402
00403 if (current_type == DBUS_TYPE_OBJECT_PATH)
00404 {
00405 DBusString str;
00406 _dbus_string_init_const_len (&str, p, claimed_len);
00407 if (!_dbus_validate_path (&str, 0,
00408 _dbus_string_get_length (&str)))
00409 return DBUS_INVALID_BAD_PATH;
00410
00411 p += claimed_len;
00412 }
00413 else if (current_type == DBUS_TYPE_STRING)
00414 {
00415 DBusString str;
00416 _dbus_string_init_const_len (&str, p, claimed_len);
00417 if (!_dbus_string_validate_utf8 (&str, 0,
00418 _dbus_string_get_length (&str)))
00419 return DBUS_INVALID_BAD_UTF8_IN_STRING;
00420
00421 p += claimed_len;
00422 }
00423 else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
00424 {
00425 DBusTypeReader sub;
00426 DBusValidity validity;
00427 const unsigned char *array_end;
00428 int array_elem_type;
00429
00430 if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
00431 return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
00432
00433
00434
00435
00436
00437 _dbus_type_reader_recurse (reader, &sub);
00438
00439 array_end = p + claimed_len;
00440
00441 array_elem_type = _dbus_type_reader_get_element_type (reader);
00442
00443
00444
00445
00446 if (dbus_type_is_fixed (array_elem_type))
00447 {
00448
00449
00450
00451 if (array_elem_type == DBUS_TYPE_BOOLEAN)
00452 {
00453 dbus_uint32_t v;
00454 alignment = _dbus_type_get_alignment (array_elem_type);
00455
00456 while (p < array_end)
00457 {
00458 v = _dbus_unpack_uint32 (byte_order, p);
00459
00460 if (!(v == 0 || v == 1))
00461 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00462
00463 p += alignment;
00464 }
00465 }
00466
00467 else
00468 {
00469 p = array_end;
00470 }
00471 }
00472
00473 else
00474 {
00475 while (p < array_end)
00476 {
00477 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00478 if (validity != DBUS_VALID)
00479 return validity;
00480 }
00481 }
00482
00483 if (p != array_end)
00484 return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
00485 }
00486
00487
00488 if (current_type != DBUS_TYPE_ARRAY)
00489 {
00490 if (p == end)
00491 return DBUS_INVALID_NOT_ENOUGH_DATA;
00492
00493 if (*p != '\0')
00494 return DBUS_INVALID_STRING_MISSING_NUL;
00495 ++p;
00496 }
00497 }
00498 break;
00499
00500 case DBUS_TYPE_SIGNATURE:
00501 {
00502 dbus_uint32_t claimed_len;
00503 DBusString str;
00504 DBusValidity validity;
00505
00506 claimed_len = *p;
00507 ++p;
00508
00509
00510 if (claimed_len + 1 > (unsigned long) (end - p))
00511 return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00512
00513 _dbus_string_init_const_len (&str, p, claimed_len);
00514 validity =
00515 _dbus_validate_signature_with_reason (&str, 0,
00516 _dbus_string_get_length (&str));
00517
00518 if (validity != DBUS_VALID)
00519 return validity;
00520
00521 p += claimed_len;
00522
00523 _dbus_assert (p < end);
00524 if (*p != DBUS_TYPE_INVALID)
00525 return DBUS_INVALID_SIGNATURE_MISSING_NUL;
00526
00527 ++p;
00528
00529 _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
00530 }
00531 break;
00532
00533 case DBUS_TYPE_VARIANT:
00534 {
00535
00536
00537
00538
00539
00540
00541
00542 dbus_uint32_t claimed_len;
00543 DBusString sig;
00544 DBusTypeReader sub;
00545 DBusValidity validity;
00546 int contained_alignment;
00547 int contained_type;
00548 DBusValidity reason;
00549
00550 claimed_len = *p;
00551 ++p;
00552
00553
00554 if (claimed_len + 1 > (unsigned long) (end - p))
00555 return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00556
00557 _dbus_string_init_const_len (&sig, p, claimed_len);
00558 reason = _dbus_validate_signature_with_reason (&sig, 0,
00559 _dbus_string_get_length (&sig));
00560 if (!(reason == DBUS_VALID))
00561 {
00562 if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
00563 return reason;
00564 else
00565 return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
00566 }
00567
00568 p += claimed_len;
00569
00570 if (*p != DBUS_TYPE_INVALID)
00571 return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
00572 ++p;
00573
00574 contained_type = _dbus_first_type_in_signature (&sig, 0);
00575 if (contained_type == DBUS_TYPE_INVALID)
00576 return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
00577
00578 contained_alignment = _dbus_type_get_alignment (contained_type);
00579
00580 a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
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_init_types_only (&sub, &sig, 0);
00591
00592 _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
00593
00594 validity = validate_body_helper (&sub, byte_order, FALSE, p, end, &p);
00595 if (validity != DBUS_VALID)
00596 return validity;
00597
00598 if (_dbus_type_reader_next (&sub))
00599 return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
00600
00601 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
00602 }
00603 break;
00604
00605 case DBUS_TYPE_DICT_ENTRY:
00606 case DBUS_TYPE_STRUCT:
00607 {
00608 DBusTypeReader sub;
00609 DBusValidity validity;
00610
00611 a = _DBUS_ALIGN_ADDRESS (p, 8);
00612 if (a > end)
00613 return DBUS_INVALID_NOT_ENOUGH_DATA;
00614 while (p != a)
00615 {
00616 if (*p != '\0')
00617 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00618 ++p;
00619 }
00620
00621 _dbus_type_reader_recurse (reader, &sub);
00622
00623 validity = validate_body_helper (&sub, byte_order, TRUE, p, end, &p);
00624 if (validity != DBUS_VALID)
00625 return validity;
00626 }
00627 break;
00628
00629 default:
00630 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00631 break;
00632 }
00633
00634 #if 0
00635 _dbus_verbose (" validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00636 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00637 (int) (end - p));
00638 #endif
00639
00640 if (p > end)
00641 {
00642 _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
00643 p, end, (int) (end - p));
00644 return DBUS_INVALID_NOT_ENOUGH_DATA;
00645 }
00646
00647 if (walk_reader_to_end)
00648 _dbus_type_reader_next (reader);
00649 else
00650 break;
00651 }
00652
00653 if (new_p)
00654 *new_p = p;
00655
00656 return DBUS_VALID;
00657 }
00658
00679 DBusValidity
00680 _dbus_validate_body_with_reason (const DBusString *expected_signature,
00681 int expected_signature_start,
00682 int byte_order,
00683 int *bytes_remaining,
00684 const DBusString *value_str,
00685 int value_pos,
00686 int len)
00687 {
00688 DBusTypeReader reader;
00689 const unsigned char *p;
00690 const unsigned char *end;
00691 DBusValidity validity;
00692
00693 _dbus_assert (len >= 0);
00694 _dbus_assert (value_pos >= 0);
00695 _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
00696
00697 _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
00698 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
00699 expected_signature_start,
00700 0));
00701
00702 _dbus_type_reader_init_types_only (&reader,
00703 expected_signature, expected_signature_start);
00704
00705 p = _dbus_string_get_const_data_len (value_str, value_pos, len);
00706 end = p + len;
00707
00708 validity = validate_body_helper (&reader, byte_order, TRUE, p, end, &p);
00709 if (validity != DBUS_VALID)
00710 return validity;
00711
00712 if (bytes_remaining)
00713 {
00714 *bytes_remaining = end - p;
00715 return DBUS_VALID;
00716 }
00717 else if (p < end)
00718 return DBUS_INVALID_TOO_MUCH_DATA;
00719 else
00720 {
00721 _dbus_assert (p == end);
00722 return DBUS_VALID;
00723 }
00724 }
00725
00730 #define VALID_INITIAL_NAME_CHARACTER(c) \
00731 ( ((c) >= 'A' && (c) <= 'Z') || \
00732 ((c) >= 'a' && (c) <= 'z') || \
00733 ((c) == '_') )
00734
00739 #define VALID_NAME_CHARACTER(c) \
00740 ( ((c) >= '0' && (c) <= '9') || \
00741 ((c) >= 'A' && (c) <= 'Z') || \
00742 ((c) >= 'a' && (c) <= 'z') || \
00743 ((c) == '_') )
00744
00761 dbus_bool_t
00762 _dbus_validate_path (const DBusString *str,
00763 int start,
00764 int len)
00765 {
00766 const unsigned char *s;
00767 const unsigned char *end;
00768 const unsigned char *last_slash;
00769
00770 _dbus_assert (start >= 0);
00771 _dbus_assert (len >= 0);
00772 _dbus_assert (start <= _dbus_string_get_length (str));
00773
00774 if (len > _dbus_string_get_length (str) - start)
00775 return FALSE;
00776
00777 if (len == 0)
00778 return FALSE;
00779
00780 s = _dbus_string_get_const_data (str) + start;
00781 end = s + len;
00782
00783 if (*s != '/')
00784 return FALSE;
00785 last_slash = s;
00786 ++s;
00787
00788 while (s != end)
00789 {
00790 if (*s == '/')
00791 {
00792 if ((s - last_slash) < 2)
00793 return FALSE;
00794
00795 last_slash = s;
00796 }
00797 else
00798 {
00799 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00800 return FALSE;
00801 }
00802
00803 ++s;
00804 }
00805
00806 if ((end - last_slash) < 2 &&
00807 len > 1)
00808 return FALSE;
00809
00810 return TRUE;
00811 }
00812
00813 const char *
00814 _dbus_validity_to_error_message (DBusValidity validity)
00815 {
00816 switch (validity)
00817 {
00818 case DBUS_VALIDITY_UNKNOWN_OOM_ERROR: return "Out of memory";
00819 case DBUS_INVALID_FOR_UNKNOWN_REASON: return "Unknown reason";
00820 case DBUS_VALID_BUT_INCOMPLETE: return "Valid but incomplete";
00821 case DBUS_VALIDITY_UNKNOWN: return "Validity unknown";
00822 case DBUS_VALID: return "Valid";
00823 case DBUS_INVALID_UNKNOWN_TYPECODE: return "Unknown typecode";
00824 case DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE: return "Missing array element type";
00825 case DBUS_INVALID_SIGNATURE_TOO_LONG: return "Signature is too long";
00826 case DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION: return "Exceeded maximum array recursion";
00827 case DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION: return "Exceeded maximum struct recursion";
00828 case DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED: return "Struct ended but not started";
00829 case DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED: return "Struct started but not ended";
00830 case DBUS_INVALID_STRUCT_HAS_NO_FIELDS: return "Struct has no fields";
00831 case DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL: return "Alignment padding not null";
00832 case DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE: return "Boolean is not zero or one";
00833 case DBUS_INVALID_NOT_ENOUGH_DATA: return "Not enough data";
00834 case DBUS_INVALID_TOO_MUCH_DATA: return "Too much data";
00835 case DBUS_INVALID_BAD_BYTE_ORDER: return "Bad byte order";
00836 case DBUS_INVALID_BAD_PROTOCOL_VERSION: return "Bad protocol version";
00837 case DBUS_INVALID_BAD_MESSAGE_TYPE: return "Bad message type";
00838 case DBUS_INVALID_BAD_SERIAL: return "Bad serial";
00839 case DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH: return "Insane fields array length";
00840 case DBUS_INVALID_INSANE_BODY_LENGTH: return "Insane body length";
00841 case DBUS_INVALID_MESSAGE_TOO_LONG: return "Message too long";
00842 case DBUS_INVALID_HEADER_FIELD_CODE: return "Header field code";
00843 case DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE: return "Header field has wrong type";
00844 case DBUS_INVALID_USES_LOCAL_INTERFACE: return "Uses local interface";
00845 case DBUS_INVALID_USES_LOCAL_PATH: return "Uses local path";
00846 case DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE: return "Header field appears twice";
00847 case DBUS_INVALID_BAD_DESTINATION: return "Bad destination";
00848 case DBUS_INVALID_BAD_INTERFACE: return "Bad interface";
00849 case DBUS_INVALID_BAD_MEMBER: return "Bad member";
00850 case DBUS_INVALID_BAD_ERROR_NAME: return "Bad error name";
00851 case DBUS_INVALID_BAD_SENDER: return "Bad sender";
00852 case DBUS_INVALID_MISSING_PATH: return "Missing path";
00853 case DBUS_INVALID_MISSING_INTERFACE: return "Missing interface";
00854 case DBUS_INVALID_MISSING_MEMBER: return "Missing member";
00855 case DBUS_INVALID_MISSING_ERROR_NAME: return "Missing error name";
00856 case DBUS_INVALID_MISSING_REPLY_SERIAL: return "Missing reply serial";
00857 case DBUS_INVALID_LENGTH_OUT_OF_BOUNDS: return "Length out of bounds";
00858 case DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM: return "Array length exceeds maximum";
00859 case DBUS_INVALID_BAD_PATH: return "Bad path";
00860 case DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Signature length out of bounds";
00861 case DBUS_INVALID_BAD_UTF8_IN_STRING: return "Bad utf8 in string";
00862 case DBUS_INVALID_ARRAY_LENGTH_INCORRECT: return "Array length incorrect";
00863 case DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Variant signature length out of bounds";
00864 case DBUS_INVALID_VARIANT_SIGNATURE_BAD: return "Variant signature bad";
00865 case DBUS_INVALID_VARIANT_SIGNATURE_EMPTY: return "Variant signature empty";
00866 case DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES: return "Variant signature specifies multiple values";
00867 case DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL: return "Variant signature missing nul";
00868 case DBUS_INVALID_STRING_MISSING_NUL: return "String missing nul";
00869 case DBUS_INVALID_SIGNATURE_MISSING_NUL: return "Signature missing nul";
00870 case DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION: return "Exceeded maximum dict entry recursion";
00871 case DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED: return "Dict entry ended but not started";
00872 case DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED: return "Dict entry started but not ended";
00873 case DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS: return "Dict entry has no fields";
00874 case DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD: return "Dict entry has only one field";
00875 case DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS: return "Dict entry has too many fields";
00876 case DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY: return "Dict entry not inside array";
00877 case DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE: return "Dict key must be basic type";
00878
00879 default:
00880 return "Invalid";
00881 }
00882 }
00883
00897 dbus_bool_t
00898 _dbus_validate_interface (const DBusString *str,
00899 int start,
00900 int len)
00901 {
00902 const unsigned char *s;
00903 const unsigned char *end;
00904 const unsigned char *iface;
00905 const unsigned char *last_dot;
00906
00907 _dbus_assert (start >= 0);
00908 _dbus_assert (len >= 0);
00909 _dbus_assert (start <= _dbus_string_get_length (str));
00910
00911 if (len > _dbus_string_get_length (str) - start)
00912 return FALSE;
00913
00914 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00915 return FALSE;
00916
00917 if (len == 0)
00918 return FALSE;
00919
00920 last_dot = NULL;
00921 iface = _dbus_string_get_const_data (str) + start;
00922 end = iface + len;
00923 s = iface;
00924
00925
00926
00927
00928 if (_DBUS_UNLIKELY (*s == '.'))
00929 return FALSE;
00930 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00931 return FALSE;
00932 else
00933 ++s;
00934
00935 while (s != end)
00936 {
00937 if (*s == '.')
00938 {
00939 if (_DBUS_UNLIKELY ((s + 1) == end))
00940 return FALSE;
00941 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
00942 return FALSE;
00943 last_dot = s;
00944 ++s;
00945 }
00946 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00947 {
00948 return FALSE;
00949 }
00950
00951 ++s;
00952 }
00953
00954 if (_DBUS_UNLIKELY (last_dot == NULL))
00955 return FALSE;
00956
00957 return TRUE;
00958 }
00959
00973 dbus_bool_t
00974 _dbus_validate_member (const DBusString *str,
00975 int start,
00976 int len)
00977 {
00978 const unsigned char *s;
00979 const unsigned char *end;
00980 const unsigned char *member;
00981
00982 _dbus_assert (start >= 0);
00983 _dbus_assert (len >= 0);
00984 _dbus_assert (start <= _dbus_string_get_length (str));
00985
00986 if (len > _dbus_string_get_length (str) - start)
00987 return FALSE;
00988
00989 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00990 return FALSE;
00991
00992 if (len == 0)
00993 return FALSE;
00994
00995 member = _dbus_string_get_const_data (str) + start;
00996 end = member + len;
00997 s = member;
00998
00999
01000
01001
01002
01003 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
01004 return FALSE;
01005 else
01006 ++s;
01007
01008 while (s != end)
01009 {
01010 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
01011 {
01012 return FALSE;
01013 }
01014
01015 ++s;
01016 }
01017
01018 return TRUE;
01019 }
01020
01034 dbus_bool_t
01035 _dbus_validate_error_name (const DBusString *str,
01036 int start,
01037 int len)
01038 {
01039
01040 return _dbus_validate_interface (str, start, len);
01041 }
01042
01047 #define VALID_INITIAL_BUS_NAME_CHARACTER(c) \
01048 ( ((c) >= 'A' && (c) <= 'Z') || \
01049 ((c) >= 'a' && (c) <= 'z') || \
01050 ((c) == '_') || ((c) == '-'))
01051
01056 #define VALID_BUS_NAME_CHARACTER(c) \
01057 ( ((c) >= '0' && (c) <= '9') || \
01058 ((c) >= 'A' && (c) <= 'Z') || \
01059 ((c) >= 'a' && (c) <= 'z') || \
01060 ((c) == '_') || ((c) == '-'))
01061
01075 dbus_bool_t
01076 _dbus_validate_bus_name (const DBusString *str,
01077 int start,
01078 int len)
01079 {
01080 const unsigned char *s;
01081 const unsigned char *end;
01082 const unsigned char *iface;
01083 const unsigned char *last_dot;
01084
01085 _dbus_assert (start >= 0);
01086 _dbus_assert (len >= 0);
01087 _dbus_assert (start <= _dbus_string_get_length (str));
01088
01089 if (len > _dbus_string_get_length (str) - start)
01090 return FALSE;
01091
01092 if (len > DBUS_MAXIMUM_NAME_LENGTH)
01093 return FALSE;
01094
01095 if (len == 0)
01096 return FALSE;
01097
01098 last_dot = NULL;
01099 iface = _dbus_string_get_const_data (str) + start;
01100 end = iface + len;
01101 s = iface;
01102
01103
01104
01105
01106 if (*s == ':')
01107 {
01108
01109 ++s;
01110 while (s != end)
01111 {
01112 if (*s == '.')
01113 {
01114 if (_DBUS_UNLIKELY ((s + 1) == end))
01115 return FALSE;
01116 if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
01117 return FALSE;
01118 ++s;
01119 }
01120 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01121 {
01122 return FALSE;
01123 }
01124
01125 ++s;
01126 }
01127
01128 return TRUE;
01129 }
01130 else if (_DBUS_UNLIKELY (*s == '.'))
01131 return FALSE;
01132 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s)))
01133 return FALSE;
01134 else
01135 ++s;
01136
01137 while (s != end)
01138 {
01139 if (*s == '.')
01140 {
01141 if (_DBUS_UNLIKELY ((s + 1) == end))
01142 return FALSE;
01143 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
01144 return FALSE;
01145 last_dot = s;
01146 ++s;
01147 }
01148 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01149 {
01150 return FALSE;
01151 }
01152
01153 ++s;
01154 }
01155
01156 if (_DBUS_UNLIKELY (last_dot == NULL))
01157 return FALSE;
01158
01159 return TRUE;
01160 }
01161
01174 dbus_bool_t
01175 _dbus_validate_signature (const DBusString *str,
01176 int start,
01177 int len)
01178 {
01179 _dbus_assert (start >= 0);
01180 _dbus_assert (start <= _dbus_string_get_length (str));
01181 _dbus_assert (len >= 0);
01182
01183 if (len > _dbus_string_get_length (str) - start)
01184 return FALSE;
01185
01186 return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
01187 }
01188
01190 DEFINE_DBUS_NAME_CHECK(path)
01192 DEFINE_DBUS_NAME_CHECK(interface)
01194 DEFINE_DBUS_NAME_CHECK(member)
01196 DEFINE_DBUS_NAME_CHECK(error_name)
01198 DEFINE_DBUS_NAME_CHECK(bus_name)
01200 DEFINE_DBUS_NAME_CHECK(signature)
01201
01204