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
00393 if (!_dbus_type_is_valid (array_elem_type))
00394 {
00395 return DBUS_INVALID_UNKNOWN_TYPECODE;
00396 }
00397
00398 alignment = _dbus_type_get_alignment (array_elem_type);
00399
00400 a = _DBUS_ALIGN_ADDRESS (p, alignment);
00401
00402
00403 if (a > end)
00404 return DBUS_INVALID_NOT_ENOUGH_DATA;
00405
00406 while (p != a)
00407 {
00408 if (*p != '\0')
00409 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00410 ++p;
00411 }
00412 }
00413
00414 if (claimed_len > (unsigned long) (end - p))
00415 return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
00416
00417 if (current_type == DBUS_TYPE_OBJECT_PATH)
00418 {
00419 DBusString str;
00420 _dbus_string_init_const_len (&str, p, claimed_len);
00421 if (!_dbus_validate_path (&str, 0,
00422 _dbus_string_get_length (&str)))
00423 return DBUS_INVALID_BAD_PATH;
00424
00425 p += claimed_len;
00426 }
00427 else if (current_type == DBUS_TYPE_STRING)
00428 {
00429 DBusString str;
00430 _dbus_string_init_const_len (&str, p, claimed_len);
00431 if (!_dbus_string_validate_utf8 (&str, 0,
00432 _dbus_string_get_length (&str)))
00433 return DBUS_INVALID_BAD_UTF8_IN_STRING;
00434
00435 p += claimed_len;
00436 }
00437 else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
00438 {
00439 DBusTypeReader sub;
00440 DBusValidity validity;
00441 const unsigned char *array_end;
00442 int array_elem_type;
00443
00444 if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
00445 return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
00446
00447
00448
00449
00450
00451 _dbus_type_reader_recurse (reader, &sub);
00452
00453 array_end = p + claimed_len;
00454
00455 array_elem_type = _dbus_type_reader_get_element_type (reader);
00456
00457
00458
00459
00460 if (dbus_type_is_fixed (array_elem_type))
00461 {
00462
00463
00464
00465 if (array_elem_type == DBUS_TYPE_BOOLEAN)
00466 {
00467 dbus_uint32_t v;
00468 alignment = _dbus_type_get_alignment (array_elem_type);
00469
00470 while (p < array_end)
00471 {
00472 v = _dbus_unpack_uint32 (byte_order, p);
00473
00474 if (!(v == 0 || v == 1))
00475 return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
00476
00477 p += alignment;
00478 }
00479 }
00480
00481 else
00482 {
00483 p = array_end;
00484 }
00485 }
00486
00487 else
00488 {
00489 while (p < array_end)
00490 {
00491 validity = validate_body_helper (&sub, byte_order, FALSE,
00492 total_depth + 1,
00493 p, end, &p);
00494 if (validity != DBUS_VALID)
00495 return validity;
00496 }
00497 }
00498
00499 if (p != array_end)
00500 return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
00501 }
00502
00503
00504 if (current_type != DBUS_TYPE_ARRAY)
00505 {
00506 if (p == end)
00507 return DBUS_INVALID_NOT_ENOUGH_DATA;
00508
00509 if (*p != '\0')
00510 return DBUS_INVALID_STRING_MISSING_NUL;
00511 ++p;
00512 }
00513 }
00514 break;
00515
00516 case DBUS_TYPE_SIGNATURE:
00517 {
00518 dbus_uint32_t claimed_len;
00519 DBusString str;
00520 DBusValidity validity;
00521
00522 claimed_len = *p;
00523 ++p;
00524
00525
00526 if (claimed_len + 1 > (unsigned long) (end - p))
00527 return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00528
00529 _dbus_string_init_const_len (&str, p, claimed_len);
00530 validity =
00531 _dbus_validate_signature_with_reason (&str, 0,
00532 _dbus_string_get_length (&str));
00533
00534 if (validity != DBUS_VALID)
00535 return validity;
00536
00537 p += claimed_len;
00538
00539 _dbus_assert (p < end);
00540 if (*p != DBUS_TYPE_INVALID)
00541 return DBUS_INVALID_SIGNATURE_MISSING_NUL;
00542
00543 ++p;
00544
00545 _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
00546 }
00547 break;
00548
00549 case DBUS_TYPE_VARIANT:
00550 {
00551
00552
00553
00554
00555
00556
00557
00558 dbus_uint32_t claimed_len;
00559 DBusString sig;
00560 DBusTypeReader sub;
00561 DBusValidity validity;
00562 int contained_alignment;
00563 int contained_type;
00564 DBusValidity reason;
00565
00566 claimed_len = *p;
00567 ++p;
00568
00569
00570 if (claimed_len + 1 > (unsigned long) (end - p))
00571 return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
00572
00573 _dbus_string_init_const_len (&sig, p, claimed_len);
00574 reason = _dbus_validate_signature_with_reason (&sig, 0,
00575 _dbus_string_get_length (&sig));
00576 if (!(reason == DBUS_VALID))
00577 {
00578 if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
00579 return reason;
00580 else
00581 return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
00582 }
00583
00584 p += claimed_len;
00585
00586 if (*p != DBUS_TYPE_INVALID)
00587 return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
00588 ++p;
00589
00590 contained_type = _dbus_first_type_in_signature (&sig, 0);
00591 if (contained_type == DBUS_TYPE_INVALID)
00592 return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
00593
00594 contained_alignment = _dbus_type_get_alignment (contained_type);
00595
00596 a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
00597 if (a > end)
00598 return DBUS_INVALID_NOT_ENOUGH_DATA;
00599 while (p != a)
00600 {
00601 if (*p != '\0')
00602 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00603 ++p;
00604 }
00605
00606 _dbus_type_reader_init_types_only (&sub, &sig, 0);
00607
00608 _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
00609
00610 validity = validate_body_helper (&sub, byte_order, FALSE,
00611 total_depth + 1,
00612 p, end, &p);
00613 if (validity != DBUS_VALID)
00614 return validity;
00615
00616 if (_dbus_type_reader_next (&sub))
00617 return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
00618
00619 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
00620 }
00621 break;
00622
00623 case DBUS_TYPE_DICT_ENTRY:
00624 case DBUS_TYPE_STRUCT:
00625 {
00626 DBusTypeReader sub;
00627 DBusValidity validity;
00628
00629 a = _DBUS_ALIGN_ADDRESS (p, 8);
00630 if (a > end)
00631 return DBUS_INVALID_NOT_ENOUGH_DATA;
00632 while (p != a)
00633 {
00634 if (*p != '\0')
00635 return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
00636 ++p;
00637 }
00638
00639 _dbus_type_reader_recurse (reader, &sub);
00640
00641 validity = validate_body_helper (&sub, byte_order, TRUE,
00642 total_depth + 1,
00643 p, end, &p);
00644 if (validity != DBUS_VALID)
00645 return validity;
00646 }
00647 break;
00648
00649 default:
00650 _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
00651 break;
00652 }
00653
00654 #if 0
00655 _dbus_verbose (" validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
00656 _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
00657 (int) (end - p));
00658 #endif
00659
00660 if (p > end)
00661 {
00662 _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
00663 p, end, (int) (end - p));
00664 return DBUS_INVALID_NOT_ENOUGH_DATA;
00665 }
00666
00667 if (walk_reader_to_end)
00668 _dbus_type_reader_next (reader);
00669 else
00670 break;
00671 }
00672
00673 if (new_p)
00674 *new_p = p;
00675
00676 return DBUS_VALID;
00677 }
00678
00699 DBusValidity
00700 _dbus_validate_body_with_reason (const DBusString *expected_signature,
00701 int expected_signature_start,
00702 int byte_order,
00703 int *bytes_remaining,
00704 const DBusString *value_str,
00705 int value_pos,
00706 int len)
00707 {
00708 DBusTypeReader reader;
00709 const unsigned char *p;
00710 const unsigned char *end;
00711 DBusValidity validity;
00712
00713 _dbus_assert (len >= 0);
00714 _dbus_assert (value_pos >= 0);
00715 _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
00716
00717 _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
00718 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
00719 expected_signature_start,
00720 0));
00721
00722 _dbus_type_reader_init_types_only (&reader,
00723 expected_signature, expected_signature_start);
00724
00725 p = _dbus_string_get_const_data_len (value_str, value_pos, len);
00726 end = p + len;
00727
00728 validity = validate_body_helper (&reader, byte_order, TRUE, 0, p, end, &p);
00729 if (validity != DBUS_VALID)
00730 return validity;
00731
00732 if (bytes_remaining)
00733 {
00734 *bytes_remaining = end - p;
00735 return DBUS_VALID;
00736 }
00737 else if (p < end)
00738 return DBUS_INVALID_TOO_MUCH_DATA;
00739 else
00740 {
00741 _dbus_assert (p == end);
00742 return DBUS_VALID;
00743 }
00744 }
00745
00750 #define VALID_INITIAL_NAME_CHARACTER(c) \
00751 ( ((c) >= 'A' && (c) <= 'Z') || \
00752 ((c) >= 'a' && (c) <= 'z') || \
00753 ((c) == '_') )
00754
00759 #define VALID_NAME_CHARACTER(c) \
00760 ( ((c) >= '0' && (c) <= '9') || \
00761 ((c) >= 'A' && (c) <= 'Z') || \
00762 ((c) >= 'a' && (c) <= 'z') || \
00763 ((c) == '_') )
00764
00781 dbus_bool_t
00782 _dbus_validate_path (const DBusString *str,
00783 int start,
00784 int len)
00785 {
00786 const unsigned char *s;
00787 const unsigned char *end;
00788 const unsigned char *last_slash;
00789
00790 _dbus_assert (start >= 0);
00791 _dbus_assert (len >= 0);
00792 _dbus_assert (start <= _dbus_string_get_length (str));
00793
00794 if (len > _dbus_string_get_length (str) - start)
00795 return FALSE;
00796
00797 if (len == 0)
00798 return FALSE;
00799
00800 s = _dbus_string_get_const_data (str) + start;
00801 end = s + len;
00802
00803 if (*s != '/')
00804 return FALSE;
00805 last_slash = s;
00806 ++s;
00807
00808 while (s != end)
00809 {
00810 if (*s == '/')
00811 {
00812 if ((s - last_slash) < 2)
00813 return FALSE;
00814
00815 last_slash = s;
00816 }
00817 else
00818 {
00819 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00820 return FALSE;
00821 }
00822
00823 ++s;
00824 }
00825
00826 if ((end - last_slash) < 2 &&
00827 len > 1)
00828 return FALSE;
00829
00830 return TRUE;
00831 }
00832
00833 const char *
00834 _dbus_validity_to_error_message (DBusValidity validity)
00835 {
00836 switch (validity)
00837 {
00838 case DBUS_VALIDITY_UNKNOWN_OOM_ERROR: return "Out of memory";
00839 case DBUS_INVALID_FOR_UNKNOWN_REASON: return "Unknown reason";
00840 case DBUS_VALID_BUT_INCOMPLETE: return "Valid but incomplete";
00841 case DBUS_VALIDITY_UNKNOWN: return "Validity unknown";
00842 case DBUS_VALID: return "Valid";
00843 case DBUS_INVALID_UNKNOWN_TYPECODE: return "Unknown typecode";
00844 case DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE: return "Missing array element type";
00845 case DBUS_INVALID_SIGNATURE_TOO_LONG: return "Signature is too long";
00846 case DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION: return "Exceeded maximum array recursion";
00847 case DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION: return "Exceeded maximum struct recursion";
00848 case DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED: return "Struct ended but not started";
00849 case DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED: return "Struct started but not ended";
00850 case DBUS_INVALID_STRUCT_HAS_NO_FIELDS: return "Struct has no fields";
00851 case DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL: return "Alignment padding not null";
00852 case DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE: return "Boolean is not zero or one";
00853 case DBUS_INVALID_NOT_ENOUGH_DATA: return "Not enough data";
00854 case DBUS_INVALID_TOO_MUCH_DATA: return "Too much data";
00855 case DBUS_INVALID_BAD_BYTE_ORDER: return "Bad byte order";
00856 case DBUS_INVALID_BAD_PROTOCOL_VERSION: return "Bad protocol version";
00857 case DBUS_INVALID_BAD_MESSAGE_TYPE: return "Bad message type";
00858 case DBUS_INVALID_BAD_SERIAL: return "Bad serial";
00859 case DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH: return "Insane fields array length";
00860 case DBUS_INVALID_INSANE_BODY_LENGTH: return "Insane body length";
00861 case DBUS_INVALID_MESSAGE_TOO_LONG: return "Message too long";
00862 case DBUS_INVALID_HEADER_FIELD_CODE: return "Header field code";
00863 case DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE: return "Header field has wrong type";
00864 case DBUS_INVALID_USES_LOCAL_INTERFACE: return "Uses local interface";
00865 case DBUS_INVALID_USES_LOCAL_PATH: return "Uses local path";
00866 case DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE: return "Header field appears twice";
00867 case DBUS_INVALID_BAD_DESTINATION: return "Bad destination";
00868 case DBUS_INVALID_BAD_INTERFACE: return "Bad interface";
00869 case DBUS_INVALID_BAD_MEMBER: return "Bad member";
00870 case DBUS_INVALID_BAD_ERROR_NAME: return "Bad error name";
00871 case DBUS_INVALID_BAD_SENDER: return "Bad sender";
00872 case DBUS_INVALID_MISSING_PATH: return "Missing path";
00873 case DBUS_INVALID_MISSING_INTERFACE: return "Missing interface";
00874 case DBUS_INVALID_MISSING_MEMBER: return "Missing member";
00875 case DBUS_INVALID_MISSING_ERROR_NAME: return "Missing error name";
00876 case DBUS_INVALID_MISSING_REPLY_SERIAL: return "Missing reply serial";
00877 case DBUS_INVALID_LENGTH_OUT_OF_BOUNDS: return "Length out of bounds";
00878 case DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM: return "Array length exceeds maximum";
00879 case DBUS_INVALID_BAD_PATH: return "Bad path";
00880 case DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Signature length out of bounds";
00881 case DBUS_INVALID_BAD_UTF8_IN_STRING: return "Bad utf8 in string";
00882 case DBUS_INVALID_ARRAY_LENGTH_INCORRECT: return "Array length incorrect";
00883 case DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS: return "Variant signature length out of bounds";
00884 case DBUS_INVALID_VARIANT_SIGNATURE_BAD: return "Variant signature bad";
00885 case DBUS_INVALID_VARIANT_SIGNATURE_EMPTY: return "Variant signature empty";
00886 case DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES: return "Variant signature specifies multiple values";
00887 case DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL: return "Variant signature missing nul";
00888 case DBUS_INVALID_STRING_MISSING_NUL: return "String missing nul";
00889 case DBUS_INVALID_SIGNATURE_MISSING_NUL: return "Signature missing nul";
00890 case DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION: return "Exceeded maximum dict entry recursion";
00891 case DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED: return "Dict entry ended but not started";
00892 case DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED: return "Dict entry started but not ended";
00893 case DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS: return "Dict entry has no fields";
00894 case DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD: return "Dict entry has only one field";
00895 case DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS: return "Dict entry has too many fields";
00896 case DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY: return "Dict entry not inside array";
00897 case DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE: return "Dict key must be basic type";
00898 case DBUS_INVALID_NESTED_TOO_DEEPLY: return "Variants cannot be used to create a hugely recursive tree of values";
00899 default:
00900 return "Invalid";
00901 }
00902 }
00903
00917 dbus_bool_t
00918 _dbus_validate_interface (const DBusString *str,
00919 int start,
00920 int len)
00921 {
00922 const unsigned char *s;
00923 const unsigned char *end;
00924 const unsigned char *iface;
00925 const unsigned char *last_dot;
00926
00927 _dbus_assert (start >= 0);
00928 _dbus_assert (len >= 0);
00929 _dbus_assert (start <= _dbus_string_get_length (str));
00930
00931 if (len > _dbus_string_get_length (str) - start)
00932 return FALSE;
00933
00934 if (len > DBUS_MAXIMUM_NAME_LENGTH)
00935 return FALSE;
00936
00937 if (len == 0)
00938 return FALSE;
00939
00940 last_dot = NULL;
00941 iface = _dbus_string_get_const_data (str) + start;
00942 end = iface + len;
00943 s = iface;
00944
00945
00946
00947
00948 if (_DBUS_UNLIKELY (*s == '.'))
00949 return FALSE;
00950 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
00951 return FALSE;
00952 else
00953 ++s;
00954
00955 while (s != end)
00956 {
00957 if (*s == '.')
00958 {
00959 if (_DBUS_UNLIKELY ((s + 1) == end))
00960 return FALSE;
00961 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
00962 return FALSE;
00963 last_dot = s;
00964 ++s;
00965 }
00966 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
00967 {
00968 return FALSE;
00969 }
00970
00971 ++s;
00972 }
00973
00974 if (_DBUS_UNLIKELY (last_dot == NULL))
00975 return FALSE;
00976
00977 return TRUE;
00978 }
00979
00993 dbus_bool_t
00994 _dbus_validate_member (const DBusString *str,
00995 int start,
00996 int len)
00997 {
00998 const unsigned char *s;
00999 const unsigned char *end;
01000 const unsigned char *member;
01001
01002 _dbus_assert (start >= 0);
01003 _dbus_assert (len >= 0);
01004 _dbus_assert (start <= _dbus_string_get_length (str));
01005
01006 if (len > _dbus_string_get_length (str) - start)
01007 return FALSE;
01008
01009 if (len > DBUS_MAXIMUM_NAME_LENGTH)
01010 return FALSE;
01011
01012 if (len == 0)
01013 return FALSE;
01014
01015 member = _dbus_string_get_const_data (str) + start;
01016 end = member + len;
01017 s = member;
01018
01019
01020
01021
01022
01023 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
01024 return FALSE;
01025 else
01026 ++s;
01027
01028 while (s != end)
01029 {
01030 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
01031 {
01032 return FALSE;
01033 }
01034
01035 ++s;
01036 }
01037
01038 return TRUE;
01039 }
01040
01054 dbus_bool_t
01055 _dbus_validate_error_name (const DBusString *str,
01056 int start,
01057 int len)
01058 {
01059
01060 return _dbus_validate_interface (str, start, len);
01061 }
01062
01067 #define VALID_INITIAL_BUS_NAME_CHARACTER(c) \
01068 ( ((c) >= 'A' && (c) <= 'Z') || \
01069 ((c) >= 'a' && (c) <= 'z') || \
01070 ((c) == '_') || ((c) == '-'))
01071
01076 #define VALID_BUS_NAME_CHARACTER(c) \
01077 ( ((c) >= '0' && (c) <= '9') || \
01078 ((c) >= 'A' && (c) <= 'Z') || \
01079 ((c) >= 'a' && (c) <= 'z') || \
01080 ((c) == '_') || ((c) == '-'))
01081
01095 dbus_bool_t
01096 _dbus_validate_bus_name (const DBusString *str,
01097 int start,
01098 int len)
01099 {
01100 const unsigned char *s;
01101 const unsigned char *end;
01102 const unsigned char *iface;
01103 const unsigned char *last_dot;
01104
01105 _dbus_assert (start >= 0);
01106 _dbus_assert (len >= 0);
01107 _dbus_assert (start <= _dbus_string_get_length (str));
01108
01109 if (len > _dbus_string_get_length (str) - start)
01110 return FALSE;
01111
01112 if (len > DBUS_MAXIMUM_NAME_LENGTH)
01113 return FALSE;
01114
01115 if (len == 0)
01116 return FALSE;
01117
01118 last_dot = NULL;
01119 iface = _dbus_string_get_const_data (str) + start;
01120 end = iface + len;
01121 s = iface;
01122
01123
01124
01125
01126 if (*s == ':')
01127 {
01128
01129 ++s;
01130 while (s != end)
01131 {
01132 if (*s == '.')
01133 {
01134 if (_DBUS_UNLIKELY ((s + 1) == end))
01135 return FALSE;
01136 if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
01137 return FALSE;
01138 ++s;
01139 }
01140 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01141 {
01142 return FALSE;
01143 }
01144
01145 ++s;
01146 }
01147
01148 return TRUE;
01149 }
01150 else if (_DBUS_UNLIKELY (*s == '.'))
01151 return FALSE;
01152 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s)))
01153 return FALSE;
01154 else
01155 ++s;
01156
01157 while (s != end)
01158 {
01159 if (*s == '.')
01160 {
01161 if (_DBUS_UNLIKELY ((s + 1) == end))
01162 return FALSE;
01163 else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
01164 return FALSE;
01165 last_dot = s;
01166 ++s;
01167 }
01168 else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
01169 {
01170 return FALSE;
01171 }
01172
01173 ++s;
01174 }
01175
01176 if (_DBUS_UNLIKELY (last_dot == NULL))
01177 return FALSE;
01178
01179 return TRUE;
01180 }
01181
01194 dbus_bool_t
01195 _dbus_validate_signature (const DBusString *str,
01196 int start,
01197 int len)
01198 {
01199 _dbus_assert (start >= 0);
01200 _dbus_assert (start <= _dbus_string_get_length (str));
01201 _dbus_assert (len >= 0);
01202
01203 if (len > _dbus_string_get_length (str) - start)
01204 return FALSE;
01205
01206 return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
01207 }
01208
01210 DEFINE_DBUS_NAME_CHECK(path)
01212 DEFINE_DBUS_NAME_CHECK(interface)
01214 DEFINE_DBUS_NAME_CHECK(member)
01216 DEFINE_DBUS_NAME_CHECK(error_name)
01218 DEFINE_DBUS_NAME_CHECK(bus_name)
01220 DEFINE_DBUS_NAME_CHECK(signature)
01221
01224