2 * Standalone program to test functionality of tvbuffs.
4 * tvbtest : tvbtest.o tvbuff.o except.o
6 * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
8 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include "exceptions.h"
20 #include "wsutil/pint.h"
22 gboolean failed = FALSE;
24 /* Tests a tvbuff against the expected pattern/length.
25 * Returns TRUE if all tests succeeed, FALSE if any test fails */
27 test(tvbuff_t *tvb, const gchar* name,
28 guint8* expected_data, guint expected_length, guint expected_reported_length)
31 guint reported_length;
33 volatile gboolean ex_thrown;
34 volatile guint32 val32;
38 length = tvb_captured_length(tvb);
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);
47 reported_length = tvb_reported_length(tvb);
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);
56 /* Test boundary case. A BoundsError exception should be thrown. */
59 tvb_get_ptr(tvb, 0, length + 1);
64 CATCH(FragmentBoundsError) {
65 printf("02: Caught wrong exception: FragmentBoundsError\n");
67 CATCH(ReportedBoundsError) {
68 printf("02: Caught wrong exception: ReportedBoundsError\n");
71 printf("02: Caught wrong exception: %lu\n", exc->except_id.except_code);
76 printf("02: Failed TVB=%s No BoundsError when retrieving %u bytes\n",
82 /* Test boundary case with reported_length+1. A ReportedBoundsError
83 exception should be thrown. */
86 tvb_get_ptr(tvb, 0, reported_length + 1);
89 printf("03: Caught wrong exception: BoundsError\n");
91 CATCH(FragmentBoundsError) {
92 printf("03: Caught wrong exception: FragmentBoundsError\n");
94 CATCH(ReportedBoundsError) {
98 printf("03: Caught wrong exception: %lu\n", exc->except_id.except_code);
103 printf("03: Failed TVB=%s No ReportedBoundsError when retrieving %u bytes\n",
104 name, reported_length + 1);
109 /* Test boundary case. A BoundsError exception should be thrown. */
112 tvb_get_ptr(tvb, -1, 2);
117 CATCH(FragmentBoundsError) {
118 printf("04: Caught wrong exception: FragmentBoundsError\n");
120 CATCH(ReportedBoundsError) {
121 printf("04: Caught wrong exception: ReportedBoundsError\n");
124 printf("04: Caught wrong exception: %lu\n", exc->except_id.except_code);
129 printf("04: Failed TVB=%s No BoundsError when retrieving 2 bytes from"
130 " offset -1\n", name);
135 /* Test boundary case. A BoundsError exception should not be thrown. */
138 tvb_get_ptr(tvb, 0, length ? 1 : 0);
143 CATCH(FragmentBoundsError) {
144 printf("05: Caught wrong exception: FragmentBoundsError\n");
146 CATCH(ReportedBoundsError) {
147 printf("05: Caught wrong exception: ReportedBoundsError\n");
150 printf("05: Caught wrong exception: %lu\n", exc->except_id.except_code);
155 printf("05: Failed TVB=%s BoundsError when retrieving 1 bytes from"
156 " offset 0\n", name);
161 /* Test boundary case. A BoundsError exception should not be thrown. */
164 tvb_get_ptr(tvb, -1, length ? 1 : 0);
169 CATCH(FragmentBoundsError) {
170 printf("06: Caught wrong exception: FragmentBoundsError\n");
172 CATCH(ReportedBoundsError) {
173 printf("06: Caught wrong exception: ReportedBoundsError\n");
176 printf("06: Caught wrong exception: %lu\n", exc->except_id.except_code);
181 printf("06: Failed TVB=%s BoundsError when retrieving 1 bytes from"
182 " offset -1\n", name);
188 /* Check data at boundary. An exception should not be thrown. */
192 val32 = tvb_get_ntohl(tvb, 0);
200 printf("07: Failed TVB=%s Exception when retrieving "
201 "guint32 from offset 0\n", name);
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);
215 /* Check data at boundary. An exception should not be thrown. */
219 val32 = tvb_get_ntohl(tvb, -4);
227 printf("09: Failed TVB=%s Exception when retrieving "
228 "guint32 from offset 0\n", name);
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);
242 /* Sweep across data in various sized increments checking
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 "
252 wmem_free(NULL, ptr);
255 wmem_free(NULL, ptr);
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);
266 wmem_free(NULL, ptr);
269 wmem_free(NULL, ptr);
272 printf("Passed TVB=%s\n", name);
282 tvbuff_t *tvb_parent;
284 tvbuff_t *tvb_small[3];
285 tvbuff_t *tvb_large[3];
286 tvbuff_t *tvb_subset[6];
287 tvbuff_t *tvb_empty_subset;
289 guint small_length[3];
290 guint small_reported_length[3];
292 guint large_length[3];
293 guint large_reported_length[3];
295 guint subset_length[6];
296 guint subset_reported_length[6];
299 tvbuff_t *tvb_comp[6];
300 guint comp_length[6];
301 guint comp_reported_length[6];
304 tvb_parent = tvb_new_real_data("", 0, 0);
305 for (i = 0; i < 3; i++) {
306 small[i] = g_new(guint8, 16);
309 for (j = 0; j < 16; j++) {
310 small[i][j] = temp + j;
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);
318 for (i = 0; i < 3; i++) {
319 large[i] = g_new(guint8, 19);
322 for (j = 0; j < 19; j++) {
323 large[i][j] = temp + j;
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);
333 tvb_empty = tvb_new_child_real_data(tvb_parent, NULL, 0, 1);
334 test(tvb_empty, "Empty", NULL, 0, 1);
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]);
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]);
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];
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];
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];
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];
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];
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];
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]);
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);
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];
393 tvb_composite_append(tvb_comp[0], tvb_small[0]);
394 tvb_composite_finalize(tvb_comp[0]);
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]);
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];
414 tvb_composite_append(tvb_comp[2], tvb_subset[1]);
415 tvb_composite_finalize(tvb_comp[2]);
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]);
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]);
442 printf("Making Composite 5\n");
443 tvb_comp[5] = tvb_new_composite();
444 comp_length[5] = comp_length[0] +
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]);
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]);
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]);
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]);
478 /* Don't free: comp[0] */
480 /* Don't free: comp[2] */
485 tvb_free_chain(tvb_parent); /* should free all tvb's and associated data */
488 /* Note: valgrind can be used to check for tvbuff memory leaks */
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);
503 * Editor modelines - http://www.wireshark.org/tools/modelines.html
508 * indent-tabs-mode: t
511 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
512 * :indentSize=8:tabSize=8:noTabs=false: