1 /*
2 * Wireshark - Network traffic analyzer
3 * By Gerald Combs <gerald@wireshark.org>
4 * Copyright 1998 Gerald Combs
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "config.h"
10
11 #include <stdio.h>
12 #include <glib.h>
13 #include <wsutil/utf8_entities.h>
14
15 #include "str_util.h"
16
17
test_format_size(void)18 static void test_format_size(void)
19 {
20 char *str;
21
22 str = format_size(10000, format_size_unit_bytes);
23 g_assert_cmpstr(str, ==, "10 kB");
24 g_free(str);
25
26 str = format_size(100000, format_size_unit_bytes|format_size_prefix_iec);
27 g_assert_cmpstr(str, ==, "97 KiB");
28 g_free(str);
29
30 str = format_size(20971520, format_size_unit_bits|format_size_prefix_iec);
31 g_assert_cmpstr(str, ==, "20 Mib");
32 g_free(str);
33 }
34
35 #include "to_str.h"
36
test_word_to_hex(void)37 static void test_word_to_hex(void)
38 {
39 static char buf[32];
40 char *str; /* String is not NULL terminated. */
41
42 str = guint8_to_hex(buf, 0x34);
43 g_assert_true(str == buf + 2);
44 g_assert_cmpint(str[-1], ==, '4');
45 g_assert_cmpint(str[-2], ==, '3');
46
47 str = word_to_hex(buf, 0x1234);
48 g_assert_true(str == buf + 4);
49 g_assert_cmpint(str[-1], ==, '4');
50 g_assert_cmpint(str[-2], ==, '3');
51 g_assert_cmpint(str[-3], ==, '2');
52 g_assert_cmpint(str[-4], ==, '1');
53
54 str = dword_to_hex(buf, 0x1234);
55 g_assert_true(str == buf + 8);
56 g_assert_cmpint(str[-1], ==, '4');
57 g_assert_cmpint(str[-2], ==, '3');
58 g_assert_cmpint(str[-3], ==, '2');
59 g_assert_cmpint(str[-4], ==, '1');
60 g_assert_cmpint(str[-5], ==, '0');
61 g_assert_cmpint(str[-6], ==, '0');
62 g_assert_cmpint(str[-7], ==, '0');
63 g_assert_cmpint(str[-8], ==, '0');
64
65 str = qword_to_hex(buf, G_GUINT64_CONSTANT(0xFEDCBA987654321));
66 g_assert_true(str == buf + 16);
67 g_assert_cmpint(str[-1], ==, '1');
68 g_assert_cmpint(str[-2], ==, '2');
69 g_assert_cmpint(str[-3], ==, '3');
70 g_assert_cmpint(str[-4], ==, '4');
71 g_assert_cmpint(str[-5], ==, '5');
72 g_assert_cmpint(str[-6], ==, '6');
73 g_assert_cmpint(str[-7], ==, '7');
74 g_assert_cmpint(str[-8], ==, '8');
75 g_assert_cmpint(str[-9], ==, '9');
76 g_assert_cmpint(str[-10], ==, 'a');
77 g_assert_cmpint(str[-11], ==, 'b');
78 g_assert_cmpint(str[-12], ==, 'c');
79 g_assert_cmpint(str[-13], ==, 'd');
80 g_assert_cmpint(str[-14], ==, 'e');
81 g_assert_cmpint(str[-15], ==, 'f');
82 g_assert_cmpint(str[-16], ==, '0');
83 }
84
test_bytes_to_str(void)85 static void test_bytes_to_str(void)
86 {
87 char *str;
88
89 const guint8 buf[] = { 1, 2, 3};
90
91 str = bytes_to_str(NULL, buf, sizeof(buf));
92 g_assert_cmpstr(str, ==, "010203");
93 g_free(str);
94 }
95
test_bytes_to_str_punct(void)96 static void test_bytes_to_str_punct(void)
97 {
98 char *str;
99
100 const guint8 buf[] = { 1, 2, 3};
101
102 str = bytes_to_str_punct(NULL, buf, sizeof(buf), ':');
103 g_assert_cmpstr(str, ==, "01:02:03");
104 g_free(str);
105 }
106
test_bytes_to_string_trunc1(void)107 static void test_bytes_to_string_trunc1(void)
108 {
109 char *str;
110
111 const guint8 buf[] = {
112 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
113 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
114 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
115 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
116 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
117 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
118 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA
119 };
120 const char *expect =
121 "112233445566778899aa"
122 "112233445566778899aa"
123 "112233445566778899aa"
124 "112233445566" UTF8_HORIZONTAL_ELLIPSIS;
125
126 str = bytes_to_str(NULL, buf, sizeof(buf));
127 g_assert_cmpstr(str, ==, expect);
128 g_free(str);
129 }
130
test_bytes_to_string_punct_trunc1(void)131 static void test_bytes_to_string_punct_trunc1(void)
132 {
133 char *str;
134
135 const guint8 buf[] = {
136 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
137 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
138 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
139 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
140 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
141 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA,
142 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA
143 };
144 const char *expect =
145 "11:22:33:44:55:66:77:88:99:aa:"
146 "11:22:33:44:55:66:77:88:99:aa:"
147 "11:22:33:44:" UTF8_HORIZONTAL_ELLIPSIS;
148
149 str = bytes_to_str_punct(NULL, buf, sizeof(buf), ':');
150 g_assert_cmpstr(str, ==, expect);
151 g_free(str);
152 }
153
154 static char to_str_back_buf[32];
155 #define BACK_PTR (&to_str_back_buf[31]) /* pointer to NUL string terminator */
156
test_oct_to_str_back(void)157 static void test_oct_to_str_back(void)
158 {
159 char *str;
160
161 str = oct_to_str_back(BACK_PTR, 958769886);
162 g_assert_cmpstr(str, ==, "07111325336");
163
164 str = oct_to_str_back(BACK_PTR, 781499127);
165 g_assert_cmpstr(str, ==, "05645135367");
166
167 str = oct_to_str_back(BACK_PTR, 1177329882);
168 g_assert_cmpstr(str, ==, "010613120332");
169 }
170
test_oct64_to_str_back(void)171 static void test_oct64_to_str_back(void)
172 {
173 char *str;
174
175 str = oct64_to_str_back(BACK_PTR, G_GUINT64_CONSTANT(13873797580070999420));
176 g_assert_cmpstr(str, ==, "01402115026217563452574");
177
178 str = oct64_to_str_back(BACK_PTR, G_GUINT64_CONSTANT(7072159458371400691));
179 g_assert_cmpstr(str, ==, "0610452670726711271763");
180
181 str = oct64_to_str_back(BACK_PTR, G_GUINT64_CONSTANT(12453513102400590374));
182 g_assert_cmpstr(str, ==, "01263236102754220511046");
183 }
184
test_hex_to_str_back_len(void)185 static void test_hex_to_str_back_len(void)
186 {
187 char *str;
188
189 str = hex_to_str_back_len(BACK_PTR, 2481, 8);
190 g_assert_cmpstr(str, ==, "0x000009b1");
191
192 str = hex_to_str_back_len(BACK_PTR, 2457, 8);
193 g_assert_cmpstr(str, ==, "0x00000999");
194
195 str = hex_to_str_back_len(BACK_PTR, 16230, 8);
196 g_assert_cmpstr(str, ==, "0x00003f66");
197 }
198
test_hex64_to_str_back_len(void)199 static void test_hex64_to_str_back_len(void)
200 {
201 char *str;
202
203 str = hex64_to_str_back_len(BACK_PTR, G_GUINT64_CONSTANT(1), 16);
204 g_assert_cmpstr(str, ==, "0x0000000000000001");
205
206 str = hex64_to_str_back_len(BACK_PTR, G_GUINT64_CONSTANT(4294967295), 16);
207 g_assert_cmpstr(str, ==, "0x00000000ffffffff");
208
209 str = hex64_to_str_back_len(BACK_PTR, G_GUINT64_CONSTANT(18446744073709551615), 16);
210 g_assert_cmpstr(str, ==, "0xffffffffffffffff");
211 }
212
test_uint_to_str_back(void)213 static void test_uint_to_str_back(void)
214 {
215 char *str;
216
217 str = uint_to_str_back(BACK_PTR, 873735883);
218 g_assert_cmpstr(str, ==, "873735883");
219
220 str = uint_to_str_back(BACK_PTR, 1801148094);
221 g_assert_cmpstr(str, ==, "1801148094");
222
223 str = uint_to_str_back(BACK_PTR, 181787997);
224 g_assert_cmpstr(str, ==, "181787997");
225 }
226
test_uint64_to_str_back(void)227 static void test_uint64_to_str_back(void)
228 {
229 char *str;
230
231 str = uint64_to_str_back(BACK_PTR, G_GUINT64_CONSTANT(585143757104211265));
232 g_assert_cmpstr(str, ==, "585143757104211265");
233
234 str = uint64_to_str_back(BACK_PTR, G_GUINT64_CONSTANT(7191580247919484847));
235 g_assert_cmpstr(str, ==, "7191580247919484847");
236
237 str = uint64_to_str_back(BACK_PTR, G_GUINT64_CONSTANT(95778573911934485));
238 g_assert_cmpstr(str, ==, "95778573911934485");
239 }
240
test_uint_to_str_back_len(void)241 static void test_uint_to_str_back_len(void)
242 {
243 char *str;
244
245 str = uint_to_str_back_len(BACK_PTR, 26630, 8);
246 g_assert_cmpstr(str, ==, "00026630");
247
248 str = uint_to_str_back_len(BACK_PTR, 25313, 8);
249 g_assert_cmpstr(str, ==, "00025313");
250
251 str = uint_to_str_back_len(BACK_PTR, 18750000, 8);
252 g_assert_cmpstr(str, ==, "18750000");
253 }
254
test_uint64_to_str_back_len(void)255 static void test_uint64_to_str_back_len(void)
256 {
257 char *str;
258
259 str = uint64_to_str_back_len(BACK_PTR, G_GUINT64_CONSTANT(1), 16);
260 g_assert_cmpstr(str, ==, "0000000000000001");
261
262 str = uint64_to_str_back_len(BACK_PTR, G_GUINT64_CONSTANT(4294967295), 16);
263 g_assert_cmpstr(str, ==, "0000004294967295");
264
265 str = uint64_to_str_back_len(BACK_PTR, G_GUINT64_CONSTANT(18446744073709551615), 16);
266 g_assert_cmpstr(str, ==, "18446744073709551615");
267 }
268
test_int_to_str_back(void)269 static void test_int_to_str_back(void)
270 {
271 char *str;
272
273 str = int_to_str_back(BACK_PTR, -763689611);
274 g_assert_cmpstr(str, ==, "-763689611");
275
276 str = int_to_str_back(BACK_PTR, -296015954);
277 g_assert_cmpstr(str, ==, "-296015954");
278
279 str = int_to_str_back(BACK_PTR, 898901469);
280 g_assert_cmpstr(str, ==, "898901469");
281 }
282
test_int64_to_str_back(void)283 static void test_int64_to_str_back(void)
284 {
285 char *str;
286
287 str = int64_to_str_back(BACK_PTR, G_GINT64_CONSTANT(-9223372036854775807));
288 g_assert_cmpstr(str, ==, "-9223372036854775807");
289
290 str = int64_to_str_back(BACK_PTR, G_GINT64_CONSTANT(1));
291 g_assert_cmpstr(str, ==, "1");
292
293 str = int64_to_str_back(BACK_PTR, G_GINT64_CONSTANT(9223372036854775807));
294 g_assert_cmpstr(str, ==, "9223372036854775807");
295 }
296
297 #include "ws_getopt.h"
298
299 #define ARGV_MAX 31
300
new_argv(int * argc_ptr,const char * args,...)301 static char **new_argv(int *argc_ptr, const char *args, ...)
302 {
303 char **argv;
304 int argc = 0;
305 va_list ap;
306
307 argv = g_malloc((ARGV_MAX + 1) * sizeof(char *));
308
309 va_start(ap, args);
310 while (args != NULL) {
311 /* Increase ARGV_MAX or use a dynamic size if this assertion fails. */
312 g_assert_true(argc < ARGV_MAX);
313 argv[argc++] = g_strdup(args);
314 args = va_arg(ap, const char *);
315 }
316 argv[argc] = NULL;
317 va_end(ap);
318
319 *argc_ptr = argc;
320 return argv;
321 }
322
free_argv(char ** argv)323 static void free_argv(char **argv)
324 {
325 for (char **p = argv; *p != NULL; p++) {
326 g_free(*p);
327 }
328 g_free(argv);
329 }
330
test_getopt_long_basic1(void)331 static void test_getopt_long_basic1(void)
332 {
333 char **argv;
334 int argc;
335
336 const char *optstring = "ab:c";
337 argv = new_argv(&argc, "/bin/ls", "-a", "-b", "arg1", "-c", "path", (char *)NULL);
338
339 ws_optind = 1;
340 int opt;
341
342 opt = ws_getopt_long(argc, argv, optstring, NULL, NULL);
343 g_assert_cmpint(opt, ==, 'a');
344 g_assert_null(ws_optarg);
345
346 opt = ws_getopt_long(argc, argv, optstring, NULL, NULL);
347 g_assert_cmpint(opt, ==, 'b');
348 g_assert_cmpstr(ws_optarg, ==, "arg1");
349
350 opt = ws_getopt_long(argc, argv, optstring, NULL, NULL);
351 g_assert_cmpint(opt, ==, 'c');
352 g_assert_null(ws_optarg);
353
354 opt = ws_getopt_long(argc, argv, optstring, NULL, NULL);
355 g_assert_cmpint(opt, ==, -1);
356
357 free_argv(argv);
358 }
359
test_getopt_long_basic2(void)360 static void test_getopt_long_basic2(void)
361 {
362 char **argv;
363 int argc;
364
365 struct ws_option longopts[] = {
366 { "opt1", ws_no_argument, NULL, '1' },
367 { "opt2", ws_required_argument, NULL, '2' },
368 { "opt3", ws_required_argument, NULL, '3' },
369 { 0, 0, 0, 0 }
370 };
371 argv = new_argv(&argc, "/bin/ls", "--opt1", "--opt2", "arg1", "--opt3=arg2", "path", (char *)NULL);
372
373 ws_optind = 1;
374 int opt;
375
376 opt = ws_getopt_long(argc, argv, "", longopts, NULL);
377 g_assert_cmpint(opt, ==, '1');
378 g_assert_null(ws_optarg);
379
380 opt = ws_getopt_long(argc, argv, "", longopts, NULL);
381 g_assert_cmpint(opt, ==, '2');
382 g_assert_cmpstr(ws_optarg, ==, "arg1");
383
384 opt = ws_getopt_long(argc, argv, "", longopts, NULL);
385 g_assert_cmpint(opt, ==, '3');
386 g_assert_cmpstr(ws_optarg, ==, "arg2");
387
388 opt = ws_getopt_long(argc, argv, "", longopts, NULL);
389 g_assert_cmpint(opt, ==, -1);
390
391 free_argv(argv);
392 }
393
test_getopt_optional_argument1(void)394 static void test_getopt_optional_argument1(void)
395 {
396 char **argv;
397 int argc;
398 int opt;
399
400 struct ws_option longopts_optional[] = {
401 { "optional", ws_optional_argument, NULL, '1' },
402 { 0, 0, 0, 0 }
403 };
404
405 argv = new_argv(&argc, "/bin/ls", "--optional=arg1", (char *)NULL);
406
407 ws_optreset = 1;
408 opt = ws_getopt_long(argc, argv, "", longopts_optional, NULL);
409 g_assert_cmpint(opt, ==, '1');
410 g_assert_cmpstr(ws_optarg, ==, "arg1");
411
412 free_argv(argv);
413 argv = new_argv(&argc, "/bin/ls", "--optional", "arg1", (char *)NULL);
414
415 ws_optreset = 1;
416 opt = ws_getopt_long(argc, argv, "", longopts_optional, NULL);
417 g_assert_cmpint(opt, ==, '1');
418 /* Optional argument does not recognize the form "--arg param" (it's ambiguous). */
419 g_assert_null(ws_optarg);
420
421 free_argv(argv);
422 argv = new_argv(&argc, "/bin/ls", "--optional", (char *)NULL);
423
424 ws_optreset = 1;
425 opt = ws_getopt_long(argc, argv, "", longopts_optional, NULL);
426 g_assert_cmpint(opt, ==, '1');
427 g_assert_null(ws_optarg);
428
429 free_argv(argv);
430 }
431
test_getopt_opterr1(void)432 static void test_getopt_opterr1(void)
433 {
434 char **argv;
435 int argc;
436
437 #ifdef _WIN32
438 g_test_skip("Not supported on Windows");
439 return;
440 #endif
441
442 if (g_test_subprocess()) {
443 const char *optstring = "ab";
444 argv = new_argv(&argc, "/bin/ls", "-a", "-z", "path", (char *)NULL);
445
446 ws_optind = 0;
447 ws_opterr = 1;
448 int opt;
449
450 opt = ws_getopt_long(argc, argv, optstring, NULL, NULL);
451 g_assert_cmpint(opt, ==, 'a');
452
453 opt = ws_getopt_long(argc, argv, optstring, NULL, NULL);
454 g_assert_cmpint(opt, ==, '?');
455 g_assert_cmpint(ws_optopt, ==, 'z');
456
457 opt = ws_getopt_long(argc, argv, optstring, NULL, NULL);
458 g_assert_cmpint(opt, ==, -1);
459
460 free_argv(argv);
461
462 return;
463 }
464
465 g_test_trap_subprocess(NULL, 0, 0);
466 g_test_trap_assert_passed();
467 g_test_trap_assert_stderr("/bin/ls: unrecognized option: z\n");
468 }
469
main(int argc,char ** argv)470 int main(int argc, char **argv)
471 {
472 int ret;
473
474 g_test_init(&argc, &argv, NULL);
475
476 g_test_add_func("/str_util/format_size", test_format_size);
477
478 g_test_add_func("/to_str/word_to_hex", test_word_to_hex);
479 g_test_add_func("/to_str/bytes_to_str", test_bytes_to_str);
480 g_test_add_func("/to_str/bytes_to_str_punct", test_bytes_to_str_punct);
481 g_test_add_func("/to_str/bytes_to_str_trunc1", test_bytes_to_string_trunc1);
482 g_test_add_func("/to_str/bytes_to_str_punct_trunc1", test_bytes_to_string_punct_trunc1);
483 g_test_add_func("/to_str/oct_to_str_back", test_oct_to_str_back);
484 g_test_add_func("/to_str/oct64_to_str_back", test_oct64_to_str_back);
485 g_test_add_func("/to_str/hex_to_str_back_len", test_hex_to_str_back_len);
486 g_test_add_func("/to_str/hex64_to_str_back_len", test_hex64_to_str_back_len);
487 g_test_add_func("/to_str/uint_to_str_back", test_uint_to_str_back);
488 g_test_add_func("/to_str/uint64_to_str_back", test_uint64_to_str_back);
489 g_test_add_func("/to_str/uint_to_str_back_len", test_uint_to_str_back_len);
490 g_test_add_func("/to_str/uint64_to_str_back_len", test_uint64_to_str_back_len);
491 g_test_add_func("/to_str/int_to_str_back", test_int_to_str_back);
492 g_test_add_func("/to_str/int64_to_str_back", test_int64_to_str_back);
493
494 g_test_add_func("/ws_getopt/basic1", test_getopt_long_basic1);
495 g_test_add_func("/ws_getopt/basic2", test_getopt_long_basic2);
496 g_test_add_func("/ws_getopt/optional1", test_getopt_optional_argument1);
497 g_test_add_func("/ws_getopt/opterr1", test_getopt_opterr1);
498
499 ret = g_test_run();
500
501 return ret;
502 }
503
504 /*
505 * Editor modelines - https://www.wireshark.org/tools/modelines.html
506 *
507 * Local variables:
508 * c-basic-offset: 4
509 * tab-width: 8
510 * indent-tabs-mode: nil
511 * End:
512 *
513 * vi: set shiftwidth=4 tabstop=8 expandtab:
514 * :indentSize=4:tabSize=8:noTabs=true:
515 */
516