As suggested by Anders: back out 37112.
[obnox/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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "tvbuff.h"
34 #include "pint.h"
35
36 gboolean failed = FALSE;
37
38 /* Tests a tvbuff against the expected pattern/length.
39  * Returns TRUE if all tests succeeed, FALSE if any test fails */
40 gboolean
41 test(tvbuff_t *tvb, gchar* name,
42                 guint8* expected_data, guint expected_length)
43 {
44         guint                   length;
45         const guint8           *cptr;
46         guint8                  *ptr;
47         volatile gboolean       ex_thrown;
48         volatile guint32        val32;
49         guint32                 expected32;
50         guint                   incr, i;
51
52         length = tvb_length(tvb);
53
54         if (length != expected_length) {
55                 printf("01: Failed TVB=%s Length of tvb=%u while expected length=%u\n",
56                                 name, length, expected_length);
57                 failed = TRUE;
58                 return FALSE;
59         }
60
61         /* Test boundary case. A BoundsError exception should be thrown. */
62         ex_thrown = FALSE;
63         TRY {
64                 cptr = tvb_get_ptr(tvb, 0, length + 1);
65         }
66         CATCH(BoundsError) {
67                 ex_thrown = TRUE;
68         }
69         CATCH(ReportedBoundsError) {
70                 printf("02: Caught wrong exception: ReportedBoundsError\n");
71         }
72         ENDTRY;
73
74         if (!ex_thrown) {
75                 printf("02: Failed TVB=%s No BoundsError when retrieving %u bytes\n",
76                                 name, length + 1);
77                 failed = TRUE;
78                 return FALSE;
79         }
80
81         /* Test boundary case with one more byte. A ReportedBoundsError
82            exception should be thrown. */
83         ex_thrown = FALSE;
84         TRY {
85                 cptr = tvb_get_ptr(tvb, 0, length + 2);
86         }
87         CATCH(BoundsError) {
88                 printf("03: Caught wrong exception: BoundsError\n");
89         }
90         CATCH(ReportedBoundsError) {
91                 ex_thrown = TRUE;
92         }
93         ENDTRY;
94
95         if (!ex_thrown) {
96                 printf("03: Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
97                                 name, length + 2);
98                 failed = TRUE;
99                 return FALSE;
100         }
101
102         /* Test boundary case. A BoundsError exception should be thrown. */
103         ex_thrown = FALSE;
104         TRY {
105                 cptr = tvb_get_ptr(tvb, -1, 2);
106         }
107         CATCH(BoundsError) {
108                 ex_thrown = TRUE;
109         }
110         CATCH(ReportedBoundsError) {
111                 printf("04: Caught wrong exception: ReportedBoundsError\n");
112         }
113         ENDTRY;
114
115         if (!ex_thrown) {
116                 printf("04: Failed TVB=%s No BoundsError when retrieving 2 bytes from"
117                                 " offset -1\n", name);
118                 failed = TRUE;
119                 return FALSE;
120         }
121
122         /* Test boundary case. A BoundsError exception should not be thrown. */
123         ex_thrown = FALSE;
124         TRY {
125                 cptr = tvb_get_ptr(tvb, 0, 1);
126         }
127         CATCH(BoundsError) {
128                 ex_thrown = TRUE;
129         }
130         CATCH(ReportedBoundsError) {
131                 printf("05: Caught wrong exception: ReportedBoundsError\n");
132         }
133         ENDTRY;
134
135         if (ex_thrown) {
136                 printf("05: Failed TVB=%s BoundsError when retrieving 1 bytes from"
137                                 " offset 0\n", name);
138                 failed = TRUE;
139                 return FALSE;
140         }
141
142         /* Test boundary case. A BoundsError exception should not be thrown. */
143         ex_thrown = FALSE;
144         TRY {
145                 cptr = tvb_get_ptr(tvb, -1, 1);
146         }
147         CATCH(BoundsError) {
148                 ex_thrown = TRUE;
149         }
150         CATCH(ReportedBoundsError) {
151                 printf("06: Caught wrong exception: ReportedBoundsError\n");
152         }
153         ENDTRY;
154
155         if (ex_thrown) {
156                 printf("06: Failed TVB=%s BoundsError when retrieving 1 bytes from"
157                                 " offset -1\n", name);
158                 failed = TRUE;
159                 return FALSE;
160         }
161
162
163         /* Check data at boundary. An exception should not be thrown. */
164         if (length >= 4) {
165                 ex_thrown = FALSE;
166                 TRY {
167                         val32 = tvb_get_ntohl(tvb, 0);
168                 }
169                 CATCH_ALL {
170                         ex_thrown = TRUE;
171                 }
172                 ENDTRY;
173
174                 if (ex_thrown) {
175                         printf("07: Failed TVB=%s Exception when retrieving "
176                                         "guint32 from offset 0\n", name);
177                         failed = TRUE;
178                         return FALSE;
179                 }
180
181                 expected32 = pntohl(expected_data);
182                 if (val32 != expected32) {
183                         printf("08: Failed TVB=%s  guint32 @ 0 %u != expected %u\n",
184                                         name, val32, expected32);
185                         failed = TRUE;
186                         return FALSE;
187                 }
188         }
189
190         /* Check data at boundary. An exception should not be thrown. */
191         if (length >= 4) {
192                 ex_thrown = FALSE;
193                 TRY {
194                         val32 = tvb_get_ntohl(tvb, -4);
195                 }
196                 CATCH_ALL {
197                         ex_thrown = TRUE;
198                 }
199                 ENDTRY;
200
201                 if (ex_thrown) {
202                         printf("09: Failed TVB=%s Exception when retrieving "
203                                         "guint32 from offset 0\n", name);
204                         failed = TRUE;
205                         return FALSE;
206                 }
207
208                 expected32 = pntohl(&expected_data[length-4]);
209                 if (val32 != expected32) {
210                         printf("10: Failed TVB=%s guint32 @ -4 %u != expected %u\n",
211                                         name, val32, expected32);
212                         failed = TRUE;
213                         return FALSE;
214                 }
215         }
216
217         /* Sweep across data in various sized increments checking
218          * tvb_memdup() */
219         for (incr = 1; incr < length; incr++) {
220                 for (i = 0; i < length - incr; i += incr) {
221                         ptr = tvb_memdup(tvb, i, incr);
222                         if (memcmp(ptr, &expected_data[i], incr) != 0) {
223                                 printf("11: Failed TVB=%s Offset=%d Length=%d "
224                                                 "Bad memdup\n",
225                                                 name, i, incr);
226                                 failed = TRUE;
227                                 g_free(ptr);
228                                 return FALSE;
229                         }
230                         g_free(ptr);
231                 }
232         }
233
234         /* One big memdup */
235         ptr = tvb_memdup(tvb, 0, -1);
236         if (memcmp(ptr, expected_data, length) != 0) {
237                 printf("12: Failed TVB=%s Offset=0 Length=-1 "
238                                 "Bad memdup\n", name);
239                 failed = TRUE;
240                 g_free(ptr);
241                 return FALSE;
242         }
243         g_free(ptr);
244
245
246         printf("Passed TVB=%s\n", name);
247
248         return TRUE;
249 }
250
251 gboolean
252 skip(tvbuff_t *tvb _U_, gchar* name,
253                 guint8* expected_data _U_, guint expected_length _U_)
254 {
255         printf("Skipping TVB=%s\n", name);
256         return FALSE;
257 }
258
259
260 void
261 run_tests(void)
262 {
263         int             i, j;
264
265         tvbuff_t        *tvb_small[3];
266         tvbuff_t        *tvb_large[3];
267         tvbuff_t        *tvb_subset[6];
268         guint8          *small[3];
269         guint8          *large[3];
270         guint8          *subset[6];
271         guint           subset_length[6];
272         guint8          temp;
273         guint8          *comp[6];
274         tvbuff_t        *tvb_comp[6];
275         guint           comp_length[6];
276         int             len;
277         
278         for (i = 0; i < 3; i++) {
279                 small[i] = g_new(guint8, 16);
280
281                 temp = 16 * i;
282                 for (j = 0; j < 16; j++) {
283                         small[i][j] = temp + j;
284                 }
285
286                 tvb_small[i] = tvb_new_real_data(small[i], 16, 17);
287         }
288
289         for (i = 0; i < 3; i++) {
290                 large[i] = g_new(guint8, 19);
291
292                 temp = 19 * i;
293                 for (j = 0; j < 19; j++) {
294                         large[i][j] = temp + j;
295                 }
296
297                 tvb_large[i] = tvb_new_real_data(large[i], 19, 20);
298         }
299
300         /* Test the TVBUFF_REAL_DATA objects. */
301         test(tvb_small[0], "Small 0", small[0], 16);
302         test(tvb_small[1], "Small 1", small[1], 16);
303         test(tvb_small[2], "Small 2", small[2], 16);
304
305         test(tvb_large[0], "Large 0", large[0], 19);
306         test(tvb_large[1], "Large 1", large[1], 19);
307         test(tvb_large[2], "Large 2", large[2], 19);
308
309         tvb_subset[0]           = tvb_new_subset(tvb_small[0], 0, 8, 9);
310         subset[0]               = &small[0][0];
311         subset_length[0]        = 8;
312
313         tvb_subset[1]           = tvb_new_subset(tvb_large[0], -10, 10, 11);
314         subset[1]               = &large[0][9];
315         subset_length[1]        = 10;
316
317         tvb_subset[2]           = tvb_new_subset(tvb_small[1], -16, -1, 17);
318         subset[2]               = &small[1][0];
319         subset_length[2]        = 16;
320
321         tvb_subset[3]           = tvb_new_subset(tvb_subset[0], 0, 3, 4);
322         subset[3]               = &small[0][0];
323         subset_length[3]        = 3;
324
325         tvb_subset[4]           = tvb_new_subset(tvb_subset[1], -5, 5, 6);
326         subset[4]               = &large[0][14];
327         subset_length[4]        = 5;
328
329         tvb_subset[5]           = tvb_new_subset(tvb_subset[2], 4, 8, 9);
330         subset[5]               = &small[1][4];
331         subset_length[5]        = 8;
332
333         /* Test the TVBUFF_SUBSET objects. */
334         test(tvb_subset[0], "Subset 0", subset[0], subset_length[0]);
335         test(tvb_subset[1], "Subset 1", subset[1], subset_length[1]);
336         test(tvb_subset[2], "Subset 2", subset[2], subset_length[2]);
337         test(tvb_subset[3], "Subset 3", subset[3], subset_length[3]);
338         test(tvb_subset[4], "Subset 4", subset[4], subset_length[4]);
339         test(tvb_subset[5], "Subset 5", subset[5], subset_length[5]);
340
341         /* Composite tvbuffs don't work at the moment -- tests commented out until
342          * they do. */
343         
344         /* One Real */
345         printf("Making Composite 0\n");
346         tvb_comp[0]             = tvb_new_composite();
347         comp[0]                 = small[0];
348         comp_length[0]          = 16;
349         tvb_composite_append(tvb_comp[0], tvb_small[0]);
350         tvb_composite_finalize(tvb_comp[0]);
351
352         /* Two Reals */
353         printf("Making Composite 1\n");
354         tvb_comp[1]             = tvb_new_composite();
355         comp[1]                 = g_malloc(32);
356         comp_length[1]          = 32;
357         memcpy(comp[1], small[0], 16);
358         memcpy(&comp[1][16], small[1], 16);
359         tvb_composite_append(tvb_comp[1], tvb_small[0]);
360         tvb_composite_append(tvb_comp[1], tvb_small[1]);
361         tvb_composite_finalize(tvb_comp[1]);
362
363         /* One subset */
364         printf("Making Composite 2\n");
365         tvb_comp[2]             = tvb_new_composite();
366         comp[2]                 = subset[1];
367         comp_length[2]          = subset_length[1];
368         tvb_composite_append(tvb_comp[2], tvb_subset[1]);
369         tvb_composite_finalize(tvb_comp[2]);
370
371         /* Two subsets */
372         printf("Making Composite 3\n");
373         tvb_comp[3]             = tvb_new_composite();
374         comp[3]                 = g_malloc(13);
375         comp_length[3]          = 13;
376         memcpy(comp[3], &large[0][14], 5);
377         memcpy(&comp[3][5], &small[1][4], 8);
378         tvb_composite_append(tvb_comp[3], tvb_subset[4]);
379         tvb_composite_append(tvb_comp[3], tvb_subset[5]);
380         tvb_composite_finalize(tvb_comp[3]);
381
382         /* One real, one subset */
383         printf("Making Composite 4\n");
384         tvb_comp[4]             = tvb_new_composite();
385         comp[4]                 = g_malloc(16 + subset_length[1]);
386         comp_length[4]          = 16 + subset_length[1];
387         memcpy(comp[4], small[0], 16);
388         memcpy(&comp[4][16], subset[1], subset_length[1]);
389         tvb_composite_append(tvb_comp[4], tvb_small[0]);
390         tvb_composite_append(tvb_comp[4], tvb_subset[1]);
391         tvb_composite_finalize(tvb_comp[4]);
392
393         /* 4 composites */
394         printf("Making Composite 5\n");
395         tvb_comp[5]             = tvb_new_composite();
396         comp_length[5]          = comp_length[0] +
397                                         comp_length[1] +
398                                         comp_length[2] +
399                                         comp_length[3];
400         comp[5]                 = g_malloc(comp_length[5]);
401
402         len = 0;
403         memcpy(&comp[5][len], comp[0], comp_length[0]);
404         len += comp_length[0];
405         memcpy(&comp[5][len], comp[1], comp_length[1]);
406         len += comp_length[1];
407         memcpy(&comp[5][len], comp[2], comp_length[2]);
408         len += comp_length[2];
409         memcpy(&comp[5][len], comp[3], comp_length[3]);
410
411         tvb_composite_append(tvb_comp[5], tvb_comp[0]);
412         tvb_composite_append(tvb_comp[5], tvb_comp[1]);
413         tvb_composite_append(tvb_comp[5], tvb_comp[2]);
414         tvb_composite_append(tvb_comp[5], tvb_comp[3]);
415         tvb_composite_finalize(tvb_comp[5]);
416
417         /* Test the TVBUFF_COMPOSITE objects. */
418         test(tvb_comp[0], "Composite 0", comp[0], comp_length[0]);
419         skip(tvb_comp[1], "Composite 1", comp[1], comp_length[1]);
420         test(tvb_comp[2], "Composite 2", comp[2], comp_length[2]);
421         skip(tvb_comp[3], "Composite 3", comp[3], comp_length[3]);
422         skip(tvb_comp[4], "Composite 4", comp[4], comp_length[4]);
423         skip(tvb_comp[5], "Composite 5", comp[5], comp_length[5]);
424 }
425
426 int
427 main(void)
428 {
429         except_init();
430         tvbuff_init();
431         run_tests();
432         tvbuff_cleanup();
433         except_deinit();
434         exit(failed?1:0);
435 }