2003-04-08 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-marshal.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal.c  Marshalling routines
3  *
4  * Copyright (C) 2002  CodeFactory AB
5  *
6  * Licensed under the Academic Free License version 1.2
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "dbus-marshal.h"
25 #include "dbus-internals.h"
26 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
27 #include "dbus-string-private.h"
28
29 #include <string.h>
30
31 /* from ORBit */
32 static void
33 swap_bytes (unsigned char *data,
34             unsigned int   len)
35 {
36   unsigned char *p1 = data;
37   unsigned char *p2 = data + len - 1;
38
39   while (p1 < p2)
40     {
41       unsigned char tmp = *p1;
42       *p1 = *p2;
43       *p2 = tmp;
44
45       --p2;
46       ++p1;
47     }
48 }
49
50 /**
51  * @defgroup DBusMarshal marshaling and unmarshaling
52  * @ingroup  DBusInternals
53  * @brief functions to marshal/unmarshal data from the wire
54  *
55  * Types and functions related to converting primitive data types from
56  * wire format to native machine format, and vice versa.
57  *
58  * @{
59  */
60
61 /**
62  * Unpacks a 32 bit unsigned integer from a data pointer
63  *
64  * @param byte_order The byte order to use
65  * @param data the data pointer
66  * @returns the integer
67  */
68 dbus_uint32_t
69 _dbus_unpack_uint32 (int                  byte_order,
70                      const unsigned char *data)
71 {
72   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
73   
74   if (byte_order == DBUS_LITTLE_ENDIAN)
75     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)data);
76   else
77     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)data);
78 }  
79
80 /**
81  * Unpacks a 32 bit signed integer from a data pointer
82  *
83  * @param byte_order The byte order to use
84  * @param data the data pointer
85  * @returns the integer
86  */
87 dbus_int32_t
88 _dbus_unpack_int32 (int                  byte_order,
89                     const unsigned char *data)
90 {
91   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
92   
93   if (byte_order == DBUS_LITTLE_ENDIAN)
94     return DBUS_INT32_FROM_LE (*(dbus_int32_t*)data);
95   else
96     return DBUS_INT32_FROM_BE (*(dbus_int32_t*)data);
97 }
98
99 /**
100  * Packs a 32 bit unsigned integer into a data pointer.
101  *
102  * @param value the value
103  * @param byte_order the byte order to use
104  * @param data the data pointer
105  */
106 void
107 _dbus_pack_uint32 (dbus_uint32_t   value,
108                    int             byte_order,
109                    unsigned char  *data)
110 {
111   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
112   
113   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
114     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_LE (value);       
115   else
116     *((dbus_uint32_t*)(data)) = DBUS_UINT32_TO_BE (value);
117 }
118
119 /**
120  * Packs a 32 bit signed integer into a data pointer.
121  *
122  * @param value the value
123  * @param byte_order the byte order to use
124  * @param data the data pointer
125  */
126 void
127 _dbus_pack_int32 (dbus_int32_t   value,
128                   int            byte_order,
129                   unsigned char *data)
130 {
131   _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 4) == data);
132   
133   if ((byte_order) == DBUS_LITTLE_ENDIAN)                  
134     *((dbus_int32_t*)(data)) = DBUS_INT32_TO_LE (value);       
135   else
136     *((dbus_int32_t*)(data)) = DBUS_INT32_TO_BE (value);
137 }
138
139 /**
140  * Sets the 4 bytes at the given offset to a marshaled signed integer,
141  * replacing anything found there previously.
142  *
143  * @param str the string to write the marshalled int to
144  * @param offset the byte offset where int should be written
145  * @param byte_order the byte order to use
146  * @param value the value
147  * 
148  */
149 void
150 _dbus_marshal_set_int32 (DBusString          *str,
151                          int                  byte_order,
152                          int                  offset,
153                          dbus_int32_t         value)
154 {
155   char *data;
156   
157   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
158                 byte_order == DBUS_BIG_ENDIAN);
159   
160   data = _dbus_string_get_data_len (str, offset, 4);
161
162   _dbus_pack_int32 (value, byte_order, data);
163 }
164
165 /**
166  * Sets the 4 bytes at the given offset to a marshaled unsigned
167  * integer, replacing anything found there previously.
168  *
169  * @param str the string to write the marshalled int to
170  * @param offset the byte offset where int should be written
171  * @param byte_order the byte order to use
172  * @param value the value
173  * 
174  */
175 void
176 _dbus_marshal_set_uint32 (DBusString          *str,
177                           int                  byte_order,
178                           int                  offset,
179                           dbus_uint32_t        value)
180 {
181   char *data;
182   
183   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
184                 byte_order == DBUS_BIG_ENDIAN);
185   
186   data = _dbus_string_get_data_len (str, offset, 4);
187
188   _dbus_pack_uint32 (value, byte_order, data);
189 }
190
191 /**
192  * Sets the existing marshaled string at the given offset with
193  * a new marshaled string. The given offset must point to
194  * an existing string or the wrong length will be deleted
195  * and replaced with the new string.
196  *
197  * @param str the string to write the marshalled string to
198  * @param offset the byte offset where string should be written
199  * @param byte_order the byte order to use
200  * @param value the value
201  * @param len the length to use
202  * @returns #TRUE on success
203  * 
204  */
205 dbus_bool_t
206 _dbus_marshal_set_string (DBusString          *str,
207                           int                  byte_order,
208                           int                  offset,
209                           const DBusString    *value,
210                           int                  len)
211 {
212   int old_len;
213   
214   _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
215                 byte_order == DBUS_BIG_ENDIAN);
216   
217   old_len = _dbus_demarshal_uint32 (str, byte_order,
218                                     offset, NULL);
219
220   if (!_dbus_string_replace_len (value, 0, len,
221                                  str, offset + 4, old_len))
222     return FALSE;
223
224   _dbus_marshal_set_uint32 (str, byte_order,
225                             offset, len);
226
227   return TRUE;
228 }
229
230 /**
231  * Marshals a double value.
232  *
233  * @param str the string to append the marshalled value to
234  * @param byte_order the byte order to use
235  * @param value the value
236  * @returns #TRUE on success
237  */
238 dbus_bool_t
239 _dbus_marshal_double (DBusString *str,
240                       int         byte_order,
241                       double      value)
242 {
243   _dbus_assert (sizeof (double) == 8);
244
245   if (!_dbus_string_align_length (str, sizeof (double)))
246     return FALSE;
247   
248   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
249     swap_bytes ((unsigned char *)&value, sizeof (double));
250
251   return _dbus_string_append_len (str, (const char *)&value, sizeof (double));
252 }
253
254 /**
255  * Marshals a 32 bit signed integer value.
256  *
257  * @param str the string to append the marshalled value to
258  * @param byte_order the byte order to use
259  * @param value the value
260  * @returns #TRUE on success
261  */
262 dbus_bool_t
263 _dbus_marshal_int32  (DBusString   *str,
264                       int           byte_order,
265                       dbus_int32_t  value)
266 {
267   if (!_dbus_string_align_length (str, sizeof (dbus_int32_t)))
268     return FALSE;
269   
270   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
271     value = DBUS_INT32_SWAP_LE_BE (value);
272
273   return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_int32_t));
274 }
275
276 /**
277  * Marshals a 32 bit unsigned integer value.
278  *
279  * @param str the string to append the marshalled value to
280  * @param byte_order the byte order to use
281  * @param value the value
282  * @returns #TRUE on success
283  */
284 dbus_bool_t
285 _dbus_marshal_uint32 (DBusString    *str,
286                       int            byte_order,
287                       dbus_uint32_t  value)
288 {
289   if (!_dbus_string_align_length (str, sizeof (dbus_uint32_t)))
290     return FALSE;
291   
292   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
293     value = DBUS_UINT32_SWAP_LE_BE (value);
294
295   return _dbus_string_append_len (str, (const char *)&value, sizeof (dbus_uint32_t));
296 }
297
298 /**
299  * Marshals a UTF-8 string
300  *
301  * @todo: If the string append fails we need to restore
302  * the old length. (also for other marshallers)
303  * 
304  * @param str the string to append the marshalled value to
305  * @param byte_order the byte order to use
306  * @param value the string
307  * @returns #TRUE on success
308  */
309 dbus_bool_t
310 _dbus_marshal_string (DBusString    *str,
311                       int            byte_order,
312                       const char    *value)
313 {
314   int len, old_string_len;
315
316   old_string_len = _dbus_string_get_length (str);
317   
318   len = strlen (value);
319
320   if (!_dbus_marshal_uint32 (str, byte_order, len))
321     {
322       /* Restore the previous length */
323       _dbus_string_set_length (str, old_string_len);
324
325       return FALSE;
326     }
327
328   return _dbus_string_append_len (str, value, len + 1);
329 }
330
331 /**
332  * Marshals a byte array
333  *
334  * @param str the string to append the marshalled value to
335  * @param byte_order the byte order to use
336  * @param value the array
337  * @param len number of elements in the array
338  * @returns #TRUE on success
339  */
340 dbus_bool_t
341 _dbus_marshal_byte_array (DBusString          *str,
342                           int                  byte_order,
343                           const unsigned char *value,
344                           int                  len)
345 {
346   int old_string_len;
347
348   old_string_len = _dbus_string_get_length (str);
349   
350   if (!_dbus_marshal_uint32 (str, byte_order, len))
351     {
352       /* Restore the previous length */
353       _dbus_string_set_length (str, old_string_len);
354
355       return FALSE;
356     }
357
358   if (len == 0)
359     return TRUE;
360   else
361     return _dbus_string_append_len (str, value, len);
362 }
363
364 /**
365  * Marshals a 32 bit signed integer array
366  *
367  * @param str the string to append the marshalled value to
368  * @param byte_order the byte order to use
369  * @param value the array
370  * @param len the length of the array
371  * @returns #TRUE on success
372  */
373 dbus_bool_t
374 _dbus_marshal_int32_array (DBusString         *str,
375                            int                 byte_order,
376                            const dbus_int32_t *value,
377                            int                 len)
378 {
379   int i, old_string_len;
380
381   old_string_len = _dbus_string_get_length (str);
382
383   if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_int32_t)))
384     goto error;
385
386   for (i = 0; i < len; i++)
387     if (!_dbus_marshal_int32 (str, byte_order, value[i]))
388       goto error;
389
390   return TRUE;
391   
392  error:
393   /* Restore previous length */
394   _dbus_string_set_length (str, old_string_len);
395   
396   return FALSE;
397 }
398
399 /**
400  * Marshals a 32 bit unsigned integer array
401  *
402  * @param str the string to append the marshalled value to
403  * @param byte_order the byte order to use
404  * @param value the array
405  * @param len the length of the array
406  * @returns #TRUE on success
407  */
408 dbus_bool_t
409 _dbus_marshal_uint32_array (DBusString          *str,
410                             int                  byte_order,
411                             const dbus_uint32_t  *value,
412                             int                  len)
413 {
414   int i, old_string_len;
415
416   old_string_len = _dbus_string_get_length (str);
417
418   if (!_dbus_marshal_uint32 (str, byte_order, len * sizeof (dbus_uint32_t)))
419     goto error;
420
421   for (i = 0; i < len; i++)
422     if (!_dbus_marshal_uint32 (str, byte_order, value[i]))
423       goto error;
424
425   return TRUE;
426   
427  error:
428   /* Restore previous length */
429   _dbus_string_set_length (str, old_string_len);
430   
431   return FALSE;  
432 }
433
434 /**
435  * Marshals a double array
436  *
437  * @param str the string to append the marshalled value to
438  * @param byte_order the byte order to use
439  * @param value the array
440  * @param len the length of the array
441  * @returns #TRUE on success
442  */
443 dbus_bool_t
444 _dbus_marshal_double_array (DBusString          *str,
445                             int                  byte_order,
446                             const double        *value,
447                             int                  len)
448 {
449   int i, old_string_len, array_start;
450
451   old_string_len = _dbus_string_get_length (str);
452
453   /* Set the length to 0 temporarily */
454   if (!_dbus_marshal_uint32 (str, byte_order, 0))
455     goto error;
456       
457   array_start = _dbus_string_get_length (str);
458       
459   for (i = 0; i < len; i++)
460     if (!_dbus_marshal_double (str, byte_order, value[i]))
461       goto error;
462
463   /* Write the length now that we know it */
464   _dbus_marshal_set_uint32 (str, byte_order,
465                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
466                             _dbus_string_get_length (str) - array_start);
467   
468   return TRUE;
469   
470  error:
471   /* Restore previous length */
472   _dbus_string_set_length (str, old_string_len);
473   
474   return FALSE;    
475 }
476
477 /**
478  * Marshals a string array
479  *
480  * @param str the string to append the marshalled value to
481  * @param byte_order the byte order to use
482  * @param value the array
483  * @param len the length of the array
484  * @returns #TRUE on success
485  */
486 dbus_bool_t
487 _dbus_marshal_string_array (DBusString  *str,
488                             int          byte_order,
489                             const char **value,
490                             int          len)
491 {
492   int i, old_string_len, array_start;
493
494   old_string_len = _dbus_string_get_length (str);
495
496   /* Set the length to 0 temporarily */
497   if (!_dbus_marshal_uint32 (str, byte_order, 0))
498     goto error;
499
500   array_start = _dbus_string_get_length (str);
501   
502   for (i = 0; i < len; i++)
503     if (!_dbus_marshal_string (str, byte_order, value[i]))
504       goto error;
505
506   /* Write the length now that we know it */
507   _dbus_marshal_set_uint32 (str, byte_order,
508                             _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
509                             _dbus_string_get_length (str) - array_start);
510   
511   return TRUE;
512   
513  error:
514   /* Restore previous length */
515   _dbus_string_set_length (str, old_string_len);
516   
517   return FALSE;      
518 }
519
520
521 /**
522  * Demarshals a double.
523  *
524  * @param str the string containing the data
525  * @param byte_order the byte order
526  * @param pos the position in the string
527  * @param new_pos the new position of the string
528  * @returns the demarshaled double.
529  */
530 double
531 _dbus_demarshal_double (const DBusString  *str,
532                         int          byte_order,
533                         int          pos,
534                         int         *new_pos)
535 {
536   double retval;
537   const char *buffer;
538
539   pos = _DBUS_ALIGN_VALUE (pos, sizeof (double));
540
541   buffer = _dbus_string_get_const_data_len (str, pos, sizeof (double));
542
543   retval = *(double *)buffer;
544   
545   if (byte_order != DBUS_COMPILER_BYTE_ORDER)
546     swap_bytes ((unsigned char *)&retval, sizeof (double));
547
548   if (new_pos)
549     *new_pos = pos + sizeof (double);
550   
551   return retval;  
552 }
553
554 /**
555  * Demarshals a 32 bit signed integer.
556  *
557  * @param str the string containing the data
558  * @param byte_order the byte order
559  * @param pos the position in the string
560  * @param new_pos the new position of the string
561  * @returns the demarshaled integer.
562  */
563 dbus_int32_t
564 _dbus_demarshal_int32  (const DBusString *str,
565                         int               byte_order,
566                         int               pos,
567                         int              *new_pos)
568 {
569   const DBusRealString *real = (const DBusRealString*) str;
570   
571   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t));
572   
573   if (new_pos)
574     *new_pos = pos + sizeof (dbus_int32_t);
575
576   if (byte_order == DBUS_LITTLE_ENDIAN)
577     return DBUS_INT32_FROM_LE (*(dbus_int32_t*)(real->str + pos));
578   else
579     return DBUS_INT32_FROM_BE (*(dbus_int32_t*)(real->str + pos));
580 }
581
582 /**
583  * Demarshals a 32 bit unsigned integer.
584  *
585  * @param str the string containing the data
586  * @param byte_order the byte order
587  * @param pos the position in the string
588  * @param new_pos the new position of the string
589  * @returns the demarshaled integer.
590  */
591 dbus_uint32_t
592 _dbus_demarshal_uint32  (const DBusString *str,
593                          int         byte_order,
594                          int         pos,
595                          int        *new_pos)
596 {
597   const DBusRealString *real = (const DBusRealString*) str;
598   
599   pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t));
600   
601   if (new_pos)
602     *new_pos = pos + sizeof (dbus_uint32_t);
603
604   if (byte_order == DBUS_LITTLE_ENDIAN)
605     return DBUS_UINT32_FROM_LE (*(dbus_uint32_t*)(real->str + pos));
606   else
607     return DBUS_UINT32_FROM_BE (*(dbus_uint32_t*)(real->str + pos));
608 }
609
610 /**
611  * Demarshals an UTF-8 string.
612  *
613  * @todo Should we check the string to make sure
614  * that it's  valid UTF-8, and maybe "fix" the string
615  * if it's broken?
616  *
617  * @todo Should probably demarshal to a DBusString,
618  * having memcpy() in here is Evil(tm).
619  *
620  * @param str the string containing the data
621  * @param byte_order the byte order
622  * @param pos the position in the string
623  * @param new_pos the new position of the string
624  * @returns the demarshaled string.
625  */
626 char *
627 _dbus_demarshal_string (const DBusString *str,
628                         int         byte_order,
629                         int         pos,
630                         int        *new_pos)
631 {
632   int len;
633   char *retval;
634   const char *data;
635   
636   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
637
638   retval = dbus_malloc (len + 1);
639
640   if (!retval)
641     return NULL;
642
643   data = _dbus_string_get_const_data_len (str, pos, len + 1);
644
645   if (!data)
646     return NULL;
647
648   memcpy (retval, data, len + 1);
649
650   if (new_pos)
651     *new_pos = pos + len + 1;
652   
653   return retval;
654 }
655
656 /**
657  * Demarshals a byte array.
658  *
659  * @todo Should probably demarshal to a DBusString,
660  * having memcpy() in here is Evil(tm).
661  *
662  * @param str the string containing the data
663  * @param byte_order the byte order
664  * @param pos the position in the string
665  * @param new_pos the new position of the string
666  * @param array the array
667  * @param array_len length of the demarshaled data
668  
669  * @returns #TRUE on success
670  */
671 dbus_bool_t
672 _dbus_demarshal_byte_array (const DBusString  *str,
673                             int                byte_order,
674                             int                pos,
675                             int               *new_pos,
676                             unsigned char    **array,
677                             int               *array_len)
678 {
679   int len;
680   unsigned char *retval;
681   const char *data;
682
683   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
684
685   if (len == 0)
686     {
687       *array_len = len;
688       *array = NULL;
689
690       if (new_pos)
691         *new_pos = pos;
692       
693       return TRUE;
694     }
695   
696   retval = dbus_malloc (len);
697
698   if (!retval)
699     return FALSE;
700
701   data = _dbus_string_get_const_data_len (str, pos, len);
702
703   if (!data)
704     {
705       dbus_free (retval);
706       return FALSE;
707     }
708
709   memcpy (retval, data, len);
710
711   if (new_pos)
712     *new_pos = pos + len;
713
714   *array = retval;
715   *array_len = len;
716   
717   return TRUE;
718 }
719
720 /**
721  * Demarshals a 32 bit signed integer array.
722  *
723  * @param str the string containing the data
724  * @param byte_order the byte order
725  * @param pos the position in the string
726  * @param new_pos the new position of the string
727  * @param array the array
728  * @param array_len length of the demarshaled data
729  * @returns #TRUE on success
730  */
731 dbus_bool_t
732 _dbus_demarshal_int32_array (const DBusString  *str,
733                              int                byte_order,
734                              int                pos,
735                              int               *new_pos,
736                              dbus_int32_t     **array,
737                              int               *array_len)
738 {
739   int len, i;
740   dbus_int32_t *retval;
741   
742   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos)  / sizeof (dbus_int32_t);
743
744   if (len == 0)
745     {
746       *array_len = 0;
747       *array = NULL;
748
749       if (new_pos)
750         *new_pos = pos;
751       
752       return TRUE;
753     }
754   
755   retval = dbus_new (dbus_int32_t, len);
756   
757   if (!retval)
758     return FALSE;
759
760   for (i = 0; i < len; i++)
761     retval[i] = _dbus_demarshal_int32 (str, byte_order, pos, &pos);
762
763   if (new_pos)
764     *new_pos = pos;
765
766   *array_len = len;
767   *array = retval;
768   
769   return TRUE;
770 }
771
772 /**
773  * Demarshals a 32 bit unsigned integer array.
774  *
775  * @param str the string containing the data
776  * @param byte_order the byte order
777  * @param pos the position in the string
778  * @param new_pos the new position of the string
779  * @param array the array
780  * @param array_len length of the demarshaled data
781  * @returns #TRUE on success
782  */
783 dbus_bool_t
784 _dbus_demarshal_uint32_array (const DBusString  *str,
785                               int                byte_order,
786                               int                pos,
787                               int               *new_pos,
788                               dbus_uint32_t    **array,
789                               int               *array_len)
790 {
791   int len, i;
792   dbus_uint32_t *retval;
793   
794   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (dbus_uint32_t);
795
796   if (len == 0)
797     {
798       *array_len = 0;
799       *array = NULL;
800
801       if (new_pos)
802         *new_pos = pos;
803       
804       return TRUE;
805     }
806   
807   retval = dbus_new (dbus_uint32_t, len);
808
809   if (!retval)
810     return FALSE;
811
812   for (i = 0; i < len; i++)
813     retval[i] = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
814
815   if (new_pos)
816     *new_pos = pos;
817
818   *array_len = len;
819   *array = retval;
820   
821   return TRUE;  
822 }
823
824 /**
825  * Demarshals a double array.
826  *
827  * @param str the string containing the data
828  * @param byte_order the byte order
829  * @param pos the position in the string
830  * @param new_pos the new position of the string
831  * @param array the array
832  * @param array_len length of the demarshaled data
833  * @returns #TRUE on success
834  */
835 dbus_bool_t
836 _dbus_demarshal_double_array (const DBusString  *str,
837                               int                byte_order,
838                               int                pos,
839                               int               *new_pos,
840                               double           **array,
841                               int               *array_len)
842 {
843   int len, i;
844   double *retval;
845   
846   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos) / sizeof (double);
847
848   if (len == 0)
849     {
850       *array_len = 0;
851       *array = NULL;
852
853       if (new_pos)
854         *new_pos = pos;
855       
856       return TRUE;
857     }
858   
859   retval = dbus_new (double, len);
860
861   if (!retval)
862     return FALSE;
863
864   for (i = 0; i < len; i++)
865     retval[i] = _dbus_demarshal_double (str, byte_order, pos, &pos);
866
867   if (new_pos)
868     *new_pos = pos;
869
870   *array_len = len;
871   *array = retval;
872   
873   return TRUE; 
874 }
875
876 /**
877  * Demarshals a string array.
878  *
879  * @param str the string containing the data
880  * @param byte_order the byte order
881  * @param pos the position in the string
882  * @param new_pos the new position of the string
883  * @param array the array
884  * @param array_len length of the demarshaled data
885  * @returns #TRUE on success
886  */
887 dbus_bool_t
888 _dbus_demarshal_string_array (const DBusString   *str,
889                               int                 byte_order,
890                               int                 pos,
891                               int                *new_pos,
892                               char             ***array,
893                               int                *array_len)
894 {
895   int len, i, j;
896   char **retval;
897
898   len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
899
900   if (len == 0)
901     {
902       *array_len = 0;
903       *array = NULL;
904
905       if (new_pos)
906         *new_pos = pos;
907       
908       return TRUE;
909     }
910   
911   retval = dbus_new (char *, len + 1);
912
913   if (!retval)
914     return FALSE;
915
916   retval[len] = NULL;
917   
918   for (i = 0; i < len; i++)
919     {
920       retval[i] = _dbus_demarshal_string (str, byte_order, pos, &pos);
921
922       if (retval[i] == 0)
923         goto error;
924     }
925
926  if (new_pos)
927     *new_pos = pos;
928
929  *array = retval;
930  *array_len = len;
931   
932   return TRUE;
933
934  error:
935   for (j = 0; j < i; j++)
936     dbus_free (retval[i]);
937   dbus_free (retval);
938
939   return FALSE;
940 }
941
942 /** 
943  * Returns the position right after the end of an argument.  PERFORMS
944  * NO VALIDATION WHATSOEVER. The message must have been previously
945  * validated.
946  *
947  * @param str a string
948  * @param byte_order the byte order to use
949  * @param type the type of the argument
950  * @param pos the pos where the arg starts
951  * @param end_pos pointer where the position right
952  * after the end position will follow
953  * @returns TRUE if more data exists after the arg
954  */
955 dbus_bool_t
956 _dbus_marshal_get_arg_end_pos (const DBusString *str,
957                                int               byte_order,
958                                int               type,
959                                int               pos,
960                                int              *end_pos)
961 {
962   if (pos >= _dbus_string_get_length (str))
963     return FALSE;
964
965   switch (type)
966     {
967     case DBUS_TYPE_INVALID:
968       return FALSE;
969       break;
970
971     case DBUS_TYPE_NIL:
972       *end_pos = pos;
973       break;
974
975     case DBUS_TYPE_BYTE:
976       *end_pos = pos + 1;
977       break;
978       
979     case DBUS_TYPE_BOOLEAN:
980       *end_pos = pos + 1;
981       break;
982
983     case DBUS_TYPE_INT32:
984       *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
985
986       break;
987
988     case DBUS_TYPE_UINT32:
989       *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
990
991       break;
992
993     case DBUS_TYPE_DOUBLE:
994       *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (double)) + sizeof (double);
995
996       break;
997
998     case DBUS_TYPE_STRING:
999       {
1000         int len;
1001         
1002         /* Demarshal the length */
1003         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1004
1005         *end_pos = pos + len + 1;
1006       }
1007       break;
1008
1009     case DBUS_TYPE_NAMED:
1010       {
1011         int len;
1012         
1013         /* Demarshal the string length */
1014         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1015
1016         *end_pos = pos + len + 1;
1017         
1018         /* Demarshal the data length */
1019         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1020
1021         *end_pos = pos + len;
1022       }
1023       break;
1024       
1025     case DBUS_TYPE_ARRAY:
1026       {
1027         int len;
1028
1029         /* Demarshal the length (element type is at pos + 0 */
1030         len = _dbus_demarshal_uint32 (str, byte_order, pos + 1, &pos);
1031         
1032         *end_pos = pos + len;
1033       }
1034       break;
1035
1036     case DBUS_TYPE_DICT:
1037       {
1038         int len;
1039
1040         /* Demarshal the length */
1041         len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
1042         
1043         *end_pos = pos + len;
1044       }
1045       break;
1046       
1047     default:
1048       _dbus_warn ("Unknown message arg type %d\n", type);
1049       _dbus_assert_not_reached ("Unknown message argument type\n");
1050       return FALSE;
1051     }
1052
1053   if (*end_pos > _dbus_string_get_length (str))
1054     return FALSE;
1055   
1056   return TRUE;
1057 }
1058
1059 /**
1060  * Demarshals and validates a length; returns < 0 if the validation
1061  * fails. The length is required to be small enough that
1062  * len*sizeof(double) will not overflow, and small enough to fit in a
1063  * signed integer. DOES NOT check whether the length points
1064  * beyond the end of the string, because it doesn't know the
1065  * size of array elements.
1066  *
1067  * @param str the string
1068  * @param byte_order the byte order
1069  * @param pos the unaligned string position (snap to next aligned)
1070  * @param new_pos return location for new position.
1071  */
1072 static int
1073 demarshal_and_validate_len (const DBusString *str,
1074                             int               byte_order,
1075                             int               pos,
1076                             int              *new_pos)
1077 {
1078   int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1079   unsigned int len;
1080
1081   _dbus_assert (new_pos != NULL);
1082   
1083   if ((align_4 + 4) > _dbus_string_get_length (str))
1084     {
1085       _dbus_verbose ("not enough room in message for array length\n");
1086       return -1;
1087     }
1088   
1089   if (!_dbus_string_validate_nul (str, pos,
1090                                   align_4 - pos))
1091     {
1092       _dbus_verbose ("array length alignment padding not initialized to nul\n");
1093       return -1;
1094     }
1095
1096   len = _dbus_demarshal_uint32 (str, byte_order, align_4, new_pos);
1097
1098   /* note that the len is the number of bytes, so we need it to be
1099    * at least SIZE_T_MAX, but make it smaller just to keep things
1100    * sane.  We end up using ints for most sizes to avoid unsigned mess
1101    * so limit to maximum 32-bit signed int divided by at least 8, more
1102    * for a bit of paranoia margin. INT_MAX/32 is about 65 megabytes.
1103    */  
1104 #define MAX_ARRAY_LENGTH (((unsigned int)_DBUS_INT_MAX) / 32)
1105   if (len > MAX_ARRAY_LENGTH)
1106     {
1107       _dbus_verbose ("array length %u exceeds maximum of %u\n",
1108                      len, MAX_ARRAY_LENGTH);
1109       return -1;
1110     }
1111   else
1112     return (int) len;
1113 }
1114
1115 static dbus_bool_t
1116 validate_string (const DBusString *str,
1117                  int               pos,
1118                  int               len_without_nul,
1119                  int              *end_pos)
1120 {
1121   *end_pos = pos + len_without_nul + 1;
1122   
1123   if (*end_pos > _dbus_string_get_length (str))
1124     {
1125       _dbus_verbose ("string length outside length of the message\n");
1126       return FALSE;
1127     }
1128   
1129   if (_dbus_string_get_byte (str, pos + len_without_nul) != '\0')
1130     {
1131       _dbus_verbose ("string arg not nul-terminated\n");
1132       return FALSE;
1133     }
1134   
1135   if (!_dbus_string_validate_utf8 (str, pos, len_without_nul))
1136     {
1137       _dbus_verbose ("string is not valid UTF-8\n");
1138       return FALSE;
1139     }
1140
1141   return TRUE;
1142 }   
1143
1144 /**
1145  * Validates and returns a typecode at a specific position
1146  * in the message
1147  *
1148  * @param str a string
1149  * @param type the type of the argument
1150  * @param pos the pos where the typecode starts
1151  * @param end_pos pointer where the position right
1152  * after the end position will follow
1153  * @returns #TRUE if the type is valid.
1154  */
1155 dbus_bool_t
1156 _dbus_marshal_validate_type   (const DBusString *str,
1157                                int               pos,
1158                                int              *type,
1159                                int              *end_pos)
1160 {
1161   const char *data;
1162   
1163   if (pos >= _dbus_string_get_length (str))
1164     return FALSE;
1165
1166   data = _dbus_string_get_const_data_len (str, pos, 1);
1167
1168   if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_LAST)
1169     {
1170       *type = *data;
1171       *end_pos = pos + 1;
1172       return TRUE;
1173     }
1174   
1175   return FALSE;
1176 }
1177
1178
1179 /** 
1180  * Validates an argument of a specific type, checking that it
1181  * is well-formed, for example no ludicrous length fields, strings
1182  * are nul-terminated, etc.
1183  * Returns the end position of the argument in end_pos, and
1184  * returns #TRUE if a valid arg begins at "pos"
1185  *
1186  * @todo security: need to audit this function.
1187  *
1188  * @todo For array types that can't be invalid, we should not
1189  * walk the whole array validating it. e.g. just skip all the
1190  * int values in an int array.
1191  * 
1192  * @param str a string
1193  * @param byte_order the byte order to use
1194  * @param depth current recursion depth, to prevent excessive recursion
1195  * @param type the type of the argument
1196  * @param pos the pos where the arg starts
1197  * @param end_pos pointer where the position right
1198  * after the end position will follow
1199  * @returns #TRUE if the arg is valid.
1200  */
1201 dbus_bool_t
1202 _dbus_marshal_validate_arg (const DBusString *str,
1203                             int               byte_order,
1204                             int               depth,
1205                             int               type,
1206                             int               pos,
1207                             int              *end_pos)
1208 {
1209   if (pos > _dbus_string_get_length (str))
1210     {
1211       _dbus_verbose ("Validation went off the end of the message\n");
1212       return FALSE;
1213     }
1214
1215 #define MAX_VALIDATION_DEPTH 32
1216   
1217   if (depth > MAX_VALIDATION_DEPTH)
1218     {
1219       _dbus_verbose ("Maximum recursion depth reached validating message\n");
1220       return FALSE;
1221     }
1222   
1223   switch (type)
1224     {
1225     case DBUS_TYPE_INVALID:
1226       return FALSE;
1227       break;
1228
1229     case DBUS_TYPE_NIL:
1230       *end_pos = pos;
1231       break;
1232
1233     case DBUS_TYPE_BYTE:
1234       if (1 > _dbus_string_get_length (str) - pos)
1235         {
1236           _dbus_verbose ("no room for byte value\n");
1237           return FALSE;
1238         }
1239         
1240       *end_pos = pos + 1;
1241       break;
1242       
1243     case DBUS_TYPE_BOOLEAN:
1244       {
1245         unsigned char c;
1246
1247         if (1 > _dbus_string_get_length (str) - pos)
1248           {
1249             _dbus_verbose ("no room for boolean value\n");
1250             return FALSE;
1251           }
1252         
1253         c = _dbus_string_get_byte (str, pos);
1254
1255         if (c != 0 && c != 1)
1256           {
1257             _dbus_verbose ("boolean value must be either 0 or 1, not %d\n", c);
1258             return FALSE;
1259           }
1260         
1261       *end_pos = pos + 1;
1262       break;
1263       }
1264     case DBUS_TYPE_INT32:
1265     case DBUS_TYPE_UINT32:
1266       {
1267         int align_4 = _DBUS_ALIGN_VALUE (pos, 4);
1268         
1269         if (!_dbus_string_validate_nul (str, pos,
1270                                         align_4 - pos))
1271           {
1272             _dbus_verbose ("int32/uint32 alignment padding not initialized to nul\n");
1273             return FALSE;
1274           }
1275
1276         *end_pos = align_4 + 4;
1277       }
1278       break;
1279
1280     case DBUS_TYPE_DOUBLE:
1281       {
1282         int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
1283
1284         _dbus_verbose_bytes_of_string (str, pos, (align_8 + 8 - pos));
1285         
1286         if (!_dbus_string_validate_nul (str, pos,
1287                                         align_8 - pos))
1288           {
1289             _dbus_verbose ("double alignment padding not initialized to nul\n");
1290             return FALSE;
1291           }
1292
1293         *end_pos = align_8 + 8;
1294       }
1295       break;
1296
1297     case DBUS_TYPE_STRING:
1298       {
1299         int len;
1300
1301         /* Demarshal the length, which does NOT include
1302          * nul termination
1303          */
1304         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1305         if (len < 0)
1306           return FALSE;
1307
1308         if (!validate_string (str, pos, len, end_pos))
1309           return FALSE;
1310       }
1311       break;
1312
1313     case DBUS_TYPE_NAMED:
1314       {
1315         int len;
1316
1317         /* Demarshal the string length, which does NOT include
1318          * nul termination
1319          */
1320         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1321         if (len < 0)
1322           return FALSE;
1323
1324         if (!validate_string (str, pos, len, &pos))
1325           return FALSE;
1326
1327         /* Validate data */
1328         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1329         if (len < 0)
1330           return FALSE;
1331
1332         *end_pos = pos + len;
1333       }
1334       break;
1335       
1336     case DBUS_TYPE_ARRAY:
1337       {
1338         int len;
1339         int end;
1340         int array_type;
1341
1342         if (!_dbus_marshal_validate_type (str, pos, &array_type, &pos))
1343           {
1344             _dbus_verbose ("invalid array type\n");
1345             return FALSE;
1346           }
1347         
1348         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1349         if (len < 0)
1350           return FALSE;
1351
1352         if (len > _dbus_string_get_length (str) - pos)
1353           {
1354             _dbus_verbose ("array length outside length of the message\n");
1355             return FALSE;
1356           }
1357         
1358         end = pos + len;
1359         
1360         while (pos < end)
1361           {
1362             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1363                                              array_type, pos, &pos))
1364               return FALSE;
1365           }
1366         
1367         if (pos > end)
1368           {
1369             _dbus_verbose ("array contents exceeds array length\n");
1370             return FALSE;
1371           }
1372
1373         *end_pos = pos;
1374       }
1375       break;
1376
1377       case DBUS_TYPE_DICT:
1378       {
1379         int dict_type;
1380         int len;
1381         int end;
1382         
1383         len = demarshal_and_validate_len (str, byte_order, pos, &pos);
1384         if (len < 0)
1385           return FALSE;
1386
1387         if (len > _dbus_string_get_length (str) - pos)
1388           {
1389             _dbus_verbose ("dict length outside length of the message\n");
1390             return FALSE;
1391           }
1392         
1393         end = pos + len;
1394         
1395         while (pos < end)
1396           {
1397             /* Validate name */
1398             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1399                                              DBUS_TYPE_STRING, pos, &pos))
1400               return FALSE;
1401             
1402             if (!_dbus_marshal_validate_type (str, pos, &dict_type, &pos))
1403               {
1404                 _dbus_verbose ("invalid dict entry type at offset %d\n", pos);
1405                 return FALSE;
1406               }
1407             
1408             /* Validate element */
1409             if (!_dbus_marshal_validate_arg (str, byte_order, depth + 1,
1410                                              dict_type, pos, &pos))
1411               return FALSE;
1412           }
1413         
1414         if (pos > end)
1415           {
1416             _dbus_verbose ("dict contents exceeds array length\n");
1417             return FALSE;
1418           }
1419         *end_pos = pos;
1420       }
1421       break;
1422       
1423     default:
1424       _dbus_verbose ("Unknown message arg type %d\n", type);
1425       return FALSE;
1426     }
1427
1428   if (*end_pos > _dbus_string_get_length (str))
1429     return FALSE;
1430   
1431   return TRUE;
1432 }
1433
1434
1435 /**
1436  * If in verbose mode, print a block of binary data.
1437  *
1438  * @todo right now it prints even if not in verbose mode
1439  * 
1440  * @param data the data
1441  * @param len the length of the data
1442  */
1443 void
1444 _dbus_verbose_bytes (const unsigned char *data,
1445                      int                  len)
1446 {
1447   int i;
1448   const unsigned char *aligned;
1449
1450   _dbus_assert (len >= 0);
1451   
1452   /* Print blanks on first row if appropriate */
1453   aligned = _DBUS_ALIGN_ADDRESS (data, 4);
1454   if (aligned > data)
1455     aligned -= 4;
1456   _dbus_assert (aligned <= data);
1457
1458   if (aligned != data)
1459     {
1460       _dbus_verbose ("%4d\t%p: ", - (data - aligned), aligned); 
1461       while (aligned != data)
1462         {
1463           _dbus_verbose ("    ");
1464           ++aligned;
1465         }
1466     }
1467
1468   /* now print the bytes */
1469   i = 0;
1470   while (i < len)
1471     {
1472       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1473         {
1474           _dbus_verbose ("%4d\t%p: ",
1475                    i, &data[i]);
1476         }
1477       
1478       if (data[i] >= 32 &&
1479           data[i] <= 126)
1480         _dbus_verbose (" '%c' ", data[i]);
1481       else
1482         _dbus_verbose ("0x%s%x ",
1483                  data[i] <= 0xf ? "0" : "", data[i]);
1484
1485       ++i;
1486
1487       if (_DBUS_ALIGN_ADDRESS (&data[i], 4) == &data[i])
1488         {
1489           if (i > 3)
1490             _dbus_verbose ("BE: %d LE: %d",
1491                            _dbus_unpack_uint32 (DBUS_BIG_ENDIAN, &data[i-4]),
1492                            _dbus_unpack_uint32 (DBUS_LITTLE_ENDIAN, &data[i-4]));
1493
1494           if (i > 7 && 
1495               _DBUS_ALIGN_ADDRESS (&data[i], 8) == &data[i])
1496             {
1497               _dbus_verbose (" dbl: %g",
1498                              *(double*)&data[i-8]);
1499             }
1500           
1501           _dbus_verbose ("\n");
1502         }
1503     }
1504
1505   _dbus_verbose ("\n");
1506 }
1507
1508 /**
1509  * Dump the given part of the string to verbose log.
1510  *
1511  * @param str the string
1512  * @param start the start of range to dump
1513  * @param len length of range
1514  */
1515 void
1516 _dbus_verbose_bytes_of_string (const DBusString    *str,
1517                                int                  start,
1518                                int                  len)
1519 {
1520   const char *d;
1521   int real_len;
1522
1523   real_len = _dbus_string_get_length (str);
1524
1525   _dbus_assert (start >= 0);
1526   
1527   if (start > real_len)
1528     {
1529       _dbus_verbose ("  [%d,%d) is not inside string of length %d\n",
1530                      start, len, real_len);
1531       return;
1532     }
1533
1534   if ((start + len) > real_len)
1535     {
1536       _dbus_verbose ("  [%d,%d) extends outside string of length %d\n",
1537                      start, len, real_len);
1538       len = real_len - start;
1539     }
1540   
1541   d = _dbus_string_get_const_data_len (str, start, len);
1542
1543   _dbus_verbose_bytes (d, len);
1544 }
1545
1546 /** @} */
1547
1548 #ifdef DBUS_BUILD_TESTS
1549 #include "dbus-test.h"
1550 #include <stdio.h>
1551
1552 dbus_bool_t
1553 _dbus_marshal_test (void)
1554 {
1555   DBusString str;
1556   char *tmp1, *tmp2;
1557   dbus_int32_t array1[3] = { 0x123, 0x456, 0x789 }, *array2;
1558   int pos = 0, len;
1559   
1560   if (!_dbus_string_init (&str))
1561     _dbus_assert_not_reached ("failed to init string");
1562
1563   /* Marshal doubles */
1564   if (!_dbus_marshal_double (&str, DBUS_BIG_ENDIAN, 3.14))
1565     _dbus_assert_not_reached ("could not marshal double value");
1566   if (!_dbus_demarshal_double (&str, DBUS_BIG_ENDIAN, pos, &pos) == 3.14)
1567     _dbus_assert_not_reached ("demarshal failed");
1568
1569   if (!_dbus_marshal_double (&str, DBUS_LITTLE_ENDIAN, 3.14))
1570     _dbus_assert_not_reached ("could not marshal double value");
1571   if (!_dbus_demarshal_double (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 3.14)
1572     _dbus_assert_not_reached ("demarshal failed");
1573   
1574   /* Marshal signed integers */
1575   if (!_dbus_marshal_int32 (&str, DBUS_BIG_ENDIAN, -12345678))
1576     _dbus_assert_not_reached ("could not marshal signed integer value");
1577   if (!_dbus_demarshal_int32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == -12345678)
1578     _dbus_assert_not_reached ("demarshal failed");
1579
1580   if (!_dbus_marshal_int32 (&str, DBUS_LITTLE_ENDIAN, -12345678))
1581     _dbus_assert_not_reached ("could not marshal signed integer value");
1582   if (!_dbus_demarshal_int32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == -12345678)
1583     _dbus_assert_not_reached ("demarshal failed");
1584   
1585   /* Marshal unsigned integers */
1586   if (!_dbus_marshal_uint32 (&str, DBUS_BIG_ENDIAN, 0x12345678))
1587     _dbus_assert_not_reached ("could not marshal signed integer value");
1588   if (!_dbus_demarshal_uint32 (&str, DBUS_BIG_ENDIAN, pos, &pos) == 0x12345678)
1589     _dbus_assert_not_reached ("demarshal failed");
1590   
1591   if (!_dbus_marshal_uint32 (&str, DBUS_LITTLE_ENDIAN, 0x12345678))
1592     _dbus_assert_not_reached ("could not marshal signed integer value");
1593   if (!_dbus_demarshal_uint32 (&str, DBUS_LITTLE_ENDIAN, pos, &pos) == 0x12345678)
1594     _dbus_assert_not_reached ("demarshal failed");
1595
1596   /* Marshal strings */
1597   tmp1 = "This is the dbus test string";
1598   if (!_dbus_marshal_string (&str, DBUS_BIG_ENDIAN, tmp1))
1599     _dbus_assert_not_reached ("could not marshal string");
1600   tmp2 = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, pos, &pos);
1601   if (!strcmp (tmp1, tmp2) == 0)
1602     _dbus_assert_not_reached ("demarshal failed");
1603   dbus_free (tmp2);
1604
1605   tmp1 = "This is the dbus test string";
1606   if (!_dbus_marshal_string (&str, DBUS_LITTLE_ENDIAN, tmp1))
1607     _dbus_assert_not_reached ("could not marshal string");
1608   tmp2 = _dbus_demarshal_string (&str, DBUS_LITTLE_ENDIAN, pos, &pos);
1609   if (!strcmp (tmp1, tmp2) == 0)
1610     _dbus_assert_not_reached ("demarshal failed");
1611   dbus_free (tmp2);
1612
1613   /* Marshal signed integer arrays */
1614   if (!_dbus_marshal_int32_array (&str, DBUS_BIG_ENDIAN, array1, 3))
1615     _dbus_assert_not_reached ("could not marshal integer array");
1616   if (!_dbus_demarshal_int32_array (&str, DBUS_BIG_ENDIAN, pos, &pos, &array2, &len))
1617     _dbus_assert_not_reached ("could not demarshal integer array");
1618
1619   if (len != 3)
1620     _dbus_assert_not_reached ("Signed integer array lengths differ!\n");
1621   dbus_free (array2);
1622   
1623   _dbus_string_free (&str);
1624   
1625       
1626   return TRUE;
1627 }
1628
1629 #endif /* DBUS_BUILD_TESTS */