2 * Copyright (c) 2016 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #include <jeffpc/hexdump.h>
24 #include <jeffpc/padding.h>
25 #include <jeffpc/types.h>
35 #define TEST_ENTRY(i, l, u) \
38 .inlen = sizeof(i) - 1, \
43 static const struct run runs
[] = {
47 TEST_ENTRY("abcdefghijklmnopqrstuvwxyz",
48 "6162636465666768696a6b6c6d6e6f707172737475767778797a",
49 "6162636465666768696A6B6C6D6E6F707172737475767778797A"),
50 TEST_ENTRY("\0\1\2\3\4\5\6\7\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
51 "000102030405060708090a0b0c0d0e0f",
52 "000102030405060708090A0B0C0D0E0F"),
56 * We allocate a temporary buffer large enough to hold the expected output,
57 * but also large enough for two redzones each REDZONE_SIZE bytes in size.
58 * One redzone is located before the location for the output and one after.
59 * We clear the whole buffer by setting each byte to a constant REDZONE_VAL.
61 #define REDZONE_SIZE 128
62 #define REDZONE_VAL 0xff
64 static void __test(void (*fxn
)(char *, const void *, size_t, bool),
65 const char *testname
, int iter
, bool upper
,
68 const struct run
*run
= &runs
[iter
];
69 const size_t nulltermlen
= (nullterm
? 1 : 0);
70 const size_t buflen
= run
->inlen
* 2 + REDZONE_SIZE
* 2 + nulltermlen
;
71 const char *expected
= run
->out
[upper
];
72 const size_t expectedlen
= 2 * run
->inlen
+ nulltermlen
;
76 snprintf(msgpfx
, sizeof(msgpfx
), "%d/%s/%s", iter
, testname
,
77 upper
? "upper" : "lower");
81 fprintf(stderr
, "%s: input length: %zu\n", msgpfx
, run
->inlen
);
82 fprintf(stderr
, "%s: expected length: %zu\n", msgpfx
, expectedlen
);
83 fprintf(stderr
, "%s: expected output: %s\n", msgpfx
, expected
);
85 if (strlen(expected
) + nulltermlen
!= expectedlen
)
86 fail("length of expected string (%zu + %zu) != calculated "
87 "length (%zu)", strlen(expected
), nulltermlen
,
90 /* clear the output buffer and redzones */
91 memset(buf
, REDZONE_VAL
, buflen
);
93 /* run the function */
94 fxn(buf
+ REDZONE_SIZE
, run
->in
, run
->inlen
, upper
);
96 /* verify the output buffer */
97 if (memcmp(buf
+ REDZONE_SIZE
, expected
, expectedlen
))
98 fail("unexpected bytes present");
100 /* verify that redzones are still intact */
101 if (!check_padding(buf
, REDZONE_VAL
, REDZONE_SIZE
))
102 fail("leading redzone modification detected");
103 if (!check_padding(buf
+ REDZONE_SIZE
+ expectedlen
,
104 REDZONE_VAL
, REDZONE_SIZE
))
105 fail("trailing redzone modification detected");
107 fprintf(stderr
, "%s: ok.\n", msgpfx
);
114 for (i
= 0; i
< ARRAY_LEN(runs
) ; i
++) {
115 __test(hexdump
, "hexdump", i
, true, false);
116 __test(hexdump
, "hexdump", i
, false, false);
117 __test(hexdumpz
, "hexdumpz", i
, true, true);
118 __test(hexdumpz
, "hexdumpz", i
, false, true);