D-Bus 1.6.12
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-signature.c Routines for reading recursive type signatures 00003 * 00004 * Copyright (C) 2005 Red Hat, Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 */ 00023 00024 #include <config.h> 00025 00026 #include "dbus-signature.h" 00027 #include "dbus-marshal-recursive.h" 00028 #include "dbus-marshal-basic.h" 00029 #include "dbus-internals.h" 00030 #include "dbus-test.h" 00031 00035 typedef struct 00036 { 00037 const char *pos; 00038 unsigned int finished : 1; 00039 unsigned int in_array : 1; 00040 } DBusSignatureRealIter; 00041 00043 #define TYPE_IS_CONTAINER(typecode) \ 00044 ((typecode) == DBUS_TYPE_STRUCT || \ 00045 (typecode) == DBUS_TYPE_DICT_ENTRY || \ 00046 (typecode) == DBUS_TYPE_VARIANT || \ 00047 (typecode) == DBUS_TYPE_ARRAY) 00048 00049 00066 void 00067 dbus_signature_iter_init (DBusSignatureIter *iter, 00068 const char *signature) 00069 { 00070 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00071 00072 real_iter->pos = signature; 00073 real_iter->finished = FALSE; 00074 real_iter->in_array = FALSE; 00075 } 00076 00091 int 00092 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter) 00093 { 00094 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00095 00096 return _dbus_first_type_in_signature_c_str (real_iter->pos, 0); 00097 } 00098 00111 char * 00112 dbus_signature_iter_get_signature (const DBusSignatureIter *iter) 00113 { 00114 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00115 DBusString str; 00116 char *ret; 00117 int pos; 00118 00119 if (!_dbus_string_init (&str)) 00120 return NULL; 00121 00122 pos = 0; 00123 _dbus_type_signature_next (real_iter->pos, &pos); 00124 00125 if (!_dbus_string_append_len (&str, real_iter->pos, pos)) 00126 return NULL; 00127 if (!_dbus_string_steal_data (&str, &ret)) 00128 ret = NULL; 00129 _dbus_string_free (&str); 00130 00131 return ret; 00132 } 00133 00145 int 00146 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter) 00147 { 00148 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00149 00150 _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID); 00151 00152 return _dbus_first_type_in_signature_c_str (real_iter->pos, 1); 00153 } 00154 00163 dbus_bool_t 00164 dbus_signature_iter_next (DBusSignatureIter *iter) 00165 { 00166 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00167 00168 if (real_iter->finished) 00169 return FALSE; 00170 else 00171 { 00172 int pos; 00173 00174 if (real_iter->in_array) 00175 { 00176 real_iter->finished = TRUE; 00177 return FALSE; 00178 } 00179 00180 pos = 0; 00181 _dbus_type_signature_next (real_iter->pos, &pos); 00182 real_iter->pos += pos; 00183 00184 if (*real_iter->pos == DBUS_STRUCT_END_CHAR 00185 || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR) 00186 { 00187 real_iter->finished = TRUE; 00188 return FALSE; 00189 } 00190 00191 return *real_iter->pos != DBUS_TYPE_INVALID; 00192 } 00193 } 00194 00206 void 00207 dbus_signature_iter_recurse (const DBusSignatureIter *iter, 00208 DBusSignatureIter *subiter) 00209 { 00210 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00211 DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter; 00212 00213 _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter))); 00214 00215 *real_sub_iter = *real_iter; 00216 real_sub_iter->in_array = FALSE; 00217 real_sub_iter->pos++; 00218 00219 if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY) 00220 real_sub_iter->in_array = TRUE; 00221 } 00222 00232 dbus_bool_t 00233 dbus_signature_validate (const char *signature, 00234 DBusError *error) 00235 00236 { 00237 DBusString str; 00238 DBusValidity reason; 00239 00240 _dbus_string_init_const (&str, signature); 00241 reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str)); 00242 00243 if (reason == DBUS_VALID) 00244 return TRUE; 00245 else 00246 { 00247 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason)); 00248 return FALSE; 00249 } 00250 } 00251 00263 dbus_bool_t 00264 dbus_signature_validate_single (const char *signature, 00265 DBusError *error) 00266 { 00267 DBusSignatureIter iter; 00268 00269 if (!dbus_signature_validate (signature, error)) 00270 return FALSE; 00271 00272 dbus_signature_iter_init (&iter, signature); 00273 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID) 00274 goto lose; 00275 if (!dbus_signature_iter_next (&iter)) 00276 return TRUE; 00277 lose: 00278 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature"); 00279 return FALSE; 00280 } 00281 00293 dbus_bool_t 00294 dbus_type_is_container (int typecode) 00295 { 00296 /* only reasonable (non-line-noise) typecodes are allowed */ 00297 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00298 FALSE); 00299 return TYPE_IS_CONTAINER (typecode); 00300 } 00301 00317 dbus_bool_t 00318 dbus_type_is_basic (int typecode) 00319 { 00320 /* only reasonable (non-line-noise) typecodes are allowed */ 00321 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00322 FALSE); 00323 00324 /* everything that isn't invalid or a container */ 00325 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode)); 00326 } 00327 00348 dbus_bool_t 00349 dbus_type_is_fixed (int typecode) 00350 { 00351 /* only reasonable (non-line-noise) typecodes are allowed */ 00352 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00353 FALSE); 00354 00355 switch (typecode) 00356 { 00357 case DBUS_TYPE_BYTE: 00358 case DBUS_TYPE_BOOLEAN: 00359 case DBUS_TYPE_INT16: 00360 case DBUS_TYPE_UINT16: 00361 case DBUS_TYPE_INT32: 00362 case DBUS_TYPE_UINT32: 00363 case DBUS_TYPE_INT64: 00364 case DBUS_TYPE_UINT64: 00365 case DBUS_TYPE_DOUBLE: 00366 case DBUS_TYPE_UNIX_FD: 00367 return TRUE; 00368 default: 00369 return FALSE; 00370 } 00371 } 00372 00382 dbus_bool_t 00383 dbus_type_is_valid (int typecode) 00384 { 00385 switch (typecode) 00386 { 00387 case DBUS_TYPE_BYTE: 00388 case DBUS_TYPE_BOOLEAN: 00389 case DBUS_TYPE_INT16: 00390 case DBUS_TYPE_UINT16: 00391 case DBUS_TYPE_INT32: 00392 case DBUS_TYPE_UINT32: 00393 case DBUS_TYPE_INT64: 00394 case DBUS_TYPE_UINT64: 00395 case DBUS_TYPE_DOUBLE: 00396 case DBUS_TYPE_STRING: 00397 case DBUS_TYPE_OBJECT_PATH: 00398 case DBUS_TYPE_SIGNATURE: 00399 case DBUS_TYPE_ARRAY: 00400 case DBUS_TYPE_STRUCT: 00401 case DBUS_TYPE_DICT_ENTRY: 00402 case DBUS_TYPE_VARIANT: 00403 case DBUS_TYPE_UNIX_FD: 00404 return TRUE; 00405 00406 default: 00407 return FALSE; 00408 } 00409 } 00410 /* end of DBusSignature group */ 00412 00413 #ifdef DBUS_BUILD_TESTS 00414 00421 dbus_bool_t 00422 _dbus_signature_test (void) 00423 { 00424 DBusSignatureIter iter; 00425 DBusSignatureIter subiter; 00426 DBusSignatureIter subsubiter; 00427 DBusSignatureIter subsubsubiter; 00428 const char *sig; 00429 dbus_bool_t boolres; 00430 00431 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter)); 00432 00433 sig = ""; 00434 _dbus_assert (dbus_signature_validate (sig, NULL)); 00435 _dbus_assert (!dbus_signature_validate_single (sig, NULL)); 00436 dbus_signature_iter_init (&iter, sig); 00437 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID); 00438 00439 sig = DBUS_TYPE_STRING_AS_STRING; 00440 _dbus_assert (dbus_signature_validate (sig, NULL)); 00441 _dbus_assert (dbus_signature_validate_single (sig, NULL)); 00442 dbus_signature_iter_init (&iter, sig); 00443 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); 00444 00445 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING; 00446 _dbus_assert (dbus_signature_validate (sig, NULL)); 00447 dbus_signature_iter_init (&iter, sig); 00448 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); 00449 boolres = dbus_signature_iter_next (&iter); 00450 _dbus_assert (boolres); 00451 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE); 00452 00453 sig = DBUS_TYPE_UINT16_AS_STRING 00454 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00455 DBUS_TYPE_STRING_AS_STRING 00456 DBUS_TYPE_UINT32_AS_STRING 00457 DBUS_TYPE_VARIANT_AS_STRING 00458 DBUS_TYPE_DOUBLE_AS_STRING 00459 DBUS_STRUCT_END_CHAR_AS_STRING; 00460 _dbus_assert (dbus_signature_validate (sig, NULL)); 00461 dbus_signature_iter_init (&iter, sig); 00462 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 00463 boolres = dbus_signature_iter_next (&iter); 00464 _dbus_assert (boolres); 00465 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 00466 dbus_signature_iter_recurse (&iter, &subiter); 00467 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING); 00468 boolres = dbus_signature_iter_next (&subiter); 00469 _dbus_assert (boolres); 00470 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 00471 boolres = dbus_signature_iter_next (&subiter); 00472 _dbus_assert (boolres); 00473 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT); 00474 boolres = dbus_signature_iter_next (&subiter); 00475 _dbus_assert (boolres); 00476 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE); 00477 00478 sig = DBUS_TYPE_UINT16_AS_STRING 00479 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00480 DBUS_TYPE_UINT32_AS_STRING 00481 DBUS_TYPE_BYTE_AS_STRING 00482 DBUS_TYPE_ARRAY_AS_STRING 00483 DBUS_TYPE_ARRAY_AS_STRING 00484 DBUS_TYPE_DOUBLE_AS_STRING 00485 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00486 DBUS_TYPE_BYTE_AS_STRING 00487 DBUS_STRUCT_END_CHAR_AS_STRING 00488 DBUS_STRUCT_END_CHAR_AS_STRING; 00489 _dbus_assert (dbus_signature_validate (sig, NULL)); 00490 dbus_signature_iter_init (&iter, sig); 00491 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 00492 boolres = dbus_signature_iter_next (&iter); 00493 _dbus_assert (boolres); 00494 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 00495 dbus_signature_iter_recurse (&iter, &subiter); 00496 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 00497 boolres = dbus_signature_iter_next (&subiter); 00498 _dbus_assert (boolres); 00499 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE); 00500 boolres = dbus_signature_iter_next (&subiter); 00501 _dbus_assert (boolres); 00502 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY); 00503 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY); 00504 00505 dbus_signature_iter_recurse (&subiter, &subsubiter); 00506 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY); 00507 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE); 00508 00509 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter); 00510 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE); 00511 boolres = dbus_signature_iter_next (&subiter); 00512 _dbus_assert (boolres); 00513 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT); 00514 dbus_signature_iter_recurse (&subiter, &subsubiter); 00515 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE); 00516 00517 sig = DBUS_TYPE_ARRAY_AS_STRING 00518 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00519 DBUS_TYPE_INT16_AS_STRING 00520 DBUS_TYPE_STRING_AS_STRING 00521 DBUS_DICT_ENTRY_END_CHAR_AS_STRING 00522 DBUS_TYPE_VARIANT_AS_STRING; 00523 _dbus_assert (dbus_signature_validate (sig, NULL)); 00524 _dbus_assert (!dbus_signature_validate_single (sig, NULL)); 00525 dbus_signature_iter_init (&iter, sig); 00526 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY); 00527 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY); 00528 00529 dbus_signature_iter_recurse (&iter, &subiter); 00530 dbus_signature_iter_recurse (&subiter, &subsubiter); 00531 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16); 00532 boolres = dbus_signature_iter_next (&subsubiter); 00533 _dbus_assert (boolres); 00534 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING); 00535 boolres = dbus_signature_iter_next (&subsubiter); 00536 _dbus_assert (!boolres); 00537 00538 boolres = dbus_signature_iter_next (&iter); 00539 _dbus_assert (boolres); 00540 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT); 00541 boolres = dbus_signature_iter_next (&iter); 00542 _dbus_assert (!boolres); 00543 00544 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING; 00545 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00546 00547 sig = DBUS_TYPE_ARRAY_AS_STRING; 00548 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00549 00550 sig = DBUS_TYPE_UINT32_AS_STRING 00551 DBUS_TYPE_ARRAY_AS_STRING; 00552 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00553 00554 sig = DBUS_TYPE_ARRAY_AS_STRING 00555 DBUS_TYPE_DICT_ENTRY_AS_STRING; 00556 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00557 00558 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; 00559 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00560 00561 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING; 00562 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00563 00564 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00565 DBUS_TYPE_INT32_AS_STRING; 00566 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00567 00568 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00569 DBUS_TYPE_INT32_AS_STRING 00570 DBUS_TYPE_STRING_AS_STRING; 00571 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00572 00573 sig = DBUS_STRUCT_END_CHAR_AS_STRING 00574 DBUS_STRUCT_BEGIN_CHAR_AS_STRING; 00575 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00576 00577 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00578 DBUS_TYPE_BOOLEAN_AS_STRING; 00579 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00580 return TRUE; 00581 #if 0 00582 oom: 00583 _dbus_assert_not_reached ("out of memory"); 00584 return FALSE; 00585 #endif 00586 } 00587 00588 #endif 00589