summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-10-24 05:26:06 +0200
committerDirk Engling <erdgeist@erdgeist.org>2026-10-24 05:26:06 +0200
commit5fb172a50fc343ef642745b0ecb4b6a44d274b15 (patch)
tree935be4f1c1905c5ff926c50eb21a4dc6ba9f7ba8 /tests
parentd95163270e022fe87ece0c151c2987fd62274ba8 (diff)
Add tests for the new ranged unsigned int scanner in ot_scan
Diffstat (limited to 'tests')
-rw-r--r--tests/runner.c1
-rw-r--r--tests/t_scan.c162
-rw-r--r--tests/test.h1
3 files changed, 164 insertions, 0 deletions
diff --git a/tests/runner.c b/tests/runner.c
index bf4fbde..370b92b 100644
--- a/tests/runner.c
+++ b/tests/runner.c
@@ -19,6 +19,7 @@ static const struct module modules[] = {{"scan_urlencoded_query", test_scan_urle
19 {"ot_vector", test_vector}, 19 {"ot_vector", test_vector},
20 {"ot_random", test_random}, 20 {"ot_random", test_random},
21 {"ot_hex", test_hex}, 21 {"ot_hex", test_hex},
22 {"ot_scan", test_scan},
22 {"ot_accesslist", test_accesslist}, 23 {"ot_accesslist", test_accesslist},
23 {NULL, NULL}}; 24 {NULL, NULL}};
24 25
diff --git a/tests/t_scan.c b/tests/t_scan.c
new file mode 100644
index 0000000..89f1590
--- /dev/null
+++ b/tests/t_scan.c
@@ -0,0 +1,162 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever.
3
4 $id$ */
5
6/* System */
7#include <stdint.h>
8#include <string.h>
9
10/* Opentracker */
11#include "ot_scan.h"
12#include "test.h"
13
14static void case_plain_numbers(void) {
15 uint64_t value;
16
17 test_case("a decimal number is read and its length reported");
18 CHECK_INT(scan_udec("0", &value, 65535), 1);
19 CHECK_INT(value, 0);
20 CHECK_INT(scan_udec("7", &value, 65535), 1);
21 CHECK_INT(value, 7);
22 CHECK_INT(scan_udec("6969", &value, 65535), 4);
23 CHECK_INT(value, 6969);
24 CHECK_INT(scan_udec("65535", &value, 65535), 5);
25 CHECK_INT(value, 65535);
26}
27
28static void case_stops_at_non_digit(void) {
29 uint64_t value;
30
31 test_case("scanning stops at the first character that is not a digit");
32 CHECK_INT(scan_udec("6969:rest", &value, 65535), 4);
33 CHECK_INT(value, 6969);
34 CHECK_INT(scan_udec("128/8", &value, 65535), 3);
35 CHECK_INT(value, 128);
36 CHECK_INT(scan_udec("42\n", &value, 65535), 2);
37 CHECK_INT(value, 42);
38}
39
40static void case_rejects_whitespace(void) {
41 uint64_t value = 0xdead;
42
43 test_case("leading whitespace is not skipped");
44 CHECK_INT(scan_udec(" 1", &value, 65535), 0);
45 CHECK_INT(scan_udec("\t1", &value, 65535), 0);
46 CHECK_INT(scan_udec("\n1", &value, 65535), 0);
47 CHECK_INT(value, 0xdead);
48}
49
50static void case_rejects_sign(void) {
51 uint64_t value = 0xdead;
52
53 test_case("a sign is not accepted");
54 CHECK_INT(scan_udec("+1", &value, 65535), 0);
55 CHECK_INT(scan_udec("-1", &value, 65535), 0);
56 CHECK_INT(scan_udec("-0", &value, 65535), 0);
57 CHECK_INT(value, 0xdead);
58}
59
60static void case_rejects_empty_and_junk(void) {
61 uint64_t value = 0xdead;
62
63 test_case("a string with no leading digit yields nothing");
64 CHECK_INT(scan_udec("", &value, 65535), 0);
65 CHECK_INT(scan_udec("x", &value, 65535), 0);
66 CHECK_INT(scan_udec(":80", &value, 65535), 0);
67 CHECK_INT(value, 0xdead);
68}
69
70static void case_no_alternative_bases(void) {
71 uint64_t value;
72
73 test_case("hexadecimal and octal notations are read as plain decimal");
74 CHECK_INT(scan_udec("0x10", &value, 65535), 1);
75 CHECK_INT(value, 0);
76 CHECK_INT(scan_udec("010", &value, 65535), 3);
77 CHECK_INT(value, 10);
78}
79
80static void case_refuses_out_of_range(void) {
81 uint64_t value = 0xdead;
82
83 test_case("a value above max is refused, not truncated");
84 CHECK_INT(scan_udec("65536", &value, 65535), 0);
85 CHECK_INT(scan_udec("99999", &value, 65535), 0);
86 CHECK_INT(scan_udec("129", &value, 128), 0);
87 CHECK_INT(value, 0xdead);
88
89 test_case("the boundary itself is accepted");
90 CHECK_INT(scan_udec("128", &value, 128), 3);
91 CHECK_INT(value, 128);
92}
93
94static void case_sixty_four_bit_range(void) {
95 uint64_t value;
96
97 test_case("the full unsigned 64 bit range is available");
98 CHECK_INT(scan_udec("18446744073709551615", &value, UINT64_MAX), 20);
99 CHECK(value == UINT64_MAX);
100
101 test_case("a number too large for 64 bits is refused");
102 CHECK_INT(scan_udec("18446744073709551616", &value, UINT64_MAX), 0);
103 CHECK_INT(scan_udec("99999999999999999999999999", &value, UINT64_MAX), 0);
104}
105
106static void case_leading_zeros_allowed(void) {
107 uint64_t value;
108
109 test_case("leading zeros are accepted outside bencode");
110 CHECK_INT(scan_udec("007", &value, 65535), 3);
111 CHECK_INT(value, 7);
112 CHECK_INT(scan_udec("0000", &value, 65535), 4);
113 CHECK_INT(value, 0);
114}
115
116static void case_bencode_rejects_leading_zeros(void) {
117 uint64_t value = 0xdead;
118
119 test_case("bencode refuses a leading zero on anything but zero");
120 CHECK_INT(scan_udec_bencode("007", &value, 65535), 0);
121 CHECK_INT(scan_udec_bencode("0000", &value, 65535), 0);
122 CHECK_INT(scan_udec_bencode("01", &value, 65535), 0);
123 CHECK_INT(value, 0xdead);
124}
125
126static void case_bencode_accepts_canonical(void) {
127 uint64_t value;
128
129 test_case("bencode accepts a canonically written number");
130 CHECK_INT(scan_udec_bencode("0", &value, 65535), 1);
131 CHECK_INT(value, 0);
132 CHECK_INT(scan_udec_bencode("0:", &value, 65535), 1);
133 CHECK_INT(value, 0);
134 CHECK_INT(scan_udec_bencode("160:", &value, 65535), 3);
135 CHECK_INT(value, 160);
136}
137
138static void case_bencode_inherits_the_rest(void) {
139 uint64_t value = 0xdead;
140
141 test_case("bencode is no laxer than the plain scanner");
142 CHECK_INT(scan_udec_bencode(" 1", &value, 65535), 0);
143 CHECK_INT(scan_udec_bencode("-1", &value, 65535), 0);
144 CHECK_INT(scan_udec_bencode("+1", &value, 65535), 0);
145 CHECK_INT(scan_udec_bencode("65536", &value, 65535), 0);
146 CHECK_INT(value, 0xdead);
147}
148
149void test_scan(void) {
150 case_plain_numbers();
151 case_stops_at_non_digit();
152 case_rejects_whitespace();
153 case_rejects_sign();
154 case_rejects_empty_and_junk();
155 case_no_alternative_bases();
156 case_refuses_out_of_range();
157 case_sixty_four_bit_range();
158 case_leading_zeros_allowed();
159 case_bencode_rejects_leading_zeros();
160 case_bencode_accepts_canonical();
161 case_bencode_inherits_the_rest();
162}
diff --git a/tests/test.h b/tests/test.h
index 8be624b..f0f2360 100644
--- a/tests/test.h
+++ b/tests/test.h
@@ -82,5 +82,6 @@ void test_vector(void);
82void test_random(void); 82void test_random(void);
83void test_hex(void); 83void test_hex(void);
84void test_accesslist(void); 84void test_accesslist(void);
85void test_scan(void);
85 86
86#endif 87#endif