1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #include <config.h>
24:
25: #ifndef DOXYGEN_SHOULD_SKIP_THIS
26:
27: #ifdef DBUS_BUILD_TESTS
28: #include "dbus-message-factory.h"
29: #include "dbus-message-private.h"
30: #include "dbus-test.h"
31: #include <stdio.h>
32:
33: typedef enum
34: {
35: CHANGE_TYPE_ADJUST,
36: CHANGE_TYPE_ABSOLUTE
37: } ChangeType;
38:
39: #define BYTE_ORDER_OFFSET 0
40: #define TYPE_OFFSET 1
41: #define BODY_LENGTH_OFFSET 4
42: #define FIELDS_ARRAY_LENGTH_OFFSET 12
43:
44: static void
45: iter_recurse (DBusMessageDataIter *iter)
46: {
47: iter->depth += 1;
48: _dbus_assert (iter->depth < _DBUS_MESSAGE_DATA_MAX_NESTING);
49: _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
50: }
51:
52: static int
53: iter_get_sequence (DBusMessageDataIter *iter)
54: {
55: _dbus_assert (iter->sequence_nos[iter->depth] >= 0);
56: return iter->sequence_nos[iter->depth];
57: }
58:
59: static void
60: iter_set_sequence (DBusMessageDataIter *iter,
61: int sequence)
62: {
63: _dbus_assert (sequence >= 0);
64: iter->sequence_nos[iter->depth] = sequence;
65: }
66:
67: static void
68: iter_unrecurse (DBusMessageDataIter *iter)
69: {
70: iter->depth -= 1;
71: _dbus_assert (iter->depth >= 0);
72: }
73:
74: static void
75: iter_next (DBusMessageDataIter *iter)
76: {
77: iter->sequence_nos[iter->depth] += 1;
78: }
79:
80: static dbus_bool_t
81: iter_first_in_series (DBusMessageDataIter *iter)
82: {
83: int i;
84:
85: i = iter->depth;
86: while (i < _DBUS_MESSAGE_DATA_MAX_NESTING)
87: {
88: if (iter->sequence_nos[i] != 0)
89: return FALSE;
90: ++i;
91: }
92: return TRUE;
93: }
94:
95: typedef dbus_bool_t (* DBusInnerGeneratorFunc) (DBusMessageDataIter *iter,
96: DBusMessage **message_p);
97: typedef dbus_bool_t (* DBusMessageGeneratorFunc) (DBusMessageDataIter *iter,
98: DBusString *data,
99: DBusValidity *expected_validity);
100:
101: static void
102: set_reply_serial (DBusMessage *message)
103: {
104: if (message == NULL)
105: _dbus_assert_not_reached ("oom");
106: if (!dbus_message_set_reply_serial (message, 100))
107: _dbus_assert_not_reached ("oom");
108: }
109:
110: static dbus_bool_t
111: generate_trivial_inner (DBusMessageDataIter *iter,
112: DBusMessage **message_p)
113: {
114: DBusMessage *message;
115:
116: switch (iter_get_sequence (iter))
117: {
118: case 0:
119: message = dbus_message_new_method_call ("org.freedesktop.TextEditor",
120: "/foo/bar",
121: "org.freedesktop.DocumentFactory",
122: "Create");
123: break;
124: case 1:
125: message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
126: set_reply_serial (message);
127: break;
128: case 2:
129: message = dbus_message_new_signal ("/foo/bar",
130: "org.freedesktop.DocumentFactory",
131: "Created");
132: break;
133: case 3:
134: message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
135:
136: if (!dbus_message_set_error_name (message,
137: "org.freedesktop.TestErrorName"))
138: _dbus_assert_not_reached ("oom");
139:
140: {
141: DBusMessageIter iter;
142: const char *v_STRING = "This is an error";
143:
144: dbus_message_iter_init_append (message, &iter);
145: if (!dbus_message_iter_append_basic (&iter,
146: DBUS_TYPE_STRING,
147: &v_STRING))
148: _dbus_assert_not_reached ("oom");
149: }
150:
151: set_reply_serial (message);
152: break;
153: default:
154: return FALSE;
155: }
156:
157: if (message == NULL)
158: _dbus_assert_not_reached ("oom");
159:
160: *message_p = message;
161:
162: return TRUE;
163: }
164:
165: static dbus_bool_t
166: generate_many_bodies_inner (DBusMessageDataIter *iter,
167: DBusMessage **message_p)
168: {
169: DBusMessage *message;
170: DBusString signature;
171: DBusString body;
172:
173:
174: message = dbus_message_new_method_call ("o.z.F",
175: "/",
176: "o.z.B",
177: "Nah");
178: if (message == NULL)
179: _dbus_assert_not_reached ("oom");
180:
181: set_reply_serial (message);
182:
183: if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
184: _dbus_assert_not_reached ("oom");
185:
186: if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter),
187: message->byte_order,
188: &signature, &body))
189: {
190: const char *v_SIGNATURE;
191:
192: v_SIGNATURE = _dbus_string_get_const_data (&signature);
193: if (!_dbus_header_set_field_basic (&message->header,
194: DBUS_HEADER_FIELD_SIGNATURE,
195: DBUS_TYPE_SIGNATURE,
196: &v_SIGNATURE))
197: _dbus_assert_not_reached ("oom");
198:
199: if (!_dbus_string_move (&body, 0, &message->body, 0))
200: _dbus_assert_not_reached ("oom");
201:
202: _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET,
203: _dbus_string_get_length (&message->body),
204: message->byte_order);
205:
206: *message_p = message;
207: }
208: else
209: {
210: dbus_message_unref (message);
211: *message_p = NULL;
212: }
213:
214: _dbus_string_free (&signature);
215: _dbus_string_free (&body);
216:
217: return *message_p != NULL;
218: }
219:
220: static void
221: generate_from_message (DBusString *data,
222: DBusValidity *expected_validity,
223: DBusMessage *message)
224: {
225: _dbus_message_set_serial (message, 1);
226: _dbus_message_lock (message);
227:
228: *expected_validity = DBUS_VALID;
229:
230:
231: if (!_dbus_string_move (&message->header.data, 0,
232: data, 0))
233: _dbus_assert_not_reached ("oom");
234:
235: if (!_dbus_string_copy (&message->body, 0,
236: data, _dbus_string_get_length (data)))
237: _dbus_assert_not_reached ("oom");
238: }
239:
240: static dbus_bool_t
241: generate_outer (DBusMessageDataIter *iter,
242: DBusString *data,
243: DBusValidity *expected_validity,
244: DBusInnerGeneratorFunc func)
245: {
246: DBusMessage *message;
247:
248: message = NULL;
249: if (!(*func)(iter, &message))
250: return FALSE;
251:
252: iter_next (iter);
253:
254: _dbus_assert (message != NULL);
255:
256: generate_from_message (data, expected_validity, message);
257:
258: dbus_message_unref (message);
259:
260: return TRUE;
261: }
262:
263: static dbus_bool_t
264: generate_trivial (DBusMessageDataIter *iter,
265: DBusString *data,
266: DBusValidity *expected_validity)
267: {
268: return generate_outer (iter, data, expected_validity,
269: generate_trivial_inner);
270: }
271:
272: static dbus_bool_t
273: generate_many_bodies (DBusMessageDataIter *iter,
274: DBusString *data,
275: DBusValidity *expected_validity)
276: {
277: return generate_outer (iter, data, expected_validity,
278: generate_many_bodies_inner);
279: }
280:
281: static DBusMessage*
282: simple_method_call (void)
283: {
284: DBusMessage *message;
285:
286: message = dbus_message_new_method_call ("o.b.Q",
287: "/f/b",
288: "o.b.Z",
289: "Fro");
290: if (message == NULL)
291: _dbus_assert_not_reached ("oom");
292: return message;
293: }
294:
295: static DBusMessage*
296: simple_signal (void)
297: {
298: DBusMessage *message;
299: message = dbus_message_new_signal ("/f/b",
300: "o.b.Z",
301: "Fro");
302: if (message == NULL)
303: _dbus_assert_not_reached ("oom");
304: return message;
305: }
306:
307: static DBusMessage*
308: simple_method_return (void)
309: {
310: DBusMessage *message;
311: message = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_RETURN);
312: if (message == NULL)
313: _dbus_assert_not_reached ("oom");
314:
315: set_reply_serial (message);
316:
317: return message;
318: }
319:
320: static DBusMessage*
321: simple_error (void)
322: {
323: DBusMessage *message;
324: message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
325: if (message == NULL)
326: _dbus_assert_not_reached ("oom");
327:
328: if (!dbus_message_set_error_name (message, "foo.bar"))
329: _dbus_assert_not_reached ("oom");
330:
331: set_reply_serial (message);
332:
333: return message;
334: }
335:
336: static dbus_bool_t
337: generate_special (DBusMessageDataIter *iter,
338: DBusString *data,
339: DBusValidity *expected_validity)
340: {
341: int item_seq;
342: DBusMessage *message;
343: int pos;
344: dbus_int32_t v_INT32;
345:
346: _dbus_assert (_dbus_string_get_length (data) == 0);
347:
348: message = NULL;
349: pos = -1;
350: v_INT32 = 42;
351: item_seq = iter_get_sequence (iter);
352:
353: if (item_seq == 0)
354: {
355: message = simple_method_call ();
356: if (!dbus_message_append_args (message,
357: DBUS_TYPE_INT32, &v_INT32,
358: DBUS_TYPE_INT32, &v_INT32,
359: DBUS_TYPE_INT32, &v_INT32,
360: DBUS_TYPE_INVALID))
361: _dbus_assert_not_reached ("oom");
362:
363: _dbus_header_get_field_raw (&message->header,
364: DBUS_HEADER_FIELD_SIGNATURE,
365: NULL, &pos);
366: generate_from_message (data, expected_validity, message);
367:
368:
369: _dbus_string_set_byte (data, pos + 1, '$');
370:
371: *expected_validity = DBUS_INVALID_UNKNOWN_TYPECODE;
372: }
373: else if (item_seq == 1)
374: {
375: char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH+2];
376: const char *v_STRING;
377: int i;
378:
379: message = simple_method_call ();
380: if (!dbus_message_append_args (message,
381: DBUS_TYPE_INT32, &v_INT32,
382: DBUS_TYPE_INT32, &v_INT32,
383: DBUS_TYPE_INT32, &v_INT32,
384: DBUS_TYPE_INVALID))
385: _dbus_assert_not_reached ("oom");
386:
387: i = 0;
388: while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
389: {
390: long_sig[i] = DBUS_TYPE_ARRAY;
391: ++i;
392: }
393: long_sig[i] = DBUS_TYPE_INVALID;
394:
395: v_STRING = long_sig;
396: if (!_dbus_header_set_field_basic (&message->header,
397: DBUS_HEADER_FIELD_SIGNATURE,
398: DBUS_TYPE_SIGNATURE,
399: &v_STRING))
400: _dbus_assert_not_reached ("oom");
401:
402: _dbus_header_get_field_raw (&message->header,
403: DBUS_HEADER_FIELD_SIGNATURE,
404: NULL, &pos);
405: generate_from_message (data, expected_validity, message);
406:
407: *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
408: }
409: else if (item_seq == 2)
410: {
411: char long_sig[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2+4];
412: const char *v_STRING;
413: int i;
414:
415: message = simple_method_call ();
416: if (!dbus_message_append_args (message,
417: DBUS_TYPE_INT32, &v_INT32,
418: DBUS_TYPE_INT32, &v_INT32,
419: DBUS_TYPE_INT32, &v_INT32,
420: DBUS_TYPE_INVALID))
421: _dbus_assert_not_reached ("oom");
422:
423: i = 0;
424: while (i <= (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH + 1))
425: {
426: long_sig[i] = DBUS_STRUCT_BEGIN_CHAR;
427: ++i;
428: }
429:
430: long_sig[i] = DBUS_TYPE_INT32;
431: ++i;
432:
433: while (i < (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH*2 + 3))
434: {
435: long_sig[i] = DBUS_STRUCT_END_CHAR;
436: ++i;
437: }
438: long_sig[i] = DBUS_TYPE_INVALID;
439:
440: v_STRING = long_sig;
441: if (!_dbus_header_set_field_basic (&message->header,
442: DBUS_HEADER_FIELD_SIGNATURE,
443: DBUS_TYPE_SIGNATURE,
444: &v_STRING))
445: _dbus_assert_not_reached ("oom");
446:
447: _dbus_header_get_field_raw (&message->header,
448: DBUS_HEADER_FIELD_SIGNATURE,
449: NULL, &pos);
450: generate_from_message (data, expected_validity, message);
451:
452: *expected_validity = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
453: }
454: else if (item_seq == 3)
455: {
456: message = simple_method_call ();
457: if (!dbus_message_append_args (message,
458: DBUS_TYPE_INT32, &v_INT32,
459: DBUS_TYPE_INT32, &v_INT32,
460: DBUS_TYPE_INT32, &v_INT32,
461: DBUS_TYPE_INVALID))
462: _dbus_assert_not_reached ("oom");
463:
464: _dbus_header_get_field_raw (&message->header,
465: DBUS_HEADER_FIELD_SIGNATURE,
466: NULL, &pos);
467: generate_from_message (data, expected_validity, message);
468:
469: _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
470:
471: *expected_validity = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
472: }
473: else if (item_seq == 4)
474: {
475: message = simple_method_call ();
476: if (!dbus_message_append_args (message,
477: DBUS_TYPE_INT32, &v_INT32,
478: DBUS_TYPE_INT32, &v_INT32,
479: DBUS_TYPE_INT32, &v_INT32,
480: DBUS_TYPE_INVALID))
481: _dbus_assert_not_reached ("oom");
482:
483: _dbus_header_get_field_raw (&message->header,
484: DBUS_HEADER_FIELD_SIGNATURE,
485: NULL, &pos);
486: generate_from_message (data, expected_validity, message);
487:
488: _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_END_CHAR);
489:
490: *expected_validity = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
491: }
492: else if (item_seq == 5)
493: {
494: message = simple_method_call ();
495: if (!dbus_message_append_args (message,
496: DBUS_TYPE_INT32, &v_INT32,
497: DBUS_TYPE_INT32, &v_INT32,
498: DBUS_TYPE_INT32, &v_INT32,
499: DBUS_TYPE_INVALID))
500: _dbus_assert_not_reached ("oom");
501:
502: _dbus_header_get_field_raw (&message->header,
503: DBUS_HEADER_FIELD_SIGNATURE,
504: NULL, &pos);
505: generate_from_message (data, expected_validity, message);
506:
507: _dbus_string_set_byte (data, pos + 1, DBUS_STRUCT_BEGIN_CHAR);
508: _dbus_string_set_byte (data, pos + 2, DBUS_STRUCT_END_CHAR);
509:
510: *expected_validity = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
511: }
512: else if (item_seq == 6)
513: {
514: message = simple_method_call ();
515: generate_from_message (data, expected_validity, message);
516:
517: _dbus_string_set_byte (data, TYPE_OFFSET, DBUS_MESSAGE_TYPE_INVALID);
518:
519: *expected_validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
520: }
521: else if (item_seq == 7)
522: {
523:
524: message = simple_method_call ();
525: generate_from_message (data, expected_validity, message);
526:
527: _dbus_string_set_byte (data, TYPE_OFFSET, 100);
528:
529: *expected_validity = DBUS_VALID;
530: }
531: else if (item_seq == 8)
532: {
533: message = simple_method_call ();
534: generate_from_message (data, expected_validity, message);
535:
536: _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET,
537: DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
538: message->byte_order);
539: _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET,
540: DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4,
541: message->byte_order);
542: *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG;
543: }
544: else if (item_seq == 9)
545: {
546: const char *v_STRING = "not a valid bus name";
547: message = simple_method_call ();
548:
549: if (!_dbus_header_set_field_basic (&message->header,
550: DBUS_HEADER_FIELD_SENDER,
551: DBUS_TYPE_STRING, &v_STRING))
552: _dbus_assert_not_reached ("oom");
553:
554: generate_from_message (data, expected_validity, message);
555:
556: *expected_validity = DBUS_INVALID_BAD_SENDER;
557: }
558: else if (item_seq == 10)
559: {
560: message = simple_method_call ();
561:
562: if (!dbus_message_set_interface (message, DBUS_INTERFACE_LOCAL))
563: _dbus_assert_not_reached ("oom");
564:
565: generate_from_message (data, expected_validity, message);
566:
567: *expected_validity = DBUS_INVALID_USES_LOCAL_INTERFACE;
568: }
569: else if (item_seq == 11)
570: {
571: message = simple_method_call ();
572:
573: if (!dbus_message_set_path (message, DBUS_PATH_LOCAL))
574: _dbus_assert_not_reached ("oom");
575:
576: generate_from_message (data, expected_validity, message);
577:
578: *expected_validity = DBUS_INVALID_USES_LOCAL_PATH;
579: }
580: else if (item_seq ==