1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-signature.c Routines for reading recursive type signatures 3 * 4 * Copyright (C) 2005 Red Hat, Inc. 5 * 6 * Licensed under the Academic Free License version 2.1 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #include <config.h> 25 26 #include "dbus-signature.h" 27 #include "dbus-marshal-recursive.h" 28 #include "dbus-marshal-basic.h" 29 #include "dbus-internals.h" 30 #include "dbus-test.h" 31 32 /** 33 * Implementation details of #DBusSignatureIter, all fields are private 34 */ 35 typedef struct 36 { 37 const char *pos; /**< current position in the signature string */ 38 unsigned int finished : 1; /**< true if we are at the end iter */ 39 unsigned int in_array : 1; /**< true if we are a subiterator pointing to an array's element type */ 40 } DBusSignatureRealIter; 41 42 /** macro that checks whether a typecode is a container type */ 43 #define TYPE_IS_CONTAINER(typecode) \ 44 ((typecode) == DBUS_TYPE_STRUCT || \ 45 (typecode) == DBUS_TYPE_DICT_ENTRY || \ 46 (typecode) == DBUS_TYPE_VARIANT || \ 47 (typecode) == DBUS_TYPE_ARRAY) 48 49 50 /** 51 * @defgroup DBusSignature Type signature parsing 52 * @ingroup DBus 53 * @brief Parsing D-Bus type signatures 54 * @{ 55 */ 56 57 /** 58 * Initializes a #DBusSignatureIter for reading a type signature. This 59 * function is not safe to use on invalid signatures; be sure to 60 * validate potentially invalid signatures with dbus_signature_validate 61 * before using this function. 62 * 63 * @param iter pointer to an iterator to initialize 64 * @param signature the type signature 65 */ 66 void 67 dbus_signature_iter_init (DBusSignatureIter *iter, 68 const char *signature) 69 { 70 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 71 72 real_iter->pos = signature; 73 real_iter->finished = FALSE; 74 real_iter->in_array = FALSE; 75 } 76 77 /** 78 * Returns the current type pointed to by the iterator. 79 * If the iterator is pointing at a type code such as 's', then 80 * it will be returned directly. 81 * 82 * However, when the parser encounters a container type start 83 * character such as '(' for a structure, the corresponding type for 84 * the container will be returned, e.g. DBUS_TYPE_STRUCT, not '('. 85 * In this case, you should initialize a sub-iterator with 86 * dbus_signature_iter_recurse() to parse the container type. 87 * 88 * @param iter pointer to an iterator 89 * @returns current type (e.g. #DBUS_TYPE_STRING, #DBUS_TYPE_ARRAY) 90 */ 91 int 92 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter) 93 { 94 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 95 96 return _dbus_first_type_in_signature_c_str (real_iter->pos, 0); 97 } 98 99 /** 100 * Returns the signature of the single complete type starting at the 101 * given iterator. 102 * 103 * For example, if the iterator is pointing at the start of "(ii)ii" 104 * (which is "a struct of two ints, followed by an int, followed by an 105 * int"), then "(ii)" would be returned. If the iterator is pointing at 106 * one of the "i" then just that "i" would be returned. 107 * 108 * @param iter pointer to an iterator 109 * @returns current signature; or #NULL if no memory. Should be freed with dbus_free() 110 */ 111 char * 112 dbus_signature_iter_get_signature (const DBusSignatureIter *iter) 113 { 114 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 115 DBusString str; 116 char *ret; 117 int pos; 118 119 if (!_dbus_string_init (&str)) 120 return NULL; 121 122 pos = 0; 123 _dbus_type_signature_next (real_iter->pos, &pos); 124 125 if (!_dbus_string_append_len (&str, real_iter->pos, pos)) 126 return NULL; 127 if (!_dbus_string_steal_data (&str, &ret)) 128 ret = NULL; 129 _dbus_string_free (&str); 130 131 return ret; 132 } 133 134 /** 135 * Convenience function for returning the element type of an array; 136 * This function allows you to avoid initializing a sub-iterator and 137 * getting its current type. 138 * 139 * Undefined behavior results if you invoke this function when the 140 * current type of the iterator is not #DBUS_TYPE_ARRAY. 141 * 142 * @param iter pointer to an iterator 143 * @returns current array element type 144 */ 145 int 146 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter) 147 { 148 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 149 150 _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID); 151 152 return _dbus_first_type_in_signature_c_str (real_iter->pos, 1); 153 } 154 155 /** 156 * Skip to the next value on this "level". e.g. the next field in a 157 * struct, the next value in an array. Returns #FALSE at the end of the 158 * current container. 159 * 160 * @param iter the iterator 161 * @returns FALSE if nothing more to read at or below this level 162 */ 163 dbus_bool_t 164 dbus_signature_iter_next (DBusSignatureIter *iter) 165 { 166 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 167 168 if (real_iter->finished) 169 return FALSE; 170 else 171 { 172 int pos; 173 174 if (real_iter->in_array) 175 { 176 real_iter->finished = TRUE; 177 return FALSE; 178 } 179 180 pos = 0; 181 _dbus_type_signature_next (real_iter->pos, &pos); 182 real_iter->pos += pos; 183 184 if (*real_iter->pos == DBUS_STRUCT_END_CHAR 185 || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR) 186 { 187 real_iter->finished = TRUE; 188 return FALSE; 189 } 190 191 return *real_iter->pos != DBUS_TYPE_INVALID; 192 } 193 } 194 195 /** 196 * Initialize a new iterator pointing to the first type in the current 197 * container. 198 * 199 * The results are undefined when calling this if the current type is 200 * a non-container (i.e. if dbus_type_is_container() returns #FALSE 201 * for the result of dbus_signature_iter_get_current_type()). 202 * 203 * @param iter the current interator 204 * @param subiter an iterator to initialize pointing to the first child 205 */ 206 void 207 dbus_signature_iter_recurse (const DBusSignatureIter *iter, 208 DBusSignatureIter *subiter) 209 { 210 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 211 DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter; 212 213 _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter))); 214 215 *real_sub_iter = *real_iter; 216 real_sub_iter->in_array = FALSE; 217 real_sub_iter->pos++; 218 219 if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY) 220 real_sub_iter->in_array = TRUE; 221 } 222 223 /** 224 * Check a type signature for validity. Remember that #NULL can always 225 * be passed instead of a DBusError*, if you don't care about having 226 * an error name and message. 227 * 228 * @param signature a potentially invalid type signature 229 * @param error error return 230 * @returns #TRUE if signature is valid or #FALSE if an error is set 231 */ 232 dbus_bool_t 233 dbus_signature_validate (const char *signature, 234 DBusError *error) 235 236 { 237 DBusString str; 238 DBusValidity reason; 239 240 _dbus_string_init_const (&str, signature); 241 reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str)); 242 243 if (reason == DBUS_VALID) 244 return TRUE; 245 else 246 { 247 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason)); 248 return FALSE; 249 } 250 } 251 252 /** 253 * Check that a type signature is both valid and contains exactly one 254 * complete type. "One complete type" means a single basic type, 255 * array, struct, or dictionary, though the struct or array may be 256 * arbitrarily recursive and complex. More than one complete type 257 * would mean for example "ii" or two integers in sequence. 258 * 259 * @param signature a potentially invalid type signature 260 * @param error error return 261 * @returns #TRUE if signature is valid and has exactly one complete type 262 */ 263 dbus_bool_t 264 dbus_signature_validate_single (const char *signature, 265 DBusError *error) 266 { 267 DBusSignatureIter iter; 268 269 if (!dbus_signature_validate (signature, error)) 270 return FALSE; 271 272 dbus_signature_iter_init (&iter, signature); 273 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID) 274 goto lose; 275 if (!dbus_signature_iter_next (&iter)) 276 return TRUE; 277 lose: 278 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature"); 279 return FALSE; 280 } 281 282 /** 283 * A "container type" can contain basic types, or nested 284 * container types. #DBUS_TYPE_INVALID is not a container type. 285 * 286 * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, 287 * to this function. The valid type-codes are defined by dbus-protocol.h 288 * and can be checked with dbus_type_is_valid(). 289 * 290 * @param typecode either a valid type-code or DBUS_TYPE_INVALID 291 * @returns #TRUE if type is a container 292 */ 293 dbus_bool_t 294 dbus_type_is_container (int typecode) 295 { 296 /* only reasonable (non-line-noise) typecodes are allowed */ 297 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 298 FALSE); 299 return TYPE_IS_CONTAINER (typecode); 300 } 301 302 /** 303 * A "basic type" is a somewhat arbitrary concept, but the intent is 304 * to include those types that are fully-specified by a single 305 * typecode, with no additional type information or nested values. So 306 * all numbers and strings are basic types and structs, arrays, and 307 * variants are not basic types. #DBUS_TYPE_INVALID is not a basic 308 * type. 309 * 310 * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, 311 * to this function. The valid type-codes are defined by dbus-protocol.h 312 * and can be checked with dbus_type_is_valid(). 313 * 314 * @param typecode either a valid type-code or DBUS_TYPE_INVALID 315 * @returns #TRUE if type is basic 316 */ 317 dbus_bool_t 318 dbus_type_is_basic (int typecode) 319 { 320 /* only reasonable (non-line-noise) typecodes are allowed */ 321 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 322 FALSE); 323 324 /* everything that isn't invalid or a container */ 325 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode)); 326 } 327 328 /** 329 * Tells you whether values of this type can change length if you set 330 * them to some other value. For this purpose, you assume that the 331 * first byte of the old and new value would be in the same location, 332 * so alignment padding is not a factor. 333 * 334 * This function is useful to determine whether 335 * dbus_message_iter_get_fixed_array() may be used. 336 * 337 * Some structs are fixed-size (if they contain only fixed-size types) 338 * but struct is not considered a fixed type for purposes of this 339 * function. 340 * 341 * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, 342 * to this function. The valid type-codes are defined by dbus-protocol.h 343 * and can be checked with dbus_type_is_valid(). 344 * 345 * @param typecode either a valid type-code or DBUS_TYPE_INVALID 346 * @returns #FALSE if the type can occupy different lengths 347 */ 348 dbus_bool_t 349 dbus_type_is_fixed (int typecode) 350 { 351 /* only reasonable (non-line-noise) typecodes are allowed */ 352 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 353 FALSE); 354 355 switch (typecode) 356 { 357 case DBUS_TYPE_BYTE: 358 case DBUS_TYPE_BOOLEAN: 359 case DBUS_TYPE_INT16: 360 case DBUS_TYPE_UINT16: 361 case DBUS_TYPE_INT32: 362 case DBUS_TYPE_UINT32: 363 case DBUS_TYPE_INT64: 364 case DBUS_TYPE_UINT64: 365 case DBUS_TYPE_DOUBLE: 366 case DBUS_TYPE_UNIX_FD: 367 return TRUE; 368 default: 369 return FALSE; 370 } 371 } 372 373 /** 374 * Return #TRUE if the argument is a valid typecode. 375 * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and 376 * random unknown bytes aren't either. This function is safe with 377 * untrusted data. 378 * 379 * @param typecode a potential type-code 380 * @returns #TRUE if valid 381 */ 382 dbus_bool_t 383 dbus_type_is_valid (int typecode) 384 { 385 switch (typecode) 386 { 387 case DBUS_TYPE_BYTE: 388 case DBUS_TYPE_BOOLEAN: 389 case DBUS_TYPE_INT16: 390 case DBUS_TYPE_UINT16: 391 case DBUS_TYPE_INT32: 392 case DBUS_TYPE_UINT32: 393 case DBUS_TYPE_INT64: 394 case DBUS_TYPE_UINT64: 395 case DBUS_TYPE_DOUBLE: 396 case DBUS_TYPE_STRING: 397 case DBUS_TYPE_OBJECT_PATH: 398 case DBUS_TYPE_SIGNATURE: 399 case DBUS_TYPE_ARRAY: 400 case DBUS_TYPE_STRUCT: 401 case DBUS_TYPE_DICT_ENTRY: 402 case DBUS_TYPE_VARIANT: 403 case DBUS_TYPE_UNIX_FD: 404 return TRUE; 405 406 default: 407 return FALSE; 408 } 409 } 410 411 /** @} */ /* end of DBusSignature group */ 412 413 #ifdef DBUS_BUILD_TESTS 414 415 /** 416 * @ingroup DBusSignatureInternals 417 * Unit test for DBusSignature. 418 * 419 * @returns #TRUE on success. 420 */ 421 dbus_bool_t 422 _dbus_signature_test (void) 423 { 424 DBusSignatureIter iter; 425 DBusSignatureIter subiter; 426 DBusSignatureIter subsubiter; 427 DBusSignatureIter subsubsubiter; 428 const char *sig; 429 dbus_bool_t boolres; 430 431 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter)); 432 433 sig = ""; 434 _dbus_assert (dbus_signature_validate (sig, NULL)); 435 _dbus_assert (!dbus_signature_validate_single (sig, NULL)); 436 dbus_signature_iter_init (&iter, sig); 437 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID); 438 439 sig = DBUS_TYPE_STRING_AS_STRING; 440 _dbus_assert (dbus_signature_validate (sig, NULL)); 441 _dbus_assert (dbus_signature_validate_single (sig, NULL)); 442 dbus_signature_iter_init (&iter, sig); 443 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); 444 445 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING; 446 _dbus_assert (dbus_signature_validate (sig, NULL)); 447 dbus_signature_iter_init (&iter, sig); 448 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); 449 boolres = dbus_signature_iter_next (&iter); 450 _dbus_assert (boolres); 451 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE); 452 453 sig = DBUS_TYPE_UINT16_AS_STRING 454 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 455 DBUS_TYPE_STRING_AS_STRING 456 DBUS_TYPE_UINT32_AS_STRING 457 DBUS_TYPE_VARIANT_AS_STRING 458 DBUS_TYPE_DOUBLE_AS_STRING 459 DBUS_STRUCT_END_CHAR_AS_STRING; 460 _dbus_assert (dbus_signature_validate (sig, NULL)); 461 dbus_signature_iter_init (&iter, sig); 462 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 463 boolres = dbus_signature_iter_next (&iter); 464 _dbus_assert (boolres); 465 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 466 dbus_signature_iter_recurse (&iter, &subiter); 467 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING); 468 boolres = dbus_signature_iter_next (&subiter); 469 _dbus_assert (boolres); 470 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 471 boolres = dbus_signature_iter_next (&subiter); 472 _dbus_assert (boolres); 473 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT); 474 boolres = dbus_signature_iter_next (&subiter); 475 _dbus_assert (boolres); 476 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE); 477 478 sig = DBUS_TYPE_UINT16_AS_STRING 479 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 480 DBUS_TYPE_UINT32_AS_STRING 481 DBUS_TYPE_BYTE_AS_STRING 482 DBUS_TYPE_ARRAY_AS_STRING 483 DBUS_TYPE_ARRAY_AS_STRING 484 DBUS_TYPE_DOUBLE_AS_STRING 485 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 486 DBUS_TYPE_BYTE_AS_STRING 487 DBUS_STRUCT_END_CHAR_AS_STRING 488 DBUS_STRUCT_END_CHAR_AS_STRING; 489 _dbus_assert (dbus_signature_validate (sig, NULL)); 490 dbus_signature_iter_init (&iter, sig); 491 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 492 boolres = dbus_signature_iter_next (&iter); 493 _dbus_assert (boolres); 494 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 495 dbus_signature_iter_recurse (&iter, &subiter); 496 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 497 boolres = dbus_signature_iter_next (&subiter); 498 _dbus_assert (boolres); 499 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE); 500 boolres = dbus_signature_iter_next (&subiter); 501 _dbus_assert (boolres); 502 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY); 503 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY); 504 505 dbus_signature_iter_recurse (&subiter, &subsubiter); 506 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY); 507 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE); 508 509 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter); 510 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE); 511 boolres = dbus_signature_iter_next (&subiter); 512 _dbus_assert (boolres); 513 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT); 514 dbus_signature_iter_recurse (&subiter, &subsubiter); 515 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE); 516 517 sig = DBUS_TYPE_ARRAY_AS_STRING 518 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 519 DBUS_TYPE_INT16_AS_STRING 520 DBUS_TYPE_STRING_AS_STRING 521 DBUS_DICT_ENTRY_END_CHAR_AS_STRING 522 DBUS_TYPE_VARIANT_AS_STRING; 523 _dbus_assert (dbus_signature_validate (sig, NULL)); 524 _dbus_assert (!dbus_signature_validate_single (sig, NULL)); 525 dbus_signature_iter_init (&iter, sig); 526 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY); 527 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY); 528 529 dbus_signature_iter_recurse (&iter, &subiter); 530 dbus_signature_iter_recurse (&subiter, &subsubiter); 531 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16); 532 boolres = dbus_signature_iter_next (&subsubiter); 533 _dbus_assert (boolres); 534 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING); 535 boolres = dbus_signature_iter_next (&subsubiter); 536 _dbus_assert (!boolres); 537 538 boolres = dbus_signature_iter_next (&iter); 539 _dbus_assert (boolres); 540 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT); 541 boolres = dbus_signature_iter_next (&iter); 542 _dbus_assert (!boolres); 543 544 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING; 545 _dbus_assert (!dbus_signature_validate (sig, NULL)); 546 547 sig = DBUS_TYPE_ARRAY_AS_STRING; 548 _dbus_assert (!dbus_signature_validate (sig, NULL)); 549 550 sig = DBUS_TYPE_UINT32_AS_STRING 551 DBUS_TYPE_ARRAY_AS_STRING; 552 _dbus_assert (!dbus_signature_validate (sig, NULL)); 553 554 sig = DBUS_TYPE_ARRAY_AS_STRING 555 DBUS_TYPE_DICT_ENTRY_AS_STRING; 556 _dbus_assert (!dbus_signature_validate (sig, NULL)); 557 558 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; 559 _dbus_assert (!dbus_signature_validate (sig, NULL)); 560 561 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING; 562 _dbus_assert (!dbus_signature_validate (sig, NULL)); 563 564 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 565 DBUS_TYPE_INT32_AS_STRING; 566 _dbus_assert (!dbus_signature_validate (sig, NULL)); 567 568 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 569 DBUS_TYPE_INT32_AS_STRING 570 DBUS_TYPE_STRING_AS_STRING; 571 _dbus_assert (!dbus_signature_validate (sig, NULL)); 572 573 sig = DBUS_STRUCT_END_CHAR_AS_STRING 574 DBUS_STRUCT_BEGIN_CHAR_AS_STRING; 575 _dbus_assert (!dbus_signature_validate (sig, NULL)); 576 577 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING 578 DBUS_TYPE_BOOLEAN_AS_STRING; 579 _dbus_assert (!dbus_signature_validate (sig, NULL)); 580 return TRUE; 581 #if 0 582 oom: 583 _dbus_assert_not_reached ("out of memory"); 584 return FALSE; 585 #endif 586 } 587 588 #endif 589 590