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