STEP06 ? add dissect_kerberos_AD_AP_OPTIONS
[metze/wireshark/wip.git] / epan / tvbtest.c
1 /* tvbtest.c
2  * Standalone program to test functionality of tvbuffs.
3  *
4  * tvbtest : tvbtest.o tvbuff.o except.o
5  *
6  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  *
10  */
11
12 #include "config.h"
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "tvbuff.h"
19 #include "exceptions.h"
20 #include "wsutil/pint.h"
21
22 gboolean failed = FALSE;
23
24 /* Tests a tvbuff against the expected pattern/length.
25  * Returns TRUE if all tests succeeed, FALSE if any test fails */
26 static gboolean
27 test(tvbuff_t *tvb, const gchar* name,
28      guint8* expected_data, guint expected_length, guint expected_reported_length)
29 {
30         guint                   length;
31         guint                   reported_length;
32         guint8                  *ptr;
33         volatile gboolean       ex_thrown;
34         volatile guint32        val32;
35         guint32                 expected32;
36         guint                   incr, i;
37
38         length = tvb_captured_length(tvb);
39
40         if (length != expected_length) {
41                 printf("01: Failed TVB=%s Length of tvb=%u while expected length=%u\n",
42                                 name, length, expected_length);
43                 failed = TRUE;
44                 return FALSE;
45         }
46
47         reported_length = tvb_reported_length(tvb);
48
49         if (reported_length != expected_reported_length) {
50                 printf("01: Failed TVB=%s Reported length of tvb=%u while expected reported length=%u\n",
51                                 name, reported_length, expected_reported_length);
52                 failed = TRUE;
53                 return FALSE;
54         }
55
56         /* Test boundary case. A BoundsError exception should be thrown. */
57         ex_thrown = FALSE;
58         TRY {
59                 tvb_get_ptr(tvb, 0, length + 1);
60         }
61         CATCH(BoundsError) {
62                 ex_thrown = TRUE;
63         }
64         CATCH(FragmentBoundsError) {
65                 printf("02: Caught wrong exception: FragmentBoundsError\n");
66         }
67         CATCH(ReportedBoundsError) {
68                 printf("02: Caught wrong exception: ReportedBoundsError\n");
69         }
70         CATCH_ALL {
71                 printf("02: Caught wrong exception: %lu\n", exc->except_id.except_code);
72         }
73         ENDTRY;
74
75         if (!ex_thrown) {
76                 printf("02: Failed TVB=%s No BoundsError when retrieving %u bytes\n",
77                                 name, length + 1);
78                 failed = TRUE;
79                 return FALSE;
80         }
81
82         /* Test boundary case with reported_length+1. A ReportedBoundsError
83            exception should be thrown. */
84         ex_thrown = FALSE;
85         TRY {
86                 tvb_get_ptr(tvb, 0, reported_length + 1);
87         }
88         CATCH(BoundsError) {
89                 printf("03: Caught wrong exception: BoundsError\n");
90         }
91         CATCH(FragmentBoundsError) {
92                 printf("03: Caught wrong exception: FragmentBoundsError\n");
93         }
94         CATCH(ReportedBoundsError) {
95                 ex_thrown = TRUE;
96         }
97         CATCH_ALL {
98                 printf("03: Caught wrong exception: %lu\n", exc->except_id.except_code);
99         }
100         ENDTRY;
101
102         if (!ex_thrown) {
103                 printf("03: Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
104                                 name, reported_length + 1);
105                 failed = TRUE;
106                 return FALSE;
107         }
108
109         /* Test boundary case. A BoundsError exception should be thrown. */
110         ex_thrown = FALSE;
111         TRY {
112                 tvb_get_ptr(tvb, -1, 2);
113         }
114         CATCH(BoundsError) {
115                 ex_thrown = TRUE;
116         }
117         CATCH(FragmentBoundsError) {
118                 printf("04: Caught wrong exception: FragmentBoundsError\n");
119         }
120         CATCH(ReportedBoundsError) {
121                 printf("04: Caught wrong exception: ReportedBoundsError\n");
122         }
123         CATCH_ALL {
124                 printf("04: Caught wrong exception: %lu\n", exc->except_id.except_code);
125         }
126         ENDTRY;
127
128         if (!ex_thrown) {
129                 printf("04: Failed TVB=%s No BoundsError when retrieving 2 bytes from"
130                                 " offset -1\n", name);
131                 failed = TRUE;
132                 return FALSE;
133         }
134
135         /* Test boundary case. A BoundsError exception should not be thrown. */
136         ex_thrown = FALSE;
137         TRY {
138                 tvb_get_ptr(tvb, 0, length ? 1 : 0);
139         }
140         CATCH(BoundsError) {
141                 ex_thrown = TRUE;
142         }
143         CATCH(FragmentBoundsError) {
144                 printf("05: Caught wrong exception: FragmentBoundsError\n");
145         }
146         CATCH(ReportedBoundsError) {
147                 printf("05: Caught wrong exception: ReportedBoundsError\n");
148         }
149         CATCH_ALL {
150                 printf("05: Caught wrong exception: %lu\n", exc->except_id.except_code);
151         }
152         ENDTRY;
153
154         if (ex_thrown) {
155                 printf("05: Failed TVB=%s BoundsError when retrieving 1 bytes from"
156                                 " offset 0\n", name);
157                 failed = TRUE;
158                 return FALSE;
159         }
160
161         /* Test boundary case. A BoundsError exception should not be thrown. */
162         ex_thrown = FALSE;
163         TRY {
164                 tvb_get_ptr(tvb, -1, length ? 1 : 0);
165         }
166         CATCH(BoundsError) {
167                 ex_thrown = TRUE;
168         }
169         CATCH(FragmentBoundsError) {
170                 printf("06: Caught wrong exception: FragmentBoundsError\n");
171         }
172         CATCH(ReportedBoundsError) {
173                 printf("06: Caught wrong exception: ReportedBoundsError\n");
174         }
175         CATCH_ALL {
176                 printf("06: Caught wrong exception: %lu\n", exc->except_id.except_code);
177         }
178         ENDTRY;
179
180         if (ex_thrown) {
181                 printf("06: Failed TVB=%s BoundsError when retrieving 1 bytes from"
182                                 " offset -1\n", name);
183                 failed = TRUE;
184                 return FALSE;
185         }
186
187
188         /* Check data at boundary. An exception should not be thrown. */
189         if (length >= 4) {
190                 ex_thrown = FALSE;
191                 TRY {
192                         val32 = tvb_get_ntohl(tvb, 0);
193                 }
194                 CATCH_ALL {
195                         ex_thrown = TRUE;
196                 }
197                 ENDTRY;
198
199                 if (ex_thrown) {
200                         printf("07: Failed TVB=%s Exception when retrieving "
201                                         "guint32 from offset 0\n", name);
202                         failed = TRUE;
203                         return FALSE;
204                 }
205
206                 expected32 = pntoh32(expected_data);
207                 if (val32 != expected32) {
208                         printf("08: Failed TVB=%s  guint32 @ 0 %u != expected %u\n",
209                                         name, val32, expected32);
210                         failed = TRUE;
211                         return FALSE;
212                 }
213         }
214
215         /* Check data at boundary. An exception should not be thrown. */
216         if (length >= 4) {
217                 ex_thrown = FALSE;
218                 TRY {
219                         val32 = tvb_get_ntohl(tvb, -4);
220                 }
221                 CATCH_ALL {
222                         ex_thrown = TRUE;
223                 }
224                 ENDTRY;
225
226                 if (ex_thrown) {
227                         printf("09: Failed TVB=%s Exception when retrieving "
228                                         "guint32 from offset 0\n", name);
229                         failed = TRUE;
230                         return FALSE;
231                 }
232
233                 expected32 = pntoh32(&expected_data[length-4]);
234                 if (val32 != expected32) {
235                         printf("10: Failed TVB=%s guint32 @ -4 %u != expected %u\n",
236                                         name, val32, expected32);
237                         failed = TRUE;
238                         return FALSE;
239                 }
240         }
241
242         /* Sweep across data in various sized increments checking
243          * tvb_memdup() */
244         for (incr = 1; incr < length; incr++) {
245                 for (i = 0; i < length - incr; i += incr) {
246                         ptr = (guint8*)tvb_memdup(NULL, tvb, i, incr);
247                         if (memcmp(ptr, &expected_data[i], incr) != 0) {
248                                 printf("11: Failed TVB=%s Offset=%u Length=%u "
249                                                 "Bad memdup\n",
250                                                 name, i, incr);
251                                 failed = TRUE;
252                                 wmem_free(NULL, ptr);
253                                 return FALSE;
254                         }
255                         wmem_free(NULL, ptr);
256                 }
257         }
258
259         /* One big memdup */
260         ptr = (guint8*)tvb_memdup(NULL, tvb, 0, -1);
261         if ((length != 0 && memcmp(ptr, expected_data, length) != 0) ||
262             (length == 0 && ptr != NULL)) {
263                 printf("12: Failed TVB=%s Offset=0 Length=-1 "
264                                 "Bad memdup\n", name);
265                 failed = TRUE;
266                 wmem_free(NULL, ptr);
267                 return FALSE;
268         }
269         wmem_free(NULL, ptr);
270
271
272         printf("Passed TVB=%s\n", name);
273
274         return TRUE;
275 }
276
277 static void
278 run_tests(void)
279 {
280         int             i, j;
281
282         tvbuff_t        *tvb_parent;
283         tvbuff_t        *tvb_empty;
284         tvbuff_t        *tvb_small[3];
285         tvbuff_t        *tvb_large[3];
286         tvbuff_t        *tvb_subset[6];
287         tvbuff_t        *tvb_empty_subset;
288         guint8          *small[3];
289         guint           small_length[3];
290         guint           small_reported_length[3];
291         guint8          *large[3];
292         guint           large_length[3];
293         guint           large_reported_length[3];
294         guint8          *subset[6];
295         guint           subset_length[6];
296         guint           subset_reported_length[6];
297         guint8          temp;
298         guint8          *comp[6];
299         tvbuff_t        *tvb_comp[6];
300         guint           comp_length[6];
301         guint           comp_reported_length[6];
302         int             len;
303
304         tvb_parent = tvb_new_real_data("", 0, 0);
305         for (i = 0; i < 3; i++) {
306                 small[i] = g_new(guint8, 16);
307
308                 temp = 16 * i;
309                 for (j = 0; j < 16; j++) {
310                         small[i][j] = temp + j;
311                 }
312                 small_length[i] = 16;
313                 small_reported_length[i] = 17;
314                 tvb_small[i] = tvb_new_child_real_data(tvb_parent, small[i], 16, 17);
315                 tvb_set_free_cb(tvb_small[i], g_free);
316         }
317
318         for (i = 0; i < 3; i++) {
319                 large[i] = g_new(guint8, 19);
320
321                 temp = 19 * i;
322                 for (j = 0; j < 19; j++) {
323                         large[i][j] = temp + j;
324                 }
325
326                 large_length[i] = 19;
327                 large_reported_length[i] = 20;
328                 tvb_large[i] = tvb_new_child_real_data(tvb_parent, large[i], 19, 20);
329                 tvb_set_free_cb(tvb_large[i], g_free);
330         }
331
332         /* Test empty tvb */
333         tvb_empty = tvb_new_child_real_data(tvb_parent, NULL, 0, 1);
334         test(tvb_empty, "Empty", NULL, 0, 1);
335
336         /* Test the "real" tvbuff objects. */
337         test(tvb_small[0], "Small 0", small[0], small_length[0], small_reported_length[0]);
338         test(tvb_small[1], "Small 1", small[1], small_length[1], small_reported_length[1]);
339         test(tvb_small[2], "Small 2", small[2], small_length[2], small_reported_length[2]);
340
341         test(tvb_large[0], "Large 0", large[0], large_length[0], large_reported_length[0]);
342         test(tvb_large[1], "Large 1", large[1], large_length[1], large_reported_length[1]);
343         test(tvb_large[2], "Large 2", large[2], large_length[2], large_reported_length[2]);
344
345         subset_length[0]          = 8;
346         subset_reported_length[0] = 9;
347         tvb_subset[0]             = tvb_new_subset_length_caplen(tvb_small[0], 0, 8, 9);
348         subset[0]                 = &small[0][0];
349
350         subset_length[1]          = 10;
351         subset_reported_length[1] = 11;
352         tvb_subset[1]             = tvb_new_subset_length_caplen(tvb_large[0], -10, 10, 11);
353         subset[1]                 = &large[0][9];
354
355         subset_length[2]          = 16;
356         subset_reported_length[2] = 17;
357         tvb_subset[2]             = tvb_new_subset_length_caplen(tvb_small[1], -16, -1, 17);
358         subset[2]                 = &small[1][0];
359
360         subset_length[3]          = 3;
361         subset_reported_length[3] = 4;
362         tvb_subset[3]             = tvb_new_subset_length_caplen(tvb_subset[0], 0, 3, 4);
363         subset[3]                 = &small[0][0];
364
365         subset_length[4]          = 5;
366         subset_reported_length[4] = 6;
367         tvb_subset[4]             = tvb_new_subset_length_caplen(tvb_subset[1], -5, 5, 6);
368         subset[4]                 = &large[0][14];
369
370         subset_length[5]          = 8;
371         subset_reported_length[5] = 9;
372         tvb_subset[5]             = tvb_new_subset_length_caplen(tvb_subset[2], 4, 8, 9);
373         subset[5]                 = &small[1][4];
374
375         /* Test the "subset" tvbuff objects. */
376         test(tvb_subset[0], "Subset 0", subset[0], subset_length[0], subset_reported_length[0]);
377         test(tvb_subset[1], "Subset 1", subset[1], subset_length[1], subset_reported_length[1]);
378         test(tvb_subset[2], "Subset 2", subset[2], subset_length[2], subset_reported_length[2]);
379         test(tvb_subset[3], "Subset 3", subset[3], subset_length[3], subset_reported_length[3]);
380         test(tvb_subset[4], "Subset 4", subset[4], subset_length[4], subset_reported_length[4]);
381         test(tvb_subset[5], "Subset 5", subset[5], subset_length[5], subset_reported_length[5]);
382
383         /* Subset of an empty tvb. */
384         tvb_empty_subset = tvb_new_subset_length_caplen(tvb_empty, 0, 0, 1);
385         test(tvb_empty_subset, "Empty Subset", NULL, 0, 1);
386
387         /* One Real */
388         printf("Making Composite 0\n");
389         tvb_comp[0]             = tvb_new_composite();
390         comp_length[0]          = small_length[0];
391         comp_reported_length[0] = small_reported_length[0];
392         comp[0]                 = small[0];
393         tvb_composite_append(tvb_comp[0], tvb_small[0]);
394         tvb_composite_finalize(tvb_comp[0]);
395
396         /* Two Reals */
397         printf("Making Composite 1\n");
398         tvb_comp[1]             = tvb_new_composite();
399         comp_length[1]          = small_length[0] + small_length[1];
400         comp_reported_length[1] = small_reported_length[0] + small_reported_length[1];
401         comp[1]                 = (guint8*)g_malloc(comp_length[1]);
402         memcpy(comp[1], small[0], small_length[0]);
403         memcpy(&comp[1][small_length[0]], small[1], small_length[1]);
404         tvb_composite_append(tvb_comp[1], tvb_small[0]);
405         tvb_composite_append(tvb_comp[1], tvb_small[1]);
406         tvb_composite_finalize(tvb_comp[1]);
407
408         /* One subset */
409         printf("Making Composite 2\n");
410         tvb_comp[2]             = tvb_new_composite();
411         comp_length[2]          = subset_length[1];
412         comp_reported_length[2] = subset_reported_length[1];
413         comp[2]                 = subset[1];
414         tvb_composite_append(tvb_comp[2], tvb_subset[1]);
415         tvb_composite_finalize(tvb_comp[2]);
416
417         /* Two subsets */
418         printf("Making Composite 3\n");
419         tvb_comp[3]             = tvb_new_composite();
420         comp_length[3]          = subset_length[4] + subset_length[5];
421         comp_reported_length[3] = subset_reported_length[4] + subset_reported_length[5];
422         comp[3]                 = (guint8*)g_malloc(comp_length[3]);
423         memcpy(comp[3], subset[4], subset_length[4]);
424         memcpy(&comp[3][subset_length[4]], subset[5], subset_length[5]);
425         tvb_composite_append(tvb_comp[3], tvb_subset[4]);
426         tvb_composite_append(tvb_comp[3], tvb_subset[5]);
427         tvb_composite_finalize(tvb_comp[3]);
428
429         /* One real, one subset */
430         printf("Making Composite 4\n");
431         tvb_comp[4]             = tvb_new_composite();
432         comp_length[4]          = small_length[0] + subset_length[1];
433         comp_reported_length[4] = small_reported_length[0] + subset_reported_length[1];
434         comp[4]                 = (guint8*)g_malloc(comp_length[4]);
435         memcpy(&comp[4][0], small[0], small_length[0]);
436         memcpy(&comp[4][small_length[0]], subset[1], subset_length[1]);
437         tvb_composite_append(tvb_comp[4], tvb_small[0]);
438         tvb_composite_append(tvb_comp[4], tvb_subset[1]);
439         tvb_composite_finalize(tvb_comp[4]);
440
441         /* 4 composites */
442         printf("Making Composite 5\n");
443         tvb_comp[5]             = tvb_new_composite();
444         comp_length[5]          = comp_length[0] +
445                                         comp_length[1] +
446                                         comp_length[2] +
447                                         comp_length[3];
448         comp_reported_length[5] = comp_reported_length[0] +
449                                         comp_reported_length[1] +
450                                         comp_reported_length[2] +
451                                         comp_reported_length[3];
452         comp[5]                 = (guint8*)g_malloc(comp_length[5]);
453
454         len = 0;
455         memcpy(&comp[5][len], comp[0], comp_length[0]);
456         len += comp_length[0];
457         memcpy(&comp[5][len], comp[1], comp_length[1]);
458         len += comp_length[1];
459         memcpy(&comp[5][len], comp[2], comp_length[2]);
460         len += comp_length[2];
461         memcpy(&comp[5][len], comp[3], comp_length[3]);
462
463         tvb_composite_append(tvb_comp[5], tvb_comp[0]);
464         tvb_composite_append(tvb_comp[5], tvb_comp[1]);
465         tvb_composite_append(tvb_comp[5], tvb_comp[2]);
466         tvb_composite_append(tvb_comp[5], tvb_comp[3]);
467         tvb_composite_finalize(tvb_comp[5]);
468
469         /* Test the "composite" tvbuff objects. */
470         test(tvb_comp[0], "Composite 0", comp[0], comp_length[0], comp_reported_length[0]);
471         test(tvb_comp[1], "Composite 1", comp[1], comp_length[1], comp_reported_length[1]);
472         test(tvb_comp[2], "Composite 2", comp[2], comp_length[2], comp_reported_length[2]);
473         test(tvb_comp[3], "Composite 3", comp[3], comp_length[3], comp_reported_length[3]);
474         test(tvb_comp[4], "Composite 4", comp[4], comp_length[4], comp_reported_length[4]);
475         test(tvb_comp[5], "Composite 5", comp[5], comp_length[5], comp_reported_length[5]);
476
477         /* free memory. */
478         /* Don't free: comp[0] */
479         g_free(comp[1]);
480         /* Don't free: comp[2] */
481         g_free(comp[3]);
482         g_free(comp[4]);
483         g_free(comp[5]);
484
485         tvb_free_chain(tvb_parent);  /* should free all tvb's and associated data */
486 }
487
488 /* Note: valgrind can be used to check for tvbuff memory leaks */
489 int
490 main(void)
491 {
492         /* For valgrind: See GLib documentation: "Running GLib Applications" */
493         g_setenv("G_DEBUG", "gc-friendly", 1);
494         g_setenv("G_SLICE", "always-malloc", 1);
495
496         except_init();
497         run_tests();
498         except_deinit();
499         exit(failed?1:0);
500 }
501
502 /*
503  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
504  *
505  * Local variables:
506  * c-basic-offset: 8
507  * tab-width: 8
508  * indent-tabs-mode: t
509  * End:
510  *
511  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
512  * :indentSize=8:tabSize=8:noTabs=false:
513  */