diff options
| -rw-r--r-- | dbus/dbus-marshal-recursive.c | 675 | ||||
| -rw-r--r-- | dbus/dbus-marshal-recursive.h | 3 | 
2 files changed, 446 insertions, 232 deletions
diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index ee4683ee..d821a11c 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -170,11 +170,6 @@ _dbus_type_reader_read_basic (DBusTypeReader    *reader,        _dbus_verbose ("  type reader %p read basic type_pos = %d value_pos = %d next = %d remaining sig '%s'\n",                       reader, reader->type_pos, reader->value_pos, next,                       _dbus_string_get_const_data_len (reader->type_str, reader->type_pos, 0)); -       -      _dbus_verbose_bytes_of_string (reader->value_str, -                                     reader->value_pos, -                                     MIN (16, -                                          _dbus_string_get_length (reader->value_str) - reader->value_pos));      }    else      { @@ -271,8 +266,10 @@ _dbus_type_reader_recurse (DBusTypeReader *reader,    else      {        _dbus_verbose ("recursing into type %s\n", _dbus_type_to_string (t)); +#ifndef DBUS_DISABLE_CHECKS        if (t == DBUS_TYPE_INVALID)          _dbus_warn ("You can't recurse into an empty array or off the end of a message body\n"); +#endif /* DBUS_DISABLE_CHECKS */        _dbus_assert_not_reached ("don't yet handle recursing into this type");      } @@ -316,22 +313,28 @@ skip_one_complete_type (const DBusString *type_str,  }  static void -skip_array_values (const DBusString *value_str, +skip_array_values (int               element_type, +                   const DBusString *value_str,                     int              *value_pos,                     int               byte_order)  {    dbus_uint32_t array_len; -  int len_pos; +  int pos; +  int alignment; -  len_pos = _DBUS_ALIGN_VALUE (*value_pos, 4); +  pos = _DBUS_ALIGN_VALUE (*value_pos, 4);    _dbus_demarshal_basic_type (value_str,                                DBUS_TYPE_UINT32,                                &array_len,                                byte_order, -                              &len_pos); +                              &pos); + +  alignment = _dbus_type_get_alignment (element_type); + +  pos = _DBUS_ALIGN_VALUE (pos, alignment); -  *value_pos = len_pos + array_len; +  *value_pos = pos + array_len;  }  /** @@ -384,7 +387,9 @@ _dbus_type_reader_next (DBusTypeReader *reader)          case DBUS_TYPE_ARRAY:            { -            skip_array_values (reader->value_str, &reader->value_pos, reader->byte_order); +            skip_array_values (first_type_in_signature (reader->type_str, +                                                        reader->type_pos + 1), +                               reader->value_str, &reader->value_pos, reader->byte_order);              skip_one_complete_type (reader->type_str, &reader->type_pos);            }            break; @@ -440,7 +445,9 @@ _dbus_type_reader_next (DBusTypeReader *reader)          }        else if (reader->u.array.element_type == DBUS_TYPE_ARRAY)          { -          skip_array_values (reader->value_str, &reader->value_pos, reader->byte_order); +          skip_array_values (first_type_in_signature (reader->type_str, +                                                      reader->type_pos + 1), +                             reader->value_str, &reader->value_pos, reader->byte_order);          }        else          { @@ -485,6 +492,9 @@ _dbus_type_writer_init (DBusTypeWriter *writer,    writer->value_pos = value_pos;    writer->container_type = DBUS_TYPE_INVALID;    writer->inside_array = FALSE; + +  _dbus_verbose ("writer %p init remaining sig '%s'\n", writer, +                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));  }  static dbus_bool_t @@ -511,56 +521,30 @@ _dbus_type_writer_write_basic_no_typecode (DBusTypeWriter *writer,    return TRUE;  } -dbus_bool_t -_dbus_type_writer_write_basic (DBusTypeWriter *writer, -                               int             type, -                               const void     *value) -{ -  dbus_bool_t retval; -   -  /* First ensure that our type realloc will succeed */ -  if (!_dbus_string_alloc_space (writer->type_str, 1)) -    return FALSE; - -  retval = FALSE; - -  if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value)) -    goto out; -   -  /* Now insert the type unless we're already covered by the array signature */ -  if (!writer->inside_array) -    { -      if (!_dbus_string_insert_byte (writer->type_str, -                                     writer->type_pos, -                                     type)) -        _dbus_assert_not_reached ("failed to insert byte after prealloc"); -       -      writer->type_pos += 1; -    } -   -  retval = TRUE; -   - out: -  _dbus_verbose ("  type writer %p basic type_pos = %d value_pos = %d inside_array = %d\n", -                 writer, writer->type_pos, writer->value_pos, writer->inside_array); -   -  return retval; -} - -dbus_bool_t -_dbus_type_writer_write_array (DBusTypeWriter *writer, -                               int             type, -                               const void     *array, -                               int             array_len) -{ - - -} - +/* If our parent is an array, things are a little bit complicated. + * + * The parent must have a complete element type, such as + * "i" or "aai" or "(ii)" or "a(ii)". There can't be + * unclosed parens, or an "a" with no following type. + * + * To recurse, the only allowed operation is to recurse into the + * first type in the element type. So for "i" you can't recurse, for + * "ai" you can recurse into the array, for "(ii)" you can recurse + * into the struct. + * + * If you recurse into the array for "ai", then you must specify + * "i" for the element type of the array you recurse into. + *  + * While inside an array at any level, we need to avoid writing to + * type_str, since the type only appears once for the whole array, + * it does not appear for each array element. + * + * While inside an array type_pos points to the expected next + * typecode, rather than the next place we could write a typecode. + */  static void  writer_recurse_init_and_check (DBusTypeWriter *writer,                                 int             container_type, -                               const char     *array_element_type,                                 DBusTypeWriter *sub)  {    _dbus_type_writer_init (sub, @@ -572,72 +556,89 @@ writer_recurse_init_and_check (DBusTypeWriter *writer,    sub->container_type = container_type; -  /* While inside an array, we never want to write to the type str. -   * We are inside an array if we're currently recursing into one. -   */    if (writer->inside_array || sub->container_type == DBUS_TYPE_ARRAY)      sub->inside_array = TRUE;    else      sub->inside_array = FALSE; - -  /* If our parent is an array, things are a little bit complicated. -   * -   * The parent must have a complete element type, such as -   * "i" or "aai" or "(ii)" or "a(ii)". There can't be -   * unclosed parens, or an "a" with no following type. -   * -   * To recurse, the only allowed operation is to recurse into the -   * first type in the element type. So for "i" you can't recurse, for -   * "ai" you can recurse into the array, for "(ii)" you can recurse -   * into the struct. -   * -   * If you recurse into the array for "ai", then you must specify -   * "i" for the element type of the array you recurse into. -   *  -   * While inside an array at any level, we need to avoid writing to -   * type_str, since the type only appears once for the whole array, -   * it does not appear for each array element. -   */ +    #ifndef DBUS_DISABLE_CHECKS -  if (writer->container_type == DBUS_TYPE_ARRAY) +  if (writer->inside_array)      { -      if ((sub->container_type == DBUS_TYPE_STRUCT && -           writer->u.array.element_type[0] != DBUS_STRUCT_BEGIN_CHAR) || -          (sub->container_type != DBUS_TYPE_STRUCT && -           writer->u.array.element_type[0] != sub->container_type)) -        { -          _dbus_warn ("Recursing into an array with element type %s not allowed with container type %s\n", -                      writer->u.array.element_type, _dbus_type_to_string (sub->container_type)); -        } +      int expected; -      if (sub->container_type == DBUS_TYPE_ARRAY) +      expected = first_type_in_signature (writer->type_str, writer->type_pos); +       +      if (expected != sub->container_type)          { -          DBusString parent_elements; -          DBusString our_elements; - -          _dbus_assert (writer->u.array.element_type[0] == DBUS_TYPE_ARRAY); -           -          _dbus_string_init_const (&parent_elements, &writer->u.array.element_type[1]); -          _dbus_string_init_const (&our_elements, array_element_type); - -          if (!_dbus_string_equal (&parent_elements, &our_elements)) -            { -              _dbus_warn ("Parent array expects elements '%s' and we are writing an array of '%s'\n", -                          writer->u.array.element_type, -                          array_element_type); -            } +          _dbus_warn ("Writing an element of type %s, but the expected type here is %s\n", +                      _dbus_type_to_string (sub->container_type), +                      _dbus_type_to_string (expected)); +          _dbus_assert_not_reached ("bad array element written");          }      }  #endif /* DBUS_DISABLE_CHECKS */ -  _dbus_verbose ("  type writer %p recurse type_pos = %d value_pos = %d inside_array = %d container_type = %s\n", +  _dbus_verbose ("  type writer %p recurse parent type_pos = %d value_pos = %d inside_array = %d container_type = %s remaining sig '%s'\n",                   writer, writer->type_pos, writer->value_pos, writer->inside_array, -                 _dbus_type_to_string (writer->container_type)); -  _dbus_verbose ("  type writer %p new sub type_pos = %d value_pos = %d inside_array = %d container_type = %s element_type = '%s'\n", +                 _dbus_type_to_string (writer->container_type), +                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0)); +  _dbus_verbose ("  type writer %p recurse sub    type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",                   sub, sub->type_pos, sub->value_pos,                   sub->inside_array, -                 _dbus_type_to_string (sub->container_type), -                 array_element_type ? array_element_type : "n/a"); +                 _dbus_type_to_string (sub->container_type)); +} + +static dbus_bool_t +write_or_verify_typecode (DBusTypeWriter *writer, +                          int             typecode) +{ +  /* A subwriter inside an array will have type_pos pointing to the +   * expected typecode; a writer not inside an array has type_pos +   * pointing to the next place to insert a typecode. +   */ +  _dbus_verbose ("  type writer %p write_or_verify start type_pos = %d remaining sig '%s'\n", +                 writer, writer->type_pos, +                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0)); +   +  if (writer->inside_array) +    { +#ifndef DBUS_DISABLE_CHECKS +      { +        int expected; +         +        expected = _dbus_string_get_byte (writer->type_str, writer->type_pos); +         +        if (expected != typecode) +          { +            _dbus_warn ("Array type requires that type %s be written, but %s was written\n", +                        _dbus_type_to_string (expected), _dbus_type_to_string (typecode)); +            _dbus_assert_not_reached ("bad type inserted somewhere inside an array"); +          } +      } +#endif /* DBUS_DISABLE_CHECKS */ + +      /* if immediately inside an array we'd always be appending an element, +       * so the expected type doesn't change; if inside a struct or something +       * below an array, we need to move through said struct or something. +       */ +      if (writer->container_type != DBUS_TYPE_ARRAY) +        writer->type_pos += 1; +    } +  else +    { +      if (!_dbus_string_insert_byte (writer->type_str, +                                     writer->type_pos, +                                     typecode)) +        return FALSE; + +      writer->type_pos += 1; +    } + +  _dbus_verbose ("  type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n", +                 writer, writer->type_pos, +                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0)); +   +  return TRUE;  }  dbus_bool_t @@ -645,26 +646,19 @@ _dbus_type_writer_recurse (DBusTypeWriter *writer,                             int             container_type,                             DBusTypeWriter *sub)  { -  writer_recurse_init_and_check (writer, container_type, NULL, sub); +  writer_recurse_init_and_check (writer, container_type, sub);    switch (container_type)      {      case DBUS_TYPE_STRUCT:        { -        if (!writer->inside_array) -          { -            /* Ensure that we'll be able to add alignment padding */ -            if (!_dbus_string_alloc_space (sub->value_str, 8)) -              return FALSE; -             -            if (!_dbus_string_insert_byte (sub->type_str, -                                           sub->type_pos, -                                           DBUS_STRUCT_BEGIN_CHAR)) -              return FALSE; - -            sub->type_pos += 1; -          } +        /* Ensure that we'll be able to add alignment padding and the typecode */ +        if (!_dbus_string_alloc_space (sub->value_str, 8)) +          return FALSE; +        if (!write_or_verify_typecode (sub, DBUS_STRUCT_BEGIN_CHAR)) +          _dbus_assert_not_reached ("failed to insert struct typecode after prealloc"); +                  if (!_dbus_string_insert_bytes (sub->value_str,                                          sub->value_pos,                                          _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos, @@ -691,9 +685,34 @@ _dbus_type_writer_recurse_array (DBusTypeWriter *writer,  {    int element_type_len;    DBusString element_type_str; +  dbus_uint32_t value = 0; +  int alignment; +  int aligned; +  DBusString str; -  writer_recurse_init_and_check (writer, DBUS_TYPE_ARRAY, element_type, sub); +  writer_recurse_init_and_check (writer, DBUS_TYPE_ARRAY, sub); +   +#ifndef DBUS_DISABLE_CHECKS +  if (writer->container_type == DBUS_TYPE_ARRAY) +    { +      DBusString parent_elements; +      _dbus_assert (element_type != NULL); +       +      _dbus_string_init_const (&parent_elements, +                               _dbus_string_get_const_data_len (writer->type_str, +                                                                writer->u.array.element_type_pos + 1, +                                                                0)); +                                                                 +      if (!_dbus_string_starts_with_c_str (&parent_elements, element_type)) +        { +          _dbus_warn ("Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n", +                      element_type); +          _dbus_assert_not_reached ("incompatible type for child array"); +        } +    } +#endif /* DBUS_DISABLE_CHECKS */ +      _dbus_string_init_const (&element_type_str, element_type);    element_type_len = _dbus_string_get_length (&element_type_str); @@ -701,71 +720,64 @@ _dbus_type_writer_recurse_array (DBusTypeWriter *writer,    if (!_dbus_string_alloc_space (sub->value_str, 8))      return FALSE; +  sub->type_pos += 1; /* move to point to the element type, since type_pos +                       * should be the expected type for further writes +                       */ +  sub->u.array.element_type_pos = sub->type_pos; +  sub->u.array.element_type_len = element_type_len; +    if (!writer->inside_array)      { +      /* sub is a toplevel/outermost array so we need to write the type data */ +              /* alloc space for array typecode, element signature, possible 7         * bytes of padding         */ -      if (!_dbus_string_alloc_space (sub->type_str, 1 + element_type_len + 7)) +      if (!_dbus_string_alloc_space (writer->type_str, 1 + element_type_len + 7))          return FALSE; -    } -       -  if (!_dbus_string_copy_data (&element_type_str, -                               &sub->u.array.element_type)) -    return FALSE; -  if (!writer->inside_array) -    { -      if (!_dbus_string_insert_byte (sub->type_str, -                                     sub->type_pos, +      if (!_dbus_string_insert_byte (writer->type_str, +                                     writer->type_pos,                                       DBUS_TYPE_ARRAY)) -        _dbus_assert_not_reached ("should not have failed to insert array typecode"); +        _dbus_assert_not_reached ("failed to insert array typecode after prealloc"); -      sub->type_pos += 1; -              if (!_dbus_string_copy (&element_type_str, 0, -                              sub->type_str, sub->type_pos)) +                              sub->type_str, sub->u.array.element_type_pos))          _dbus_assert_not_reached ("should not have failed to insert array element typecodes"); -   -      sub->type_pos += element_type_len;      } -   + +  /* Write the length */    sub->u.array.len_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 4); -  { -    dbus_uint32_t value = 0; -    int alignment; -    int aligned; -    DBusString str; -     -    if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32, -                                                    &value)) -      _dbus_assert_not_reached ("should not have failed to insert array len"); - -    _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4); - -    _dbus_string_init_const (&str, element_type); -    alignment = element_type_get_alignment (&str, 0); - -    aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment); -    if (aligned != sub->value_pos) -      { -        if (!_dbus_string_insert_bytes (sub->value_str, -                                        sub->value_pos, -                                        aligned - sub->value_pos, -                                        '\0')) -          _dbus_assert_not_reached ("should not have failed to insert alignment padding"); +  if (!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32, +                                                  &value)) +    _dbus_assert_not_reached ("should not have failed to insert array len"); +   +  _dbus_assert (sub->u.array.len_pos == sub->value_pos - 4); -        sub->value_pos = aligned; -      } -    sub->u.array.start_pos = sub->value_pos; -  } +  /* Write alignment padding for array elements */ +  _dbus_string_init_const (&str, element_type); +  alignment = element_type_get_alignment (&str, 0); + +  aligned = _DBUS_ALIGN_VALUE (sub->value_pos, alignment); +  if (aligned != sub->value_pos) +    { +      if (!_dbus_string_insert_bytes (sub->value_str, +                                      sub->value_pos, +                                      aligned - sub->value_pos, +                                      '\0')) +        _dbus_assert_not_reached ("should not have failed to insert alignment padding"); +       +      sub->value_pos = aligned; +    } +  sub->u.array.start_pos = sub->value_pos;    _dbus_assert (sub->u.array.start_pos == sub->value_pos);    _dbus_assert (sub->u.array.len_pos < sub->u.array.start_pos); -   -  /* value_pos now points to the place for array data, and len_pos to the length */ +  _dbus_verbose ("  type writer %p recurse array done remaining sig '%s'\n", sub, +                 _dbus_string_get_const_data_len (sub->type_str, sub->type_pos, 0)); +      return TRUE;  } @@ -778,30 +790,19 @@ _dbus_type_writer_unrecurse (DBusTypeWriter *writer,    _dbus_verbose ("  type writer %p unrecurse type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",                   writer, writer->type_pos, writer->value_pos, writer->inside_array,                   _dbus_type_to_string (writer->container_type)); -  _dbus_verbose ("  type writer %p unrecurse sub type_pos = %d value_pos = %d inside_array = %d container_type = %s element_type = '%s'\n", +  _dbus_verbose ("  type writer %p unrecurse sub type_pos = %d value_pos = %d inside_array = %d container_type = %s\n",                   sub, sub->type_pos, sub->value_pos,                   sub->inside_array, -                 _dbus_type_to_string (sub->container_type), -                 sub->container_type == DBUS_TYPE_ARRAY ? -                 sub->u.array.element_type : "n/a"); +                 _dbus_type_to_string (sub->container_type));    if (sub->container_type == DBUS_TYPE_STRUCT)      { -      if (!sub->inside_array) -        { -          if (!_dbus_string_insert_byte (sub->type_str, -                                         sub->type_pos,  -                                         DBUS_STRUCT_END_CHAR)) -            return FALSE; -          sub->type_pos += 1; -        } +      if (!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR)) +        return FALSE;      }    else if (sub->container_type == DBUS_TYPE_ARRAY)      {        dbus_uint32_t len; -       -      dbus_free (sub->u.array.element_type); -      sub->u.array.element_type = NULL;        /* Set the array length */        len = sub->value_pos - sub->u.array.start_pos; @@ -814,12 +815,68 @@ _dbus_type_writer_unrecurse (DBusTypeWriter *writer,      }    /* Jump the parent writer to the new location */ -  writer->type_pos = sub->type_pos; +  if (!writer->inside_array) +    { +      if (sub->inside_array) +        { +          /* Transition back to type_pos = insertion point from type_pos = expected */ +           +          _dbus_assert (sub->container_type == DBUS_TYPE_ARRAY); +          writer->type_pos = sub->u.array.element_type_pos + sub->u.array.element_type_len; +        } +      else +        { +          writer->type_pos = sub->type_pos; +        } +    }    writer->value_pos = sub->value_pos; + + +  _dbus_verbose ("  type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n", +                 writer, writer->type_pos, writer->value_pos, +                 _dbus_string_get_const_data_len (writer->type_str, writer->type_pos, 0));    return TRUE;  } +dbus_bool_t +_dbus_type_writer_write_basic (DBusTypeWriter *writer, +                               int             type, +                               const void     *value) +{ +  dbus_bool_t retval; +   +  /* First ensure that our type realloc will succeed */ +  if (!_dbus_string_alloc_space (writer->type_str, 1)) +    return FALSE; + +  retval = FALSE; + +  if (!_dbus_type_writer_write_basic_no_typecode (writer, type, value)) +    goto out; +   +  if (!write_or_verify_typecode (writer, type)) +    _dbus_assert_not_reached ("failed to write typecode after prealloc"); +   +  retval = TRUE; +   + out: +  _dbus_verbose ("  type writer %p basic type_pos = %d value_pos = %d inside_array = %d\n", +                 writer, writer->type_pos, writer->value_pos, writer->inside_array); +   +  return retval; +} + +dbus_bool_t +_dbus_type_writer_write_array (DBusTypeWriter *writer, +                               int             type, +                               const void     *array, +                               int             array_len) +{ + + +} +  /** @} */ /* end of DBusMarshal group */  #ifdef DBUS_BUILD_TESTS @@ -905,21 +962,21 @@ data_block_init_reader_writer (DataBlock      *block,                            _dbus_string_get_length (&block->body));  } -#define NEXT_EXPECTING_TRUE(reader)  do { if (!_dbus_type_reader_next (reader)) \ - {                                                                              \ -    _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d",  \ -                              _DBUS_FUNCTION_NAME, __LINE__);                   \ -    _dbus_assert_not_reached ("test failed");                                   \ - }                                                                              \ +#define NEXT_EXPECTING_TRUE(reader)  do { if (!_dbus_type_reader_next (reader))         \ + {                                                                                      \ +    _dbus_warn ("_dbus_type_reader_next() should have returned TRUE at %s %d\n",        \ +                              _DBUS_FUNCTION_NAME, __LINE__);                           \ +    _dbus_assert_not_reached ("test failed");                                           \ + }                                                                                      \  } while (0) -#define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader))  \ - {                                                                              \ -    _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d", \ -                              _DBUS_FUNCTION_NAME, __LINE__);                   \ -    _dbus_assert_not_reached ("test failed");                                   \ - }                                                                              \ - check_expected_type (reader, DBUS_TYPE_INVALID);                               \ +#define NEXT_EXPECTING_FALSE(reader) do { if (_dbus_type_reader_next (reader))          \ + {                                                                                      \ +    _dbus_warn ("_dbus_type_reader_next() should have returned FALSE at %s %d\n",       \ +                              _DBUS_FUNCTION_NAME, __LINE__);                           \ +    _dbus_assert_not_reached ("test failed");                                           \ + }                                                                                      \ + check_expected_type (reader, DBUS_TYPE_INVALID);                                       \  } while (0)  #define SAMPLE_INT32           12345678 @@ -951,11 +1008,6 @@ real_check_expected_type (DBusTypeReader *reader,                    _dbus_type_to_string (t),                    _dbus_type_to_string (expected),                    funcname, line); - -      _dbus_verbose_bytes_of_string (reader->type_str, 0, -                                     _dbus_string_get_length (reader->type_str)); -      _dbus_verbose_bytes_of_string (reader->value_str, 0, -                                     _dbus_string_get_length (reader->value_str));        exit (1);      } @@ -980,8 +1032,8 @@ read_int32 (DataBlock      *block,  }  static dbus_bool_t -write_struct_with_int32s (DataBlock      *block, -                          DBusTypeWriter *writer) +write_struct_of_int32 (DataBlock      *block, +                       DBusTypeWriter *writer)  {    dbus_int32_t v;    DataBlockState saved; @@ -1022,8 +1074,8 @@ write_struct_with_int32s (DataBlock      *block,  }  static dbus_bool_t -read_struct_with_int32s (DataBlock      *block, -                         DBusTypeReader *reader) +read_struct_of_int32 (DataBlock      *block, +                      DBusTypeReader *reader)  {    dbus_int32_t v;    DBusTypeReader sub; @@ -1066,17 +1118,17 @@ write_struct_of_structs (DataBlock      *block,                                    &sub))      return FALSE; -  if (!write_struct_with_int32s (block, &sub)) +  if (!write_struct_of_int32 (block, &sub))      {        data_block_restore (block, &saved);        return FALSE;      } -  if (!write_struct_with_int32s (block, &sub)) +  if (!write_struct_of_int32 (block, &sub))      {        data_block_restore (block, &saved);        return FALSE;      } -  if (!write_struct_with_int32s (block, &sub)) +  if (!write_struct_of_int32 (block, &sub))      {        data_block_restore (block, &saved);        return FALSE; @@ -1101,15 +1153,15 @@ read_struct_of_structs (DataBlock      *block,    _dbus_type_reader_recurse (reader, &sub); -  if (!read_struct_with_int32s (block, &sub)) +  if (!read_struct_of_int32 (block, &sub))      return FALSE;    NEXT_EXPECTING_TRUE (&sub); -  if (!read_struct_with_int32s (block, &sub)) +  if (!read_struct_of_int32 (block, &sub))      return FALSE;    NEXT_EXPECTING_TRUE (&sub); -  if (!read_struct_with_int32s (block, &sub)) +  if (!read_struct_of_int32 (block, &sub))      return FALSE;    NEXT_EXPECTING_FALSE (&sub); @@ -1484,10 +1536,143 @@ read_array_of_array_of_array_of_int32 (DataBlock      *block,    return TRUE;  } +static dbus_bool_t +write_struct_of_array_of_int32 (DataBlock      *block, +                                DBusTypeWriter *writer) +{ +  DataBlockState saved; +  DBusTypeWriter sub; + +  data_block_save (block, &saved); +   +  if (!_dbus_type_writer_recurse (writer, +                                  DBUS_TYPE_STRUCT, +                                  &sub)) +    return FALSE; + +  if (!write_array_of_int32 (block, &sub)) +    { +      data_block_restore (block, &saved); +      return FALSE; +    } + +  if (!write_array_of_int32_empty (block, &sub)) +    { +      data_block_restore (block, &saved); +      return FALSE; +    } +       +  if (!_dbus_type_writer_unrecurse (writer, &sub)) +    { +      data_block_restore (block, &saved); +      return FALSE; +    } +   +  return TRUE; +} + +static dbus_bool_t +read_struct_of_array_of_int32 (DataBlock      *block, +                               DBusTypeReader *reader) +{ +  DBusTypeReader sub; + +  check_expected_type (reader, DBUS_TYPE_STRUCT); +   +  _dbus_type_reader_recurse (reader, &sub); + +  check_expected_type (&sub, DBUS_TYPE_ARRAY); + +  if (!read_array_of_int32 (block, &sub)) +    return FALSE; + +  NEXT_EXPECTING_TRUE (&sub); +  if (!read_array_of_int32_empty (block, &sub)) +    return FALSE; +   +  NEXT_EXPECTING_FALSE (&sub); +   +  return TRUE; +} + +static dbus_bool_t +write_array_of_struct_of_int32 (DataBlock      *block, +                                DBusTypeWriter *writer) +{ +  DataBlockState saved; +  DBusTypeWriter sub; + +  data_block_save (block, &saved); + +  if (!_dbus_type_writer_recurse_array (writer, +                                        DBUS_STRUCT_BEGIN_CHAR_AS_STRING +                                        DBUS_TYPE_INT32_AS_STRING +                                        DBUS_TYPE_INT32_AS_STRING +                                        DBUS_STRUCT_END_CHAR_AS_STRING, +                                        &sub)) +    return FALSE; + +  if (!write_struct_of_int32 (block, &sub)) +    { +      data_block_restore (block, &saved); +      return FALSE; +    } + +  if (!write_struct_of_int32 (block, &sub)) +    { +      data_block_restore (block, &saved); +      return FALSE; +    } + +  if (!write_struct_of_int32 (block, &sub)) +    { +      data_block_restore (block, &saved); +      return FALSE; +    } +   +  if (!_dbus_type_writer_unrecurse (writer, &sub)) +    { +      data_block_restore (block, &saved); +      return FALSE; +    } +   +  return TRUE; +} + +static dbus_bool_t +read_array_of_struct_of_int32 (DataBlock      *block, +                               DBusTypeReader *reader) +{ +  DBusTypeReader sub; + +  check_expected_type (reader, DBUS_TYPE_ARRAY); +   +  _dbus_type_reader_recurse (reader, &sub); + +  check_expected_type (&sub, DBUS_TYPE_STRUCT); + +  if (!read_struct_of_int32 (block, &sub)) +    return FALSE; +   +  NEXT_EXPECTING_TRUE (&sub); + +  if (!read_struct_of_int32 (block, &sub)) +    return FALSE; +   +  NEXT_EXPECTING_TRUE (&sub); + +  if (!read_struct_of_int32 (block, &sub)) +    return FALSE; +   +  NEXT_EXPECTING_FALSE (&sub); +   +  return TRUE; +} +  typedef enum {    ITEM_INVALID = -1,    ITEM_INT32 = 0, -  ITEM_STRUCT_WITH_INT32S, +  ITEM_STRUCT_OF_INT32,    ITEM_STRUCT_OF_STRUCTS,    ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS,    ITEM_ARRAY_OF_INT32, @@ -1495,6 +1680,8 @@ typedef enum {    ITEM_ARRAY_OF_ARRAY_OF_INT32,    ITEM_ARRAY_OF_ARRAY_OF_INT32_EMPTY,    ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, +  ITEM_STRUCT_OF_ARRAY_OF_INT32, +  ITEM_ARRAY_OF_STRUCT_OF_INT32,    ITEM_LAST  } WhichItem; @@ -1516,7 +1703,7 @@ static CheckMarshalItem items[] = {    { "int32",      ITEM_INT32, write_int32, read_int32 },    { "struct with two int32", -    ITEM_STRUCT_WITH_INT32S, write_struct_with_int32s, read_struct_with_int32s }, +    ITEM_STRUCT_OF_INT32, write_struct_of_int32, read_struct_of_int32 },    { "struct with three structs of two int32",      ITEM_STRUCT_OF_STRUCTS, write_struct_of_structs, read_struct_of_structs },    { "struct of two structs of three structs of two int32", @@ -1535,7 +1722,11 @@ static CheckMarshalItem items[] = {      write_array_of_array_of_int32_empty, read_array_of_array_of_int32_empty },    { "array of array of array of int32",      ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, -    write_array_of_array_of_array_of_int32, read_array_of_array_of_array_of_int32 } +    write_array_of_array_of_array_of_int32, read_array_of_array_of_array_of_int32 }, +  { "struct of array of int32", +    ITEM_STRUCT_OF_ARRAY_OF_INT32, write_struct_of_array_of_int32, read_struct_of_array_of_int32 }, +  { "array of struct of int32", +    ITEM_ARRAY_OF_STRUCT_OF_INT32, write_array_of_struct_of_int32, read_array_of_struct_of_int32 },  };  typedef struct @@ -1552,18 +1743,18 @@ static TestRun runs[] = {    { { ITEM_INT32, ITEM_INT32, ITEM_INVALID } },    { { ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_INVALID } }, -  /* STRUCT_WITH_INT32S */ -  { { ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } }, -  { { ITEM_STRUCT_WITH_INT32S, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } }, -  { { ITEM_STRUCT_WITH_INT32S, ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } }, -  { { ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } }, -  { { ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_STRUCT_WITH_INT32S, ITEM_INVALID } }, +  /* STRUCT_OF_INT32 */ +  { { ITEM_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INT32, ITEM_INT32, ITEM_INT32, ITEM_STRUCT_OF_INT32, ITEM_INVALID } },    /* STRUCT_OF_STRUCTS */    { { ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } }, -  { { ITEM_STRUCT_WITH_INT32S, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS, ITEM_INVALID } }, @@ -1571,7 +1762,7 @@ static TestRun runs[] = {    { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } }, -  { { ITEM_STRUCT_WITH_INT32S, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } }, @@ -1584,7 +1775,7 @@ static TestRun runs[] = {    { { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },    { { ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } }, -  { { ITEM_STRUCT_WITH_INT32S, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },    { { ITEM_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_INT32, ITEM_INVALID } },    /* ARRAY_OF_ARRAY_OF_INT32 */ @@ -1596,7 +1787,7 @@ static TestRun runs[] = {    { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },    { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } }, -  { { ITEM_STRUCT_WITH_INT32S, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },    { { ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },    /* ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32 */ @@ -1608,9 +1799,24 @@ static TestRun runs[] = {    { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } },    { { ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } },    { { ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_STRUCTS_OF_STRUCTS, ITEM_INVALID } }, -  { { ITEM_STRUCT_WITH_INT32S, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } }, -  { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } } - +  { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_ARRAY_OF_ARRAY_OF_INT32, ITEM_INVALID } }, + +  /* STRUCT_OF_ARRAY_OF_INT32 */ +  { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_STRUCT_OF_ARRAY_OF_INT32, ITEM_INVALID } }, + +  /* ARRAY_OF_STRUCT_OF_INT32 */ +  { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }, +  { { ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_ARRAY_OF_STRUCT_OF_INT32, ITEM_INVALID } }  }; @@ -1664,6 +1870,13 @@ perform_one_run (DataBlock *block,      {        CheckMarshalItem *item = &items[run->items[i]]; +      _dbus_verbose (">>data for reading %s\n", item->desc); +       +      _dbus_verbose_bytes_of_string (reader.type_str, 0, +                                     _dbus_string_get_length (reader.type_str)); +      _dbus_verbose_bytes_of_string (reader.value_str, 0, +                                     _dbus_string_get_length (reader.value_str)); +              _dbus_verbose (">>reading %s\n", item->desc);        if (!(* item->read_item_func) (block, &reader)) diff --git a/dbus/dbus-marshal-recursive.h b/dbus/dbus-marshal-recursive.h index e3200f39..8e5427bd 100644 --- a/dbus/dbus-marshal-recursive.h +++ b/dbus/dbus-marshal-recursive.h @@ -96,7 +96,8 @@ struct DBusTypeWriter      struct {        int start_pos; /* first element */        int len_pos; -      char *element_type; +      int element_type_pos; /* position in type_str of array element type */ +      int element_type_len;      } array;      struct {  | 
