/work/testing/misc_tools.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: GPL-3.0-or-later |
2 | | * Copyright © 2016-2018 The TokTok team. |
3 | | * Copyright © 2013 Tox project. |
4 | | */ |
5 | | |
6 | | /* |
7 | | * Miscellaneous functions and data structures for doing random things. |
8 | | */ |
9 | | #ifndef _POSIX_C_SOURCE |
10 | | // For nanosleep(). |
11 | | #define _POSIX_C_SOURCE 200112L |
12 | | #endif |
13 | | |
14 | | #include "misc_tools.h" |
15 | | |
16 | | #include <assert.h> |
17 | | #include <ctype.h> |
18 | | #include <stdint.h> |
19 | | #include <stdio.h> |
20 | | #include <stdlib.h> |
21 | | #include <string.h> |
22 | | |
23 | | #include <sodium.h> |
24 | | |
25 | | #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) |
26 | | #include <windows.h> |
27 | | #else |
28 | | #include <time.h> |
29 | | #endif |
30 | | |
31 | | #include "../toxcore/ccompat.h" |
32 | | #include "../toxcore/tox.h" |
33 | | |
34 | | void c_sleep(uint32_t x) |
35 | 47.3k | { |
36 | | #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) |
37 | | Sleep(x); |
38 | | #else |
39 | 47.3k | struct timespec req; |
40 | 47.3k | req.tv_sec = x / 1000; |
41 | 47.3k | req.tv_nsec = (long)x % 1000 * 1000 * 1000; |
42 | 47.3k | nanosleep(&req, nullptr); |
43 | 47.3k | #endif |
44 | 47.3k | } |
45 | | |
46 | | // You are responsible for freeing the return value! |
47 | | uint8_t *hex_string_to_bin(const char *hex_string) |
48 | 0 | { |
49 | | // byte is represented by exactly 2 hex digits, so length of binary string |
50 | | // is half of that of the hex one. only hex string with even length |
51 | | // valid. the more proper implementation would be to check if strlen(hex_string) |
52 | | // is odd and return error code if it is. we assume strlen is even. if it's not |
53 | | // then the last byte just won't be written in 'ret'. |
54 | 0 | size_t i, len = strlen(hex_string) / 2; |
55 | 0 | uint8_t *ret = (uint8_t *)malloc(len); |
56 | 0 | const char *pos = hex_string; |
57 | |
|
58 | 0 | if (ret == nullptr) { |
59 | 0 | return nullptr; |
60 | 0 | } |
61 | | |
62 | 0 | for (i = 0; i < len; ++i, pos += 2) { |
63 | 0 | unsigned int val; |
64 | 0 | sscanf(pos, "%02x", &val); |
65 | 0 | ret[i] = val; |
66 | 0 | } |
67 | |
|
68 | 0 | return ret; |
69 | 0 | } |
70 | | |
71 | | void to_hex(char *out, uint8_t *in, int size) |
72 | 1 | { |
73 | 39 | while (size--) { |
74 | 38 | if (*in >> 4 < 0xA) { |
75 | 25 | *out++ = '0' + (*in >> 4); |
76 | 25 | } else { |
77 | 13 | *out++ = 'A' + (*in >> 4) - 0xA; |
78 | 13 | } |
79 | | |
80 | 38 | if ((*in & 0xf) < 0xA) { |
81 | 17 | *out++ = '0' + (*in & 0xF); |
82 | 21 | } else { |
83 | 21 | *out++ = 'A' + (*in & 0xF) - 0xA; |
84 | 21 | } |
85 | | |
86 | 38 | in++; |
87 | 38 | } |
88 | 1 | } |
89 | | |
90 | | /* Reimplementation of strncasecmp() function from strings.h, as strings.h is |
91 | | * POSIX and not portable. Specifically it doesn't exist on MSVC. |
92 | | */ |
93 | | int tox_strncasecmp(const char *s1, const char *s2, size_t n) |
94 | 288 | { |
95 | 1.27k | while (n--) { |
96 | 1.11k | int c1 = tolower(*(s1++)); |
97 | 1.11k | int c2 = tolower(*(s2++)); |
98 | | |
99 | 1.11k | if (c1 == '\0' || c2 == '\0' || c1 != c2) { |
100 | 126 | return c1 - c2; |
101 | 126 | } |
102 | 1.11k | } |
103 | | |
104 | 162 | return 0; |
105 | 288 | } |
106 | | |
107 | | int cmdline_parsefor_ipv46(int argc, char **argv, bool *ipv6enabled) |
108 | 0 | { |
109 | 0 | int argvoffset = 0, argi; |
110 | |
|
111 | 0 | for (argi = 1; argi < argc; argi++) { |
112 | 0 | if (!tox_strncasecmp(argv[argi], "--ipv", 5)) { |
113 | 0 | if (argv[argi][5] && !argv[argi][6]) { |
114 | 0 | char c = argv[argi][5]; |
115 | |
|
116 | 0 | if (c == '4') { |
117 | 0 | *ipv6enabled = false; |
118 | 0 | } else if (c == '6') { |
119 | 0 | *ipv6enabled = true; |
120 | 0 | } else { |
121 | 0 | printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); |
122 | 0 | return -1; |
123 | 0 | } |
124 | 0 | } else { |
125 | 0 | printf("Invalid argument: %s. Try --ipv4 or --ipv6!\n", argv[argi]); |
126 | 0 | return -1; |
127 | 0 | } |
128 | | |
129 | 0 | if (argvoffset != argi - 1) { |
130 | 0 | printf("Argument must come first: %s.\n", argv[argi]); |
131 | 0 | return -1; |
132 | 0 | } |
133 | | |
134 | 0 | argvoffset++; |
135 | 0 | } |
136 | 0 | } |
137 | | |
138 | 0 | return argvoffset; |
139 | 0 | } |
140 | | |
141 | | |
142 | | static const char *test_rng_name(void) |
143 | 0 | { |
144 | 0 | return "test_rng"; |
145 | 0 | } |
146 | | |
147 | | static uint32_t rng_state; |
148 | | |
149 | | static uint32_t test_rng_random(void) |
150 | 0 | { |
151 | 0 | rng_state = 2624534371 * rng_state + 1; |
152 | 0 | return rng_state; |
153 | 0 | } |
154 | | |
155 | | static void test_rng_buf(void *const buf, const size_t size) |
156 | 0 | { |
157 | 0 | uint8_t *p = (uint8_t *)buf; |
158 | 0 | uint32_t r = 0; |
159 | |
|
160 | 0 | for (size_t i = 0; i < size; i++) { |
161 | 0 | if ((i % 4) == 0) { |
162 | 0 | r = test_rng_random(); |
163 | 0 | } |
164 | |
|
165 | 0 | *p = (r >> ((i % 4) * 8)) & 0xff; |
166 | 0 | ++p; |
167 | 0 | } |
168 | 0 | } |
169 | | |
170 | | static uint32_t test_rng_uniform(const uint32_t upper_bound) |
171 | 0 | { |
172 | | // XXX: Not uniform! But that's ok for testing purposes. |
173 | 0 | return test_rng_random() % upper_bound; |
174 | 0 | } |
175 | | |
176 | 0 | static void test_rng_stir(void) { } |
177 | | static int test_rng_close(void) |
178 | 0 | { |
179 | 0 | return 0; |
180 | 0 | } |
181 | | |
182 | | static randombytes_implementation test_rng = { |
183 | | test_rng_name, |
184 | | test_rng_random, |
185 | | test_rng_stir, |
186 | | test_rng_uniform, |
187 | | test_rng_buf, |
188 | | test_rng_close |
189 | | }; |
190 | | |
191 | | /* Simple insecure PRNG for testing purposes */ |
192 | | int use_test_rng(uint32_t seed) |
193 | 0 | { |
194 | 0 | rng_state = seed; |
195 | |
|
196 | 0 | return randombytes_set_implementation(&test_rng); |
197 | 0 | } |