1 /* Copyright (c) 2001-2004, Roger Dingledine.
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 #include "orconfig.h"
7 #define COMPAT_TIME_PRIVATE
8 #define UTIL_MALLOC_PRIVATE
9 #define PROCESS_WIN32_PRIVATE
10 #define TIME_FMT_PRIVATE
11 #include "lib/testsupport/testsupport.h"
12 #include "core/or/or.h"
13 #include "lib/buf/buffers.h"
14 #include "app/config/config.h"
15 #include "feature/control/control.h"
16 #include "feature/control/control_proto.h"
17 #include "feature/client/transports.h"
18 #include "lib/crypt_ops/crypto_format.h"
19 #include "lib/crypt_ops/crypto_rand.h"
20 #include "lib/defs/time.h"
21 #include "test/test.h"
22 #include "test/test_helpers.h"
23 #include "lib/memarea/memarea.h"
24 #include "lib/process/waitpid.h"
25 #include "lib/process/process_win32.h"
26 #include "test/log_test_helpers.h"
27 #include "lib/compress/compress.h"
28 #include "lib/compress/compress_zstd.h"
29 #include "lib/encoding/keyval.h"
30 #include "lib/fdio/fdio.h"
31 #include "lib/fs/winlib.h"
32 #include "lib/process/env.h"
33 #include "lib/process/pidfile.h"
34 #include "lib/intmath/weakrng.h"
35 #include "lib/intmath/muldiv.h"
36 #include "lib/thread/numcpus.h"
37 #include "lib/math/fp.h"
38 #include "lib/math/laplace.h"
39 #include "lib/meminfo/meminfo.h"
40 #include "lib/time/tvdiff.h"
41 #include "lib/encoding/confline.h"
42 #include "lib/net/socketpair.h"
43 #include "lib/malloc/map_anon.h"
44 
45 #ifdef HAVE_PWD_H
46 #include <pwd.h>
47 #endif
48 #ifdef HAVE_SYS_UTIME_H
49 #include <sys/utime.h>
50 #endif
51 #ifdef HAVE_UTIME_H
52 #include <utime.h>
53 #endif
54 #ifdef HAVE_SYS_STAT_H
55 #include <sys/stat.h>
56 #endif
57 #ifdef HAVE_FCNTL_H
58 #include <fcntl.h>
59 #endif
60 #ifdef HAVE_UNISTD_H
61 #include <unistd.h>
62 #endif
63 #ifdef HAVE_SYS_MMAN_H
64 #include <sys/mman.h>
65 #endif
66 #ifdef HAVE_SYS_WAIT_H
67 #include <sys/wait.h>
68 #endif
69 
70 #ifdef _WIN32
71 #include <tchar.h>
72 #endif
73 #include <math.h>
74 #include <ctype.h>
75 #include <float.h>
76 
77 /* These platforms don't have meaningful pwdb or homedirs. */
78 #if defined(_WIN32) || defined(__ANDROID__)
79 #define DISABLE_PWDB_TESTS
80 #endif
81 
82 static void set_file_mtime(const char *fname, time_t when);
83 
84 #define INFINITY_DBL ((double)INFINITY)
85 #define NAN_DBL ((double)NAN)
86 
87 /** Test the tor_isinf() wrapper */
88 static void
test_tor_isinf(void * arg)89 test_tor_isinf(void *arg)
90 {
91   (void) arg;
92 
93   tt_assert(tor_isinf(INFINITY_DBL));
94 
95   tt_assert(!tor_isinf(NAN_DBL));
96   tt_assert(!tor_isinf(DBL_EPSILON));
97   tt_assert(!tor_isinf(DBL_MAX));
98   tt_assert(!tor_isinf(DBL_MIN));
99 
100   tt_assert(!tor_isinf(0.0));
101   tt_assert(!tor_isinf(0.1));
102   tt_assert(!tor_isinf(3));
103   tt_assert(!tor_isinf(3.14));
104 
105  done:
106   ;
107 }
108 
109 /* XXXX this is a minimal wrapper to make the unit tests compile with the
110  * changed tor_timegm interface. */
111 static time_t
tor_timegm_wrapper(const struct tm * tm)112 tor_timegm_wrapper(const struct tm *tm)
113 {
114   time_t t;
115   if (tor_timegm_impl(tm, &t) < 0)
116     return -1;
117   return t;
118 }
119 
120 #define tor_timegm tor_timegm_wrapper
121 
122 static void
test_util_read_until_eof_impl(const char * fname,size_t file_len,size_t read_limit)123 test_util_read_until_eof_impl(const char *fname, size_t file_len,
124                               size_t read_limit)
125 {
126   char *fifo_name = NULL;
127   char *test_str = NULL;
128   char *str = NULL;
129   size_t sz = 9999999;
130   int fd = -1;
131   int r;
132 
133   fifo_name = tor_strdup(get_fname(fname));
134   test_str = tor_malloc(file_len);
135   crypto_rand(test_str, file_len);
136 
137   r = write_bytes_to_file(fifo_name, test_str, file_len, 1);
138   tt_int_op(r, OP_EQ, 0);
139 
140   fd = open(fifo_name, O_RDONLY|O_BINARY);
141   tt_int_op(fd, OP_GE, 0);
142   str = read_file_to_str_until_eof(fd, read_limit, &sz);
143   tt_ptr_op(str, OP_NE, NULL);
144 
145   if (read_limit < file_len)
146     tt_int_op(sz, OP_EQ, read_limit);
147   else
148     tt_int_op(sz, OP_EQ, file_len);
149 
150   tt_mem_op(test_str, OP_EQ, str, sz);
151   tt_int_op(str[sz], OP_EQ, '\0');
152 
153  done:
154   unlink(fifo_name);
155   tor_free(fifo_name);
156   tor_free(test_str);
157   tor_free(str);
158   if (fd >= 0)
159     close(fd);
160 }
161 
162 static void
test_util_read_file_eof_tiny_limit(void * arg)163 test_util_read_file_eof_tiny_limit(void *arg)
164 {
165   (void)arg;
166   // purposely set limit shorter than what we wrote to the FIFO to
167   // test the maximum, and that it puts the NUL in the right spot
168 
169   test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
170 }
171 
172 static void
test_util_read_file_eof_one_loop_a(void * arg)173 test_util_read_file_eof_one_loop_a(void *arg)
174 {
175   (void)arg;
176   test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
177 }
178 
179 static void
test_util_read_file_eof_one_loop_b(void * arg)180 test_util_read_file_eof_one_loop_b(void *arg)
181 {
182   (void)arg;
183   test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
184 }
185 
186 static void
test_util_read_file_eof_two_loops(void * arg)187 test_util_read_file_eof_two_loops(void *arg)
188 {
189   (void)arg;
190   // write more than 1024 bytes to the FIFO to test two passes through
191   // the loop in the method; if the re-alloc size is changed this
192   // should be updated as well.
193 
194   test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
195 }
196 
197 static void
test_util_read_file_eof_two_loops_b(void * arg)198 test_util_read_file_eof_two_loops_b(void *arg)
199 {
200   (void)arg;
201 
202   test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
203 }
204 
205 static void
test_util_read_file_eof_zero_bytes(void * arg)206 test_util_read_file_eof_zero_bytes(void *arg)
207 {
208   (void)arg;
209   // zero-byte fifo
210   test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
211 }
212 
213 static void
test_util_read_file_endlines(void * arg)214 test_util_read_file_endlines(void *arg)
215 {
216   (void)arg;
217 
218   char *fname = NULL;
219   char *read_content = NULL;
220   int r = -1;
221 
222   /* Write a file that contains both \n and \r\n as line ending. */
223   const char *file_content = "foo bar\n"
224                              "foo bar baz\r\n"
225                              "foo bar\r\n";
226 
227   const char *expected_file_content = "foo bar\n"
228                                       "foo bar baz\n"
229                                       "foo bar\n";
230 
231   fname = tor_strdup(get_fname("file_with_crlf_ending"));
232 
233   r = write_bytes_to_file(fname, file_content, strlen(file_content), 1);
234   tt_int_op(r, OP_EQ, 0);
235 
236   /* Read the file in text mode: we strip \r's from the files on both Windows
237    * and UNIX. */
238   read_content = read_file_to_str(fname, 0, NULL);
239 
240   tt_ptr_op(read_content, OP_NE, NULL);
241   tt_int_op(strlen(read_content), OP_EQ, strlen(expected_file_content));
242   tt_str_op(read_content, OP_EQ, expected_file_content);
243 
244   tor_free(read_content);
245 
246   /* Read the file in binary mode: we should preserve the \r here. */
247   read_content = read_file_to_str(fname, RFTS_BIN, NULL);
248 
249   tt_ptr_op(read_content, OP_NE, NULL);
250   tt_int_op(strlen(read_content), OP_EQ, strlen(file_content));
251   tt_str_op(read_content, OP_EQ, file_content);
252 
253   tor_free(read_content);
254 
255  done:
256   unlink(fname);
257   tor_free(fname);
258   tor_free(read_content);
259 }
260 
261 /* Test the basic expected behaviour for write_chunks_to_file.
262  * NOTE: This will need to be updated if we ever change the tempfile location
263  * or extension */
264 static void
test_util_write_chunks_to_file(void * arg)265 test_util_write_chunks_to_file(void *arg)
266 {
267   char *fname = NULL;
268   char *tempname = NULL;
269   char *str = NULL;
270   int r;
271   struct stat st;
272 
273   /* These should be two different sizes to ensure the data is different
274    * between the data file and the temp file's 'known string' */
275   int temp_str_len = 1024;
276   int data_str_len = 512;
277   char *data_str = tor_malloc(data_str_len);
278   char *temp_str = tor_malloc(temp_str_len);
279 
280   smartlist_t *chunks = smartlist_new();
281   sized_chunk_t c = {data_str, data_str_len/2};
282   sized_chunk_t c2 = {data_str + data_str_len/2, data_str_len/2};
283   (void)arg;
284 
285   crypto_rand(temp_str, temp_str_len);
286   crypto_rand(data_str, data_str_len);
287 
288   // Ensure it can write multiple chunks
289 
290   smartlist_add(chunks, &c);
291   smartlist_add(chunks, &c2);
292 
293   /*
294   * Check if it writes using a tempfile
295   */
296   fname = tor_strdup(get_fname("write_chunks_with_tempfile"));
297   tor_asprintf(&tempname, "%s.tmp", fname);
298 
299   // write a known string to a file where the tempfile will be
300   r = write_bytes_to_file(tempname, temp_str, temp_str_len, 1);
301   tt_int_op(r, OP_EQ, 0);
302 
303   // call write_chunks_to_file
304   r = write_chunks_to_file(fname, chunks, 1, 0);
305   tt_int_op(r, OP_EQ, 0);
306 
307   // assert the file has been written (expected size)
308   str = read_file_to_str(fname, RFTS_BIN, &st);
309   tt_assert(str != NULL);
310   tt_u64_op((uint64_t)st.st_size, OP_EQ, data_str_len);
311   tt_mem_op(data_str, OP_EQ, str, data_str_len);
312   tor_free(str);
313 
314   // assert that the tempfile is removed (should not leave artifacts)
315   str = read_file_to_str(tempname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
316   tt_assert(str == NULL);
317 
318   // Remove old testfile for second test
319   r = unlink(fname);
320   tt_int_op(r, OP_EQ, 0);
321   tor_free(fname);
322   tor_free(tempname);
323 
324   /*
325   *  Check if it skips using a tempfile with flags
326   */
327   fname = tor_strdup(get_fname("write_chunks_with_no_tempfile"));
328   tor_asprintf(&tempname, "%s.tmp", fname);
329 
330   // write a known string to a file where the tempfile will be
331   r = write_bytes_to_file(tempname, temp_str, temp_str_len, 1);
332   tt_int_op(r, OP_EQ, 0);
333 
334   // call write_chunks_to_file with no_tempfile = true
335   r = write_chunks_to_file(fname, chunks, 1, 1);
336   tt_int_op(r, OP_EQ, 0);
337 
338   // assert the file has been written (expected size)
339   str = read_file_to_str(fname, RFTS_BIN, &st);
340   tt_assert(str != NULL);
341   tt_u64_op((uint64_t)st.st_size, OP_EQ, data_str_len);
342   tt_mem_op(data_str, OP_EQ, str, data_str_len);
343   tor_free(str);
344 
345   // assert the tempfile still contains the known string
346   str = read_file_to_str(tempname, RFTS_BIN, &st);
347   tt_assert(str != NULL);
348   tt_u64_op((uint64_t)st.st_size, OP_EQ, temp_str_len);
349   tt_mem_op(temp_str, OP_EQ, str, temp_str_len);
350 
351  done:
352   unlink(fname);
353   unlink(tempname);
354   smartlist_free(chunks);
355   tor_free(fname);
356   tor_free(tempname);
357   tor_free(str);
358   tor_free(data_str);
359   tor_free(temp_str);
360 }
361 
362 /* Test write_str_to_file_if_not_equal(). */
363 static void
test_util_write_str_if_changed(void * arg)364 test_util_write_str_if_changed(void *arg)
365 {
366   (void)arg;
367   char *fname = tor_strdup(get_fname("write_if_changed"));
368   char *s = NULL;
369   int rv;
370   const char str1[] = "The wombat lives across the seas";
371   const char str2[] = "Among the far Antipodes"; /* -- Ogden Nash */
372 
373   /* We can create files. */
374   rv = write_str_to_file_if_not_equal(fname, str1);
375   tt_int_op(rv, OP_EQ, 0);
376   s = read_file_to_str(fname, 0, NULL);
377   tt_str_op(s, OP_EQ, str1);
378   tor_free(s);
379 
380   /* We can replace files. */
381   rv = write_str_to_file_if_not_equal(fname, str2);
382   tt_int_op(rv, OP_EQ, 0);
383   s = read_file_to_str(fname, 0, NULL);
384   tt_str_op(s, OP_EQ, str2);
385   tor_free(s);
386 
387   /* Make sure we don't replace files when they're equal. (That's the whole
388    * point of the function we're testing. */
389   /* First, change the mtime of the file so that we can tell whether we
390    * replaced it. */
391   const time_t now = time(NULL);
392   const time_t five_sec_ago = now - 5;
393   set_file_mtime(fname, five_sec_ago);
394   rv = write_str_to_file_if_not_equal(fname, str2);
395   tt_int_op(rv, OP_EQ, 0);
396   /* Make sure that the file's mtime is unchanged... */
397   struct stat st;
398   rv = stat(fname, &st);
399   tt_int_op(rv, OP_EQ, 0);
400   tt_i64_op(st.st_mtime, OP_EQ, five_sec_ago);
401   /* And make sure its contents are unchanged. */
402   s = read_file_to_str(fname, 0, NULL);
403   tt_str_op(s, OP_EQ, str2);
404   tor_free(s);
405 
406  done:
407   tor_free(fname);
408   tor_free(s);
409 }
410 
411 #ifndef COCCI
412 #define _TFE(a, b, f)  tt_int_op((a).f, OP_EQ, (b).f)
413 /** test the minimum set of struct tm fields needed for a unique epoch value
414  * this is also the set we use to test tor_timegm */
415 #define TM_EQUAL(a, b)           \
416           TT_STMT_BEGIN          \
417             _TFE(a, b, tm_year); \
418             _TFE(a, b, tm_mon ); \
419             _TFE(a, b, tm_mday); \
420             _TFE(a, b, tm_hour); \
421             _TFE(a, b, tm_min ); \
422             _TFE(a, b, tm_sec ); \
423           TT_STMT_END
424 #endif /* !defined(COCCI) */
425 
426 static void
test_util_time(void * arg)427 test_util_time(void *arg)
428 {
429   struct timeval start, end;
430   struct tm a_time, b_time;
431   char timestr[128];
432   time_t t_res;
433   int i;
434   struct timeval tv;
435 
436   /* Test tv_udiff and tv_mdiff */
437 
438   (void)arg;
439   start.tv_sec = 5;
440   start.tv_usec = 5000;
441 
442   end.tv_sec = 5;
443   end.tv_usec = 5000;
444 
445   tt_int_op(0L,OP_EQ, tv_udiff(&start, &end));
446   tt_int_op(0L,OP_EQ, tv_mdiff(&start, &end));
447   tt_int_op(0L,OP_EQ, tv_udiff(&end, &start));
448   tt_int_op(0L,OP_EQ, tv_mdiff(&end, &start));
449 
450   end.tv_usec = 7000;
451 
452   tt_int_op(2000L,OP_EQ, tv_udiff(&start, &end));
453   tt_int_op(2L,OP_EQ, tv_mdiff(&start, &end));
454   tt_int_op(-2000L,OP_EQ, tv_udiff(&end, &start));
455   tt_int_op(-2L,OP_EQ, tv_mdiff(&end, &start));
456 
457   end.tv_sec = 6;
458 
459   tt_int_op(1002000L,OP_EQ, tv_udiff(&start, &end));
460   tt_int_op(1002L,OP_EQ, tv_mdiff(&start, &end));
461   tt_int_op(-1002000L,OP_EQ, tv_udiff(&end, &start));
462   tt_int_op(-1002L,OP_EQ, tv_mdiff(&end, &start));
463 
464   end.tv_usec = 0;
465 
466   tt_int_op(995000L,OP_EQ, tv_udiff(&start, &end));
467   tt_int_op(995L,OP_EQ, tv_mdiff(&start, &end));
468   tt_int_op(-995000L,OP_EQ, tv_udiff(&end, &start));
469   tt_int_op(-995L,OP_EQ, tv_mdiff(&end, &start));
470 
471   end.tv_sec = 4;
472 
473   tt_int_op(-1005000L,OP_EQ, tv_udiff(&start, &end));
474   tt_int_op(-1005L,OP_EQ, tv_mdiff(&start, &end));
475   tt_int_op(1005000L,OP_EQ, tv_udiff(&end, &start));
476   tt_int_op(1005L,OP_EQ, tv_mdiff(&end, &start));
477 
478   /* Negative tv_sec values, these will break on platforms where tv_sec is
479    * unsigned */
480 
481   end.tv_sec = -10;
482 
483   tt_int_op(-15005000L,OP_EQ, tv_udiff(&start, &end));
484   tt_int_op(-15005L,OP_EQ, tv_mdiff(&start, &end));
485   tt_int_op(15005000L,OP_EQ, tv_udiff(&end, &start));
486   tt_int_op(15005L,OP_EQ, tv_mdiff(&end, &start));
487 
488   start.tv_sec = -100;
489 
490   tt_int_op(89995000L,OP_EQ, tv_udiff(&start, &end));
491   tt_int_op(89995L,OP_EQ, tv_mdiff(&start, &end));
492   tt_int_op(-89995000L,OP_EQ, tv_udiff(&end, &start));
493   tt_int_op(-89995L,OP_EQ, tv_mdiff(&end, &start));
494 
495   /* Test that tv_usec values round away from zero when converted to msec */
496   start.tv_sec = 0;
497   start.tv_usec = 0;
498   end.tv_sec = 10;
499   end.tv_usec = 499;
500 
501   tt_int_op(10000499L, OP_EQ, tv_udiff(&start, &end));
502   tt_int_op(10000L, OP_EQ, tv_mdiff(&start, &end));
503   tt_int_op(-10000499L, OP_EQ, tv_udiff(&end, &start));
504   tt_int_op(-10000L, OP_EQ, tv_mdiff(&end, &start));
505 
506   start.tv_sec = 0;
507   start.tv_usec = 0;
508   end.tv_sec = 10;
509   end.tv_usec = 500;
510 
511   tt_int_op(10000500L, OP_EQ, tv_udiff(&start, &end));
512   tt_int_op(10001L, OP_EQ, tv_mdiff(&start, &end));
513   tt_int_op(-10000500L, OP_EQ, tv_udiff(&end, &start));
514   tt_int_op(-10000L, OP_EQ, tv_mdiff(&end, &start));
515 
516   start.tv_sec = 0;
517   start.tv_usec = 0;
518   end.tv_sec = 10;
519   end.tv_usec = 501;
520 
521   tt_int_op(10000501L, OP_EQ, tv_udiff(&start, &end));
522   tt_int_op(10001L, OP_EQ, tv_mdiff(&start, &end));
523   tt_int_op(-10000501L, OP_EQ, tv_udiff(&end, &start));
524   tt_int_op(-10001L, OP_EQ, tv_mdiff(&end, &start));
525 
526   /* Overflow conditions */
527 
528 #ifdef _WIN32
529   /* Would you believe that tv_sec is a long on windows? Of course you would.*/
530 #define TV_SEC_MAX LONG_MAX
531 #define TV_SEC_MIN LONG_MIN
532 #else
533   /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
534    * Which means TIME_MAX is not actually the maximum value of tv_sec.
535    * But that's ok for the moment, because the code correctly performs 64-bit
536    * calculations internally, then catches the overflow. */
537 #define TV_SEC_MAX TIME_MAX
538 #define TV_SEC_MIN TIME_MIN
539 #endif /* defined(_WIN32) */
540 
541 /* Assume tv_usec is an unsigned integer until proven otherwise */
542 #define TV_USEC_MAX UINT_MAX
543 
544   /* Overflows in the result type */
545 
546   /* All comparisons work */
547   start.tv_sec = 0;
548   start.tv_usec = 0;
549   end.tv_sec = LONG_MAX/1000 - 2;
550   end.tv_usec = 0;
551 
552   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
553   tt_int_op(end.tv_sec*1000L, OP_EQ, tv_mdiff(&start, &end));
554   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
555   tt_int_op(-end.tv_sec*1000L, OP_EQ, tv_mdiff(&end, &start));
556 
557   start.tv_sec = 0;
558   start.tv_usec = 0;
559   end.tv_sec = LONG_MAX/1000000 - 1;
560   end.tv_usec = 0;
561 
562   tt_int_op(end.tv_sec*1000000L, OP_EQ, tv_udiff(&start, &end));
563   tt_int_op(end.tv_sec*1000L, OP_EQ, tv_mdiff(&start, &end));
564   tt_int_op(-end.tv_sec*1000000L, OP_EQ, tv_udiff(&end, &start));
565   tt_int_op(-end.tv_sec*1000L, OP_EQ, tv_mdiff(&end, &start));
566 
567   /* No comparisons work */
568   start.tv_sec = 0;
569   start.tv_usec = 0;
570   end.tv_sec = LONG_MAX/1000 + 1;
571   end.tv_usec = 0;
572 
573   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
574   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
575   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
576   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
577 
578   start.tv_sec = 0;
579   start.tv_usec = 0;
580   end.tv_sec = LONG_MAX/1000000 + 1;
581   end.tv_usec = 0;
582 
583   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
584   tt_int_op(end.tv_sec*1000L, OP_EQ, tv_mdiff(&start, &end));
585   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
586   tt_int_op(-end.tv_sec*1000L, OP_EQ, tv_mdiff(&end, &start));
587 
588   start.tv_sec = 0;
589   start.tv_usec = 0;
590   end.tv_sec = LONG_MAX/1000;
591   end.tv_usec = TOR_USEC_PER_SEC;
592 
593   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
594   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
595   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
596   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
597 
598   start.tv_sec = 0;
599   start.tv_usec = 0;
600   end.tv_sec = LONG_MAX/1000000;
601   end.tv_usec = TOR_USEC_PER_SEC;
602 
603   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
604   tt_int_op((end.tv_sec + 1)*1000L, OP_EQ, tv_mdiff(&start, &end));
605   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
606   tt_int_op(-(end.tv_sec + 1)*1000L, OP_EQ, tv_mdiff(&end, &start));
607 
608   /* Overflows on comparison to zero */
609 
610   start.tv_sec = 0;
611   start.tv_usec = 0;
612 
613   end.tv_sec = TV_SEC_MAX;
614   end.tv_usec = 0;
615 
616   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
617   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
618   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
619   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
620 
621   end.tv_sec = TV_SEC_MAX;
622   end.tv_usec = TOR_USEC_PER_SEC;
623 
624   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
625   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
626   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
627   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
628 
629   end.tv_sec = 0;
630   end.tv_usec = TV_USEC_MAX;
631 
632   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
633   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
634   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
635   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
636 
637   end.tv_sec = TV_SEC_MAX;
638   end.tv_usec = TV_USEC_MAX;
639 
640   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
641   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
642   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
643   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
644 
645   end.tv_sec = 0;
646   end.tv_usec = 0;
647 
648   start.tv_sec = TV_SEC_MIN;
649   start.tv_usec = 0;
650 
651   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
652   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
653   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
654   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
655 
656   start.tv_sec = TV_SEC_MIN;
657   start.tv_usec = TOR_USEC_PER_SEC;
658 
659   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
660   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
661   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
662   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
663 
664   start.tv_sec = TV_SEC_MIN;
665   start.tv_usec = TV_USEC_MAX;
666 
667   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
668   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
669   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
670   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
671 
672   /* overflows on comparison to maxima / minima */
673 
674   start.tv_sec = TV_SEC_MIN;
675   start.tv_usec = 0;
676 
677   end.tv_sec = TV_SEC_MAX;
678   end.tv_usec = 0;
679 
680   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
681   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
682   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
683   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
684 
685   end.tv_sec = TV_SEC_MAX;
686   end.tv_usec = TOR_USEC_PER_SEC;
687 
688   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
689   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
690   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
691   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
692 
693   end.tv_sec = TV_SEC_MAX;
694   end.tv_usec = 0;
695 
696   start.tv_sec = TV_SEC_MIN;
697   start.tv_usec = 0;
698 
699   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
700   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
701   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
702   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
703 
704   start.tv_sec = TV_SEC_MIN;
705   start.tv_usec = TOR_USEC_PER_SEC;
706 
707   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
708   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
709   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
710   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
711 
712   /* overflows on comparison to maxima / minima with extra usec */
713 
714   start.tv_sec = TV_SEC_MIN;
715   start.tv_usec = TOR_USEC_PER_SEC;
716 
717   end.tv_sec = TV_SEC_MAX;
718   end.tv_usec = 0;
719 
720   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
721   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
722   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
723   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
724 
725   end.tv_sec = TV_SEC_MAX;
726   end.tv_usec = TOR_USEC_PER_SEC;
727 
728   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
729   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
730   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
731   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
732 
733   end.tv_sec = TV_SEC_MAX;
734   end.tv_usec = TOR_USEC_PER_SEC;
735 
736   start.tv_sec = TV_SEC_MIN;
737   start.tv_usec = 0;
738 
739   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
740   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
741   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
742   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
743 
744   start.tv_sec = TV_SEC_MIN;
745   start.tv_usec = TOR_USEC_PER_SEC;
746 
747   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
748   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
749   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
750   tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
751 
752   /* Test tor_timegm & tor_gmtime_r */
753 
754   /* The test values here are confirmed to be correct on a platform
755    * with a working timegm & gmtime_r. */
756 
757   /* Start with known-zero a_time and b_time.
758    * This avoids passing uninitialised values to TM_EQUAL in a_time.
759    * Zeroing may not be needed for b_time, as long as tor_gmtime_r
760    * never reads the existing values in the structure.
761    * But we really don't want intermittently failing tests. */
762   memset(&a_time, 0, sizeof(struct tm));
763   memset(&b_time, 0, sizeof(struct tm));
764 
765   a_time.tm_year = 2003-1900;
766   a_time.tm_mon = 7;
767   a_time.tm_mday = 30;
768   a_time.tm_hour = 6;
769   a_time.tm_min = 14;
770   a_time.tm_sec = 55;
771   t_res = 1062224095UL;
772   tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
773   tor_gmtime_r(&t_res, &b_time);
774   TM_EQUAL(a_time, b_time);
775 
776   a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
777   t_res = 1093846495UL;
778   tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
779   tor_gmtime_r(&t_res, &b_time);
780   TM_EQUAL(a_time, b_time);
781 
782   a_time.tm_mon = 1;          /* Try a leap year, in feb. */
783   a_time.tm_mday = 10;
784   t_res = 1076393695UL;
785   tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
786   tor_gmtime_r(&t_res, &b_time);
787   TM_EQUAL(a_time, b_time);
788 
789   a_time.tm_mon = 0;
790   t_res = 1073715295UL;
791   tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
792   tor_gmtime_r(&t_res, &b_time);
793   TM_EQUAL(a_time, b_time);
794 
795   /* This value is in range with 32 bit and 64 bit time_t */
796   a_time.tm_year = 2037-1900;
797   t_res = 2115180895UL;
798   tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
799   tor_gmtime_r(&t_res, &b_time);
800   TM_EQUAL(a_time, b_time);
801 
802   /* This value is out of range with 32 bit time_t, but in range for 64 bit
803    * time_t */
804   a_time.tm_year = 2039-1900;
805 #if SIZEOF_TIME_T == 4
806   setup_full_capture_of_logs(LOG_WARN);
807   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
808   //expect_single_log_msg_containing("Result does not fit in tor_timegm");
809   teardown_capture_of_logs();
810 #elif SIZEOF_TIME_T == 8
811   t_res = 2178252895UL;
812   tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
813   tor_gmtime_r(&t_res, &b_time);
814   TM_EQUAL(a_time, b_time);
815 #endif /* SIZEOF_TIME_T == 4 || ... */
816 
817   /* Test tor_timegm out of range */
818 
819   /* The below tests will all cause a BUG message, so we capture, suppress,
820    * and detect. */
821 #define CAPTURE() do {                                          \
822     teardown_capture_of_logs();                                 \
823     setup_full_capture_of_logs(LOG_WARN);                       \
824   } while (0)
825 #define CHECK_TIMEGM_WARNING(msg) do { \
826     expect_single_log_msg_containing(msg);                              \
827   } while (0)
828 #define CHECK_POSSIBLE_EINVAL() do {                            \
829     if (mock_saved_log_n_entries()) {                           \
830       expect_single_log_msg_containing("Invalid argument");     \
831     }                                                           \
832   } while (0)
833 
834 #define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
835     CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
836 
837   /* year */
838 
839   /* Wrong year < 1970 */
840   a_time.tm_year = 1969-1900;
841   CAPTURE();
842   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
843   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
844 
845   a_time.tm_year = -1-1900;
846   CAPTURE();
847   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
848   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
849 
850 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
851     a_time.tm_year = -1*(1 << 16);
852     CAPTURE();
853     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
854     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
855 
856     /* one of the smallest tm_year values my 64 bit system supports:
857      * t_res = -9223372036854775LL without clamping */
858     a_time.tm_year = -292275055-1900;
859     CAPTURE();
860     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
861     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
862 
863     a_time.tm_year = INT32_MIN;
864     CAPTURE();
865     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
866     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
867 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
868 
869 #if SIZEOF_INT == 8
870     a_time.tm_year = -1*(1 << 48);
871     CAPTURE();
872     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
873     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
874 
875     /* while unlikely, the system's gmtime(_r) could return
876      * a "correct" retrospective gregorian negative year value,
877      * which I'm pretty sure is:
878      * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
879      * 730485 is the number of days in two millennia, including leap days */
880     a_time.tm_year = -292277022657-1900;
881     CAPTURE();
882     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
883     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
884 
885     a_time.tm_year = INT64_MIN;
886     CAPTURE();
887     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
888     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
889 #endif /* SIZEOF_INT == 8 */
890 
891   /* Wrong year >= INT32_MAX - 1900 */
892 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
893     a_time.tm_year = INT32_MAX-1900;
894     CAPTURE();
895     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
896     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
897 
898     a_time.tm_year = INT32_MAX;
899     CAPTURE();
900     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
901     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
902 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
903 
904 #if SIZEOF_INT == 8
905     /* one of the largest tm_year values my 64 bit system supports */
906     a_time.tm_year = 292278994-1900;
907     CAPTURE();
908     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
909     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
910 
911     /* while unlikely, the system's gmtime(_r) could return
912      * a "correct" proleptic gregorian year value,
913      * which I'm pretty sure is:
914      * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
915      * 730485 is the number of days in two millennia, including leap days */
916     a_time.tm_year = 292277026596-1900;
917     CAPTURE();
918     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
919     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
920 
921     a_time.tm_year = INT64_MAX-1900;
922     CAPTURE();
923     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
924     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
925 
926     a_time.tm_year = INT64_MAX;
927     CAPTURE();
928     tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
929     CHECK_TIMEGM_ARG_OUT_OF_RANGE();
930 #endif /* SIZEOF_INT == 8 */
931 
932   /* month */
933   a_time.tm_year = 2007-1900;  /* restore valid year */
934 
935   a_time.tm_mon = 12;          /* Wrong month, it's 0-based */
936   CAPTURE();
937   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
938   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
939 
940   a_time.tm_mon = -1;          /* Wrong month */
941   CAPTURE();
942   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
943   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
944 
945   /* day */
946   a_time.tm_mon = 6;            /* Try July */
947   a_time.tm_mday = 32;          /* Wrong day */
948   CAPTURE();
949   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
950   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
951 
952   a_time.tm_mon = 5;            /* Try June */
953   a_time.tm_mday = 31;          /* Wrong day */
954   CAPTURE();
955   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
956   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
957 
958   a_time.tm_year = 2008-1900;   /* Try a leap year */
959   a_time.tm_mon = 1;            /* in feb. */
960   a_time.tm_mday = 30;          /* Wrong day */
961   CAPTURE();
962   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
963   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
964 
965   a_time.tm_year = 2011-1900;   /* Try a non-leap year */
966   a_time.tm_mon = 1;            /* in feb. */
967   a_time.tm_mday = 29;          /* Wrong day */
968   CAPTURE();
969   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
970   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
971 
972   a_time.tm_mday = 0;           /* Wrong day, it's 1-based (to be different) */
973   CAPTURE();
974   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
975   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
976 
977   /* hour */
978   a_time.tm_mday = 3;           /* restore valid month day */
979 
980   a_time.tm_hour = 24;          /* Wrong hour, it's 0-based */
981   CAPTURE();
982   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
983   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
984 
985   a_time.tm_hour = -1;          /* Wrong hour */
986   CAPTURE();
987   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
988   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
989 
990   /* minute */
991   a_time.tm_hour = 22;          /* restore valid hour */
992 
993   a_time.tm_min = 60;           /* Wrong minute, it's 0-based */
994   CAPTURE();
995   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
996   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
997 
998   a_time.tm_min = -1;           /* Wrong minute */
999   CAPTURE();
1000   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
1001   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1002 
1003   /* second */
1004   a_time.tm_min = 37;           /* restore valid minute */
1005 
1006   a_time.tm_sec = 61;           /* Wrong second: 0-based with leap seconds */
1007   CAPTURE();
1008   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
1009   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1010 
1011   a_time.tm_sec = -1;           /* Wrong second */
1012   CAPTURE();
1013   tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
1014   CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1015 
1016   /* Test tor_gmtime_r out of range */
1017 
1018   /* time_t < 0 yields a year clamped to 1 or 1970,
1019    * depending on whether the implementation of the system gmtime(_r)
1020    * sets struct tm (1) or not (1970) */
1021   t_res = -1;
1022   CAPTURE();
1023   tor_gmtime_r(&t_res, &b_time);
1024   CHECK_POSSIBLE_EINVAL();
1025   tt_assert(b_time.tm_year == (1970-1900) ||
1026             b_time.tm_year == (1969-1900));
1027 
1028   if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
1029     t_res = -1*(1 << 30);
1030     CAPTURE();
1031     tor_gmtime_r(&t_res, &b_time);
1032     CHECK_POSSIBLE_EINVAL();
1033     tt_assert(b_time.tm_year == (1970-1900) ||
1034               b_time.tm_year == (1935-1900));
1035 
1036     t_res = INT32_MIN;
1037     CAPTURE();
1038     tor_gmtime_r(&t_res, &b_time);
1039     CHECK_POSSIBLE_EINVAL();
1040     tt_assert(b_time.tm_year == (1970-1900) ||
1041               b_time.tm_year == (1901-1900));
1042   }
1043 
1044 #if SIZEOF_TIME_T == 8
1045   {
1046     /* one of the smallest tm_year values my 64 bit system supports:
1047      * b_time.tm_year == (-292275055LL-1900LL) without clamping */
1048     t_res = -9223372036854775LL;
1049     CAPTURE();
1050     tor_gmtime_r(&t_res, &b_time);
1051     CHECK_POSSIBLE_EINVAL();
1052     tt_assert(b_time.tm_year == (1970-1900) ||
1053               b_time.tm_year == (1-1900));
1054 
1055     /* while unlikely, the system's gmtime(_r) could return
1056      * a "correct" retrospective gregorian negative year value,
1057      * which I'm pretty sure is:
1058      * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
1059      * 730485 is the number of days in two millennia, including leap days
1060      * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
1061     t_res = INT64_MIN;
1062     CAPTURE();
1063     tor_gmtime_r(&t_res, &b_time);
1064     if (! (b_time.tm_year == (1970-1900) ||
1065            b_time.tm_year == (1-1900))) {
1066       tt_int_op(b_time.tm_year, OP_EQ, 1970-1900);
1067     }
1068     if (b_time.tm_year != 1970-1900) {
1069       CHECK_TIMEGM_WARNING("Rounding up to ");
1070     } else {
1071       teardown_capture_of_logs();
1072     }
1073   }
1074   {
1075     /* As above, but with localtime. */
1076     t_res = -9223372036854775LL;
1077     CAPTURE();
1078     tor_localtime_r(&t_res, &b_time);
1079     CHECK_POSSIBLE_EINVAL();
1080     tt_assert(b_time.tm_year == (1970-1900) ||
1081               b_time.tm_year == (1-1900));
1082 
1083     /* while unlikely, the system's gmtime(_r) could return
1084      * a "correct" retrospective gregorian negative year value,
1085      * which I'm pretty sure is:
1086      * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
1087      * 730485 is the number of days in two millennia, including leap days
1088      * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
1089     t_res = INT64_MIN;
1090     CAPTURE();
1091     tor_localtime_r(&t_res, &b_time);
1092     if (! (b_time.tm_year == (1970-1900) ||
1093            b_time.tm_year == (1-1900))) {
1094       tt_int_op(b_time.tm_year, OP_EQ, 1970-1900);
1095     }
1096     if (b_time.tm_year != 1970-1900) {
1097       CHECK_TIMEGM_WARNING("Rounding up to ");
1098     } else {
1099       teardown_capture_of_logs();
1100     }
1101   }
1102 #endif /* SIZEOF_TIME_T == 8 */
1103 
1104   /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
1105    * depending on whether the implementation of the system gmtime(_r)
1106    * sets struct tm (9999) or not (2037) */
1107 #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
1108   {
1109     t_res = 3*(1 << 29);
1110     tor_gmtime_r(&t_res, &b_time);
1111     tt_assert(b_time.tm_year == (2021-1900));
1112 
1113     t_res = INT32_MAX;
1114     tor_gmtime_r(&t_res, &b_time);
1115     tt_assert(b_time.tm_year == (2037-1900) ||
1116               b_time.tm_year == (2038-1900));
1117   }
1118   {
1119     /* as above but with localtime. */
1120     t_res = 3*(1 << 29);
1121     tor_localtime_r(&t_res, &b_time);
1122     tt_assert(b_time.tm_year == (2021-1900));
1123 
1124     t_res = INT32_MAX;
1125     tor_localtime_r(&t_res, &b_time);
1126     tt_assert(b_time.tm_year == (2037-1900) ||
1127               b_time.tm_year == (2038-1900));
1128   }
1129 #endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
1130 
1131 #if SIZEOF_TIME_T == 8
1132   {
1133     /* one of the largest tm_year values my 64 bit system supports:
1134      * b_time.tm_year == (292278994L-1900L) without clamping */
1135     t_res = 9223372036854775LL;
1136     CAPTURE();
1137     tor_gmtime_r(&t_res, &b_time);
1138     CHECK_POSSIBLE_EINVAL();
1139     tt_assert(b_time.tm_year == (2037-1900) ||
1140               b_time.tm_year == (9999-1900));
1141 
1142     /* while unlikely, the system's gmtime(_r) could return
1143      * a "correct" proleptic gregorian year value,
1144      * which I'm pretty sure is:
1145      * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1146      * 730485 is the number of days in two millennia, including leap days
1147      * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1148     t_res = INT64_MAX;
1149     CAPTURE();
1150     tor_gmtime_r(&t_res, &b_time);
1151     CHECK_TIMEGM_WARNING("Rounding down to ");
1152 
1153     tt_assert(b_time.tm_year == (2037-1900) ||
1154               b_time.tm_year == (9999-1900));
1155   }
1156   {
1157     /* As above but with localtime. */
1158     t_res = 9223372036854775LL;
1159     CAPTURE();
1160     tor_localtime_r(&t_res, &b_time);
1161     CHECK_POSSIBLE_EINVAL();
1162     tt_assert(b_time.tm_year == (2037-1900) ||
1163               b_time.tm_year == (9999-1900));
1164 
1165     /* while unlikely, the system's gmtime(_r) could return
1166      * a "correct" proleptic gregorian year value,
1167      * which I'm pretty sure is:
1168      * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1169      * 730485 is the number of days in two millennia, including leap days
1170      * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1171     t_res = INT64_MAX;
1172     CAPTURE();
1173     tor_localtime_r(&t_res, &b_time);
1174     CHECK_TIMEGM_WARNING("Rounding down to ");
1175 
1176     tt_assert(b_time.tm_year == (2037-1900) ||
1177               b_time.tm_year == (9999-1900));
1178   }
1179 #endif /* SIZEOF_TIME_T == 8 */
1180 
1181   /* Test {format,parse}_rfc1123_time */
1182 
1183   format_rfc1123_time(timestr, 0);
1184   tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ, timestr);
1185   format_rfc1123_time(timestr, (time_t)1091580502UL);
1186   tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ, timestr);
1187 
1188   t_res = 0;
1189   i = parse_rfc1123_time(timestr, &t_res);
1190   tt_int_op(0,OP_EQ, i);
1191   tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
1192 
1193   /* This value is in range with 32 bit and 64 bit time_t */
1194   format_rfc1123_time(timestr, (time_t)2080000000UL);
1195   tt_str_op("Fri, 30 Nov 2035 01:46:40 GMT",OP_EQ, timestr);
1196 
1197   t_res = 0;
1198   i = parse_rfc1123_time(timestr, &t_res);
1199   tt_int_op(0,OP_EQ, i);
1200   tt_int_op(t_res,OP_EQ, (time_t)2080000000UL);
1201 
1202   /* This value is out of range with 32 bit time_t, but in range for 64 bit
1203    * time_t */
1204   CAPTURE();
1205   format_rfc1123_time(timestr, (time_t)2150000000UL);
1206   CHECK_POSSIBLE_EINVAL();
1207 
1208 #if SIZEOF_TIME_T == 4
1209 #if 0
1210   /* Wrapping around will have made it this. */
1211   /* On windows, at least, this is clipped to 1 Jan 1970. ??? */
1212   tt_str_op("Sat, 11 Jan 1902 23:45:04 GMT",OP_EQ, timestr);
1213 #endif
1214   /* Make sure that the right date doesn't parse. */
1215   strlcpy(timestr, "Wed, 17 Feb 2038 06:13:20 GMT", sizeof(timestr));
1216 
1217   t_res = 0;
1218   CAPTURE();
1219   i = parse_rfc1123_time(timestr, &t_res);
1220   // CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1221   tt_int_op(-1,OP_EQ, i);
1222 #elif SIZEOF_TIME_T == 8
1223   tt_str_op("Wed, 17 Feb 2038 06:13:20 GMT",OP_EQ, timestr);
1224 
1225   t_res = 0;
1226   i = parse_rfc1123_time(timestr, &t_res);
1227   tt_int_op(0,OP_EQ, i);
1228   tt_int_op(t_res,OP_EQ, (time_t)2150000000UL);
1229 #endif /* SIZEOF_TIME_T == 4 || ... */
1230 
1231   /* The timezone doesn't matter */
1232   t_res = 0;
1233   tt_int_op(0,OP_EQ,
1234             parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res));
1235   tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
1236   tt_int_op(-1,OP_EQ,
1237             parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
1238   tt_int_op(-1,OP_EQ,
1239             parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res));
1240   tt_int_op(-1,OP_EQ,
1241             parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res));
1242   tt_int_op(-1,OP_EQ,
1243             parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res));
1244   tt_int_op(-1,OP_EQ,
1245             parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res));
1246   tt_int_op(-1,OP_EQ,
1247             parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res));
1248   tt_int_op(-1,OP_EQ,
1249             parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res));
1250   tt_int_op(-1,OP_EQ,
1251             parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res));
1252   tt_int_op(-1,OP_EQ,
1253             parse_rfc1123_time("Wed, 30 Mar 1900 23:59:59 GMT", &t_res));
1254 
1255   /* Leap year. */
1256   tt_int_op(-1,OP_EQ,
1257             parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res));
1258   tt_int_op(0,OP_EQ,
1259             parse_rfc1123_time("Wed, 29 Feb 2012 16:00:00 GMT", &t_res));
1260 
1261   /* Leap second plus one */
1262   tt_int_op(-1,OP_EQ,
1263             parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res));
1264 
1265   /* Test parse_iso_time */
1266 
1267   t_res = 0;
1268   i = parse_iso_time("", &t_res);
1269   tt_int_op(-1,OP_EQ, i);
1270   t_res = 0;
1271   i = parse_iso_time("2004-08-32 00:48:22", &t_res);
1272   tt_int_op(-1,OP_EQ, i);
1273   t_res = 0;
1274   i = parse_iso_time("1969-08-03 00:48:22", &t_res);
1275   tt_int_op(-1,OP_EQ, i);
1276 
1277   t_res = 0;
1278   i = parse_iso_time("2004-08-04 00:48:22", &t_res);
1279   tt_int_op(0,OP_EQ, i);
1280   tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
1281   t_res = 0;
1282   i = parse_iso_time("2004-8-4 0:48:22", &t_res);
1283   tt_int_op(0,OP_EQ, i);
1284   tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
1285 
1286   /* This value is in range with 32 bit and 64 bit time_t */
1287   t_res = 0;
1288   i = parse_iso_time("2035-11-30 01:46:40", &t_res);
1289   tt_int_op(0,OP_EQ, i);
1290   tt_int_op(t_res,OP_EQ, (time_t)2080000000UL);
1291 
1292   /* This value is out of range with 32 bit time_t, but in range for 64 bit
1293    * time_t */
1294   t_res = 0;
1295 #if SIZEOF_TIME_T == 4
1296   CAPTURE();
1297   i = parse_iso_time("2038-02-17 06:13:20", &t_res);
1298   tt_int_op(-1,OP_EQ, i);
1299   //CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1300 #elif SIZEOF_TIME_T == 8
1301   i = parse_iso_time("2038-02-17 06:13:20", &t_res);
1302   tt_int_op(0,OP_EQ, i);
1303   tt_int_op(t_res,OP_EQ, (time_t)2150000000UL);
1304 #endif /* SIZEOF_TIME_T == 4 || ... */
1305 
1306   tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99", &t_res));
1307   tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00", &t_res));
1308   tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 24:00:00", &t_res));
1309   tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:60:00", &t_res));
1310   tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59:62", &t_res));
1311   tt_int_op(-1,OP_EQ, parse_iso_time("1969-03-30 23:59:59", &t_res));
1312   tt_int_op(-1,OP_EQ, parse_iso_time("2011-00-30 23:59:59", &t_res));
1313   tt_int_op(-1,OP_EQ, parse_iso_time("2147483647-08-29 14:00:00", &t_res));
1314   tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59", &t_res));
1315   tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22.100", &t_res));
1316   tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res));
1317 
1318   /* but... that _is_ acceptable if we aren't being strict. */
1319   t_res = 0;
1320   i = parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res, 0, 0);
1321   tt_int_op(0,OP_EQ, i);
1322   tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
1323 
1324   /* try nospace variant. */
1325   t_res = 0;
1326   i = parse_iso_time_nospace("2004-08-04T00:48:22", &t_res);
1327   tt_int_op(0,OP_EQ, i);
1328   tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
1329 
1330   tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04T00:48:22", &t_res));
1331   tt_int_op(-1,OP_EQ, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res));
1332   tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04x00:48:22", &t_res));
1333   tt_int_op(-1,OP_EQ, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res));
1334 
1335   /* Test tor_gettimeofday */
1336 
1337   end.tv_sec = 4;
1338   end.tv_usec = 999990;
1339   start.tv_sec = 1;
1340   start.tv_usec = 500;
1341 
1342   tor_gettimeofday(&start);
1343   /* now make sure time works. */
1344   tor_gettimeofday(&end);
1345   /* We might've timewarped a little. */
1346   tt_int_op(tv_udiff(&start, &end), OP_GE, -5000);
1347 
1348   /* Test format_iso_time */
1349 
1350   tv.tv_sec = (time_t)1326296338UL;
1351   tv.tv_usec = 3060;
1352   format_iso_time(timestr, (time_t)tv.tv_sec);
1353   tt_str_op("2012-01-11 15:38:58",OP_EQ, timestr);
1354   /* The output of format_local_iso_time will vary by timezone, and setting
1355      our timezone for testing purposes would be a nontrivial flaky pain.
1356      Skip this test for now.
1357   format_local_iso_time(timestr, tv.tv_sec);
1358   test_streq("2012-01-11 10:38:58", timestr);
1359   */
1360   format_iso_time_nospace(timestr, (time_t)tv.tv_sec);
1361   tt_str_op("2012-01-11T15:38:58",OP_EQ, timestr);
1362   tt_int_op(strlen(timestr),OP_EQ, ISO_TIME_LEN);
1363   format_iso_time_nospace_usec(timestr, &tv);
1364   tt_str_op("2012-01-11T15:38:58.003060",OP_EQ, timestr);
1365   tt_int_op(strlen(timestr),OP_EQ, ISO_TIME_USEC_LEN);
1366 
1367   tv.tv_usec = 0;
1368   /* This value is in range with 32 bit and 64 bit time_t */
1369   tv.tv_sec = (time_t)2080000000UL;
1370   format_iso_time(timestr, (time_t)tv.tv_sec);
1371   tt_str_op("2035-11-30 01:46:40",OP_EQ, timestr);
1372 
1373   /* This value is out of range with 32 bit time_t, but in range for 64 bit
1374    * time_t */
1375   tv.tv_sec = (time_t)2150000000UL;
1376   CAPTURE();
1377   format_iso_time(timestr, (time_t)tv.tv_sec);
1378   CHECK_POSSIBLE_EINVAL();
1379 #if SIZEOF_TIME_T == 4
1380   /* format_iso_time should indicate failure on overflow, but it doesn't yet.
1381    * Hopefully #18480 will improve the failure semantics in this case.
1382    tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
1383    */
1384 #elif SIZEOF_TIME_T == 8
1385 #ifndef _WIN32
1386   /* This SHOULD work on windows too; see bug #18665 */
1387   tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
1388 #endif
1389 #endif /* SIZEOF_TIME_T == 4 || ... */
1390 
1391 #undef CAPTURE
1392 #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
1393 #undef CHECK_POSSIBLE_EINVAL
1394 
1395  done:
1396   teardown_capture_of_logs();
1397 }
1398 
1399 static void
test_util_parse_http_time(void * arg)1400 test_util_parse_http_time(void *arg)
1401 {
1402   struct tm a_time;
1403   char b[ISO_TIME_LEN+1];
1404   (void)arg;
1405 
1406 #define T(s) do {                               \
1407     format_iso_time(b, tor_timegm(&a_time));    \
1408     tt_str_op(b, OP_EQ, (s));                      \
1409     b[0]='\0';                                  \
1410   } while (0)
1411 
1412   /* Test parse_http_time */
1413 
1414   tt_int_op(-1,OP_EQ,
1415             parse_http_time("", &a_time));
1416   tt_int_op(-1,OP_EQ,
1417             parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time));
1418   tt_int_op(-1,OP_EQ,
1419             parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time));
1420   tt_int_op(-1,OP_EQ,
1421             parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time));
1422   tt_int_op(-1,OP_EQ,
1423             parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time));
1424   tt_int_op(-1,OP_EQ,
1425             parse_http_time("Sunday, August the third", &a_time));
1426   tt_int_op(-1,OP_EQ,
1427             parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time));
1428 
1429   tt_int_op(0,OP_EQ,
1430             parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time));
1431   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1432   T("1994-08-04 00:48:22");
1433   tt_int_op(0,OP_EQ,
1434             parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time));
1435   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1436   T("1994-08-04 00:48:22");
1437   tt_int_op(0,OP_EQ,
1438             parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time));
1439   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1440   T("1994-08-04 00:48:22");
1441   tt_int_op(0,OP_EQ,
1442             parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time));
1443   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1444   T("1994-08-04 00:48:22");
1445   tt_int_op(0,OP_EQ,
1446             parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time));
1447   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1448   T("1994-08-04 00:48:22");
1449   tt_int_op(0,OP_EQ,
1450             parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time));
1451   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1452   T("1994-08-04 00:48:22");
1453   tt_int_op(0,OP_EQ, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time));
1454   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1455   T("1994-08-04 00:48:22");
1456   tt_int_op(0,OP_EQ, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time));
1457   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1458   T("1994-08-04 00:48:22");
1459   tt_int_op(0,OP_EQ, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time));
1460   tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
1461   T("1994-08-04 00:48:22");
1462   tt_int_op(0,OP_EQ,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time));
1463   tt_int_op((time_t)1325376000UL,OP_EQ, tor_timegm(&a_time));
1464   T("2012-01-01 00:00:00");
1465   tt_int_op(0,OP_EQ,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time));
1466   tt_int_op((time_t)1356912000UL,OP_EQ, tor_timegm(&a_time));
1467   T("2012-12-31 00:00:00");
1468 
1469   /* This value is in range with 32 bit and 64 bit time_t */
1470   tt_int_op(0,OP_EQ,parse_http_time("Fri, 30 Nov 2035 01:46:40 GMT", &a_time));
1471   tt_int_op((time_t)2080000000UL,OP_EQ, tor_timegm(&a_time));
1472   T("2035-11-30 01:46:40");
1473 
1474   /* This value is out of range with 32 bit time_t, but in range for 64 bit
1475    * time_t */
1476 #if SIZEOF_TIME_T == 4
1477   /* parse_http_time should indicate failure on overflow, but it doesn't yet.
1478    * Hopefully #18480 will improve the failure semantics in this case. */
1479   setup_full_capture_of_logs(LOG_WARN);
1480   tt_int_op(0,OP_EQ,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time));
1481   tt_int_op((time_t)-1,OP_EQ, tor_timegm(&a_time));
1482   //expect_single_log_msg_containing("does not fit in tor_timegm");
1483   teardown_capture_of_logs();
1484 #elif SIZEOF_TIME_T == 8
1485   tt_int_op(0,OP_EQ,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time));
1486   tt_int_op((time_t)2150000000UL,OP_EQ, tor_timegm(&a_time));
1487   T("2038-02-17 06:13:20");
1488 #endif /* SIZEOF_TIME_T == 4 || ... */
1489 
1490   tt_int_op(-1,OP_EQ, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time));
1491   tt_int_op(-1,OP_EQ, parse_http_time("2011-03-32 00:00:00 GMT", &a_time));
1492   tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 24:00:00 GMT", &a_time));
1493   tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:60:00 GMT", &a_time));
1494   tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:59:62 GMT", &a_time));
1495   tt_int_op(-1,OP_EQ, parse_http_time("1969-03-30 23:59:59 GMT", &a_time));
1496   tt_int_op(-1,OP_EQ, parse_http_time("2011-00-30 23:59:59 GMT", &a_time));
1497   tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:59", &a_time));
1498 
1499 #undef T
1500  done:
1501   teardown_capture_of_logs();
1502 }
1503 
1504 static void
test_util_timegm_real(void * arg)1505 test_util_timegm_real(void *arg)
1506 {
1507   (void)arg;
1508   /* Get the real timegm again!  We're not testing our impl; we want the
1509    * one that will actually get called. */
1510 #undef tor_timegm
1511 
1512   /* Now check: is timegm the real inverse of gmtime? */
1513   time_t now = time(NULL), time2=0;
1514   struct tm tm, *p;
1515   p = tor_gmtime_r(&now, &tm);
1516   tt_ptr_op(p, OP_NE, NULL);
1517 
1518   int r = tor_timegm(&tm, &time2);
1519   tt_int_op(r, OP_EQ, 0);
1520   tt_i64_op((int64_t) now, OP_EQ, (int64_t) time2);
1521 
1522  done:
1523   ;
1524 }
1525 
1526 static void
test_util_config_line(void * arg)1527 test_util_config_line(void *arg)
1528 {
1529   char buf[1024];
1530   char *k=NULL, *v=NULL;
1531   const char *str;
1532 
1533   /* Test parse_config_line_from_str */
1534   (void)arg;
1535   strlcpy(buf, "k v\n" " key    value with spaces   \n" "keykey val\n"
1536           "k2\n"
1537           "k3 \n" "\n" "   \n" "#comment\n"
1538           "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
1539           "kseven   \"a quoted 'string\"\n"
1540           "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
1541           "k9 a line that\\\n spans two lines.\n\n"
1542           "k10 more than\\\n one contin\\\nuation\n"
1543           "k11  \\\ncontinuation at the start\n"
1544           "k12 line with a\\\n#comment\n embedded\n"
1545           "k13\\\ncontinuation at the very start\n"
1546           "k14 a line that has a comment and # ends with a slash \\\n"
1547           "k15 this should be the next new line\n"
1548           "k16 a line that has a comment and # ends without a slash \n"
1549           "k17 this should be the next new line\n"
1550           , sizeof(buf));
1551   str = buf;
1552 
1553   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1554   tt_str_op(k,OP_EQ, "k");
1555   tt_str_op(v,OP_EQ, "v");
1556   tor_free(k); tor_free(v);
1557   tt_assert(!strcmpstart(str, "key    value with"));
1558 
1559   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1560   tt_str_op(k,OP_EQ, "key");
1561   tt_str_op(v,OP_EQ, "value with spaces");
1562   tor_free(k); tor_free(v);
1563   tt_assert(!strcmpstart(str, "keykey"));
1564 
1565   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1566   tt_str_op(k,OP_EQ, "keykey");
1567   tt_str_op(v,OP_EQ, "val");
1568   tor_free(k); tor_free(v);
1569   tt_assert(!strcmpstart(str, "k2\n"));
1570 
1571   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1572   tt_str_op(k,OP_EQ, "k2");
1573   tt_str_op(v,OP_EQ, "");
1574   tor_free(k); tor_free(v);
1575   tt_assert(!strcmpstart(str, "k3 \n"));
1576 
1577   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1578   tt_str_op(k,OP_EQ, "k3");
1579   tt_str_op(v,OP_EQ, "");
1580   tor_free(k); tor_free(v);
1581   tt_assert(!strcmpstart(str, "#comment"));
1582 
1583   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1584   tt_str_op(k,OP_EQ, "k4");
1585   tt_str_op(v,OP_EQ, "");
1586   tor_free(k); tor_free(v);
1587   tt_assert(!strcmpstart(str, "k5#abc"));
1588 
1589   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1590   tt_str_op(k,OP_EQ, "k5");
1591   tt_str_op(v,OP_EQ, "");
1592   tor_free(k); tor_free(v);
1593   tt_assert(!strcmpstart(str, "k6"));
1594 
1595   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1596   tt_str_op(k,OP_EQ, "k6");
1597   tt_str_op(v,OP_EQ, "val");
1598   tor_free(k); tor_free(v);
1599   tt_assert(!strcmpstart(str, "kseven"));
1600 
1601   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1602   tt_str_op(k,OP_EQ, "kseven");
1603   tt_str_op(v,OP_EQ, "a quoted \'string");
1604   tor_free(k); tor_free(v);
1605   tt_assert(!strcmpstart(str, "k8 "));
1606 
1607   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1608   tt_str_op(k,OP_EQ, "k8");
1609   tt_str_op(v,OP_EQ, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
1610   tor_free(k); tor_free(v);
1611 
1612   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1613   tt_str_op(k,OP_EQ, "k9");
1614   tt_str_op(v,OP_EQ, "a line that spans two lines.");
1615   tor_free(k); tor_free(v);
1616 
1617   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1618   tt_str_op(k,OP_EQ, "k10");
1619   tt_str_op(v,OP_EQ, "more than one continuation");
1620   tor_free(k); tor_free(v);
1621 
1622   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1623   tt_str_op(k,OP_EQ, "k11");
1624   tt_str_op(v,OP_EQ, "continuation at the start");
1625   tor_free(k); tor_free(v);
1626 
1627   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1628   tt_str_op(k,OP_EQ, "k12");
1629   tt_str_op(v,OP_EQ, "line with a embedded");
1630   tor_free(k); tor_free(v);
1631 
1632   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1633   tt_str_op(k,OP_EQ, "k13");
1634   tt_str_op(v,OP_EQ, "continuation at the very start");
1635   tor_free(k); tor_free(v);
1636 
1637   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1638   tt_str_op(k,OP_EQ, "k14");
1639   tt_str_op(v,OP_EQ, "a line that has a comment and" );
1640   tor_free(k); tor_free(v);
1641 
1642   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1643   tt_str_op(k,OP_EQ, "k15");
1644   tt_str_op(v,OP_EQ, "this should be the next new line");
1645   tor_free(k); tor_free(v);
1646 
1647   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1648   tt_str_op(k,OP_EQ, "k16");
1649   tt_str_op(v,OP_EQ, "a line that has a comment and" );
1650   tor_free(k); tor_free(v);
1651 
1652   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1653   tt_str_op(k,OP_EQ, "k17");
1654   tt_str_op(v,OP_EQ, "this should be the next new line");
1655   tor_free(k); tor_free(v);
1656 
1657   tt_str_op(str,OP_EQ, "");
1658 
1659  done:
1660   tor_free(k);
1661   tor_free(v);
1662 }
1663 
1664 static void
test_util_config_line_quotes(void * arg)1665 test_util_config_line_quotes(void *arg)
1666 {
1667   char buf1[1024];
1668   char buf2[128];
1669   char buf3[128];
1670   char buf4[128];
1671   char *k=NULL, *v=NULL;
1672   const char *str;
1673 
1674   /* Test parse_config_line_from_str */
1675   (void)arg;
1676   strlcpy(buf1, "kTrailingSpace \"quoted value\"   \n"
1677           "kTrailingGarbage \"quoted value\"trailing garbage\n"
1678           , sizeof(buf1));
1679   strlcpy(buf2, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
1680           , sizeof(buf2));
1681   strlcpy(buf3, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
1682           , sizeof(buf3));
1683   strlcpy(buf4, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
1684           , sizeof(buf4));
1685   str = buf1;
1686 
1687   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1688   tt_str_op(k,OP_EQ, "kTrailingSpace");
1689   tt_str_op(v,OP_EQ, "quoted value");
1690   tor_free(k); tor_free(v);
1691 
1692   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1693   tt_ptr_op(str,OP_EQ, NULL);
1694   tor_free(k); tor_free(v);
1695 
1696   str = buf2;
1697 
1698   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1699   tt_ptr_op(str,OP_EQ, NULL);
1700   tor_free(k); tor_free(v);
1701 
1702   str = buf3;
1703 
1704   const char *err = NULL;
1705   str = parse_config_line_from_str_verbose(str, &k, &v, &err);
1706   tt_ptr_op(str,OP_EQ, NULL);
1707   tor_free(k); tor_free(v);
1708   tt_str_op(err, OP_EQ, "Invalid escape sequence in quoted string");
1709 
1710   str = buf4;
1711 
1712   err = NULL;
1713   str = parse_config_line_from_str_verbose(str, &k, &v, &err);
1714   tt_ptr_op(str,OP_EQ, NULL);
1715   tor_free(k); tor_free(v);
1716   tt_str_op(err, OP_EQ, "Invalid escape sequence in quoted string");
1717 
1718  done:
1719   tor_free(k);
1720   tor_free(v);
1721 }
1722 
1723 static void
test_util_config_line_comment_character(void * arg)1724 test_util_config_line_comment_character(void *arg)
1725 {
1726   char buf[1024];
1727   char *k=NULL, *v=NULL;
1728   const char *str;
1729 
1730   /* Test parse_config_line_from_str */
1731   (void)arg;
1732   strlcpy(buf, "k1 \"# in quotes\"\n"
1733           "k2 some value    # some comment\n"
1734           "k3 /home/user/myTorNetwork#2\n"    /* Testcase for #1323 */
1735           , sizeof(buf));
1736   str = buf;
1737 
1738   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1739   tt_str_op(k,OP_EQ, "k1");
1740   tt_str_op(v,OP_EQ, "# in quotes");
1741   tor_free(k); tor_free(v);
1742 
1743   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1744   tt_str_op(k,OP_EQ, "k2");
1745   tt_str_op(v,OP_EQ, "some value");
1746   tor_free(k); tor_free(v);
1747 
1748   tt_str_op(str,OP_EQ, "k3 /home/user/myTorNetwork#2\n");
1749 
1750 #if 0
1751   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1752   test_streq(k, "k3");
1753   test_streq(v, "/home/user/myTorNetwork#2");
1754   tor_free(k); tor_free(v);
1755 
1756   test_streq(str, "");
1757 #endif /* 0 */
1758 
1759  done:
1760   tor_free(k);
1761   tor_free(v);
1762 }
1763 
1764 static void
test_util_config_line_escaped_content(void * arg)1765 test_util_config_line_escaped_content(void *arg)
1766 {
1767   char buf1[1024];
1768   char buf2[128];
1769   char buf3[128];
1770   char buf4[128];
1771   char buf5[128];
1772   char buf6[128];
1773   char *k=NULL, *v=NULL;
1774   const char *str;
1775 
1776   /* Test parse_config_line_from_str */
1777   (void)arg;
1778   strlcpy(buf1, "HexadecimalLower \"\\x2a\"\n"
1779           "HexadecimalUpper \"\\x2A\"\n"
1780           "HexadecimalUpperX \"\\X2A\"\n"
1781           "Octal \"\\52\"\n"
1782           "Newline \"\\n\"\n"
1783           "Tab \"\\t\"\n"
1784           "CarriageReturn \"\\r\"\n"
1785           "DoubleQuote \"\\\"\"\n"
1786           "SimpleQuote \"\\'\"\n"
1787           "Backslash \"\\\\\"\n"
1788           "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
1789           , sizeof(buf1));
1790 
1791   strlcpy(buf2, "BrokenEscapedContent \"\\a\"\n"
1792           , sizeof(buf2));
1793 
1794   strlcpy(buf3, "BrokenEscapedContent \"\\x\"\n"
1795           , sizeof(buf3));
1796 
1797   strlcpy(buf4, "BrokenOctal \"\\8\"\n"
1798           , sizeof(buf4));
1799 
1800   strlcpy(buf5, "BrokenHex \"\\xg4\"\n"
1801           , sizeof(buf5));
1802 
1803   strlcpy(buf6, "BrokenEscape \"\\"
1804           , sizeof(buf6));
1805 
1806   str = buf1;
1807 
1808   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1809   tt_str_op(k,OP_EQ, "HexadecimalLower");
1810   tt_str_op(v,OP_EQ, "*");
1811   tor_free(k); tor_free(v);
1812 
1813   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1814   tt_str_op(k,OP_EQ, "HexadecimalUpper");
1815   tt_str_op(v,OP_EQ, "*");
1816   tor_free(k); tor_free(v);
1817 
1818   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1819   tt_str_op(k,OP_EQ, "HexadecimalUpperX");
1820   tt_str_op(v,OP_EQ, "*");
1821   tor_free(k); tor_free(v);
1822 
1823   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1824   tt_str_op(k,OP_EQ, "Octal");
1825   tt_str_op(v,OP_EQ, "*");
1826   tor_free(k); tor_free(v);
1827 
1828   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1829   tt_str_op(k,OP_EQ, "Newline");
1830   tt_str_op(v,OP_EQ, "\n");
1831   tor_free(k); tor_free(v);
1832 
1833   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1834   tt_str_op(k,OP_EQ, "Tab");
1835   tt_str_op(v,OP_EQ, "\t");
1836   tor_free(k); tor_free(v);
1837 
1838   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1839   tt_str_op(k,OP_EQ, "CarriageReturn");
1840   tt_str_op(v,OP_EQ, "\r");
1841   tor_free(k); tor_free(v);
1842 
1843   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1844   tt_str_op(k,OP_EQ, "DoubleQuote");
1845   tt_str_op(v,OP_EQ, "\"");
1846   tor_free(k); tor_free(v);
1847 
1848   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1849   tt_str_op(k,OP_EQ, "SimpleQuote");
1850   tt_str_op(v,OP_EQ, "'");
1851   tor_free(k); tor_free(v);
1852 
1853   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1854   tt_str_op(k,OP_EQ, "Backslash");
1855   tt_str_op(v,OP_EQ, "\\");
1856   tor_free(k); tor_free(v);
1857 
1858   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1859   tt_str_op(k,OP_EQ, "Mix");
1860   tt_str_op(v,OP_EQ, "This is a \"star\":\t'*'\nAnd second line");
1861   tor_free(k); tor_free(v);
1862   tt_str_op(str,OP_EQ, "");
1863 
1864   str = buf2;
1865 
1866   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1867   tt_ptr_op(str,OP_EQ, NULL);
1868   tor_free(k); tor_free(v);
1869 
1870   str = buf3;
1871 
1872   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1873   tt_ptr_op(str,OP_EQ, NULL);
1874   tor_free(k); tor_free(v);
1875 
1876   str = buf4;
1877 
1878   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1879   tt_ptr_op(str,OP_EQ, NULL);
1880   tor_free(k); tor_free(v);
1881 
1882 #if 0
1883   str = buf5;
1884 
1885   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1886   tt_ptr_op(str, OP_EQ, NULL);
1887   tor_free(k); tor_free(v);
1888 #endif /* 0 */
1889 
1890   str = buf6;
1891 
1892   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1893   tt_ptr_op(str,OP_EQ, NULL);
1894   tor_free(k); tor_free(v);
1895 
1896   /* more things to try. */
1897   /* Bad hex: */
1898   strlcpy(buf1, "Foo \"\\x9g\"\n", sizeof(buf1));
1899   strlcpy(buf2, "Foo \"\\xg0\"\n", sizeof(buf2));
1900   strlcpy(buf3, "Foo \"\\xf\"\n", sizeof(buf3));
1901   /* bad escape */
1902   strlcpy(buf4, "Foo \"\\q\"\n", sizeof(buf4));
1903   /* missing endquote */
1904   strlcpy(buf5, "Foo \"hello\n", sizeof(buf5));
1905   /* extra stuff */
1906   strlcpy(buf6, "Foo \"hello\" world\n", sizeof(buf6));
1907 
1908   str=buf1;
1909   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1910   tt_ptr_op(str,OP_EQ, NULL);
1911   tor_free(k); tor_free(v);
1912 
1913   str=buf2;
1914   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1915   tt_ptr_op(str,OP_EQ, NULL);
1916   tor_free(k); tor_free(v);
1917 
1918   str=buf3;
1919   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1920   tt_ptr_op(str,OP_EQ, NULL);
1921   tor_free(k); tor_free(v);
1922 
1923   str=buf4;
1924   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1925   tt_ptr_op(str,OP_EQ, NULL);
1926   tor_free(k); tor_free(v);
1927 
1928   str=buf5;
1929 
1930   str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
1931   tt_ptr_op(str,OP_EQ, NULL);
1932   tor_free(k); tor_free(v);
1933 
1934   str=buf6;
1935   const char *err = NULL;
1936   str = parse_config_line_from_str_verbose(str, &k, &v, &err);
1937   tt_ptr_op(str,OP_EQ, NULL);
1938   tor_free(k); tor_free(v);
1939   tt_str_op(err,OP_EQ, "Excess data after quoted string");
1940 
1941  done:
1942   tor_free(k);
1943   tor_free(v);
1944 }
1945 
1946 static void
test_util_config_line_crlf(void * arg)1947 test_util_config_line_crlf(void *arg)
1948 {
1949   char *k=NULL, *v=NULL;
1950   const char *err = NULL;
1951   (void)arg;
1952   const char *str =
1953     "Hello world\r\n"
1954     "Hello \"nice big world\"\r\n";
1955 
1956   str = parse_config_line_from_str_verbose(str, &k, &v, &err);
1957   tt_assert(str);
1958   tt_str_op(k,OP_EQ,"Hello");
1959   tt_str_op(v,OP_EQ,"world");
1960   tt_ptr_op(err, OP_EQ, NULL);
1961   tor_free(k); tor_free(v);
1962 
1963   str = parse_config_line_from_str_verbose(str, &k, &v, &err);
1964   tt_assert(str);
1965   tt_str_op(k,OP_EQ,"Hello");
1966   tt_str_op(v,OP_EQ,"nice big world");
1967   tt_ptr_op(err, OP_EQ, NULL);
1968   tor_free(k); tor_free(v);
1969   tt_str_op(str,OP_EQ, "");
1970 
1971  done:
1972   tor_free(k); tor_free(v);
1973 }
1974 
1975 static void
test_util_config_line_partition(void * arg)1976 test_util_config_line_partition(void *arg)
1977 {
1978   (void)arg;
1979   config_line_t *lines = NULL, *orig, *rest = NULL;
1980 
1981   config_line_append(&lines, "Header", "X");
1982   config_line_append(&lines, "Item", "Y");
1983   config_line_append(&lines, "Thing", "Z");
1984 
1985   config_line_append(&lines, "HEADER", "X2");
1986 
1987   config_line_append(&lines, "header", "X3");
1988   config_line_append(&lines, "Item3", "Foob");
1989 
1990   /* set up h2 and h3 to point to the places where we hope the headers will
1991      be. */
1992   config_line_t *h2 = lines->next->next->next;
1993   config_line_t *h3 = h2->next;
1994   tt_str_op(h2->key, OP_EQ, "HEADER");
1995   tt_str_op(h3->key, OP_EQ, "header");
1996 
1997   orig = lines;
1998   rest = config_lines_partition(lines, "Header");
1999   tt_ptr_op(lines, OP_EQ, orig);
2000   tt_ptr_op(rest, OP_EQ, h2);
2001   tt_str_op(lines->next->key, OP_EQ, "Item");
2002   tt_str_op(lines->next->next->key, OP_EQ, "Thing");
2003   tt_ptr_op(lines->next->next->next, OP_EQ, NULL);
2004   config_free_lines(lines);
2005 
2006   orig = lines = rest;
2007   rest = config_lines_partition(lines, "Header");
2008   tt_ptr_op(lines, OP_EQ, orig);
2009   tt_ptr_op(rest, OP_EQ, h3);
2010   tt_ptr_op(lines->next, OP_EQ, NULL);
2011   config_free_lines(lines);
2012 
2013   orig = lines = rest;
2014   rest = config_lines_partition(lines, "Header");
2015   tt_ptr_op(lines, OP_EQ, orig);
2016   tt_ptr_op(rest, OP_EQ, NULL);
2017   tt_str_op(lines->next->key, OP_EQ, "Item3");
2018   tt_ptr_op(lines->next->next, OP_EQ, NULL);
2019 
2020  done:
2021   config_free_lines(lines);
2022   config_free_lines(rest);
2023 }
2024 
2025 #ifndef DISABLE_PWDB_TESTS
2026 static void
test_util_expand_filename(void * arg)2027 test_util_expand_filename(void *arg)
2028 {
2029   char *str;
2030 
2031   (void)arg;
2032   setenv("HOME", "/home/itv", 1); /* For "internal test value" */
2033 
2034   str = expand_filename("");
2035   tt_str_op("",OP_EQ, str);
2036   tor_free(str);
2037 
2038   str = expand_filename("/normal/path");
2039   tt_str_op("/normal/path",OP_EQ, str);
2040   tor_free(str);
2041 
2042   str = expand_filename("/normal/trailing/path/");
2043   tt_str_op("/normal/trailing/path/",OP_EQ, str);
2044   tor_free(str);
2045 
2046   str = expand_filename("~");
2047   tt_str_op("/home/itv/",OP_EQ, str);
2048   tor_free(str);
2049 
2050   str = expand_filename("$HOME/nodice");
2051   tt_str_op("$HOME/nodice",OP_EQ, str);
2052   tor_free(str);
2053 
2054   str = expand_filename("~/");
2055   tt_str_op("/home/itv/",OP_EQ, str);
2056   tor_free(str);
2057 
2058   str = expand_filename("~/foobarqux");
2059   tt_str_op("/home/itv/foobarqux",OP_EQ, str);
2060   tor_free(str);
2061 
2062   str = expand_filename("~/../../etc/passwd");
2063   tt_str_op("/home/itv/../../etc/passwd",OP_EQ, str);
2064   tor_free(str);
2065 
2066   str = expand_filename("~/trailing/");
2067   tt_str_op("/home/itv/trailing/",OP_EQ, str);
2068   tor_free(str);
2069   /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
2070      have to somehow inject/fake the get_user_homedir call) */
2071 
2072   /* $HOME ending in a trailing slash */
2073   setenv("HOME", "/home/itv/", 1);
2074 
2075   str = expand_filename("~");
2076   tt_str_op("/home/itv/",OP_EQ, str);
2077   tor_free(str);
2078 
2079   str = expand_filename("~/");
2080   tt_str_op("/home/itv/",OP_EQ, str);
2081   tor_free(str);
2082 
2083   str = expand_filename("~/foo");
2084   tt_str_op("/home/itv/foo",OP_EQ, str);
2085   tor_free(str);
2086 
2087   /* Try with empty $HOME */
2088 
2089   setenv("HOME", "", 1);
2090 
2091   str = expand_filename("~");
2092   tt_str_op("/",OP_EQ, str);
2093   tor_free(str);
2094 
2095   str = expand_filename("~/");
2096   tt_str_op("/",OP_EQ, str);
2097   tor_free(str);
2098 
2099   str = expand_filename("~/foobar");
2100   tt_str_op("/foobar",OP_EQ, str);
2101   tor_free(str);
2102 
2103   /* Try with $HOME unset */
2104 
2105   unsetenv("HOME");
2106 
2107   str = expand_filename("~");
2108   tt_str_op("/",OP_EQ, str);
2109   tor_free(str);
2110 
2111   str = expand_filename("~/");
2112   tt_str_op("/",OP_EQ, str);
2113   tor_free(str);
2114 
2115   str = expand_filename("~/foobar");
2116   tt_str_op("/foobar",OP_EQ, str);
2117   tor_free(str);
2118 
2119  done:
2120   tor_free(str);
2121 }
2122 #endif /* !defined(DISABLE_PWDB_TESTS) */
2123 
2124 /** Test tor_escape_str_for_pt_args(). */
2125 static void
test_util_escape_string_socks(void * arg)2126 test_util_escape_string_socks(void *arg)
2127 {
2128   char *escaped_string = NULL;
2129 
2130   /** Simple backslash escape. */
2131   (void)arg;
2132   escaped_string = tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
2133   tt_assert(escaped_string);
2134   tt_str_op(escaped_string,OP_EQ, "This is a backslash: \\\\");
2135   tor_free(escaped_string);
2136 
2137   /** Simple semicolon escape. */
2138   escaped_string = tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
2139   tt_assert(escaped_string);
2140   tt_str_op(escaped_string,OP_EQ, "First rule:Do not use \\;");
2141   tor_free(escaped_string);
2142 
2143   /** Empty string. */
2144   escaped_string = tor_escape_str_for_pt_args("", ";\\");
2145   tt_assert(escaped_string);
2146   tt_str_op(escaped_string,OP_EQ, "");
2147   tor_free(escaped_string);
2148 
2149   /** Escape all characters. */
2150   escaped_string = tor_escape_str_for_pt_args(";\\;\\", ";\\");
2151   tt_assert(escaped_string);
2152   tt_str_op(escaped_string,OP_EQ, "\\;\\\\\\;\\\\");
2153   tor_free(escaped_string);
2154 
2155   escaped_string = tor_escape_str_for_pt_args(";", ";\\");
2156   tt_assert(escaped_string);
2157   tt_str_op(escaped_string,OP_EQ, "\\;");
2158   tor_free(escaped_string);
2159 
2160  done:
2161   tor_free(escaped_string);
2162 }
2163 
2164 static void
test_util_string_is_key_value(void * ptr)2165 test_util_string_is_key_value(void *ptr)
2166 {
2167   (void)ptr;
2168   tt_assert(string_is_key_value(LOG_WARN, "key=value"));
2169   tt_assert(string_is_key_value(LOG_WARN, "k=v"));
2170   tt_assert(string_is_key_value(LOG_WARN, "key="));
2171   tt_assert(string_is_key_value(LOG_WARN, "x="));
2172   tt_assert(string_is_key_value(LOG_WARN, "xx="));
2173   tt_assert(!string_is_key_value(LOG_WARN, "=value"));
2174   tt_assert(!string_is_key_value(LOG_WARN, "=x"));
2175   tt_assert(!string_is_key_value(LOG_WARN, "="));
2176 
2177   /* ??? */
2178   /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
2179  done:
2180   ;
2181 }
2182 
2183 /** Test basic string functionality. */
2184 static void
test_util_strmisc(void * arg)2185 test_util_strmisc(void *arg)
2186 {
2187   char buf[1024];
2188   char *cp_tmp = NULL;
2189 
2190   /* Test strl operations */
2191   (void)arg;
2192   tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 0));
2193   tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 10));
2194   tt_str_op(buf,OP_EQ, "Hello");
2195   tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 6));
2196   tt_str_op(buf,OP_EQ, "Hello");
2197   tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 5));
2198   tt_str_op(buf,OP_EQ, "Hell");
2199   strlcpy(buf, "Hello", sizeof(buf));
2200   tt_int_op(10,OP_EQ, strlcat(buf, "Hello", 5));
2201 
2202   /* Test strstrip() */
2203   strlcpy(buf, "Testing 1 2 3", sizeof(buf));
2204   tor_strstrip(buf, ",!");
2205   tt_str_op(buf,OP_EQ, "Testing 1 2 3");
2206   strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
2207   tor_strstrip(buf, "!? ");
2208   tt_str_op(buf,OP_EQ, "Testing123");
2209   strlcpy(buf, "!!!Testing 1 2 3??", sizeof(buf));
2210   tor_strstrip(buf, "!? ");
2211   tt_str_op(buf,OP_EQ, "Testing123");
2212 
2213   /* Test snprintf */
2214   /* Returning -1 when there's not enough room in the output buffer */
2215   tt_int_op(-1,OP_EQ, tor_snprintf(buf, 0, "Foo"));
2216   tt_int_op(-1,OP_EQ, tor_snprintf(buf, 2, "Foo"));
2217   tt_int_op(-1,OP_EQ, tor_snprintf(buf, 3, "Foo"));
2218   tt_int_op(-1,OP_NE, tor_snprintf(buf, 4, "Foo"));
2219   /* Always NUL-terminate the output */
2220   tor_snprintf(buf, 5, "abcdef");
2221   tt_int_op(0,OP_EQ, buf[4]);
2222   tor_snprintf(buf, 10, "abcdef");
2223   tt_int_op(0,OP_EQ, buf[6]);
2224   /* uint64 */
2225   tor_snprintf(buf, sizeof(buf), "x!%"PRIu64"!x",
2226                (UINT64_C(12345678901)));
2227   tt_str_op("x!12345678901!x",OP_EQ, buf);
2228 
2229   /* Test str{,case}cmpstart */
2230   tt_assert(strcmpstart("abcdef", "abcdef")==0);
2231   tt_assert(strcmpstart("abcdef", "abc")==0);
2232   tt_assert(strcmpstart("abcdef", "abd")<0);
2233   tt_assert(strcmpstart("abcdef", "abb")>0);
2234   tt_assert(strcmpstart("ab", "abb")<0);
2235   tt_assert(strcmpstart("ab", "")==0);
2236   tt_assert(strcmpstart("ab", "ab ")<0);
2237   tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
2238   tt_assert(strcasecmpstart("abcDeF", "abc")==0);
2239   tt_assert(strcasecmpstart("abcdef", "Abd")<0);
2240   tt_assert(strcasecmpstart("Abcdef", "abb")>0);
2241   tt_assert(strcasecmpstart("ab", "Abb")<0);
2242   tt_assert(strcasecmpstart("ab", "")==0);
2243   tt_assert(strcasecmpstart("ab", "ab ")<0);
2244 
2245   /* Test str{,case}cmpend */
2246   tt_assert(strcmpend("abcdef", "abcdef")==0);
2247   tt_assert(strcmpend("abcdef", "def")==0);
2248   tt_assert(strcmpend("abcdef", "deg")<0);
2249   tt_assert(strcmpend("abcdef", "dee")>0);
2250   tt_assert(strcmpend("ab", "aab")>0);
2251   tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
2252   tt_assert(strcasecmpend("abcdef", "dEF")==0);
2253   tt_assert(strcasecmpend("abcdef", "Deg")<0);
2254   tt_assert(strcasecmpend("abcDef", "dee")>0);
2255   tt_assert(strcasecmpend("AB", "abb")<0);
2256 
2257   /* Test digest_is_zero */
2258   memset(buf,0,20);
2259   buf[20] = 'x';
2260   tt_assert(tor_digest_is_zero(buf));
2261   buf[19] = 'x';
2262   tt_assert(!tor_digest_is_zero(buf));
2263 
2264   /* Test mem_is_zero */
2265   memset(buf,0,128);
2266   buf[128] = 'x';
2267   tt_assert(fast_mem_is_zero(buf, 10));
2268   tt_assert(fast_mem_is_zero(buf, 20));
2269   tt_assert(fast_mem_is_zero(buf, 128));
2270   tt_assert(!fast_mem_is_zero(buf, 129));
2271   buf[60] = (char)255;
2272   tt_assert(!fast_mem_is_zero(buf, 128));
2273   buf[0] = (char)1;
2274   tt_assert(!fast_mem_is_zero(buf, 10));
2275 
2276   /* Test 'escaped' */
2277   tt_ptr_op(escaped(NULL), OP_EQ, NULL);
2278   tt_str_op("\"\"",OP_EQ, escaped(""));
2279   tt_str_op("\"abcd\"",OP_EQ, escaped("abcd"));
2280   tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ, escaped("\\ \n\r\t\"'"));
2281   tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ,
2282              escaped("unnecessary \'backslashes\'"));
2283   /* Non-printable characters appear as octal */
2284   tt_str_op("\"z\\001abc\\277d\"",OP_EQ,  escaped("z\001abc\277d"));
2285   tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ, escaped("z\xde\xad\x20;foo"));
2286 
2287   /* Other cases of esc_for_log{,_len} */
2288   cp_tmp = esc_for_log(NULL);
2289   tt_str_op(cp_tmp, OP_EQ, "(null)");
2290   tor_free(cp_tmp);
2291   cp_tmp = esc_for_log_len("abcdefg", 3);
2292   tt_str_op(cp_tmp, OP_EQ, "\"abc\"");
2293   tor_free(cp_tmp);
2294   cp_tmp = esc_for_log_len("abcdefg", 100);
2295   tt_str_op(cp_tmp, OP_EQ, "\"abcdefg\"");
2296   tor_free(cp_tmp);
2297 
2298   /* Test strndup and memdup */
2299   {
2300     const char *s = "abcdefghijklmnopqrstuvwxyz";
2301     cp_tmp = tor_strndup(s, 30);
2302     tt_str_op(cp_tmp,OP_EQ, s); /* same string, */
2303     tt_ptr_op(cp_tmp,OP_NE,s); /* but different pointers. */
2304     tor_free(cp_tmp);
2305 
2306     cp_tmp = tor_strndup(s, 5);
2307     tt_str_op(cp_tmp,OP_EQ, "abcde");
2308     tor_free(cp_tmp);
2309 
2310     s = "a\0b\0c\0d\0e\0";
2311     cp_tmp = tor_memdup(s,10);
2312     tt_mem_op(cp_tmp,OP_EQ, s, 10); /* same ram, */
2313     tt_ptr_op(cp_tmp,OP_NE,s); /* but different pointers. */
2314     tor_free(cp_tmp);
2315   }
2316 
2317   /* Test str-foo functions */
2318   cp_tmp = tor_strdup("abcdef");
2319   tt_assert(tor_strisnonupper(cp_tmp));
2320   cp_tmp[3] = 'D';
2321   tt_assert(!tor_strisnonupper(cp_tmp));
2322   tor_strupper(cp_tmp);
2323   tt_str_op(cp_tmp,OP_EQ, "ABCDEF");
2324   tor_strlower(cp_tmp);
2325   tt_str_op(cp_tmp,OP_EQ, "abcdef");
2326   tt_assert(tor_strisnonupper(cp_tmp));
2327   tt_assert(tor_strisprint(cp_tmp));
2328   cp_tmp[3] = 3;
2329   tt_assert(!tor_strisprint(cp_tmp));
2330   tor_free(cp_tmp);
2331 
2332   /* Test memmem and memstr */
2333   {
2334     const char *haystack = "abcde";
2335     tt_ptr_op(tor_memmem(haystack, 5, "ef", 2), OP_EQ, NULL);
2336     tt_ptr_op(tor_memmem(haystack, 5, "cd", 2),OP_EQ, haystack + 2);
2337     tt_ptr_op(tor_memmem(haystack, 5, "cde", 3),OP_EQ, haystack + 2);
2338     tt_ptr_op(tor_memmem(haystack, 4, "cde", 3), OP_EQ, NULL);
2339     haystack = "ababcad";
2340     tt_ptr_op(tor_memmem(haystack, 7, "abc", 3),OP_EQ, haystack + 2);
2341     tt_ptr_op(tor_memmem(haystack, 7, "ad", 2),OP_EQ, haystack + 5);
2342     tt_ptr_op(tor_memmem(haystack, 7, "cad", 3),OP_EQ, haystack + 4);
2343     tt_ptr_op(tor_memmem(haystack, 7, "dadad", 5), OP_EQ, NULL);
2344     tt_ptr_op(tor_memmem(haystack, 7, "abcdefghij", 10), OP_EQ, NULL);
2345     /* memstr */
2346     tt_ptr_op(tor_memstr(haystack, 7, "abc"),OP_EQ, haystack + 2);
2347     tt_ptr_op(tor_memstr(haystack, 7, "cad"),OP_EQ, haystack + 4);
2348     tt_ptr_op(tor_memstr(haystack, 6, "cad"), OP_EQ, NULL);
2349     tt_ptr_op(tor_memstr(haystack, 7, "cadd"), OP_EQ, NULL);
2350     tt_ptr_op(tor_memstr(haystack, 7, "fe"), OP_EQ, NULL);
2351     tt_ptr_op(tor_memstr(haystack, 7, "ababcade"), OP_EQ, NULL);
2352   }
2353 
2354   /* Test hex_str */
2355   {
2356     char binary_data[68];
2357     size_t idx;
2358     for (idx = 0; idx < sizeof(binary_data); ++idx)
2359       binary_data[idx] = idx;
2360     tt_str_op(hex_str(binary_data, 0),OP_EQ, "");
2361     tt_str_op(hex_str(binary_data, 1),OP_EQ, "00");
2362     tt_str_op(hex_str(binary_data, 17),OP_EQ,
2363               "000102030405060708090A0B0C0D0E0F10");
2364     tt_str_op(hex_str(binary_data, 32),OP_EQ,
2365                "000102030405060708090A0B0C0D0E0F"
2366                "101112131415161718191A1B1C1D1E1F");
2367     tt_str_op(hex_str(binary_data, 34),OP_EQ,
2368                "000102030405060708090A0B0C0D0E0F"
2369                "101112131415161718191A1B1C1D1E1F");
2370     /* Repeat these tests for shorter strings after longer strings
2371        have been tried, to make sure we're correctly terminating strings */
2372     tt_str_op(hex_str(binary_data, 1),OP_EQ, "00");
2373     tt_str_op(hex_str(binary_data, 0),OP_EQ, "");
2374   }
2375 
2376   /* Test strcmp_opt */
2377   tt_int_op(strcmp_opt("",   "foo"), OP_LT, 0);
2378   tt_int_op(strcmp_opt("",    ""),  OP_EQ, 0);
2379   tt_int_op(strcmp_opt("foo", ""),   OP_GT, 0);
2380 
2381   tt_int_op(strcmp_opt(NULL,  ""),    OP_LT, 0);
2382   tt_int_op(strcmp_opt(NULL,  NULL), OP_EQ, 0);
2383   tt_int_op(strcmp_opt("",    NULL),  OP_GT, 0);
2384 
2385   tt_int_op(strcmp_opt(NULL,  "foo"), OP_LT, 0);
2386   tt_int_op(strcmp_opt("foo", NULL),  OP_GT, 0);
2387 
2388  done:
2389   tor_free(cp_tmp);
2390 }
2391 
2392 static void
test_util_parse_integer(void * arg)2393 test_util_parse_integer(void *arg)
2394 {
2395   (void)arg;
2396   int i;
2397   char *cp;
2398 
2399   /* Test parse_long */
2400   /* Empty/zero input */
2401   tt_int_op(0L,OP_EQ, tor_parse_long("",10,0,100,&i,NULL));
2402   tt_int_op(0,OP_EQ, i);
2403   tt_int_op(0L,OP_EQ, tor_parse_long("0",10,0,100,&i,NULL));
2404   tt_int_op(1,OP_EQ, i);
2405   /* Normal cases */
2406   tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,100,&i,NULL));
2407   tt_int_op(1,OP_EQ, i);
2408   tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,10,&i,NULL));
2409   tt_int_op(1,OP_EQ, i);
2410   tt_int_op(10L,OP_EQ, tor_parse_long("10",10,10,100,&i,NULL));
2411   tt_int_op(1,OP_EQ, i);
2412   tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,100,&i,NULL));
2413   tt_int_op(1,OP_EQ, i);
2414   tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,0,&i,NULL));
2415   tt_int_op(1,OP_EQ, i);
2416   tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-50,0,&i,NULL));
2417   tt_int_op(1,OP_EQ, i);
2418   /* Extra garbage */
2419   tt_int_op(0L,OP_EQ, tor_parse_long("10m",10,0,100,&i,NULL));
2420   tt_int_op(0,OP_EQ, i);
2421   tt_int_op(0L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
2422   tt_int_op(0,OP_EQ, i);
2423   tt_int_op(10L,OP_EQ, tor_parse_long("10m",10,0,100,&i,&cp));
2424   tt_int_op(1,OP_EQ, i);
2425   tt_str_op(cp,OP_EQ, "m");
2426   tt_int_op(-50L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
2427   tt_int_op(1,OP_EQ, i);
2428   tt_str_op(cp,OP_EQ, " plus garbage");
2429   /* Illogical min max */
2430   tt_int_op(0L,OP_EQ,  tor_parse_long("10",10,50,4,&i,NULL));
2431   tt_int_op(0,OP_EQ, i);
2432   tt_int_op(0L,OP_EQ,   tor_parse_long("-50",10,100,-100,&i,NULL));
2433   tt_int_op(0,OP_EQ, i);
2434   /* Out of bounds */
2435   tt_int_op(0L,OP_EQ,  tor_parse_long("10",10,50,100,&i,NULL));
2436   tt_int_op(0,OP_EQ, i);
2437   tt_int_op(0L,OP_EQ,   tor_parse_long("-50",10,0,100,&i,NULL));
2438   tt_int_op(0,OP_EQ, i);
2439   /* Base different than 10 */
2440   tt_int_op(2L,OP_EQ,   tor_parse_long("10",2,0,100,NULL,NULL));
2441   tt_int_op(0L,OP_EQ,   tor_parse_long("2",2,0,100,NULL,NULL));
2442   tt_int_op(68284L,OP_EQ, tor_parse_long("10abc",16,0,70000,NULL,NULL));
2443   tt_int_op(68284L,OP_EQ, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
2444   tt_int_op(0L,OP_EQ,   tor_parse_long("10",-2,0,100,NULL,NULL));
2445   tt_int_op(0,OP_EQ, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
2446   tt_int_op(i,OP_EQ, 0);
2447 
2448   /* Test parse_ulong */
2449   tt_int_op(0UL,OP_EQ, tor_parse_ulong("",10,0,100,NULL,NULL));
2450   tt_int_op(0UL,OP_EQ, tor_parse_ulong("0",10,0,100,NULL,NULL));
2451   tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,100,NULL,NULL));
2452   tt_int_op(0UL,OP_EQ, tor_parse_ulong("10",10,50,100,NULL,NULL));
2453   tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,10,NULL,NULL));
2454   tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,10,100,NULL,NULL));
2455   tt_int_op(0UL,OP_EQ, tor_parse_ulong("8",8,0,100,NULL,NULL));
2456   tt_int_op(50UL,OP_EQ, tor_parse_ulong("50",10,50,100,NULL,NULL));
2457   tt_int_op(0UL,OP_EQ, tor_parse_ulong("-50",10,0,100,NULL,NULL));
2458   tt_int_op(0UL,OP_EQ, tor_parse_ulong("50",-1,50,100,&i,NULL));
2459   tt_int_op(0,OP_EQ, i);
2460   tt_int_op(0UL,OP_EQ, tor_parse_ulong("-50",10,0,100,&i,NULL));
2461   tt_int_op(0,OP_EQ, i);
2462 
2463   /* Test parse_uint64 */
2464   tt_assert(UINT64_C(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
2465   tt_int_op(1,OP_EQ, i);
2466   tt_str_op(cp,OP_EQ, " x");
2467   tt_assert(UINT64_C(12345678901) ==
2468               tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
2469   tt_int_op(1,OP_EQ, i);
2470   tt_str_op(cp,OP_EQ, "");
2471   tt_assert(UINT64_C(0) ==
2472               tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
2473   tt_int_op(0,OP_EQ, i);
2474   tt_assert(UINT64_C(0) ==
2475               tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp));
2476   tt_int_op(0,OP_EQ, i);
2477 
2478   {
2479   /* Test parse_double */
2480   double d = tor_parse_double("10", 0, (double)UINT64_MAX,&i,NULL);
2481   tt_int_op(1,OP_EQ, i);
2482   tt_assert(((uint64_t)d) == 10);
2483   d = tor_parse_double("0", 0, (double)UINT64_MAX,&i,NULL);
2484   tt_int_op(1,OP_EQ, i);
2485   tt_assert(((uint64_t)d) == 0);
2486   d = tor_parse_double(" ", 0, (double)UINT64_MAX,&i,NULL);
2487   tt_double_op(fabs(d), OP_LT, 1e-10);
2488   tt_int_op(0,OP_EQ, i);
2489   d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,NULL);
2490   tt_double_op(fabs(d), OP_LT, 1e-10);
2491   tt_int_op(0,OP_EQ, i);
2492   d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,&cp);
2493   tt_double_op(fabs(d), OP_LT, 1e-10);
2494   tt_int_op(1,OP_EQ, i);
2495   d = tor_parse_double("-.0", 0, (double)UINT64_MAX,&i,NULL);
2496   tt_int_op(1,OP_EQ, i);
2497   tt_assert(((uint64_t)d) == 0);
2498   d = tor_parse_double("-10", -100.0, 100.0,&i,NULL);
2499   tt_int_op(1,OP_EQ, i);
2500   tt_double_op(fabs(d - -10.0),OP_LT, 1E-12);
2501   }
2502 
2503   {
2504     /* Test tor_parse_* where we overflow/underflow the underlying type. */
2505     /* This string should overflow 64-bit ints. */
2506 #define TOOBIG "100000000000000000000000000"
2507     tt_int_op(0L, OP_EQ,
2508               tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
2509     tt_int_op(i,OP_EQ, 0);
2510     tt_int_op(0L,OP_EQ,
2511               tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
2512     tt_int_op(i,OP_EQ, 0);
2513     tt_int_op(0UL,OP_EQ, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
2514     tt_int_op(i,OP_EQ, 0);
2515     tt_u64_op(UINT64_C(0), OP_EQ, tor_parse_uint64(TOOBIG, 10,
2516                                              0, UINT64_MAX, &i, NULL));
2517     tt_int_op(i,OP_EQ, 0);
2518   }
2519  done:
2520   ;
2521 }
2522 
2523 static void
test_util_pow2(void * arg)2524 test_util_pow2(void *arg)
2525 {
2526   /* Test tor_log2(). */
2527   (void)arg;
2528   tt_int_op(tor_log2(64),OP_EQ, 6);
2529   tt_int_op(tor_log2(65),OP_EQ, 6);
2530   tt_int_op(tor_log2(63),OP_EQ, 5);
2531   /* incorrect mathematically, but as specified: */
2532   tt_int_op(tor_log2(0),OP_EQ, 0);
2533   tt_int_op(tor_log2(1),OP_EQ, 0);
2534   tt_int_op(tor_log2(2),OP_EQ, 1);
2535   tt_int_op(tor_log2(3),OP_EQ, 1);
2536   tt_int_op(tor_log2(4),OP_EQ, 2);
2537   tt_int_op(tor_log2(5),OP_EQ, 2);
2538   tt_int_op(tor_log2(UINT64_C(40000000000000000)),OP_EQ, 55);
2539   tt_int_op(tor_log2(UINT64_MAX),OP_EQ, 63);
2540 
2541   /* Test round_to_power_of_2 */
2542   tt_u64_op(round_to_power_of_2(120), OP_EQ, 128);
2543   tt_u64_op(round_to_power_of_2(128), OP_EQ, 128);
2544   tt_u64_op(round_to_power_of_2(130), OP_EQ, 128);
2545   tt_u64_op(round_to_power_of_2(UINT64_C(40000000000000000)), OP_EQ,
2546             UINT64_C(1)<<55);
2547   tt_u64_op(round_to_power_of_2(UINT64_C(0xffffffffffffffff)), OP_EQ,
2548           UINT64_C(1)<<63);
2549   tt_u64_op(round_to_power_of_2(0), OP_EQ, 1);
2550   tt_u64_op(round_to_power_of_2(1), OP_EQ, 1);
2551   tt_u64_op(round_to_power_of_2(2), OP_EQ, 2);
2552   tt_u64_op(round_to_power_of_2(3), OP_EQ, 2);
2553   tt_u64_op(round_to_power_of_2(4), OP_EQ, 4);
2554   tt_u64_op(round_to_power_of_2(5), OP_EQ, 4);
2555   tt_u64_op(round_to_power_of_2(6), OP_EQ, 4);
2556   tt_u64_op(round_to_power_of_2(7), OP_EQ, 8);
2557 
2558  done:
2559   ;
2560 }
2561 
2562 static void
test_util_compress_impl(compress_method_t method)2563 test_util_compress_impl(compress_method_t method)
2564 {
2565   char *buf1=NULL, *buf2=NULL, *buf3=NULL;
2566   size_t len1, len2;
2567 
2568   tt_assert(tor_compress_supports_method(method));
2569 
2570   if (method != NO_METHOD) {
2571     tt_ptr_op(tor_compress_version_str(method), OP_NE, NULL);
2572     tt_ptr_op(tor_compress_header_version_str(method), OP_NE, NULL);
2573   }
2574 
2575   buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
2576   tt_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
2577 
2578   tt_assert(!tor_compress(&buf2, &len1, buf1, strlen(buf1)+1, method));
2579   tt_ptr_op(buf2, OP_NE, NULL);
2580   if (method == NO_METHOD) {
2581     // The identity transform doesn't actually compress, and it isn't
2582     // detectable as "the identity transform."
2583     tt_int_op(len1, OP_EQ, strlen(buf1)+1);
2584     tt_int_op(detect_compression_method(buf2, len1), OP_EQ, UNKNOWN_METHOD);
2585   } else {
2586     tt_int_op(len1, OP_LT, strlen(buf1));
2587     tt_int_op(detect_compression_method(buf2, len1), OP_EQ, method);
2588   }
2589 
2590   tt_assert(!tor_uncompress(&buf3, &len2, buf2, len1, method, 1, LOG_INFO));
2591   tt_ptr_op(buf3, OP_NE, NULL);
2592   tt_int_op(strlen(buf1) + 1, OP_EQ, len2);
2593   tt_str_op(buf1, OP_EQ, buf3);
2594   tt_int_op(buf3[len2], OP_EQ, 0);
2595 
2596   /* Check whether we can uncompress concatenated, compressed strings. */
2597   tor_free(buf3);
2598   buf2 = tor_reallocarray(buf2, len1, 2);
2599   memcpy(buf2+len1, buf2, len1);
2600   tt_assert(!tor_uncompress(&buf3, &len2, buf2, len1*2, method, 1, LOG_INFO));
2601   tt_int_op((strlen(buf1)+1)*2, OP_EQ, len2);
2602   tt_mem_op(buf3, OP_EQ,
2603              "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
2604              "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
2605              (strlen(buf1)+1)*2);
2606   tt_int_op(buf3[len2], OP_EQ, 0);
2607 
2608   /* Check whether we can uncompress partial strings */
2609 
2610   tor_free(buf1);
2611   tor_free(buf2);
2612   tor_free(buf3);
2613 
2614   size_t b1len = 1<<10;
2615   if (method == ZSTD_METHOD) {
2616     // zstd needs a big input before it starts generating output that it
2617     // can partially decompress.
2618     b1len = 1<<18;
2619   }
2620   buf1 = tor_malloc(b1len);
2621   crypto_rand(buf1, b1len);
2622   tt_assert(!tor_compress(&buf2, &len1, buf1, b1len, method));
2623   tt_int_op(len1, OP_GT, 16);
2624   /* when we allow an incomplete output we should succeed.*/
2625   tt_assert(!tor_uncompress(&buf3, &len2, buf2, len1-16,
2626                             method, 0, LOG_INFO));
2627   tt_int_op(len2, OP_GT, 5);
2628   tt_int_op(len2, OP_LE, len1);
2629   tt_assert(fast_memeq(buf1, buf3, len2));
2630   tt_int_op(buf3[len2], OP_EQ, 0);
2631 
2632   /* when we demand a complete output from a real compression method, this
2633    * must fail. */
2634   tor_free(buf3);
2635   if (method != NO_METHOD) {
2636     tt_assert(tor_uncompress(&buf3, &len2, buf2, len1-16,
2637                              method, 1, LOG_INFO));
2638     tt_ptr_op(buf3, OP_EQ, NULL);
2639   }
2640 
2641  done:
2642   tor_free(buf1);
2643   tor_free(buf2);
2644   tor_free(buf3);
2645 }
2646 
2647 static void
test_util_compress_stream_impl(compress_method_t method,compression_level_t level)2648 test_util_compress_stream_impl(compress_method_t method,
2649                                compression_level_t level)
2650 {
2651   char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
2652   const char *ccp2;
2653   size_t len1, len2;
2654 
2655   tor_compress_state_t *state = NULL;
2656   state = tor_compress_new(1, method, level);
2657   tt_assert(state);
2658   cp1 = buf1 = tor_malloc(1024);
2659   len1 = 1024;
2660   ccp2 = "ABCDEFGHIJABCDEFGHIJ";
2661   len2 = 21;
2662   tt_int_op(tor_compress_process(state, &cp1, &len1, &ccp2, &len2, 0),
2663             OP_EQ, TOR_COMPRESS_OK);
2664   tt_int_op(0, OP_EQ, len2); /* Make sure we compressed it all. */
2665   tt_assert(cp1 > buf1);
2666 
2667   len2 = 0;
2668   cp2 = cp1;
2669   tt_int_op(tor_compress_process(state, &cp1, &len1, &ccp2, &len2, 1),
2670             OP_EQ, TOR_COMPRESS_DONE);
2671   tt_int_op(0, OP_EQ, len2);
2672   if (method == NO_METHOD) {
2673     tt_ptr_op(cp1, OP_EQ, cp2);
2674   } else {
2675     tt_assert(cp1 > cp2); /* Make sure we really added something. */
2676   }
2677 
2678   tt_int_op(tor_compress_state_size(state), OP_GT, 0);
2679 
2680   tt_assert(!tor_uncompress(&buf3, &len2, buf1, 1024-len1,
2681                             method, 1, LOG_WARN));
2682   /* Make sure it compressed right. */
2683   tt_str_op(buf3, OP_EQ, "ABCDEFGHIJABCDEFGHIJ");
2684   tt_int_op(21, OP_EQ, len2);
2685 
2686  done:
2687   if (state)
2688     tor_compress_free(state);
2689   tor_free(buf1);
2690   tor_free(buf2);
2691   tor_free(buf3);
2692 }
2693 
2694 /** Setup function for compression tests: handles x-zstd:nostatic
2695  */
2696 static void *
compression_test_setup(const struct testcase_t * testcase)2697 compression_test_setup(const struct testcase_t *testcase)
2698 {
2699   tor_assert(testcase->setup_data);
2700   tor_assert(testcase->setup_data != (void*)TT_SKIP);
2701   const char *methodname = testcase->setup_data;
2702 
2703   if (!strcmp(methodname, "x-zstd:nostatic")) {
2704     methodname = "x-zstd";
2705     tor_zstd_set_static_apis_disabled_for_testing(1);
2706   }
2707 
2708   return (void *)methodname;
2709 }
2710 
2711 /** Cleanup for compression tests: disables nostatic */
2712 static int
compression_test_cleanup(const struct testcase_t * testcase,void * ptr)2713 compression_test_cleanup(const struct testcase_t *testcase, void *ptr)
2714 {
2715   (void)testcase;
2716   (void)ptr;
2717   tor_zstd_set_static_apis_disabled_for_testing(0);
2718   return 1;
2719 }
2720 
2721 static const struct testcase_setup_t compress_setup = {
2722   compression_test_setup, compression_test_cleanup
2723 };
2724 
2725 /** Run unit tests for compression functions */
2726 static void
test_util_compress(void * arg)2727 test_util_compress(void *arg)
2728 {
2729   const char *methodname = arg;
2730   tt_assert(methodname);
2731 
2732   compress_method_t method = compression_method_get_by_name(methodname);
2733   tt_int_op(method, OP_NE, UNKNOWN_METHOD);
2734 
2735   if (! tor_compress_supports_method(method)) {
2736     tt_skip();
2737   }
2738 
2739   compression_level_t levels[] = {
2740     BEST_COMPRESSION,
2741     HIGH_COMPRESSION,
2742     MEDIUM_COMPRESSION,
2743     LOW_COMPRESSION
2744   };
2745 
2746   test_util_compress_impl(method);
2747 
2748   for (unsigned l = 0; l < ARRAY_LENGTH(levels); ++l) {
2749     compression_level_t level = levels[l];
2750     test_util_compress_stream_impl(method, level);
2751   }
2752  done:
2753   ;
2754 }
2755 
2756 static void
test_util_decompress_concatenated_impl(compress_method_t method)2757 test_util_decompress_concatenated_impl(compress_method_t method)
2758 {
2759   char input[4096];
2760   char *c1 = NULL, *c2 = NULL, *c3 = NULL;
2761   char *result = NULL;
2762   size_t sz1, sz2, sz3, szr;
2763   int r;
2764 
2765   crypto_rand(input, sizeof(input));
2766 
2767   /* Compress the input in two chunks. */
2768   r = tor_compress(&c1, &sz1, input, 2048, method);
2769   tt_int_op(r, OP_EQ, 0);
2770   r = tor_compress(&c2, &sz2, input+2048, 2048, method);
2771   tt_int_op(r, OP_EQ, 0);
2772 
2773   /* concatenate the chunks. */
2774   sz3 = sz1 + sz2;
2775   c3 = tor_malloc(sz3);
2776   memcpy(c3, c1, sz1);
2777   memcpy(c3+sz1, c2, sz2);
2778 
2779   /* decompress the concatenated result */
2780   r = tor_uncompress(&result, &szr, c3, sz3, method, 0, LOG_WARN);
2781   tt_int_op(r, OP_EQ, 0);
2782   tt_int_op(szr, OP_EQ, sizeof(input));
2783   tt_mem_op(result, OP_EQ, input, sizeof(input));
2784 
2785  done:
2786   tor_free(c1);
2787   tor_free(c2);
2788   tor_free(c3);
2789   tor_free(result);
2790 }
2791 
2792 static void
test_util_decompress_concatenated(void * arg)2793 test_util_decompress_concatenated(void *arg)
2794 {
2795   const char *methodname = arg;
2796   tt_assert(methodname);
2797 
2798   compress_method_t method = compression_method_get_by_name(methodname);
2799   tt_int_op(method, OP_NE, UNKNOWN_METHOD);
2800   if (! tor_compress_supports_method(method)) {
2801     tt_skip();
2802   }
2803 
2804   test_util_decompress_concatenated_impl(method);
2805  done:
2806   ;
2807 }
2808 
2809 static void
test_util_decompress_junk_impl(compress_method_t method)2810 test_util_decompress_junk_impl(compress_method_t method)
2811 {
2812   char input[4096];
2813   char *result = NULL, *result2 = NULL;
2814   size_t szr, szr2, sz;
2815   int r;
2816 
2817   /* This shouldn't be a compressed string according to any method. */
2818   strlcpy(input, "This shouldn't be a compressed string by any means.",
2819           sizeof(input));
2820   sz = strlen(input);
2821   setup_capture_of_logs(LOG_WARN);
2822   r = tor_uncompress(&result, &szr, input, sz, method, 0, LOG_WARN);
2823   tt_int_op(r, OP_EQ, -1);
2824   tt_ptr_op(result, OP_EQ, NULL);
2825   expect_log_msg_containing("Error while uncompressing data: bad input?");
2826   mock_clean_saved_logs();
2827 
2828   /* Now try again, with a compressed object that starts out good and turns to
2829      junk. */
2830   crypto_rand(input, sizeof(input));
2831   r = tor_compress(&result, &szr, input, sizeof(input), method);
2832   tt_int_op(r, OP_EQ, 0);
2833   crypto_rand(result+szr/2, szr-(szr/2)); // trash the 2nd half of the result
2834   r = tor_uncompress(&result2, &szr2, result, szr, method, 0, LOG_WARN);
2835   tt_int_op(r, OP_EQ, -1);
2836   expect_log_msg_containing("Error while uncompressing data: bad input?");
2837 
2838  done:
2839   teardown_capture_of_logs();
2840   tor_free(result);
2841   tor_free(result2);
2842 }
2843 
2844 static void
test_util_decompress_junk(void * arg)2845 test_util_decompress_junk(void *arg)
2846 {
2847   const char *methodname = arg;
2848   tt_assert(methodname);
2849 
2850   compress_method_t method = compression_method_get_by_name(methodname);
2851   tt_int_op(method, OP_NE, UNKNOWN_METHOD);
2852   if (! tor_compress_supports_method(method)) {
2853     tt_skip();
2854   }
2855 
2856   test_util_decompress_junk_impl(method);
2857  done:
2858   ;
2859 }
2860 
2861 /* mock replacement for tor_compress_is_compression_bomb that doesn't
2862  * believe in compression bombs. */
2863 static int
mock_is_never_compression_bomb(size_t in,size_t out)2864 mock_is_never_compression_bomb(size_t in, size_t out)
2865 {
2866   (void)in;
2867   (void) out;
2868   return 0;
2869 }
2870 
2871 static void
test_util_decompress_dos_impl(compress_method_t method)2872 test_util_decompress_dos_impl(compress_method_t method)
2873 {
2874   char *input;
2875   char *result = NULL, *result2 = NULL;
2876   size_t szr, szr2;
2877   int r;
2878 
2879   const size_t big = 1024*1024;
2880   /* one megabyte of 0s. */
2881   input = tor_malloc_zero(big);
2882 
2883   /* Compress it into "result": it should fail. */
2884   setup_full_capture_of_logs(LOG_WARN);
2885   r = tor_compress(&result, &szr, input, big, method);
2886   tt_int_op(r, OP_EQ, -1);
2887   expect_log_msg_containing(
2888                  "other Tors would think this was a compression bomb");
2889   teardown_capture_of_logs();
2890 
2891   /* Try again, but this time suppress compression-bomb detection */
2892   MOCK(tor_compress_is_compression_bomb, mock_is_never_compression_bomb);
2893   r = tor_compress(&result, &szr, input, big, method);
2894   UNMOCK(tor_compress_is_compression_bomb);
2895   tt_int_op(r, OP_EQ, 0);
2896   tt_ptr_op(result, OP_NE, NULL);
2897 
2898   /* We should refuse to uncomrpess it again, since it looks like a
2899    * compression bomb. */
2900   setup_capture_of_logs(LOG_WARN);
2901   r = tor_uncompress(&result2, &szr2, result, szr, method, 0, LOG_WARN);
2902   tt_int_op(r, OP_EQ, -1);
2903   expect_log_msg_containing("bomb; abandoning stream");
2904 
2905  done:
2906   teardown_capture_of_logs();
2907   tor_free(input);
2908   tor_free(result);
2909   tor_free(result2);
2910 }
2911 
2912 static void
test_util_decompress_dos(void * arg)2913 test_util_decompress_dos(void *arg)
2914 {
2915   const char *methodname = arg;
2916   tt_assert(methodname);
2917 
2918   compress_method_t method = compression_method_get_by_name(methodname);
2919   tt_int_op(method, OP_NE, UNKNOWN_METHOD);
2920   if (! tor_compress_supports_method(method)) {
2921     tt_skip();
2922   }
2923 
2924   test_util_decompress_dos_impl(method);
2925  done:
2926   ;
2927 }
2928 
2929 static void
test_util_gzip_compression_bomb(void * arg)2930 test_util_gzip_compression_bomb(void *arg)
2931 {
2932   /* A 'compression bomb' is a very small object that uncompresses to a huge
2933    * one. Most compression formats support them, but they can be a DOS vector.
2934    * In Tor we try not to generate them, and we don't accept them.
2935    */
2936   (void) arg;
2937   size_t one_million = 1<<20;
2938   char *one_mb = tor_malloc_zero(one_million);
2939   char *result = NULL;
2940   size_t result_len = 0;
2941   tor_compress_state_t *state = NULL;
2942 
2943   /* Make sure we can't produce a compression bomb */
2944   setup_full_capture_of_logs(LOG_WARN);
2945   tt_int_op(-1, OP_EQ, tor_compress(&result, &result_len,
2946                                     one_mb, one_million,
2947                                     ZLIB_METHOD));
2948   expect_single_log_msg_containing(
2949          "We compressed something and got an insanely high "
2950          "compression factor; other Tors would think this "
2951          "was a compression bomb.");
2952   teardown_capture_of_logs();
2953 
2954   /* Here's a compression bomb that we made manually. */
2955   const char compression_bomb[1039] =
2956     { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2,
2957       0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ };
2958   tt_int_op(-1, OP_EQ, tor_uncompress(&result, &result_len,
2959                                       compression_bomb, 1039,
2960                                       ZLIB_METHOD, 0, LOG_WARN));
2961 
2962   /* Now try streaming that. */
2963   state = tor_compress_new(0, ZLIB_METHOD, HIGH_COMPRESSION);
2964   tor_compress_output_t r;
2965   const char *inp = compression_bomb;
2966   size_t inlen = 1039;
2967   do {
2968     char *outp = one_mb;
2969     size_t outleft = 4096; /* small on purpose */
2970     r = tor_compress_process(state, &outp, &outleft, &inp, &inlen, 0);
2971     tt_int_op(inlen, OP_NE, 0);
2972   } while (r == TOR_COMPRESS_BUFFER_FULL);
2973 
2974   tt_int_op(r, OP_EQ, TOR_COMPRESS_ERROR);
2975 
2976  done:
2977   tor_free(one_mb);
2978   tor_compress_free(state);
2979 }
2980 
2981 /** Run unit tests for mmap() wrapper functionality. */
2982 static void
test_util_mmap(void * arg)2983 test_util_mmap(void *arg)
2984 {
2985   char *fname1 = tor_strdup(get_fname("mapped_1"));
2986   char *fname2 = tor_strdup(get_fname("mapped_2"));
2987   char *fname3 = tor_strdup(get_fname("mapped_3"));
2988   const size_t buflen = 17000;
2989   char *buf = tor_malloc(17000);
2990   tor_mmap_t *mapping = NULL;
2991 
2992   (void)arg;
2993   crypto_rand(buf, buflen);
2994 
2995   mapping = tor_mmap_file(fname1);
2996   tt_ptr_op(mapping, OP_EQ, NULL);
2997 
2998   write_str_to_file(fname1, "Short file.", 1);
2999 
3000   mapping = tor_mmap_file(fname1);
3001   tt_assert(mapping);
3002   tt_int_op(mapping->size,OP_EQ, strlen("Short file."));
3003   tt_str_op(mapping->data,OP_EQ, "Short file.");
3004 #ifdef _WIN32
3005   tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
3006   mapping = NULL;
3007   tt_assert(unlink(fname1) == 0);
3008 #else
3009   /* make sure we can unlink. */
3010   tt_assert(unlink(fname1) == 0);
3011   tt_str_op(mapping->data,OP_EQ, "Short file.");
3012   tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
3013   mapping = NULL;
3014 #endif /* defined(_WIN32) */
3015 
3016   /* Now a zero-length file. */
3017   write_str_to_file(fname1, "", 1);
3018   mapping = tor_mmap_file(fname1);
3019   tt_ptr_op(mapping,OP_EQ, NULL);
3020   tt_int_op(ERANGE,OP_EQ, errno);
3021   unlink(fname1);
3022 
3023   /* Make sure that we fail to map a no-longer-existent file. */
3024   mapping = tor_mmap_file(fname1);
3025   tt_ptr_op(mapping, OP_EQ, NULL);
3026 
3027   /* Now try a big file that stretches across a few pages and isn't aligned */
3028   write_bytes_to_file(fname2, buf, buflen, 1);
3029   mapping = tor_mmap_file(fname2);
3030   tt_assert(mapping);
3031   tt_int_op(mapping->size,OP_EQ, buflen);
3032   tt_mem_op(mapping->data,OP_EQ, buf, buflen);
3033   tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
3034   mapping = NULL;
3035 
3036   /* Now try a big aligned file. */
3037   write_bytes_to_file(fname3, buf, 16384, 1);
3038   mapping = tor_mmap_file(fname3);
3039   tt_assert(mapping);
3040   tt_int_op(mapping->size,OP_EQ, 16384);
3041   tt_mem_op(mapping->data,OP_EQ, buf, 16384);
3042   tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
3043   mapping = NULL;
3044 
3045  done:
3046   unlink(fname1);
3047   unlink(fname2);
3048   unlink(fname3);
3049 
3050   tor_free(fname1);
3051   tor_free(fname2);
3052   tor_free(fname3);
3053   tor_free(buf);
3054 
3055   tor_munmap_file(mapping);
3056 }
3057 
3058 /** Run unit tests for escaping/unescaping data for use by controllers. */
3059 static void
test_util_control_formats(void * arg)3060 test_util_control_formats(void *arg)
3061 {
3062   char *out = NULL;
3063   const char *inp =
3064     "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
3065   size_t sz;
3066 
3067   (void)arg;
3068   sz = read_escaped_data(inp, strlen(inp), &out);
3069   tt_str_op(out,OP_EQ,
3070              ".This is a test\nof the emergency \n.system.\n\rZ.\n");
3071   tt_int_op(sz,OP_EQ, strlen(out));
3072 
3073  done:
3074   tor_free(out);
3075 }
3076 
3077 #define test_feq(value1,value2) do {                               \
3078     double v1 = (value1), v2=(value2);                             \
3079     double tf_diff = v1-v2;                                        \
3080     double tf_tolerance = ((v1+v2)/2.0)/1e8;                       \
3081     if (tf_diff<0) tf_diff=-tf_diff;                               \
3082     if (tf_tolerance<0) tf_tolerance=-tf_tolerance;                \
3083     if (tf_diff<tf_tolerance) {                                    \
3084       TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2));  \
3085     } else {                                                       \
3086       TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
3087     }                                                              \
3088   } while (0)
3089 
3090 static void
test_util_sscanf(void * arg)3091 test_util_sscanf(void *arg)
3092 {
3093   unsigned u1, u2, u3;
3094   unsigned long ulng;
3095   char s1[20], s2[10], s3[10], ch, *huge = NULL;
3096   int r;
3097   long lng1,lng2;
3098   int int1, int2;
3099   double d1,d2,d3,d4;
3100 
3101   /* Simple tests (malformed patterns, literal matching, ...) */
3102   (void)arg;
3103   tt_int_op(-1,OP_EQ, tor_sscanf("123", "%i", &r)); /* %i is not supported */
3104   tt_int_op(-1,OP_EQ,
3105             tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */
3106   tt_int_op(-1,OP_EQ, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */
3107   /* this will fail because we don't allow widths longer than 9999 */
3108   {
3109     huge = tor_malloc(1000000);
3110     r = tor_sscanf("prettylongstring", "%99999s", huge);
3111     tor_free(huge);
3112     tt_int_op(-1,OP_EQ, r);
3113   }
3114 #if 0
3115   /* GCC thinks these two are illegal. */
3116   test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1));
3117   test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL));
3118 #endif
3119   /* No '%'-strings: always "success" */
3120   tt_int_op(0,OP_EQ, tor_sscanf("hello world", "hello world"));
3121   tt_int_op(0,OP_EQ, tor_sscanf("hello world", "good bye"));
3122   /* Excess data */
3123   tt_int_op(0,OP_EQ,
3124             tor_sscanf("hello 3", "%u", &u1));  /* have to match the start */
3125   tt_int_op(0,OP_EQ, tor_sscanf(" 3 hello", "%u", &u1));
3126   tt_int_op(0,OP_EQ,
3127             tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */
3128   tt_int_op(1,OP_EQ,
3129             tor_sscanf("3 hello", "%u", &u1));  /* but trailing is alright */
3130 
3131   /* Numbers (ie. %u) */
3132   tt_int_op(0,OP_EQ,
3133             tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */
3134   tt_int_op(1,OP_EQ, tor_sscanf("12345", "%u", &u1));
3135   tt_int_op(12345u,OP_EQ, u1);
3136   tt_int_op(1,OP_EQ, tor_sscanf("12346 ", "%u", &u1));
3137   tt_int_op(12346u,OP_EQ, u1);
3138   tt_int_op(0,OP_EQ, tor_sscanf(" 12347", "%u", &u1));
3139   tt_int_op(1,OP_EQ, tor_sscanf(" 12348", " %u", &u1));
3140   tt_int_op(12348u,OP_EQ, u1);
3141   tt_int_op(1,OP_EQ, tor_sscanf("0", "%u", &u1));
3142   tt_int_op(0u,OP_EQ, u1);
3143   tt_int_op(1,OP_EQ, tor_sscanf("0000", "%u", &u2));
3144   tt_int_op(0u,OP_EQ, u2);
3145   tt_int_op(0,OP_EQ, tor_sscanf("", "%u", &u1)); /* absent number */
3146   tt_int_op(0,OP_EQ, tor_sscanf("A", "%u", &u1)); /* bogus number */
3147   tt_int_op(0,OP_EQ, tor_sscanf("-1", "%u", &u1)); /* negative number */
3148 
3149   /* Numbers with size (eg. %2u) */
3150   tt_int_op(0,OP_EQ, tor_sscanf("-1", "%2u", &u1));
3151   tt_int_op(2,OP_EQ, tor_sscanf("123456", "%2u%u", &u1, &u2));
3152   tt_int_op(12u,OP_EQ, u1);
3153   tt_int_op(3456u,OP_EQ, u2);
3154   tt_int_op(1,OP_EQ, tor_sscanf("123456", "%8u", &u1));
3155   tt_int_op(123456u,OP_EQ, u1);
3156   tt_int_op(1,OP_EQ, tor_sscanf("123457  ", "%8u", &u1));
3157   tt_int_op(123457u,OP_EQ, u1);
3158   tt_int_op(0,OP_EQ, tor_sscanf("  123456", "%8u", &u1));
3159   tt_int_op(3,OP_EQ, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3));
3160   tt_int_op(12u,OP_EQ, u1);
3161   tt_int_op(3u,OP_EQ, u2);
3162   tt_int_op(456u,OP_EQ, u3);
3163   tt_int_op(3,OP_EQ,
3164             tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */
3165   tt_int_op(67u,OP_EQ, u1);
3166   tt_int_op(8u,OP_EQ, u2);
3167   tt_int_op(99u,OP_EQ, u3);
3168   /* %u does not match space.*/
3169   tt_int_op(2,OP_EQ, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3));
3170   tt_int_op(12u,OP_EQ, u1);
3171   tt_int_op(3u,OP_EQ, u2);
3172   /* %u does not match negative numbers. */
3173   tt_int_op(2,OP_EQ, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3));
3174   tt_int_op(67u,OP_EQ, u1);
3175   tt_int_op(8u,OP_EQ, u2);
3176   /* Arbitrary amounts of 0-padding are okay */
3177   tt_int_op(3,OP_EQ, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
3178                         &u1, &u2, &u3));
3179   tt_int_op(12u,OP_EQ, u1);
3180   tt_int_op(3u,OP_EQ, u2);
3181   tt_int_op(99u,OP_EQ, u3);
3182 
3183   /* Hex (ie. %x) */
3184   tt_int_op(3,OP_EQ,
3185             tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3));
3186   tt_int_op(0x1234,OP_EQ, u1);
3187   tt_int_op(0x2ABCDEF,OP_EQ, u2);
3188   tt_int_op(0xFF,OP_EQ, u3);
3189   /* Width works on %x */
3190   tt_int_op(3,OP_EQ, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3));
3191   tt_int_op(0xf00d,OP_EQ, u1);
3192   tt_int_op(0xcafe,OP_EQ, u2);
3193   tt_int_op(444,OP_EQ, u3);
3194 
3195   /* Literal '%' (ie. '%%') */
3196   tt_int_op(1,OP_EQ, tor_sscanf("99% fresh", "%3u%% fresh", &u1));
3197   tt_int_op(99,OP_EQ, u1);
3198   tt_int_op(0,OP_EQ, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1));
3199   tt_int_op(1,OP_EQ, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1));
3200   tt_int_op(2,OP_EQ, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1));
3201   tt_int_op(99,OP_EQ, u1);
3202   tt_str_op(s1,OP_EQ, "fresh");
3203   tt_int_op(1,OP_EQ, tor_sscanf("% boo", "%% %3s", s1));
3204   tt_str_op("boo",OP_EQ, s1);
3205 
3206   /* Strings (ie. %s) */
3207   tt_int_op(2,OP_EQ, tor_sscanf("hello", "%3s%7s", s1, s2));
3208   tt_str_op(s1,OP_EQ, "hel");
3209   tt_str_op(s2,OP_EQ, "lo");
3210   tt_int_op(2,OP_EQ, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */
3211   tt_str_op(s3,OP_EQ, "WD");
3212   tt_int_op(40,OP_EQ, u1);
3213   tt_int_op(2,OP_EQ, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */
3214   tt_str_op(s3,OP_EQ, "WD4");
3215   tt_int_op(0,OP_EQ, u1);
3216   tt_int_op(2,OP_EQ, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */
3217   tt_int_op(76,OP_EQ, u1);
3218   tt_str_op(s1,OP_EQ, "trombones");
3219   {
3220     huge = tor_malloc(1000);
3221     r = tor_sscanf("prettylongstring", "%999s", huge);
3222     tt_int_op(1,OP_EQ, r);
3223     tt_str_op(huge,OP_EQ, "prettylongstring");
3224     tor_free(huge);
3225   }
3226   /* %s doesn't eat spaces */
3227   tt_int_op(2,OP_EQ, tor_sscanf("hello world", "%9s %9s", s1, s2));
3228   tt_str_op(s1,OP_EQ, "hello");
3229   tt_str_op(s2,OP_EQ, "world");
3230   tt_int_op(2,OP_EQ, tor_sscanf("bye   world?", "%9s %9s", s1, s2));
3231   tt_str_op(s1,OP_EQ, "bye");
3232   tt_str_op(s2,OP_EQ, "");
3233   tt_int_op(3,OP_EQ,
3234             tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */
3235   tt_str_op(s1,OP_EQ, "hi");
3236   tt_str_op(s2,OP_EQ, "");
3237   tt_str_op(s3,OP_EQ, "");
3238 
3239   tt_int_op(3,OP_EQ, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
3240   tt_int_op(4,OP_EQ,
3241             tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
3242   tt_int_op(' ',OP_EQ, ch);
3243 
3244   r = tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1, &lng1, &int2);
3245   tt_int_op(r,OP_EQ, 3);
3246   tt_int_op(int1,OP_EQ, 12345);
3247   tt_int_op(lng1,OP_EQ, -67890);
3248   tt_int_op(int2,OP_EQ, -1);
3249 
3250 #if SIZEOF_INT == 4
3251   /* %u */
3252   /* UINT32_MAX should work */
3253   tt_int_op(1,OP_EQ, tor_sscanf("4294967295", "%u", &u1));
3254   tt_int_op(4294967295U,OP_EQ, u1);
3255 
3256   /* But UINT32_MAX + 1 shouldn't work */
3257   tt_int_op(0,OP_EQ, tor_sscanf("4294967296", "%u", &u1));
3258   /* but parsing only 9... */
3259   tt_int_op(1,OP_EQ, tor_sscanf("4294967296", "%9u", &u1));
3260   tt_int_op(429496729U,OP_EQ, u1);
3261 
3262   /* %x */
3263   /* UINT32_MAX should work */
3264   tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFF", "%x", &u1));
3265   tt_int_op(0xFFFFFFFF,OP_EQ, u1);
3266 
3267   /* But UINT32_MAX + 1 shouldn't work */
3268   tt_int_op(0,OP_EQ, tor_sscanf("100000000", "%x", &u1));
3269 
3270   /* %d */
3271   /* INT32_MIN and INT32_MAX should work */
3272   r = tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1, &int2);
3273   tt_int_op(r,OP_EQ, 2);
3274   tt_int_op(int1,OP_EQ, -2147483647 - 1);
3275   tt_int_op(int2,OP_EQ, 2147483647);
3276 
3277   /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3278   r = tor_sscanf("-2147483649.", "%d.", &int1);
3279   tt_int_op(r,OP_EQ, 0);
3280 
3281   r = tor_sscanf("2147483648.", "%d.", &int1);
3282   tt_int_op(r,OP_EQ, 0);
3283 
3284   /* and the first failure stops further processing */
3285   r = tor_sscanf("-2147483648. 2147483648.",
3286                  "%d. %d.", &int1, &int2);
3287   tt_int_op(r,OP_EQ, 1);
3288 
3289   r = tor_sscanf("-2147483649. 2147483647.",
3290                  "%d. %d.", &int1, &int2);
3291   tt_int_op(r,OP_EQ, 0);
3292 
3293   r = tor_sscanf("2147483648. -2147483649.",
3294                  "%d. %d.", &int1, &int2);
3295   tt_int_op(r,OP_EQ, 0);
3296 #elif SIZEOF_INT == 8
3297   /* %u */
3298   /* UINT64_MAX should work */
3299   tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551615", "%u", &u1));
3300   tt_int_op(18446744073709551615U,OP_EQ, u1);
3301 
3302   /* But UINT64_MAX + 1 shouldn't work */
3303   tt_int_op(0,OP_EQ, tor_sscanf("18446744073709551616", "%u", &u1));
3304   /* but parsing only 19... */
3305   tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551616", "%19u", &u1));
3306   tt_int_op(1844674407370955161U,OP_EQ, u1);
3307 
3308   /* %x */
3309   /* UINT64_MAX should work */
3310   tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1));
3311   tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ, u1);
3312 
3313   /* But UINT64_MAX + 1 shouldn't work */
3314   tt_int_op(0,OP_EQ, tor_sscanf("10000000000000000", "%x", &u1));
3315 
3316   /* %d */
3317   /* INT64_MIN and INT64_MAX should work */
3318   r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
3319                  "%d. %d.", &int1, &int2);
3320   tt_int_op(r,OP_EQ, 2);
3321   tt_int_op(int1,OP_EQ, -9223372036854775807 - 1);
3322   tt_int_op(int2,OP_EQ, 9223372036854775807);
3323 
3324   /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3325   r = tor_sscanf("-9223372036854775809.", "%d.", &int1);
3326   tt_int_op(r,OP_EQ, 0);
3327 
3328   r = tor_sscanf("9223372036854775808.", "%d.", &int1);
3329   tt_int_op(r,OP_EQ, 0);
3330 
3331   /* and the first failure stops further processing */
3332   r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
3333                  "%d. %d.", &int1, &int2);
3334   tt_int_op(r,OP_EQ, 1);
3335 
3336   r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
3337                  "%d. %d.", &int1, &int2);
3338   tt_int_op(r,OP_EQ, 0);
3339 
3340   r = tor_sscanf("9223372036854775808. -9223372036854775809.",
3341                  "%d. %d.", &int1, &int2);
3342   tt_int_op(r,OP_EQ, 0);
3343 #endif /* SIZEOF_INT == 4 || ... */
3344 
3345 #if SIZEOF_LONG == 4
3346   /* %lu */
3347   /* UINT32_MAX should work */
3348   tt_int_op(1,OP_EQ, tor_sscanf("4294967295", "%lu", &ulng));
3349   tt_int_op(4294967295UL,OP_EQ, ulng);
3350 
3351   /* But UINT32_MAX + 1 shouldn't work */
3352   tt_int_op(0,OP_EQ, tor_sscanf("4294967296", "%lu", &ulng));
3353   /* but parsing only 9... */
3354   tt_int_op(1,OP_EQ, tor_sscanf("4294967296", "%9lu", &ulng));
3355   tt_int_op(429496729UL,OP_EQ, ulng);
3356 
3357   /* %lx */
3358   /* UINT32_MAX should work */
3359   tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFF", "%lx", &ulng));
3360   tt_int_op(0xFFFFFFFFUL,OP_EQ, ulng);
3361 
3362   /* But UINT32_MAX + 1 shouldn't work */
3363   tt_int_op(0,OP_EQ, tor_sscanf("100000000", "%lx", &ulng));
3364 
3365   /* %ld */
3366   /* INT32_MIN and INT32_MAX should work */
3367   r = tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1, &lng2);
3368   tt_int_op(r,OP_EQ, 2);
3369   tt_int_op(lng1,OP_EQ, -2147483647L - 1L);
3370   tt_int_op(lng2,OP_EQ, 2147483647L);
3371 
3372   /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3373   r = tor_sscanf("-2147483649.", "%ld.", &lng1);
3374   tt_int_op(r,OP_EQ, 0);
3375 
3376   r = tor_sscanf("2147483648.", "%ld.", &lng1);
3377   tt_int_op(r,OP_EQ, 0);
3378 
3379   /* and the first failure stops further processing */
3380   r = tor_sscanf("-2147483648. 2147483648.",
3381                  "%ld. %ld.", &lng1, &lng2);
3382   tt_int_op(r,OP_EQ, 1);
3383 
3384   r = tor_sscanf("-2147483649. 2147483647.",
3385                  "%ld. %ld.", &lng1, &lng2);
3386   tt_int_op(r,OP_EQ, 0);
3387 
3388   r = tor_sscanf("2147483648. -2147483649.",
3389                  "%ld. %ld.", &lng1, &lng2);
3390   tt_int_op(r,OP_EQ, 0);
3391 #elif SIZEOF_LONG == 8
3392   /* %lu */
3393   /* UINT64_MAX should work */
3394   tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551615", "%lu", &ulng));
3395   tt_int_op(18446744073709551615UL,OP_EQ, ulng);
3396 
3397   /* But UINT64_MAX + 1 shouldn't work */
3398   tt_int_op(0,OP_EQ, tor_sscanf("18446744073709551616", "%lu", &ulng));
3399   /* but parsing only 19... */
3400   tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551616", "%19lu", &ulng));
3401   tt_int_op(1844674407370955161UL,OP_EQ, ulng);
3402 
3403   /* %lx */
3404   /* UINT64_MAX should work */
3405   tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng));
3406   tt_int_op(0xFFFFFFFFFFFFFFFFUL,OP_EQ, ulng);
3407 
3408   /* But UINT64_MAX + 1 shouldn't work */
3409   tt_int_op(0,OP_EQ, tor_sscanf("10000000000000000", "%lx", &ulng));
3410 
3411   /* %ld */
3412   /* INT64_MIN and INT64_MAX should work */
3413   r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
3414                  "%ld. %ld.", &lng1, &lng2);
3415   tt_int_op(r,OP_EQ, 2);
3416   tt_int_op(lng1,OP_EQ, -9223372036854775807L - 1L);
3417   tt_int_op(lng2,OP_EQ, 9223372036854775807L);
3418 
3419   /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3420   r = tor_sscanf("-9223372036854775809.", "%ld.", &lng1);
3421   tt_int_op(r,OP_EQ, 0);
3422 
3423   r = tor_sscanf("9223372036854775808.", "%ld.", &lng1);
3424   tt_int_op(r,OP_EQ, 0);
3425 
3426   /* and the first failure stops further processing */
3427   r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
3428                  "%ld. %ld.", &lng1, &lng2);
3429   tt_int_op(r,OP_EQ, 1);
3430 
3431   r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
3432                  "%ld. %ld.", &lng1, &lng2);
3433   tt_int_op(r,OP_EQ, 0);
3434 
3435   r = tor_sscanf("9223372036854775808. -9223372036854775809.",
3436                  "%ld. %ld.", &lng1, &lng2);
3437   tt_int_op(r,OP_EQ, 0);
3438 #endif /* SIZEOF_LONG == 4 || ... */
3439 
3440   r = tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
3441                  "%lf %lf %lf %lf", &d1,&d2,&d3,&d4);
3442   tt_int_op(r,OP_EQ, 4);
3443   test_feq(d1, 123.456);
3444   test_feq(d2, .000007);
3445   test_feq(d3, -900123123.2000787);
3446   test_feq(d4, 3.2);
3447 
3448   /* missing float */
3449   r = tor_sscanf("3 ", "%d %lf", &int1, &d1);
3450   tt_int_op(r, OP_EQ, 1);
3451   tt_int_op(int1, OP_EQ, 3);
3452 
3453   /* not a float */
3454   r = tor_sscanf("999 notafloat", "%d %lf", &int1, &d1);
3455   tt_int_op(r, OP_EQ, 1);
3456   tt_int_op(int1, OP_EQ, 999);
3457 
3458   /* %s but no buffer. */
3459   char *nullbuf = NULL;
3460   r = tor_sscanf("hello", "%3s", nullbuf);
3461   tt_int_op(r, OP_EQ, 0);
3462 
3463  done:
3464   tor_free(huge);
3465 }
3466 
3467 #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
3468 #define tt_ci_char_op(a,op,b) \
3469   tt_char_op(TOR_TOLOWER((int)a),op,TOR_TOLOWER((int)b))
3470 
3471 #ifndef HAVE_STRNLEN
3472 static size_t
strnlen(const char * s,size_t len)3473 strnlen(const char *s, size_t len)
3474 {
3475   const char *p = memchr(s, 0, len);
3476   if (!p)
3477     return len;
3478   return p - s;
3479 }
3480 #endif /* !defined(HAVE_STRNLEN) */
3481 
3482 static void
test_util_format_time_interval(void * arg)3483 test_util_format_time_interval(void *arg)
3484 {
3485   /* use the same sized buffer and integers as tor uses */
3486 #define DBUF_SIZE 64
3487   char dbuf[DBUF_SIZE];
3488 #define T_        "%ld"
3489   long sec, min, hour, day;
3490 
3491   /* we don't care about the exact spelling of the
3492    * second(s), minute(s), hour(s), day(s) labels */
3493 #define LABEL_SIZE 21
3494 #define L_        "%20s"
3495   char label_s[LABEL_SIZE];
3496   char label_m[LABEL_SIZE];
3497   char label_h[LABEL_SIZE];
3498   char label_d[LABEL_SIZE];
3499 
3500 #define TL_       T_ " " L_
3501 
3502   int r;
3503 
3504   (void)arg;
3505 
3506   /* In these tests, we're not picky about
3507    * spelling or abbreviations */
3508 
3509   /* seconds: 0, 1, 9, 10, 59 */
3510 
3511   /* ignore exact spelling of "second(s)"*/
3512   format_time_interval(dbuf, sizeof(dbuf), 0);
3513   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3514   r = tor_sscanf(dbuf, TL_, &sec, label_s);
3515   tt_int_op(r,OP_EQ, 2);
3516   tt_ci_char_op(label_s[0],OP_EQ, 's');
3517   tt_int_op(sec,OP_EQ, 0);
3518 
3519   format_time_interval(dbuf, sizeof(dbuf), 1);
3520   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3521   r = tor_sscanf(dbuf, TL_, &sec, label_s);
3522   tt_int_op(r,OP_EQ, 2);
3523   tt_ci_char_op(label_s[0],OP_EQ, 's');
3524   tt_int_op(sec,OP_EQ, 1);
3525 
3526   format_time_interval(dbuf, sizeof(dbuf), 10);
3527   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3528   r = tor_sscanf(dbuf, TL_, &sec, label_s);
3529   tt_int_op(r,OP_EQ, 2);
3530   tt_ci_char_op(label_s[0],OP_EQ, 's');
3531   tt_int_op(sec,OP_EQ, 10);
3532 
3533   format_time_interval(dbuf, sizeof(dbuf), 59);
3534   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3535   r = tor_sscanf(dbuf, TL_, &sec, label_s);
3536   tt_int_op(r,OP_EQ, 2);
3537   tt_ci_char_op(label_s[0],OP_EQ, 's');
3538   tt_int_op(sec,OP_EQ, 59);
3539 
3540   /* negative seconds are reported as their absolute value */
3541 
3542   format_time_interval(dbuf, sizeof(dbuf), -4);
3543   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3544   r = tor_sscanf(dbuf, TL_, &sec, label_s);
3545   tt_int_op(r,OP_EQ, 2);
3546   tt_ci_char_op(label_s[0],OP_EQ, 's');
3547   tt_int_op(sec,OP_EQ, 4);
3548   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3549 
3550   format_time_interval(dbuf, sizeof(dbuf), -32);
3551   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3552   r = tor_sscanf(dbuf, TL_, &sec, label_s);
3553   tt_int_op(r,OP_EQ, 2);
3554   tt_ci_char_op(label_s[0],OP_EQ, 's');
3555   tt_int_op(sec,OP_EQ, 32);
3556   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3557 
3558   /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
3559 
3560   /* ignore trailing "0 second(s)", if present */
3561   format_time_interval(dbuf, sizeof(dbuf), 60);
3562   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3563   r = tor_sscanf(dbuf, TL_, &min, label_m);
3564   tt_int_op(r,OP_EQ, 2);
3565   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3566   tt_int_op(min,OP_EQ, 1);
3567   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3568 
3569   /* ignore exact spelling of "minute(s)," and "second(s)" */
3570   format_time_interval(dbuf, sizeof(dbuf), 60 + 1);
3571   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3572   r = tor_sscanf(dbuf, TL_ " " TL_,
3573                  &min, label_m, &sec, label_s);
3574   tt_int_op(r,OP_EQ, 4);
3575   tt_int_op(min,OP_EQ, 1);
3576   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3577   tt_int_op(sec,OP_EQ, 1);
3578   tt_ci_char_op(label_s[0],OP_EQ, 's');
3579   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3580 
3581   format_time_interval(dbuf, sizeof(dbuf), 60*2 - 1);
3582   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3583   r = tor_sscanf(dbuf, TL_ " " TL_,
3584                  &min, label_m, &sec, label_s);
3585   tt_int_op(r,OP_EQ, 4);
3586   tt_int_op(min,OP_EQ, 1);
3587   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3588   tt_int_op(sec,OP_EQ, 59);
3589   tt_ci_char_op(label_s[0],OP_EQ, 's');
3590 
3591   /* ignore trailing "0 second(s)", if present */
3592   format_time_interval(dbuf, sizeof(dbuf), 60*2);
3593   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3594   r = tor_sscanf(dbuf, TL_, &min, label_m);
3595   tt_int_op(r,OP_EQ, 2);
3596   tt_int_op(min,OP_EQ, 2);
3597   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3598 
3599   /* ignore exact spelling of "minute(s)," and "second(s)" */
3600   format_time_interval(dbuf, sizeof(dbuf), 60*2 + 1);
3601   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3602   r = tor_sscanf(dbuf, TL_ " " TL_,
3603                  &min, label_m, &sec, label_s);
3604   tt_int_op(r,OP_EQ, 4);
3605   tt_int_op(min,OP_EQ, 2);
3606   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3607   tt_int_op(sec,OP_EQ, 1);
3608   tt_ci_char_op(label_s[0],OP_EQ, 's');
3609 
3610   format_time_interval(dbuf, sizeof(dbuf), 60*60 - 1);
3611   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3612   r = tor_sscanf(dbuf, TL_ " " TL_,
3613                  &min, label_m, &sec, label_s);
3614   tt_int_op(r,OP_EQ, 4);
3615   tt_int_op(min,OP_EQ, 59);
3616   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3617   tt_int_op(sec,OP_EQ, 59);
3618   tt_ci_char_op(label_s[0],OP_EQ, 's');
3619 
3620   /* negative minutes are reported as their absolute value */
3621 
3622   /* ignore trailing "0 second(s)", if present */
3623   format_time_interval(dbuf, sizeof(dbuf), -3*60);
3624   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3625   r = tor_sscanf(dbuf, TL_, &min, label_m);
3626   tt_int_op(r,OP_EQ, 2);
3627   tt_int_op(min,OP_EQ, 3);
3628   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3629 
3630   /* ignore exact spelling of "minute(s)," and "second(s)" */
3631   format_time_interval(dbuf, sizeof(dbuf), -96);
3632   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3633   r = tor_sscanf(dbuf, TL_ " " TL_,
3634                  &min, label_m, &sec, label_s);
3635   tt_int_op(r,OP_EQ, 4);
3636   tt_int_op(min,OP_EQ, 1);
3637   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3638   tt_int_op(sec,OP_EQ, 36);
3639   tt_ci_char_op(label_s[0],OP_EQ, 's');
3640 
3641   format_time_interval(dbuf, sizeof(dbuf), -2815);
3642   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3643   r = tor_sscanf(dbuf, TL_ " " TL_,
3644                  &min, label_m, &sec, label_s);
3645   tt_int_op(r,OP_EQ, 4);
3646   tt_int_op(min,OP_EQ, 46);
3647   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3648   tt_int_op(sec,OP_EQ, 55);
3649   tt_ci_char_op(label_s[0],OP_EQ, 's');
3650 
3651   /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
3652   /* always ignore trailing seconds, if present */
3653 
3654   /* ignore trailing "0 minute(s)" etc., if present */
3655   format_time_interval(dbuf, sizeof(dbuf), 60*60);
3656   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3657   r = tor_sscanf(dbuf, TL_, &hour, label_h);
3658   tt_int_op(r,OP_EQ, 2);
3659   tt_int_op(hour,OP_EQ, 1);
3660   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3661 
3662   format_time_interval(dbuf, sizeof(dbuf), 60*60 + 1);
3663   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3664   r = tor_sscanf(dbuf, TL_, &hour, label_h);
3665   tt_int_op(r,OP_EQ, 2);
3666   tt_int_op(hour,OP_EQ, 1);
3667   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3668 
3669   /* ignore exact spelling of "hour(s)," etc. */
3670   format_time_interval(dbuf, sizeof(dbuf), 60*60 + 60);
3671   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3672   r = tor_sscanf(dbuf, TL_ " " TL_,
3673                  &hour, label_h, &min, label_m);
3674   tt_int_op(r,OP_EQ, 4);
3675   tt_int_op(hour,OP_EQ, 1);
3676   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3677   tt_int_op(min,OP_EQ, 1);
3678   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3679 
3680   format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 60);
3681   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3682   r = tor_sscanf(dbuf, TL_ " " TL_,
3683                  &hour, label_h, &min, label_m);
3684   tt_int_op(r,OP_EQ, 4);
3685   tt_int_op(hour,OP_EQ, 23);
3686   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3687   tt_int_op(min,OP_EQ, 59);
3688   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3689 
3690   format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 1);
3691   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3692   r = tor_sscanf(dbuf, TL_ " " TL_,
3693                  &hour, label_h, &min, label_m);
3694   tt_int_op(r,OP_EQ, 4);
3695   tt_int_op(hour,OP_EQ, 23);
3696   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3697   tt_int_op(min,OP_EQ, 59);
3698   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3699 
3700   /* negative hours are reported as their absolute value */
3701 
3702   /* ignore exact spelling of "hour(s)," etc., if present */
3703   format_time_interval(dbuf, sizeof(dbuf), -2*60*60);
3704   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3705   r = tor_sscanf(dbuf, TL_, &hour, label_h);
3706   tt_int_op(r,OP_EQ, 2);
3707   tt_int_op(hour,OP_EQ, 2);
3708   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3709 
3710   format_time_interval(dbuf, sizeof(dbuf), -75804);
3711   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3712   r = tor_sscanf(dbuf, TL_ " " TL_,
3713                  &hour, label_h, &min, label_m);
3714   tt_int_op(r,OP_EQ, 4);
3715   tt_int_op(hour,OP_EQ, 21);
3716   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3717   tt_int_op(min,OP_EQ, 3);
3718   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3719 
3720   /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
3721   /* always ignore trailing seconds, if present */
3722 
3723   /* ignore trailing "0 hours(s)" etc., if present */
3724   format_time_interval(dbuf, sizeof(dbuf), 24*60*60);
3725   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3726   r = tor_sscanf(dbuf, TL_, &day, label_d);
3727   tt_int_op(r,OP_EQ, 2);
3728   tt_int_op(day,OP_EQ, 1);
3729   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3730 
3731   format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 1);
3732   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3733   r = tor_sscanf(dbuf, TL_, &day, label_d);
3734   tt_int_op(r,OP_EQ, 2);
3735   tt_int_op(day,OP_EQ, 1);
3736   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3737 
3738   /* ignore exact spelling of "days(s)," etc. */
3739   format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60);
3740   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3741   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3742                  &day, label_d, &hour, label_h, &min, label_m);
3743   if (r == -1) {
3744     /* ignore 0 hours(s), if present */
3745     r = tor_sscanf(dbuf, TL_ " " TL_,
3746                    &day, label_d, &min, label_m);
3747   }
3748   tt_assert(r == 4 || r == 6);
3749   tt_int_op(day,OP_EQ, 1);
3750   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3751   if (r == 6) {
3752     tt_int_op(hour,OP_EQ, 0);
3753     tt_ci_char_op(label_h[0],OP_EQ, 'h');
3754   }
3755   tt_int_op(min,OP_EQ, 1);
3756   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3757 
3758   /* ignore trailing "0 minutes(s)" etc., if present */
3759   format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60*60);
3760   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3761   r = tor_sscanf(dbuf, TL_ " " TL_,
3762                  &day, label_d, &hour, label_h);
3763   tt_int_op(r,OP_EQ, 4);
3764   tt_int_op(day,OP_EQ, 1);
3765   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3766   tt_int_op(hour,OP_EQ, 1);
3767   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3768 
3769   /* negative days are reported as their absolute value */
3770 
3771   format_time_interval(dbuf, sizeof(dbuf), -21936184);
3772   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3773   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3774                  &day, label_d, &hour, label_h, &min, label_m);
3775   tt_int_op(r,OP_EQ, 6);
3776   tt_int_op(day,OP_EQ, 253);
3777   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3778   tt_int_op(hour,OP_EQ, 21);
3779   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3780   tt_int_op(min,OP_EQ, 23);
3781   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3782 
3783   /* periods > 1 year are reported in days (warn?) */
3784 
3785   /* ignore exact spelling of "days(s)," etc., if present */
3786   format_time_interval(dbuf, sizeof(dbuf), 758635154);
3787   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3788   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3789                  &day, label_d, &hour, label_h, &min, label_m);
3790   tt_int_op(r,OP_EQ, 6);
3791   tt_int_op(day,OP_EQ, 8780);
3792   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3793   tt_int_op(hour,OP_EQ, 11);
3794   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3795   tt_int_op(min,OP_EQ, 59);
3796   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3797 
3798   /* negative periods > 1 year are reported in days (warn?) */
3799 
3800   format_time_interval(dbuf, sizeof(dbuf), -1427014922);
3801   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3802   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3803                  &day, label_d, &hour, label_h, &min, label_m);
3804   tt_int_op(r,OP_EQ, 6);
3805   tt_int_op(day,OP_EQ, 16516);
3806   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3807   tt_int_op(hour,OP_EQ, 9);
3808   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3809   tt_int_op(min,OP_EQ, 2);
3810   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3811 
3812 #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
3813 
3814   /* We can try INT32_MIN/MAX */
3815   /* Always ignore second(s) */
3816 
3817   /* INT32_MAX */
3818   format_time_interval(dbuf, sizeof(dbuf), 2147483647);
3819   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3820   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3821                  &day, label_d, &hour, label_h, &min, label_m);
3822   tt_int_op(r,OP_EQ, 6);
3823   tt_int_op(day,OP_EQ, 24855);
3824   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3825   tt_int_op(hour,OP_EQ, 3);
3826   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3827   tt_int_op(min,OP_EQ, 14);
3828   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3829   /* and 7 seconds - ignored */
3830 
3831   /* INT32_MIN: check that we get the absolute value of interval,
3832    * which doesn't actually fit in int32_t.
3833    * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
3834   format_time_interval(dbuf, sizeof(dbuf), -2147483647L - 1L);
3835   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3836   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3837                  &day, label_d, &hour, label_h, &min, label_m);
3838   tt_int_op(r,OP_EQ, 6);
3839   tt_int_op(day,OP_EQ, 24855);
3840   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3841   tt_int_op(hour,OP_EQ, 3);
3842   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3843   tt_int_op(min,OP_EQ, 14);
3844   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3845   /* and 7 or 8 seconds - ignored */
3846 
3847 #endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */
3848 
3849 #if SIZEOF_LONG == 8
3850 
3851   /* We can try INT64_MIN/MAX */
3852   /* Always ignore second(s) */
3853 
3854   /* INT64_MAX */
3855   format_time_interval(dbuf, sizeof(dbuf), 9223372036854775807L);
3856   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3857   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3858                  &day, label_d, &hour, label_h, &min, label_m);
3859   tt_int_op(r,OP_EQ, 6);
3860   tt_int_op(day,OP_EQ, 106751991167300L);
3861   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3862   tt_int_op(hour,OP_EQ, 15);
3863   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3864   tt_int_op(min,OP_EQ, 30);
3865   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3866   /* and 7 seconds - ignored */
3867 
3868   /* INT64_MIN: check that we get the absolute value of interval,
3869    * which doesn't actually fit in int64_t.
3870    * We expect INT64_MAX */
3871   format_time_interval(dbuf, sizeof(dbuf),
3872                        -9223372036854775807L - 1L);
3873   tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
3874   r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
3875                  &day, label_d, &hour, label_h, &min, label_m);
3876   tt_int_op(r,OP_EQ, 6);
3877   tt_int_op(day,OP_EQ, 106751991167300L);
3878   tt_ci_char_op(label_d[0],OP_EQ, 'd');
3879   tt_int_op(hour,OP_EQ, 15);
3880   tt_ci_char_op(label_h[0],OP_EQ, 'h');
3881   tt_int_op(min,OP_EQ, 30);
3882   tt_ci_char_op(label_m[0],OP_EQ, 'm');
3883   /* and 7 or 8 seconds - ignored */
3884 
3885 #endif /* SIZEOF_LONG == 8 */
3886 
3887  done:
3888   ;
3889 }
3890 
3891 #undef tt_char_op
3892 #undef tt_ci_char_op
3893 #undef DBUF_SIZE
3894 #undef T_
3895 #undef LABEL_SIZE
3896 #undef L_
3897 #undef TL_
3898 
3899 static void
test_util_path_is_relative(void * arg)3900 test_util_path_is_relative(void *arg)
3901 {
3902   /* OS-independent tests */
3903   (void)arg;
3904   tt_int_op(1,OP_EQ, path_is_relative(""));
3905   tt_int_op(1,OP_EQ, path_is_relative("dir"));
3906   tt_int_op(1,OP_EQ, path_is_relative("dir/"));
3907   tt_int_op(1,OP_EQ, path_is_relative("./dir"));
3908   tt_int_op(1,OP_EQ, path_is_relative("../dir"));
3909 
3910   tt_int_op(0,OP_EQ, path_is_relative("/"));
3911   tt_int_op(0,OP_EQ, path_is_relative("/dir"));
3912   tt_int_op(0,OP_EQ, path_is_relative("/dir/"));
3913 
3914   /* Windows */
3915 #ifdef _WIN32
3916   /* I don't have Windows so I can't test this, hence the "#ifdef
3917      0". These are tests that look useful, so please try to get them
3918      running and uncomment if it all works as it should */
3919   tt_int_op(1,OP_EQ, path_is_relative("dir"));
3920   tt_int_op(1,OP_EQ, path_is_relative("dir\\"));
3921   tt_int_op(1,OP_EQ, path_is_relative("dir\\a:"));
3922   tt_int_op(1,OP_EQ, path_is_relative("dir\\a:\\"));
3923   tt_int_op(1,OP_EQ, path_is_relative("http:\\dir"));
3924 
3925   tt_int_op(0,OP_EQ, path_is_relative("\\dir"));
3926   tt_int_op(0,OP_EQ, path_is_relative("a:\\dir"));
3927   tt_int_op(0,OP_EQ, path_is_relative("z:\\dir"));
3928 #endif /* defined(_WIN32) */
3929 
3930  done:
3931   ;
3932 }
3933 
3934 /** Run unittests for memory area allocator */
3935 static void
test_util_memarea(void * arg)3936 test_util_memarea(void *arg)
3937 {
3938   memarea_t *area = memarea_new();
3939   char *p1, *p2, *p3, *p1_orig;
3940   void *malloced_ptr = NULL;
3941   int i;
3942 
3943 #ifdef DISABLE_MEMORY_SENTINELS
3944   /* If memory sentinels are disabled, this whole module is just an alias for
3945      malloc(), which is free to lay out memory most any way it wants. */
3946   if (1)
3947     tt_skip();
3948 #endif /* defined(DISABLE_MEMORY_SENTINELS) */
3949 
3950   (void)arg;
3951   tt_assert(area);
3952 
3953   p1_orig = p1 = memarea_alloc(area,64);
3954   p2 = memarea_alloc_zero(area,52);
3955   p3 = memarea_alloc(area,11);
3956 
3957   tt_assert(memarea_owns_ptr(area, p1));
3958   tt_assert(memarea_owns_ptr(area, p2));
3959   tt_assert(memarea_owns_ptr(area, p3));
3960   /* Make sure we left enough space. */
3961   tt_assert(p1+64 <= p2);
3962   tt_assert(p2+52 <= p3);
3963   /* Make sure we aligned. */
3964   tt_int_op(((uintptr_t)p1) % sizeof(void*),OP_EQ, 0);
3965   tt_int_op(((uintptr_t)p2) % sizeof(void*),OP_EQ, 0);
3966   tt_int_op(((uintptr_t)p3) % sizeof(void*),OP_EQ, 0);
3967   tt_assert(!memarea_owns_ptr(area, p3+8192));
3968   tt_assert(!memarea_owns_ptr(area, p3+30));
3969   tt_assert(fast_mem_is_zero(p2, 52));
3970   /* Make sure we don't overalign. */
3971   p1 = memarea_alloc(area, 1);
3972   p2 = memarea_alloc(area, 1);
3973   tt_ptr_op(p1+sizeof(void*),OP_EQ, p2);
3974   {
3975     malloced_ptr = tor_malloc(64);
3976     tt_assert(!memarea_owns_ptr(area, malloced_ptr));
3977     tor_free(malloced_ptr);
3978   }
3979 
3980   /* memarea_memdup */
3981   {
3982     malloced_ptr = tor_malloc(64);
3983     crypto_rand((char*)malloced_ptr, 64);
3984     p1 = memarea_memdup(area, malloced_ptr, 64);
3985     tt_assert(p1 != malloced_ptr);
3986     tt_mem_op(p1,OP_EQ, malloced_ptr, 64);
3987     tor_free(malloced_ptr);
3988   }
3989 
3990   /* memarea_strdup. */
3991   p1 = memarea_strdup(area,"");
3992   p2 = memarea_strdup(area, "abcd");
3993   tt_assert(p1);
3994   tt_assert(p2);
3995   tt_str_op(p1,OP_EQ, "");
3996   tt_str_op(p2,OP_EQ, "abcd");
3997 
3998   /* memarea_strndup. */
3999   {
4000     const char *s = "Ad ogni porta batte la morte e grida: il nome!";
4001     /* (From Turandot, act 3.) */
4002     size_t len = strlen(s);
4003     p1 = memarea_strndup(area, s, 1000);
4004     p2 = memarea_strndup(area, s, 10);
4005     tt_str_op(p1,OP_EQ, s);
4006     tt_assert(p2 >= p1 + len + 1);
4007     tt_mem_op(s,OP_EQ, p2, 10);
4008     tt_int_op(p2[10],OP_EQ, '\0');
4009     p3 = memarea_strndup(area, s, len);
4010     tt_str_op(p3,OP_EQ, s);
4011     p3 = memarea_strndup(area, s, len-1);
4012     tt_mem_op(s,OP_EQ, p3, len-1);
4013     tt_int_op(p3[len-1],OP_EQ, '\0');
4014   }
4015 
4016   memarea_clear(area);
4017   p1 = memarea_alloc(area, 1);
4018   tt_ptr_op(p1,OP_EQ, p1_orig);
4019   memarea_clear(area);
4020   size_t total = 0, initial_allocation, allocation2, dummy;
4021   memarea_get_stats(area, &initial_allocation, &dummy);
4022 
4023   /* Check for running over an area's size. */
4024   for (i = 0; i < 4096; ++i) {
4025     size_t n = crypto_rand_int(6);
4026     p1 = memarea_alloc(area, n);
4027     total += n;
4028     tt_assert(memarea_owns_ptr(area, p1));
4029   }
4030   memarea_assert_ok(area);
4031   memarea_get_stats(area, &allocation2, &dummy);
4032   /* Make sure we can allocate a too-big object. */
4033   p1 = memarea_alloc_zero(area, 9000);
4034   p2 = memarea_alloc_zero(area, 16);
4035   total += 9000;
4036   total += 16;
4037   tt_assert(memarea_owns_ptr(area, p1));
4038   tt_assert(memarea_owns_ptr(area, p2));
4039 
4040   /* Now test stats... */
4041   size_t allocated = 0, used = 0;
4042   memarea_get_stats(area, &allocated, &used);
4043   tt_int_op(used, OP_LE, allocated);
4044   tt_int_op(used, OP_GE, total); /* not EQ, because of alignment and headers*/
4045   tt_int_op(allocated, OP_GT, allocation2);
4046 
4047   tt_int_op(allocation2, OP_GT, initial_allocation);
4048 
4049   memarea_clear(area);
4050   memarea_get_stats(area, &allocated, &used);
4051   tt_int_op(used, OP_LT, 128); /* Not 0, because of header */
4052   tt_int_op(allocated, OP_EQ, initial_allocation);
4053 
4054  done:
4055   memarea_drop_all(area);
4056   tor_free(malloced_ptr);
4057 }
4058 
4059 /** Run unit tests for utility functions to get file names relative to
4060  * the data directory. */
4061 static void
test_util_datadir(void * arg)4062 test_util_datadir(void *arg)
4063 {
4064   char buf[1024];
4065   char *f = NULL;
4066   char *temp_dir = NULL;
4067 
4068   (void)arg;
4069   temp_dir = get_datadir_fname(NULL);
4070   f = get_datadir_fname("state");
4071   tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
4072   tt_str_op(f,OP_EQ, buf);
4073   tor_free(f);
4074   f = get_datadir_fname2("cache", "thingy");
4075   tor_snprintf(buf, sizeof(buf),
4076                "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
4077   tt_str_op(f,OP_EQ, buf);
4078   tor_free(f);
4079   f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
4080   tor_snprintf(buf, sizeof(buf),
4081                "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
4082   tt_str_op(f,OP_EQ, buf);
4083   tor_free(f);
4084   f = get_datadir_fname_suffix("cache", ".foo");
4085   tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
4086                temp_dir);
4087   tt_str_op(f,OP_EQ, buf);
4088 
4089  done:
4090   tor_free(f);
4091   tor_free(temp_dir);
4092 }
4093 
4094 static void
test_util_strtok(void * arg)4095 test_util_strtok(void *arg)
4096 {
4097   char buf[128];
4098   char buf2[128];
4099   int i;
4100   char *cp1, *cp2;
4101 
4102   (void)arg;
4103   for (i = 0; i < 3; i++) {
4104     const char *pad1="", *pad2="";
4105     switch (i) {
4106     case 0:
4107       break;
4108     case 1:
4109       pad1 = " ";
4110       pad2 = "!";
4111       break;
4112     case 2:
4113       pad1 = "  ";
4114       pad2 = ";!";
4115       break;
4116     }
4117     tor_snprintf(buf, sizeof(buf), "%s", pad1);
4118     tor_snprintf(buf2, sizeof(buf2), "%s", pad2);
4119     tt_ptr_op(tor_strtok_r_impl(buf, " ", &cp1), OP_EQ, NULL);
4120     tt_ptr_op(tor_strtok_r_impl(buf2, ".!..;!", &cp2), OP_EQ, NULL);
4121 
4122     tor_snprintf(buf, sizeof(buf),
4123                  "%sGraved on the dark  in gestures of descent%s", pad1, pad1);
4124     tor_snprintf(buf2, sizeof(buf2),
4125                 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2);
4126     /*  -- "Year's End", Richard Wilbur */
4127 
4128     tt_str_op("Graved",OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
4129     tt_str_op("they",OP_EQ, tor_strtok_r_impl(buf2, ".!..;!", &cp2));
4130 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
4131 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
4132     tt_str_op("on",OP_EQ, S1());
4133     tt_str_op("the",OP_EQ, S1());
4134     tt_str_op("dark",OP_EQ, S1());
4135     tt_str_op("seemed",OP_EQ, S2());
4136     tt_str_op("their",OP_EQ, S2());
4137     tt_str_op("own",OP_EQ, S2());
4138     tt_str_op("in",OP_EQ, S1());
4139     tt_str_op("gestures",OP_EQ, S1());
4140     tt_str_op("of",OP_EQ, S1());
4141     tt_str_op("most",OP_EQ, S2());
4142     tt_str_op("perfect",OP_EQ, S2());
4143     tt_str_op("descent",OP_EQ, S1());
4144     tt_str_op("monument",OP_EQ, S2());
4145     tt_ptr_op(NULL,OP_EQ, S1());
4146     tt_ptr_op(NULL,OP_EQ, S2());
4147   }
4148 
4149   buf[0] = 0;
4150   tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
4151   tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, "!", &cp1));
4152 
4153   strlcpy(buf, "Howdy!", sizeof(buf));
4154   tt_str_op("Howdy",OP_EQ, tor_strtok_r_impl(buf, "!", &cp1));
4155   tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(NULL, "!", &cp1));
4156 
4157   strlcpy(buf, " ", sizeof(buf));
4158   tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
4159   strlcpy(buf, "  ", sizeof(buf));
4160   tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
4161 
4162   strlcpy(buf, "something  ", sizeof(buf));
4163   tt_str_op("something",OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
4164   tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(NULL, ";", &cp1));
4165  done:
4166   ;
4167 }
4168 
4169 static void
test_util_find_str_at_start_of_line(void * ptr)4170 test_util_find_str_at_start_of_line(void *ptr)
4171 {
4172   const char *long_string =
4173     "howdy world. how are you? i hope it's fine.\n"
4174     "hello kitty\n"
4175     "third line";
4176   char *line2 = strchr(long_string,'\n')+1;
4177   char *line3 = strchr(line2,'\n')+1;
4178   const char *short_string = "hello kitty\n"
4179     "second line\n";
4180   char *short_line2 = strchr(short_string,'\n')+1;
4181 
4182   (void)ptr;
4183 
4184   tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, ""));
4185   tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(short_string, "nonsense"));
4186   tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "nonsense"));
4187   tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "\n"));
4188   tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "how "));
4189   tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "kitty"));
4190   tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, "h"));
4191   tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, "how"));
4192   tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "he"));
4193   tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "hell"));
4194   tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "hello k"));
4195   tt_ptr_op(line2,OP_EQ,
4196             find_str_at_start_of_line(long_string, "hello kitty\n"));
4197   tt_ptr_op(line2,OP_EQ,
4198             find_str_at_start_of_line(long_string, "hello kitty\nt"));
4199   tt_ptr_op(line3,OP_EQ, find_str_at_start_of_line(long_string, "third"));
4200   tt_ptr_op(line3,OP_EQ, find_str_at_start_of_line(long_string, "third line"));
4201   tt_ptr_op(NULL, OP_EQ,
4202             find_str_at_start_of_line(long_string, "third line\n"));
4203   tt_ptr_op(short_line2,OP_EQ, find_str_at_start_of_line(short_string,
4204                                                      "second line\n"));
4205  done:
4206   ;
4207 }
4208 
4209 static void
test_util_tor_strreplacechar(void * ptr)4210 test_util_tor_strreplacechar(void *ptr)
4211 {
4212   (void)ptr;
4213   char empty[] = "";
4214   char not_contain[] = "bbb";
4215   char contains[] = "bab";
4216   char contains_all[] = "aaa";
4217 
4218   tor_strreplacechar(empty, 'a', 'b');
4219   tt_str_op(empty, OP_EQ, "");
4220 
4221   tor_strreplacechar(not_contain, 'a', 'b');
4222   tt_str_op(not_contain, OP_EQ, "bbb");
4223 
4224   tor_strreplacechar(contains, 'a', 'b');
4225   tt_str_op(contains, OP_EQ, "bbb");
4226 
4227   tor_strreplacechar(contains_all, 'a', 'b');
4228   tt_str_op(contains_all, OP_EQ, "bbb");
4229 
4230  done:
4231   ;
4232 }
4233 
4234 static void
test_util_string_is_C_identifier(void * ptr)4235 test_util_string_is_C_identifier(void *ptr)
4236 {
4237   (void)ptr;
4238 
4239   tt_int_op(1,OP_EQ, string_is_C_identifier("string_is_C_identifier"));
4240   tt_int_op(1,OP_EQ, string_is_C_identifier("_string_is_C_identifier"));
4241   tt_int_op(1,OP_EQ, string_is_C_identifier("_"));
4242   tt_int_op(1,OP_EQ, string_is_C_identifier("i"));
4243   tt_int_op(1,OP_EQ, string_is_C_identifier("_____"));
4244   tt_int_op(1,OP_EQ, string_is_C_identifier("__00__"));
4245   tt_int_op(1,OP_EQ, string_is_C_identifier("__init__"));
4246   tt_int_op(1,OP_EQ, string_is_C_identifier("_0"));
4247   tt_int_op(1,OP_EQ, string_is_C_identifier("_0string_is_C_identifier"));
4248   tt_int_op(1,OP_EQ, string_is_C_identifier("_0"));
4249 
4250   tt_int_op(0,OP_EQ, string_is_C_identifier("0_string_is_C_identifier"));
4251   tt_int_op(0,OP_EQ, string_is_C_identifier("0"));
4252   tt_int_op(0,OP_EQ, string_is_C_identifier(""));
4253   tt_int_op(0,OP_EQ, string_is_C_identifier(";"));
4254   tt_int_op(0,OP_EQ, string_is_C_identifier("i;"));
4255   tt_int_op(0,OP_EQ, string_is_C_identifier("_;"));
4256   tt_int_op(0,OP_EQ, string_is_C_identifier("í"));
4257   tt_int_op(0,OP_EQ, string_is_C_identifier("ñ"));
4258 
4259  done:
4260   ;
4261 }
4262 
4263 static void
test_util_string_is_utf8(void * ptr)4264 test_util_string_is_utf8(void *ptr)
4265 {
4266   (void)ptr;
4267 
4268   tt_int_op(1, OP_EQ, string_is_utf8(NULL, 0));
4269   tt_int_op(1, OP_EQ, string_is_utf8("", 1));
4270   tt_int_op(1, OP_EQ, string_is_utf8("\uFEFF", 3));
4271   tt_int_op(1, OP_EQ, string_is_utf8("\uFFFE", 3));
4272   tt_int_op(1, OP_EQ, string_is_utf8("ascii\x7f\n", 7));
4273   tt_int_op(1, OP_EQ, string_is_utf8("Risqu\u00e9=1", 9));
4274 
4275   /* Test the utf8_no_bom function */
4276   tt_int_op(0, OP_EQ, string_is_utf8_no_bom("\uFEFF", 3));
4277   tt_int_op(0, OP_EQ, string_is_utf8_no_bom("\uFFFE", 3));
4278   tt_int_op(0, OP_EQ, string_is_utf8_no_bom("\uFEFFlove", 7));
4279   tt_int_op(1, OP_EQ, string_is_utf8_no_bom("loveandrespect",
4280                                             strlen("loveandrespect")));
4281 
4282   // Validate exactly 'len' bytes.
4283   tt_int_op(0, OP_EQ, string_is_utf8("\0\x80", 2));
4284   tt_int_op(0, OP_EQ, string_is_utf8("Risqu\u00e9=1", 6));
4285 
4286   // Reject sequences with missing bytes.
4287   tt_int_op(0, OP_EQ, string_is_utf8("\x80", 1));
4288   tt_int_op(0, OP_EQ, string_is_utf8("\xc2", 1));
4289   tt_int_op(0, OP_EQ, string_is_utf8("\xc2 ", 2));
4290   tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80", 2));
4291   tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80 ", 3));
4292   tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80", 3));
4293   tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80 ", 4));
4294 
4295   // Reject encodings that are overly long.
4296   tt_int_op(0, OP_EQ, string_is_utf8("\xc1\xbf", 2));
4297   tt_int_op(1, OP_EQ, string_is_utf8("\xc2\x80", 2));
4298   tt_int_op(0, OP_EQ, string_is_utf8("\xe0\x9f\xbf", 3));
4299   tt_int_op(1, OP_EQ, string_is_utf8("\xe0\xa0\x80", 3));
4300   tt_int_op(0, OP_EQ, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
4301   tt_int_op(1, OP_EQ, string_is_utf8("\xf0\x90\x80\x80", 4));
4302 
4303   // Reject UTF-16 surrogate halves.
4304   tt_int_op(1, OP_EQ, string_is_utf8("\xed\x9f\xbf", 3));
4305   tt_int_op(0, OP_EQ, string_is_utf8("\xed\xa0\x80", 3));
4306   tt_int_op(0, OP_EQ, string_is_utf8("\xed\xbf\xbf", 3));
4307   tt_int_op(1, OP_EQ, string_is_utf8("\xee\x80\x80", 3));
4308 
4309   // The minimum legal codepoint, 0x00.
4310   tt_int_op(1, OP_EQ, string_is_utf8("\0", 1));
4311 
4312   // The maximum legal codepoint, 0x10FFFF.
4313   tt_int_op(1, OP_EQ, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
4314   tt_int_op(0, OP_EQ, string_is_utf8("\xf4\x90\x80\x80", 4));
4315 
4316   /* Test cases that vary between programming languages /
4317    * UTF-8 implementations.
4318    * Source: POC||GTFO 19, page 43
4319    * https://www.alchemistowl.org/pocorgtfo/
4320    */
4321 
4322   // Invalid (in most implementations)
4323   // surrogate
4324   tt_int_op(0, OP_EQ, string_is_utf8("\xed\xa0\x81", 3));
4325   // nullsurrog
4326   tt_int_op(0, OP_EQ, string_is_utf8("\x30\x00\xed\xa0\x81", 5));
4327   // threehigh
4328   tt_int_op(0, OP_EQ, string_is_utf8("\xed\xbf\xbf", 3));
4329   // fourhigh
4330   tt_int_op(0, OP_EQ, string_is_utf8("\xf4\x90\xbf\xbf", 4));
4331   // fivebyte
4332   tt_int_op(0, OP_EQ, string_is_utf8("\xfb\x80\x80\x80\x80", 5));
4333   // sixbyte
4334   tt_int_op(0, OP_EQ, string_is_utf8("\xfd\x80\x80\x80\x80", 5));
4335   // sixhigh
4336   tt_int_op(0, OP_EQ, string_is_utf8("\xfd\xbf\xbf\xbf\xbf", 5));
4337 
4338   // Valid (in most implementations)
4339   // fourbyte
4340   tt_int_op(1, OP_EQ, string_is_utf8("\xf0\x90\x8d\x88", 4));
4341   // fourbyte2
4342   tt_int_op(1, OP_EQ, string_is_utf8("\xf0\xbf\xbf\xbf", 4));
4343   // nullbyte
4344   tt_int_op(1, OP_EQ, string_is_utf8("\x30\x31\x32\x00\x33", 5));
4345 
4346  done:
4347   ;
4348 }
4349 
4350 static void
test_util_asprintf(void * ptr)4351 test_util_asprintf(void *ptr)
4352 {
4353 #define LOREMIPSUM                                              \
4354   "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
4355   char *cp=NULL, *cp2=NULL;
4356   int r;
4357   (void)ptr;
4358 
4359   /* simple string */
4360   r = tor_asprintf(&cp, "simple string 100%% safe");
4361   tt_assert(cp);
4362   tt_str_op("simple string 100% safe",OP_EQ, cp);
4363   tt_int_op(strlen(cp),OP_EQ, r);
4364   tor_free(cp);
4365 
4366   /* empty string */
4367   r = tor_asprintf(&cp, "%s", "");
4368   tt_assert(cp);
4369   tt_str_op("",OP_EQ, cp);
4370   tt_int_op(strlen(cp),OP_EQ, r);
4371   tor_free(cp);
4372 
4373   /* numbers (%i) */
4374   r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2);
4375   tt_assert(cp);
4376   tt_str_op("I like numbers--1, 2, etc.",OP_EQ, cp);
4377   tt_int_op(strlen(cp),OP_EQ, r);
4378   /* don't free cp; next test uses it. */
4379 
4380   /* numbers (%d) */
4381   r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
4382   tt_assert(cp2);
4383   tt_int_op(strlen(cp2),OP_EQ, r);
4384   tt_str_op("First=101, Second=202",OP_EQ, cp2);
4385   tt_assert(cp != cp2);
4386   tor_free(cp);
4387   tor_free(cp2);
4388 
4389   /* Glass-box test: a string exactly 128 characters long. */
4390   r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM);
4391   tt_assert(cp);
4392   tt_int_op(128,OP_EQ, r);
4393   tt_int_op(cp[128], OP_EQ, '\0');
4394   tt_str_op("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM,OP_EQ, cp);
4395   tor_free(cp);
4396 
4397   /* String longer than 128 characters */
4398   r = tor_asprintf(&cp, "1: %s 2: %s 3: %s",
4399                    LOREMIPSUM, LOREMIPSUM, LOREMIPSUM);
4400   tt_assert(cp);
4401   tt_int_op(strlen(cp),OP_EQ, r);
4402   tt_str_op("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM,OP_EQ, cp);
4403 
4404  done:
4405   tor_free(cp);
4406   tor_free(cp2);
4407 }
4408 
4409 static void
test_util_listdir(void * ptr)4410 test_util_listdir(void *ptr)
4411 {
4412   smartlist_t *dir_contents = NULL;
4413   char *fname1=NULL, *fname2=NULL, *fname3=NULL, *dir1=NULL, *dirname=NULL;
4414   int r;
4415   (void)ptr;
4416 
4417   fname1 = tor_strdup(get_fname("hopscotch"));
4418   fname2 = tor_strdup(get_fname("mumblety-peg"));
4419   fname3 = tor_strdup(get_fname(".hidden-file"));
4420   dir1   = tor_strdup(get_fname("some-directory"));
4421   dirname = tor_strdup(get_fname(NULL));
4422 
4423   tt_int_op(0,OP_EQ, write_str_to_file(fname1, "X\n", 0));
4424   tt_int_op(0,OP_EQ, write_str_to_file(fname2, "Y\n", 0));
4425   tt_int_op(0,OP_EQ, write_str_to_file(fname3, "Z\n", 0));
4426 #ifdef _WIN32
4427   r = mkdir(dir1);
4428 #else
4429   r = mkdir(dir1, 0700);
4430 #endif
4431   if (r) {
4432     fprintf(stderr, "Can't create directory %s:", dir1);
4433     perror("");
4434     exit(1);
4435   }
4436 
4437   dir_contents = tor_listdir(dirname);
4438   tt_assert(dir_contents);
4439   /* make sure that each filename is listed. */
4440   tt_assert(smartlist_contains_string_case(dir_contents, "hopscotch"));
4441   tt_assert(smartlist_contains_string_case(dir_contents, "mumblety-peg"));
4442   tt_assert(smartlist_contains_string_case(dir_contents, ".hidden-file"));
4443   tt_assert(smartlist_contains_string_case(dir_contents, "some-directory"));
4444 
4445   tt_assert(!smartlist_contains_string(dir_contents, "."));
4446   tt_assert(!smartlist_contains_string(dir_contents, ".."));
4447 
4448  done:
4449   tor_free(fname1);
4450   tor_free(fname2);
4451   tor_free(fname3);
4452   tor_free(dir1);
4453   tor_free(dirname);
4454   if (dir_contents) {
4455     SMARTLIST_FOREACH(dir_contents, char *, cp, tor_free(cp));
4456     smartlist_free(dir_contents);
4457   }
4458 }
4459 
4460 static void
test_util_glob(void * ptr)4461 test_util_glob(void *ptr)
4462 {
4463   (void)ptr;
4464 
4465 #ifdef HAVE_GLOB
4466   smartlist_t *results = NULL;
4467   int r, i;
4468   char *dir1 = NULL, *dir2 = NULL, *forbidden = NULL, *dirname = NULL;
4469   char *expected = NULL, *pattern = NULL;
4470   // used for cleanup
4471   char *dir1_forbidden = NULL, *dir2_forbidden = NULL;
4472   char *forbidden_forbidden = NULL;
4473 
4474   dirname = tor_strdup(get_fname("test_glob"));
4475   tt_ptr_op(dirname, OP_NE, NULL);
4476 
4477 #ifdef _WIN32
4478   r = mkdir(dirname);
4479 #else
4480   r = mkdir(dirname, 0700);
4481 #endif
4482   if (r) {
4483     fprintf(stderr, "Can't create directory %s:", dirname);
4484     perror("");
4485     exit(1);
4486   }
4487 
4488   tt_int_op(0, OP_EQ, create_test_directory_structure(dirname));
4489   tor_asprintf(&dir1, "%s"PATH_SEPARATOR"dir1", dirname);
4490   tor_asprintf(&dir1_forbidden,
4491                "%s"PATH_SEPARATOR"dir1"PATH_SEPARATOR"forbidden", dirname);
4492   tt_int_op(0, OP_EQ, create_test_directory_structure(dir1));
4493   tor_asprintf(&dir2, "%s"PATH_SEPARATOR"dir2", dirname);
4494   tor_asprintf(&dir2_forbidden,
4495                "%s"PATH_SEPARATOR"dir2"PATH_SEPARATOR"forbidden", dirname);
4496   tt_int_op(0, OP_EQ, create_test_directory_structure(dir2));
4497   tor_asprintf(&forbidden, "%s"PATH_SEPARATOR"forbidden", dirname);
4498   tor_asprintf(&forbidden_forbidden,
4499                "%s"PATH_SEPARATOR"forbidden"PATH_SEPARATOR"forbidden",dirname);
4500 #ifndef _WIN32
4501   tt_int_op(0, OP_EQ, chmod(forbidden, 0700));
4502 #endif
4503   tt_int_op(0, OP_EQ, create_test_directory_structure(forbidden));
4504 #ifndef _WIN32
4505   tt_int_op(0, OP_EQ, chmod(forbidden, 0));
4506 #endif
4507 
4508 #define TEST(input) \
4509   do { \
4510     tor_asprintf(&pattern, "%s"PATH_SEPARATOR"%s", dirname, input); \
4511     results = tor_glob(pattern); \
4512     tor_free(pattern); \
4513     tt_assert(results); \
4514     smartlist_sort_strings(results); \
4515   } while (0);
4516 
4517 #define EXPECT(result) \
4518   do { \
4519     tt_int_op(smartlist_len(results), OP_EQ, \
4520                             sizeof(result)/sizeof(*result)); \
4521     i = 0; \
4522     SMARTLIST_FOREACH_BEGIN(results, const char *, f) { \
4523       tor_asprintf(&expected, "%s"PATH_SEPARATOR"%s", dirname, result[i]); \
4524       tt_str_op(f, OP_EQ, expected); \
4525       i++; \
4526       tor_free(expected); \
4527     } SMARTLIST_FOREACH_END(f); \
4528     SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4529     smartlist_free(results); \
4530   } while (0);
4531 
4532 #define EXPECT_EMPTY() \
4533   do { \
4534     tt_int_op(smartlist_len(results), OP_EQ, 0); \
4535     SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4536     smartlist_free(results); \
4537   } while (0);
4538 
4539   // wildcards at beginning
4540   const char *results_test1[] = {"dir2", "file2"};
4541   TEST("*2");
4542   EXPECT(results_test1);
4543 
4544   // wildcards at end
4545   const char *results_test2[] = {"dir1", "dir2"};
4546   TEST("d*");
4547   EXPECT(results_test2);
4548 
4549   // wildcards at beginning and end
4550 #ifdef _WIN32
4551   // dot files are not ignored on Windows
4552   const char *results_test3[] = {".test-hidden", "dir1", "dir2", "file1",
4553                                  "file2", "forbidden"};
4554 #else
4555   const char *results_test3[] = {"dir1", "dir2", "file1", "file2",
4556                                  "forbidden"};
4557 #endif /* defined(_WIN32) */
4558   TEST("*i*");
4559   EXPECT(results_test3);
4560 
4561   // wildcards in middle
4562   const char *results_test4[] = {"dir1", "dir2"};
4563   TEST("d?r*");
4564   EXPECT(results_test4);
4565 
4566   // test file that does not exist
4567   TEST("not-exist");
4568   EXPECT_EMPTY();
4569 
4570   // test wildcard that matches nothing
4571   TEST("*not-exist*");
4572   EXPECT_EMPTY();
4573 
4574   // test path separator at end - no wildcards
4575   const char *results_test7[] = {"dir1"};
4576   TEST("dir1");
4577   EXPECT(results_test7);
4578 
4579   const char *results_test8[] = {"dir1"};
4580   TEST("dir1"PATH_SEPARATOR);
4581   EXPECT(results_test8);
4582 
4583   const char *results_test9[] = {"file1"};
4584   TEST("file1");
4585   EXPECT(results_test9);
4586 
4587   TEST("file1"PATH_SEPARATOR);
4588   EXPECT_EMPTY();
4589 
4590   // test path separator at end - with wildcards and linux path separator
4591   const char *results_test11[] = {"dir1", "dir2", "forbidden"};
4592   TEST("*/");
4593   EXPECT(results_test11);
4594 
4595 #ifdef _WIN32
4596   // dot files are not ignored on Windows
4597   const char *results_test12[] = {".test-hidden", "dir1", "dir2", "empty",
4598                                   "file1", "file2", "forbidden"};
4599 #else
4600   const char *results_test12[] = {"dir1", "dir2", "empty", "file1", "file2",
4601                                   "forbidden"};
4602 #endif /* defined(_WIN32) */
4603   TEST("*");
4604   EXPECT(results_test12);
4605 
4606   // wildcards on folder and file and linux path separator
4607   const char *results_test13[] = {"dir1"PATH_SEPARATOR"dir1",
4608                                   "dir1"PATH_SEPARATOR"dir2",
4609                                   "dir1"PATH_SEPARATOR"file1",
4610                                   "dir1"PATH_SEPARATOR"file2",
4611                                   "dir2"PATH_SEPARATOR"dir1",
4612                                   "dir2"PATH_SEPARATOR"dir2",
4613                                   "dir2"PATH_SEPARATOR"file1",
4614                                   "dir2"PATH_SEPARATOR"file2"};
4615   TEST("?i*/?i*");
4616   EXPECT(results_test13);
4617 
4618   // wildcards on file only
4619   const char *results_test14[] = {"dir1"PATH_SEPARATOR"dir1",
4620                                   "dir1"PATH_SEPARATOR"dir2",
4621                                   "dir1"PATH_SEPARATOR"file1",
4622                                   "dir1"PATH_SEPARATOR"file2"};
4623   TEST("dir1"PATH_SEPARATOR"?i*");
4624   EXPECT(results_test14);
4625 
4626   // wildcards on folder only
4627   const char *results_test15[] = {"dir1"PATH_SEPARATOR"file1",
4628                                   "dir2"PATH_SEPARATOR"file1"};
4629   TEST("?i*"PATH_SEPARATOR"file1");
4630   EXPECT(results_test15);
4631 
4632   // wildcards after file name
4633   TEST("file1"PATH_SEPARATOR"*");
4634   EXPECT_EMPTY();
4635 
4636 #ifndef _WIN32
4637   // test wildcard escaping
4638   TEST("\\*");
4639   EXPECT_EMPTY();
4640 
4641   if (getuid() != 0) {
4642     // test forbidden directory, if we're not root.
4643     // (Root will be able to see this directory anyway.)
4644     tor_asprintf(&pattern, "%s"PATH_SEPARATOR"*"PATH_SEPARATOR"*", dirname);
4645     results = tor_glob(pattern);
4646     tor_free(pattern);
4647     tt_assert(!results);
4648   }
4649 #endif /* !defined(_WIN32) */
4650 
4651 #undef TEST
4652 #undef EXPECT
4653 #undef EXPECT_EMPTY
4654 
4655  done:
4656 #ifndef _WIN32
4657   (void) chmod(forbidden, 0700);
4658   (void) chmod(dir1_forbidden, 0700);
4659   (void) chmod(dir2_forbidden, 0700);
4660   (void) chmod(forbidden_forbidden, 0700);
4661 #endif /* !defined(_WIN32) */
4662   tor_free(dir1);
4663   tor_free(dir2);
4664   tor_free(forbidden);
4665   tor_free(dirname);
4666   tor_free(dir1_forbidden);
4667   tor_free(dir2_forbidden);
4668   tor_free(forbidden_forbidden);
4669   tor_free(expected);
4670   tor_free(pattern);
4671   if (results) {
4672     SMARTLIST_FOREACH(results, char *, f, tor_free(f));
4673     smartlist_free(results);
4674   }
4675 #else /* !defined(HAVE_GLOB) */
4676   tt_skip();
4677  done:
4678   return;
4679 #endif /* defined(HAVE_GLOB) */
4680 }
4681 
4682 static void
test_util_get_glob_opened_files(void * ptr)4683 test_util_get_glob_opened_files(void *ptr)
4684 {
4685   (void)ptr;
4686 
4687 #ifdef HAVE_GLOB
4688   smartlist_t *results = NULL;
4689   int r, i;
4690   char *dir1 = NULL, *dir2 = NULL, *forbidden = NULL, *dirname = NULL;
4691   char *expected = NULL, *pattern = NULL;
4692   // used for cleanup
4693   char *dir1_forbidden = NULL, *dir2_forbidden = NULL;
4694   char *forbidden_forbidden = NULL;
4695 
4696   dirname = tor_strdup(get_fname("test_get_glob_opened_files"));
4697   tt_ptr_op(dirname, OP_NE, NULL);
4698 
4699 #ifdef _WIN32
4700   r = mkdir(dirname);
4701 #else
4702   r = mkdir(dirname, 0700);
4703 #endif
4704   if (r) {
4705     fprintf(stderr, "Can't create directory %s:", dirname);
4706     perror("");
4707     exit(1);
4708   }
4709 
4710   tt_int_op(0, OP_EQ, create_test_directory_structure(dirname));
4711   tor_asprintf(&dir1, "%s"PATH_SEPARATOR"dir1", dirname);
4712   tor_asprintf(&dir1_forbidden,
4713                "%s"PATH_SEPARATOR"dir1"PATH_SEPARATOR"forbidden", dirname);
4714   tt_int_op(0, OP_EQ, create_test_directory_structure(dir1));
4715   tor_asprintf(&dir2, "%s"PATH_SEPARATOR"dir2", dirname);
4716   tor_asprintf(&dir2_forbidden,
4717                "%s"PATH_SEPARATOR"dir2"PATH_SEPARATOR"forbidden", dirname);
4718   tt_int_op(0, OP_EQ, create_test_directory_structure(dir2));
4719   tor_asprintf(&forbidden, "%s"PATH_SEPARATOR"forbidden", dirname);
4720   tor_asprintf(&forbidden_forbidden,
4721                "%s"PATH_SEPARATOR"forbidden"PATH_SEPARATOR"forbidden",dirname);
4722 #ifndef _WIN32
4723   chmod(forbidden, 0700);
4724 #endif
4725   tt_int_op(0, OP_EQ, create_test_directory_structure(forbidden));
4726 #ifndef _WIN32
4727   chmod(forbidden, 0);
4728 #endif
4729 
4730 #define TEST(input) \
4731   do { \
4732     if (*input) { \
4733       tor_asprintf(&pattern, "%s"PATH_SEPARATOR"%s", dirname, input); \
4734     } else { /* do not add path separator if empty string */ \
4735       tor_asprintf(&pattern, "%s", dirname); \
4736     } \
4737     results = get_glob_opened_files(pattern); \
4738     tor_free(pattern); \
4739     tt_assert(results); \
4740     smartlist_sort_strings(results); \
4741   } while (0);
4742 
4743 #define EXPECT(result) \
4744   do { \
4745     tt_int_op(smartlist_len(results), OP_EQ, \
4746                           sizeof(result)/sizeof(*result)); \
4747     i = 0; \
4748     SMARTLIST_FOREACH_BEGIN(results, const char *, f) { \
4749       if (*result[i]) { \
4750         tor_asprintf(&expected, "%s"PATH_SEPARATOR"%s", dirname, result[i]); \
4751       } else { /* do not add path separator if empty string */ \
4752         tor_asprintf(&expected, "%s", dirname); \
4753       } \
4754       tt_str_op(f, OP_EQ, expected); \
4755       i++; \
4756       tor_free(expected); \
4757     } SMARTLIST_FOREACH_END(f); \
4758     SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4759     smartlist_free(results); \
4760   } while (0);
4761 
4762 #define EXPECT_EMPTY() \
4763   do { \
4764     tt_int_op(smartlist_len(results), OP_EQ, 0); \
4765     SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4766     smartlist_free(results); \
4767   } while (0);
4768 
4769   // all files on folder
4770   const char *results_test1[] = {""}; // only the folder is read
4771   TEST("*");
4772   EXPECT(results_test1);
4773 
4774   // same as before but ending in path separator
4775   const char *results_test2[] = {""}; // only the folder is read
4776   TEST("*"PATH_SEPARATOR);
4777   EXPECT(results_test2);
4778 
4779   // wildcards in multiple path components
4780 #ifndef _WIN32
4781   const char *results_test3[] = {"", "dir1", "dir2", "empty", "file1", "file2",
4782                                  "forbidden"};
4783 #else
4784   // dot files are not special on windows
4785   const char *results_test3[] = {"", ".test-hidden", "dir1", "dir2", "empty",
4786                                  "file1", "file2", "forbidden"};
4787 #endif /* !defined(_WIN32) */
4788   TEST("*"PATH_SEPARATOR"*");
4789   EXPECT(results_test3);
4790 
4791   // same as before but ending in path separator
4792 #ifndef _WIN32
4793   const char *results_test4[] = {"", "dir1", "dir2", "empty", "file1", "file2",
4794                                  "forbidden"};
4795 #else
4796   // dot files are not special on windows
4797   const char *results_test4[] = {"", ".test-hidden", "dir1", "dir2", "empty",
4798                                  "file1", "file2", "forbidden"};
4799 #endif /* !defined(_WIN32) */
4800   TEST("*"PATH_SEPARATOR"*"PATH_SEPARATOR);
4801   EXPECT(results_test4);
4802 
4803   // no glob - folder
4804   TEST("");
4805   EXPECT_EMPTY();
4806 
4807   // same as before but ending in path separator
4808   TEST(PATH_SEPARATOR);
4809   EXPECT_EMPTY();
4810 
4811   // no glob - file
4812   TEST("file1");
4813   EXPECT_EMPTY();
4814 
4815   // same as before but ending in path separator and linux path separator
4816   TEST("file1/");
4817   EXPECT_EMPTY();
4818 
4819   // file but with wildcard after
4820   const char *results_test9[] = {"file1"};
4821   TEST("file1"PATH_SEPARATOR"*");
4822   EXPECT(results_test9);
4823 
4824   // dir inside dir and linux path separator
4825   TEST("dir1/dir1");
4826   EXPECT_EMPTY();
4827 
4828   // same as before but ending in path separator
4829   TEST("dir1"PATH_SEPARATOR"dir1"PATH_SEPARATOR);
4830   EXPECT_EMPTY();
4831 
4832   // no glob - empty
4833   TEST("empty");
4834   EXPECT_EMPTY();
4835 
4836   // same as before but ending in path separator
4837   TEST("empty"PATH_SEPARATOR);
4838   EXPECT_EMPTY();
4839 
4840   // no glob - does not exist
4841   TEST("not_exist");
4842   EXPECT_EMPTY();
4843 
4844 #undef TEST
4845 #undef EXPECT
4846 #undef EXPECT_EMPTY
4847 
4848  done:
4849 #ifndef _WIN32
4850   {
4851     int chmod_failed = 0;
4852     if (forbidden)
4853     chmod_failed |= chmod(forbidden, 0700);
4854     if (dir1_forbidden)
4855       chmod_failed |= chmod(dir1_forbidden, 0700);
4856     if (dir2_forbidden)
4857       chmod_failed |= chmod(dir2_forbidden, 0700);
4858     if (forbidden_forbidden)
4859       chmod_failed |= chmod(forbidden_forbidden, 0700);
4860     if (chmod_failed) {
4861       TT_FAIL(("unable to chmod a file on cleanup: %s", strerror(errno)));
4862     }
4863   }
4864 #endif /* !defined(_WIN32) */
4865   tor_free(dir1);
4866   tor_free(dir2);
4867   tor_free(forbidden);
4868   tor_free(dirname);
4869   tor_free(dir1_forbidden);
4870   tor_free(dir2_forbidden);
4871   tor_free(forbidden_forbidden);
4872   tor_free(expected);
4873   tor_free(pattern);
4874   if (results) {
4875     SMARTLIST_FOREACH(results, char *, f, tor_free(f));
4876     smartlist_free(results);
4877   }
4878 #else /* !defined(HAVE_GLOB) */
4879   tt_skip();
4880  done:
4881   return;
4882 #endif /* defined(HAVE_GLOB) */
4883 }
4884 
4885 static void
test_util_parent_dir(void * ptr)4886 test_util_parent_dir(void *ptr)
4887 {
4888   char *cp;
4889   (void)ptr;
4890 
4891 #define T(output,expect_ok,input)               \
4892   do {                                          \
4893     int ok;                                     \
4894     cp = tor_strdup(input);                     \
4895     ok = get_parent_directory(cp);              \
4896     tt_int_op(expect_ok, OP_EQ, ok);               \
4897     if (ok==0)                                  \
4898       tt_str_op(output, OP_EQ, cp);                \
4899     tor_free(cp);                               \
4900   } while (0);
4901 
4902   T("/home/wombat", 0, "/home/wombat/knish");
4903   T("/home/wombat", 0, "/home/wombat/knish/");
4904   T("/home/wombat", 0, "/home/wombat/knish///");
4905   T("./home/wombat", 0, "./home/wombat/knish/");
4906   T("/", 0, "/home");
4907   T("/", 0, "/home//");
4908   T(".", 0, "./wombat");
4909   T(".", 0, "./wombat/");
4910   T(".", 0, "./wombat//");
4911   T("wombat", 0, "wombat/foo");
4912   T("wombat/..", 0, "wombat/../foo");
4913   T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
4914   T("wombat/.", 0, "wombat/./foo");
4915   T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
4916   T("wombat", 0, "wombat/..//");
4917   T("wombat", 0, "wombat/foo/");
4918   T("wombat", 0, "wombat/.foo");
4919   T("wombat", 0, "wombat/.foo/");
4920 
4921   T("wombat", -1, "");
4922   T("w", -1, "");
4923   T("wombat", 0, "wombat/knish");
4924 
4925   T("/", 0, "/");
4926   T("/", 0, "////");
4927 
4928  done:
4929   tor_free(cp);
4930 }
4931 
4932 static void
test_util_ftruncate(void * ptr)4933 test_util_ftruncate(void *ptr)
4934 {
4935   char *buf = NULL;
4936   const char *fname;
4937   int fd = -1;
4938   const char *message = "Hello world";
4939   const char *message2 = "Hola mundo";
4940   struct stat st;
4941 
4942   (void) ptr;
4943 
4944   fname = get_fname("ftruncate");
4945 
4946   fd = tor_open_cloexec(fname, O_WRONLY|O_CREAT, 0600);
4947   tt_int_op(fd, OP_GE, 0);
4948 
4949   /* Make the file be there. */
4950   tt_int_op(strlen(message), OP_EQ,
4951             write_all_to_fd(fd, message, strlen(message)));
4952   tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message));
4953   tt_int_op(0, OP_EQ, fstat(fd, &st));
4954   tt_int_op((int)st.st_size, OP_EQ, strlen(message));
4955 
4956   /* Truncate and see if it got truncated */
4957   tt_int_op(0, OP_EQ, tor_ftruncate(fd));
4958   tt_int_op((int)tor_fd_getpos(fd), OP_EQ, 0);
4959   tt_int_op(0, OP_EQ, fstat(fd, &st));
4960   tt_int_op((int)st.st_size, OP_EQ, 0);
4961 
4962   /* Replace, and see if it got replaced */
4963   tt_int_op(strlen(message2), OP_EQ,
4964             write_all_to_fd(fd, message2, strlen(message2)));
4965   tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message2));
4966   tt_int_op(0, OP_EQ, fstat(fd, &st));
4967   tt_int_op((int)st.st_size, OP_EQ, strlen(message2));
4968 
4969   close(fd);
4970   fd = -1;
4971 
4972   buf = read_file_to_str(fname, 0, NULL);
4973   tt_str_op(message2, OP_EQ, buf);
4974 
4975  done:
4976   if (fd >= 0)
4977     close(fd);
4978   tor_free(buf);
4979 }
4980 
4981 static void
test_util_num_cpus(void * arg)4982 test_util_num_cpus(void *arg)
4983 {
4984   (void)arg;
4985   int num = compute_num_cpus();
4986   if (num < 0)
4987     tt_skip();
4988 
4989   tt_int_op(num, OP_GE, 1);
4990   tt_int_op(num, OP_LE, 16);
4991 
4992  done:
4993   ;
4994 }
4995 
4996 #ifdef _WIN32
4997 static void
test_util_load_win_lib(void * ptr)4998 test_util_load_win_lib(void *ptr)
4999 {
5000   HANDLE h = load_windows_system_library(_T("advapi32.dll"));
5001   (void) ptr;
5002 
5003   tt_assert(h);
5004  done:
5005   if (h)
5006     FreeLibrary(h);
5007 }
5008 #endif /* defined(_WIN32) */
5009 
5010 /**
5011  * Test for format_hex_number_sigsafe()
5012  */
5013 
5014 static void
test_util_format_hex_number(void * ptr)5015 test_util_format_hex_number(void *ptr)
5016 {
5017   int i, len;
5018   char buf[33];
5019   const struct {
5020     const char *str;
5021     unsigned int x;
5022   } test_data[] = {
5023     {"0", 0},
5024     {"1", 1},
5025     {"273A", 0x273a},
5026     {"FFFF", 0xffff},
5027     {"7FFFFFFF", 0x7fffffff},
5028     {"FFFFFFFF", 0xffffffff},
5029 #if UINT_MAX >= 0xffffffff
5030     {"31BC421D", 0x31bc421d},
5031     {"FFFFFFFF", 0xffffffff},
5032 #endif
5033     {NULL, 0}
5034   };
5035 
5036   (void)ptr;
5037 
5038   for (i = 0; test_data[i].str != NULL; ++i) {
5039     len = format_hex_number_sigsafe(test_data[i].x, buf, sizeof(buf));
5040     tt_int_op(len,OP_NE, 0);
5041     tt_int_op(len,OP_EQ, strlen(buf));
5042     tt_str_op(buf,OP_EQ, test_data[i].str);
5043   }
5044 
5045   tt_int_op(4,OP_EQ, format_hex_number_sigsafe(0xffff, buf, 5));
5046   tt_str_op(buf,OP_EQ, "FFFF");
5047   tt_int_op(0,OP_EQ, format_hex_number_sigsafe(0xffff, buf, 4));
5048   tt_int_op(0,OP_EQ, format_hex_number_sigsafe(0, buf, 1));
5049 
5050  done:
5051   return;
5052 }
5053 
5054 /**
5055  * Test for format_hex_number_sigsafe()
5056  */
5057 
5058 static void
test_util_format_dec_number(void * ptr)5059 test_util_format_dec_number(void *ptr)
5060 {
5061   int i, len;
5062   char buf[33];
5063   const struct {
5064     const char *str;
5065     unsigned int x;
5066   } test_data[] = {
5067     {"0", 0},
5068     {"1", 1},
5069     {"1234", 1234},
5070     {"12345678", 12345678},
5071     {"99999999",  99999999},
5072     {"100000000", 100000000},
5073     {"4294967295", 4294967295u},
5074 #if UINT_MAX > 0xffffffff
5075     {"18446744073709551615", 18446744073709551615u },
5076 #endif
5077     {NULL, 0}
5078   };
5079 
5080   (void)ptr;
5081 
5082   for (i = 0; test_data[i].str != NULL; ++i) {
5083     len = format_dec_number_sigsafe(test_data[i].x, buf, sizeof(buf));
5084     tt_int_op(len,OP_NE, 0);
5085     tt_int_op(len,OP_EQ, strlen(buf));
5086     tt_str_op(buf,OP_EQ, test_data[i].str);
5087 
5088     len = format_dec_number_sigsafe(test_data[i].x, buf,
5089                                     (int)(strlen(test_data[i].str) + 1));
5090     tt_int_op(len,OP_EQ, strlen(buf));
5091     tt_str_op(buf,OP_EQ, test_data[i].str);
5092   }
5093 
5094   tt_int_op(4,OP_EQ, format_dec_number_sigsafe(7331, buf, 5));
5095   tt_str_op(buf,OP_EQ, "7331");
5096   tt_int_op(0,OP_EQ, format_dec_number_sigsafe(7331, buf, 4));
5097   tt_int_op(1,OP_EQ, format_dec_number_sigsafe(0, buf, 2));
5098   tt_int_op(0,OP_EQ, format_dec_number_sigsafe(0, buf, 1));
5099 
5100  done:
5101   return;
5102 }
5103 
5104 #define MAX_SPLIT_LINE_COUNT 4
5105 struct split_lines_test_t {
5106   const char *orig_line; // Line to be split (may contain \0's)
5107   int orig_length; // Length of orig_line
5108   const char *split_line[MAX_SPLIT_LINE_COUNT]; // Split lines
5109 };
5110 
5111 static void
test_util_di_ops(void * arg)5112 test_util_di_ops(void *arg)
5113 {
5114 #define LT -1
5115 #define GT 1
5116 #define EQ 0
5117   const struct {
5118     const char *a; int want_sign; const char *b;
5119   } examples[] = {
5120     { "Foo", EQ, "Foo" },
5121     { "foo", GT, "bar", },
5122     { "foobar", EQ ,"foobar" },
5123     { "foobar", LT, "foobaw" },
5124     { "foobar", GT, "f00bar" },
5125     { "foobar", GT, "boobar" },
5126     { "", EQ, "" },
5127     { NULL, 0, NULL },
5128   };
5129 
5130   int i;
5131 
5132   (void)arg;
5133   for (i = 0; examples[i].a; ++i) {
5134     size_t len = strlen(examples[i].a);
5135     int eq1, eq2, neq1, neq2, cmp1, cmp2;
5136     tt_int_op(len,OP_EQ, strlen(examples[i].b));
5137     /* We do all of the operations, with operands in both orders. */
5138     eq1 = tor_memeq(examples[i].a, examples[i].b, len);
5139     eq2 = tor_memeq(examples[i].b, examples[i].a, len);
5140     neq1 = tor_memneq(examples[i].a, examples[i].b, len);
5141     neq2 = tor_memneq(examples[i].b, examples[i].a, len);
5142     cmp1 = tor_memcmp(examples[i].a, examples[i].b, len);
5143     cmp2 = tor_memcmp(examples[i].b, examples[i].a, len);
5144 
5145     /* Check for correctness of cmp1 */
5146     if (cmp1 < 0 && examples[i].want_sign != LT)
5147       TT_DIE(("Assertion failed."));
5148     else if (cmp1 > 0 && examples[i].want_sign != GT)
5149       TT_DIE(("Assertion failed."));
5150     else if (cmp1 == 0 && examples[i].want_sign != EQ)
5151       TT_DIE(("Assertion failed."));
5152 
5153     /* Check for consistency of everything else with cmp1 */
5154     tt_int_op(eq1,OP_EQ, eq2);
5155     tt_int_op(neq1,OP_EQ, neq2);
5156     tt_int_op(cmp1,OP_EQ, -cmp2);
5157     tt_int_op(eq1,OP_EQ, cmp1 == 0);
5158     tt_int_op(neq1,OP_EQ, !eq1);
5159   }
5160 
5161   {
5162     uint8_t zz = 0;
5163     uint8_t ii = 0;
5164     int z;
5165 
5166     /* exhaustively test tor_memeq and tor_memcmp
5167      * against each possible single-byte numeric difference
5168      * some arithmetic bugs only appear with certain bit patterns */
5169     for (z = 0; z < 256; z++) {
5170       for (i = 0; i < 256; i++) {
5171         ii = (uint8_t)i;
5172         zz = (uint8_t)z;
5173         tt_int_op(tor_memeq(&zz, &ii, 1),OP_EQ, zz == ii);
5174         tt_int_op(tor_memcmp(&zz, &ii, 1) > 0 ? GT : EQ,OP_EQ,
5175                   zz > ii ? GT : EQ);
5176         tt_int_op(tor_memcmp(&ii, &zz, 1) < 0 ? LT : EQ,OP_EQ,
5177                   ii < zz ? LT : EQ);
5178       }
5179     }
5180   }
5181 
5182   tt_int_op(1, OP_EQ, safe_mem_is_zero("", 0));
5183   tt_int_op(1, OP_EQ, safe_mem_is_zero("", 1));
5184   tt_int_op(0, OP_EQ, safe_mem_is_zero("a", 1));
5185   tt_int_op(0, OP_EQ, safe_mem_is_zero("a", 2));
5186   tt_int_op(0, OP_EQ, safe_mem_is_zero("\0a", 2));
5187   tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0a", 2));
5188   tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
5189   tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
5190   tt_int_op(0, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
5191 
5192  done:
5193   ;
5194 }
5195 
5196 static void
test_util_memcpy_iftrue_timei(void * arg)5197 test_util_memcpy_iftrue_timei(void *arg)
5198 {
5199   (void)arg;
5200   char buf1[25];
5201   char buf2[25];
5202   char buf3[25];
5203 
5204   for (int i = 0; i < 100; ++i) {
5205     crypto_rand(buf1, sizeof(buf1));
5206     crypto_rand(buf2, sizeof(buf2));
5207     memcpy(buf3, buf1, sizeof(buf1));
5208 
5209     /* We just copied buf1 into buf3.  Now we're going to copy buf2 into buf2,
5210        iff our coin flip comes up heads. */
5211     bool coinflip = crypto_rand_int(2) == 0;
5212 
5213     memcpy_if_true_timei(coinflip, buf3, buf2, sizeof(buf3));
5214 
5215     if (coinflip) {
5216       tt_mem_op(buf3, OP_EQ, buf2, sizeof(buf2));
5217     } else {
5218       tt_mem_op(buf3, OP_EQ, buf1, sizeof(buf1));
5219     }
5220   }
5221  done:
5222   ;
5223 }
5224 
5225 static void
test_util_di_map(void * arg)5226 test_util_di_map(void *arg)
5227 {
5228   (void)arg;
5229   di_digest256_map_t *dimap = NULL;
5230   uint8_t key1[] = "Robert Anton Wilson            ";
5231   uint8_t key2[] = "Martin Gardner, _Fads&fallacies";
5232   uint8_t key3[] = "Tom Lehrer, _Be Prepared_.     ";
5233   uint8_t key4[] = "Ursula Le Guin,_A Wizard of... ";
5234 
5235   char dflt_entry[] = "'You have made a good beginning', but no more";
5236 
5237   tt_int_op(32, OP_EQ, sizeof(key1));
5238   tt_int_op(32, OP_EQ, sizeof(key2));
5239   tt_int_op(32, OP_EQ, sizeof(key3));
5240 
5241   tt_ptr_op(dflt_entry, OP_EQ, dimap_search(dimap, key1, dflt_entry));
5242 
5243   char *str1 = tor_strdup("You are precisely as big as what you love"
5244                           " and precisely as small as what you allow"
5245                           " to annoy you.");
5246   char *str2 = tor_strdup("Let us hope that Lysenko's success in Russia will"
5247                           " serve for many generations to come as another"
5248                           " reminder to the world of how quickly and easily"
5249                           " a science can be corrupted when ignorant"
5250                           " political leaders deem themselves competent"
5251                           " to arbitrate scientific disputes");
5252   char *str3 = tor_strdup("Don't write naughty words on walls "
5253                           "if you can't spell.");
5254 
5255   dimap_add_entry(&dimap, key1, str1);
5256   dimap_add_entry(&dimap, key2, str2);
5257   dimap_add_entry(&dimap, key3, str3);
5258 
5259   tt_ptr_op(str1, OP_EQ, dimap_search(dimap, key1, dflt_entry));
5260   tt_ptr_op(str3, OP_EQ, dimap_search(dimap, key3, dflt_entry));
5261   tt_ptr_op(str2, OP_EQ, dimap_search(dimap, key2, dflt_entry));
5262   tt_ptr_op(dflt_entry, OP_EQ, dimap_search(dimap, key4, dflt_entry));
5263 
5264  done:
5265   dimap_free(dimap, tor_free_);
5266 }
5267 
5268 /**
5269  * Test counting high bits
5270  */
5271 static void
test_util_n_bits_set(void * ptr)5272 test_util_n_bits_set(void *ptr)
5273 {
5274   (void)ptr;
5275   tt_int_op(0,OP_EQ, n_bits_set_u8(0));
5276   tt_int_op(1,OP_EQ, n_bits_set_u8(1));
5277   tt_int_op(3,OP_EQ, n_bits_set_u8(7));
5278   tt_int_op(1,OP_EQ, n_bits_set_u8(8));
5279   tt_int_op(2,OP_EQ, n_bits_set_u8(129));
5280   tt_int_op(8,OP_EQ, n_bits_set_u8(255));
5281  done:
5282   ;
5283 }
5284 
5285 /**
5286  * Test LHS whitespace (and comment) eater
5287  */
5288 static void
test_util_eat_whitespace(void * ptr)5289 test_util_eat_whitespace(void *ptr)
5290 {
5291   const char ws[] = { ' ', '\t', '\r' }; /* Except NL */
5292   char str[80];
5293   size_t i;
5294 
5295   (void)ptr;
5296 
5297   /* Try one leading ws */
5298   strlcpy(str, "fuubaar", sizeof(str));
5299   for (i = 0; i < sizeof(ws); ++i) {
5300     str[0] = ws[i];
5301     tt_ptr_op(str + 1,OP_EQ, eat_whitespace(str));
5302     tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
5303     tt_ptr_op(str + 1,OP_EQ, eat_whitespace_no_nl(str));
5304     tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
5305   }
5306   str[0] = '\n';
5307   tt_ptr_op(str + 1,OP_EQ, eat_whitespace(str));
5308   tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
5309   tt_ptr_op(str,OP_EQ,     eat_whitespace_no_nl(str));
5310   tt_ptr_op(str,OP_EQ,     eat_whitespace_eos_no_nl(str, str + strlen(str)));
5311 
5312   /* Empty string */
5313   strlcpy(str, "", sizeof(str));
5314   tt_ptr_op(str,OP_EQ, eat_whitespace(str));
5315   tt_ptr_op(str,OP_EQ, eat_whitespace_eos(str, str));
5316   tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
5317   tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str));
5318 
5319   /* Only ws */
5320   strlcpy(str, " \t\r\n", sizeof(str));
5321   tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
5322   tt_ptr_op(str + strlen(str),OP_EQ,
5323             eat_whitespace_eos(str, str + strlen(str)));
5324   tt_ptr_op(str + strlen(str) - 1,OP_EQ,
5325               eat_whitespace_no_nl(str));
5326   tt_ptr_op(str + strlen(str) - 1,OP_EQ,
5327               eat_whitespace_eos_no_nl(str, str + strlen(str)));
5328 
5329   strlcpy(str, " \t\r ", sizeof(str));
5330   tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
5331   tt_ptr_op(str + strlen(str),OP_EQ,
5332               eat_whitespace_eos(str, str + strlen(str)));
5333   tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace_no_nl(str));
5334   tt_ptr_op(str + strlen(str),OP_EQ,
5335               eat_whitespace_eos_no_nl(str, str + strlen(str)));
5336 
5337   /* Multiple ws */
5338   strlcpy(str, "fuubaar", sizeof(str));
5339   for (i = 0; i < sizeof(ws); ++i)
5340     str[i] = ws[i];
5341   tt_ptr_op(str + sizeof(ws),OP_EQ, eat_whitespace(str));
5342   tt_ptr_op(str + sizeof(ws),OP_EQ,
5343             eat_whitespace_eos(str, str + strlen(str)));
5344   tt_ptr_op(str + sizeof(ws),OP_EQ, eat_whitespace_no_nl(str));
5345   tt_ptr_op(str + sizeof(ws),OP_EQ,
5346               eat_whitespace_eos_no_nl(str, str + strlen(str)));
5347 
5348   /* Eat comment */
5349   strlcpy(str, "# Comment \n No Comment", sizeof(str));
5350   tt_str_op("No Comment",OP_EQ, eat_whitespace(str));
5351   tt_str_op("No Comment",OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
5352   tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
5353   tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
5354 
5355   /* Eat comment & ws mix */
5356   strlcpy(str, " # \t Comment \n\t\nNo Comment", sizeof(str));
5357   tt_str_op("No Comment",OP_EQ, eat_whitespace(str));
5358   tt_str_op("No Comment",OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
5359   tt_ptr_op(str + 1,OP_EQ, eat_whitespace_no_nl(str));
5360   tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
5361 
5362   /* Eat entire comment */
5363   strlcpy(str, "#Comment", sizeof(str));
5364   tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
5365   tt_ptr_op(str + strlen(str),OP_EQ,
5366             eat_whitespace_eos(str, str + strlen(str)));
5367   tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
5368   tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
5369 
5370   /* Blank line, then comment */
5371   strlcpy(str, " \t\n # Comment", sizeof(str));
5372   tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
5373   tt_ptr_op(str + strlen(str),OP_EQ,
5374             eat_whitespace_eos(str, str + strlen(str)));
5375   tt_ptr_op(str + 2,OP_EQ, eat_whitespace_no_nl(str));
5376   tt_ptr_op(str + 2,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
5377 
5378  done:
5379   ;
5380 }
5381 
5382 /** Return a newly allocated smartlist containing the lines of text in
5383  * <b>lines</b>.  The returned strings are heap-allocated, and must be
5384  * freed by the caller.
5385  *
5386  * XXXX? Move to container.[hc] ? */
5387 static smartlist_t *
smartlist_new_from_text_lines(const char * lines)5388 smartlist_new_from_text_lines(const char *lines)
5389 {
5390   smartlist_t *sl = smartlist_new();
5391   char *last_line;
5392 
5393   smartlist_split_string(sl, lines, "\n", 0, 0);
5394 
5395   last_line = smartlist_pop_last(sl);
5396   if (last_line != NULL && *last_line != '\0') {
5397     smartlist_add(sl, last_line);
5398   } else {
5399     tor_free(last_line);
5400   }
5401 
5402   return sl;
5403 }
5404 
5405 /** Test smartlist_new_from_text_lines */
5406 static void
test_util_sl_new_from_text_lines(void * ptr)5407 test_util_sl_new_from_text_lines(void *ptr)
5408 {
5409   (void)ptr;
5410 
5411   { /* Normal usage */
5412     smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz\n");
5413     int sl_len = smartlist_len(sl);
5414 
5415     tt_want_int_op(sl_len, OP_EQ, 3);
5416 
5417     if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
5418     if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), OP_EQ, "bar");
5419     if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), OP_EQ, "baz");
5420 
5421     SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
5422     smartlist_free(sl);
5423   }
5424 
5425   { /* No final newline */
5426     smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz");
5427     int sl_len = smartlist_len(sl);
5428 
5429     tt_want_int_op(sl_len, OP_EQ, 3);
5430 
5431     if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
5432     if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), OP_EQ, "bar");
5433     if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), OP_EQ, "baz");
5434 
5435     SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
5436     smartlist_free(sl);
5437   }
5438 
5439   { /* No newlines */
5440     smartlist_t *sl = smartlist_new_from_text_lines("foo");
5441     int sl_len = smartlist_len(sl);
5442 
5443     tt_want_int_op(sl_len, OP_EQ, 1);
5444 
5445     if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
5446 
5447     SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
5448     smartlist_free(sl);
5449   }
5450 
5451   { /* No text at all */
5452     smartlist_t *sl = smartlist_new_from_text_lines("");
5453     int sl_len = smartlist_len(sl);
5454 
5455     tt_want_int_op(sl_len, OP_EQ, 0);
5456 
5457     SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
5458     smartlist_free(sl);
5459   }
5460 }
5461 
5462 static void
test_util_envnames(void * ptr)5463 test_util_envnames(void *ptr)
5464 {
5465   (void) ptr;
5466 
5467   tt_assert(environment_variable_names_equal("abc", "abc"));
5468   tt_assert(environment_variable_names_equal("abc", "abc="));
5469   tt_assert(environment_variable_names_equal("abc", "abc=def"));
5470   tt_assert(environment_variable_names_equal("abc=def", "abc"));
5471   tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
5472 
5473   tt_assert(environment_variable_names_equal("abc", "abc"));
5474   tt_assert(environment_variable_names_equal("abc", "abc="));
5475   tt_assert(environment_variable_names_equal("abc", "abc=def"));
5476   tt_assert(environment_variable_names_equal("abc=def", "abc"));
5477   tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
5478 
5479   tt_assert(!environment_variable_names_equal("abc", "abcd"));
5480   tt_assert(!environment_variable_names_equal("abc=", "abcd"));
5481   tt_assert(!environment_variable_names_equal("abc=", "abcd"));
5482   tt_assert(!environment_variable_names_equal("abc=", "def"));
5483   tt_assert(!environment_variable_names_equal("abc=", "def="));
5484   tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
5485 
5486   tt_assert(!environment_variable_names_equal("", "a=def"));
5487   /* A bit surprising. */
5488   tt_assert(environment_variable_names_equal("", "=def"));
5489   tt_assert(environment_variable_names_equal("=y", "=x"));
5490 
5491  done:
5492   ;
5493 }
5494 
5495 /** Test process_environment_make */
5496 static void
test_util_make_environment(void * ptr)5497 test_util_make_environment(void *ptr)
5498 {
5499   const char *env_vars_string =
5500     "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5501     "HOME=/home/foozer\n";
5502   const char expected_windows_env_block[] =
5503     "HOME=/home/foozer\000"
5504     "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
5505     "\000";
5506   size_t expected_windows_env_block_len =
5507     sizeof(expected_windows_env_block) - 1;
5508 
5509   smartlist_t *env_vars = smartlist_new_from_text_lines(env_vars_string);
5510   smartlist_t *env_vars_sorted = smartlist_new();
5511   smartlist_t *env_vars_in_unixoid_env_block_sorted = smartlist_new();
5512 
5513   process_environment_t *env;
5514 
5515   (void)ptr;
5516 
5517   env = process_environment_make(env_vars);
5518 
5519   /* Check that the Windows environment block is correct. */
5520   tt_want(tor_memeq(expected_windows_env_block, env->windows_environment_block,
5521                     expected_windows_env_block_len));
5522 
5523   /* Now for the Unixoid environment block.  We don't care which order
5524    * these environment variables are in, so we sort both lists first. */
5525 
5526   smartlist_add_all(env_vars_sorted, env_vars);
5527 
5528   {
5529     char **v;
5530     for (v = env->unixoid_environment_block; *v; ++v) {
5531       smartlist_add(env_vars_in_unixoid_env_block_sorted, *v);
5532     }
5533   }
5534 
5535   smartlist_sort_strings(env_vars_sorted);
5536   smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted);
5537 
5538   tt_want_int_op(smartlist_len(env_vars_sorted), OP_EQ,
5539                  smartlist_len(env_vars_in_unixoid_env_block_sorted));
5540   {
5541     int len = smartlist_len(env_vars_sorted);
5542     int i;
5543 
5544     if (smartlist_len(env_vars_in_unixoid_env_block_sorted) < len) {
5545       len = smartlist_len(env_vars_in_unixoid_env_block_sorted);
5546     }
5547 
5548     for (i = 0; i < len; ++i) {
5549       tt_want_str_op(smartlist_get(env_vars_sorted, i), OP_EQ,
5550                      smartlist_get(env_vars_in_unixoid_env_block_sorted, i));
5551     }
5552   }
5553 
5554   /* Clean up. */
5555   smartlist_free(env_vars_in_unixoid_env_block_sorted);
5556   smartlist_free(env_vars_sorted);
5557 
5558   SMARTLIST_FOREACH(env_vars, char *, x, tor_free(x));
5559   smartlist_free(env_vars);
5560 
5561   process_environment_free(env);
5562 }
5563 
5564 /** Test set_environment_variable_in_smartlist */
5565 static void
test_util_set_env_var_in_sl(void * ptr)5566 test_util_set_env_var_in_sl(void *ptr)
5567 {
5568   /* The environment variables in these strings are in arbitrary
5569    * order; we sort the resulting lists before comparing them.
5570    *
5571    * (They *will not* end up in the order shown in
5572    * expected_resulting_env_vars_string.) */
5573 
5574   const char *base_env_vars_string =
5575     "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5576     "HOME=/home/foozer\n"
5577     "TERM=xterm\n"
5578     "SHELL=/bin/ksh\n"
5579     "USER=foozer\n"
5580     "LOGNAME=foozer\n"
5581     "USERNAME=foozer\n"
5582     "LANG=en_US.utf8\n"
5583     ;
5584 
5585   const char *new_env_vars_string =
5586     "TERM=putty\n"
5587     "DISPLAY=:18.0\n"
5588     ;
5589 
5590   const char *expected_resulting_env_vars_string =
5591     "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5592     "HOME=/home/foozer\n"
5593     "TERM=putty\n"
5594     "SHELL=/bin/ksh\n"
5595     "USER=foozer\n"
5596     "LOGNAME=foozer\n"
5597     "USERNAME=foozer\n"
5598     "LANG=en_US.utf8\n"
5599     "DISPLAY=:18.0\n"
5600     ;
5601 
5602   smartlist_t *merged_env_vars =
5603     smartlist_new_from_text_lines(base_env_vars_string);
5604   smartlist_t *new_env_vars =
5605     smartlist_new_from_text_lines(new_env_vars_string);
5606   smartlist_t *expected_resulting_env_vars =
5607     smartlist_new_from_text_lines(expected_resulting_env_vars_string);
5608 
5609   /* Elements of merged_env_vars are heap-allocated, and must be
5610    * freed.  Some of them are (or should) be freed by
5611    * set_environment_variable_in_smartlist.
5612    *
5613    * Elements of new_env_vars are heap-allocated, but are copied into
5614    * merged_env_vars, so they are not freed separately at the end of
5615    * the function.
5616    *
5617    * Elements of expected_resulting_env_vars are heap-allocated, and
5618    * must be freed. */
5619 
5620   (void)ptr;
5621 
5622   SMARTLIST_FOREACH(new_env_vars, char *, env_var,
5623                     set_environment_variable_in_smartlist(merged_env_vars,
5624                                                           env_var,
5625                                                           tor_free_,
5626                                                           1));
5627 
5628   smartlist_sort_strings(merged_env_vars);
5629   smartlist_sort_strings(expected_resulting_env_vars);
5630 
5631   tt_want_int_op(smartlist_len(merged_env_vars), OP_EQ,
5632                  smartlist_len(expected_resulting_env_vars));
5633   {
5634     int len = smartlist_len(merged_env_vars);
5635     int i;
5636 
5637     if (smartlist_len(expected_resulting_env_vars) < len) {
5638       len = smartlist_len(expected_resulting_env_vars);
5639     }
5640 
5641     for (i = 0; i < len; ++i) {
5642       tt_want_str_op(smartlist_get(merged_env_vars, i), OP_EQ,
5643                      smartlist_get(expected_resulting_env_vars, i));
5644     }
5645   }
5646 
5647   /* Clean up. */
5648   SMARTLIST_FOREACH(merged_env_vars, char *, x, tor_free(x));
5649   smartlist_free(merged_env_vars);
5650 
5651   smartlist_free(new_env_vars);
5652 
5653   SMARTLIST_FOREACH(expected_resulting_env_vars, char *, x, tor_free(x));
5654   smartlist_free(expected_resulting_env_vars);
5655 }
5656 
5657 static void
test_util_weak_random(void * arg)5658 test_util_weak_random(void *arg)
5659 {
5660   int i, j, n[16];
5661   tor_weak_rng_t rng;
5662   (void) arg;
5663 
5664   tor_init_weak_random(&rng, (unsigned)time(NULL));
5665 
5666   for (i = 1; i <= 256; ++i) {
5667     for (j=0;j<100;++j) {
5668       int r = tor_weak_random_range(&rng, i);
5669       tt_int_op(0, OP_LE, r);
5670       tt_int_op(r, OP_LT, i);
5671     }
5672   }
5673 
5674   memset(n,0,sizeof(n));
5675   for (j=0;j<8192;++j) {
5676     n[tor_weak_random_range(&rng, 16)]++;
5677   }
5678 
5679   for (i=0;i<16;++i)
5680     tt_int_op(n[i], OP_GT, 0);
5681  done:
5682   ;
5683 }
5684 
5685 static void
test_util_mathlog(void * arg)5686 test_util_mathlog(void *arg)
5687 {
5688   double d;
5689   (void) arg;
5690 
5691   d = tor_mathlog(2.718281828);
5692   tt_double_op(fabs(d - 1.0), OP_LT, .000001);
5693   d = tor_mathlog(10);
5694   tt_double_op(fabs(d - 2.30258509), OP_LT, .000001);
5695  done:
5696   ;
5697 }
5698 
5699 static void
test_util_fraction(void * arg)5700 test_util_fraction(void *arg)
5701 {
5702   uint64_t a,b;
5703   (void)arg;
5704 
5705   a = 99; b = 30;
5706   simplify_fraction64(&a,&b);
5707   tt_u64_op(a, OP_EQ, 33);
5708   tt_u64_op(b, OP_EQ, 10);
5709 
5710   a = 3000000; b = 10000000;
5711   simplify_fraction64(&a,&b);
5712   tt_u64_op(a, OP_EQ, 3);
5713   tt_u64_op(b, OP_EQ, 10);
5714 
5715   a = 0; b = 15;
5716   simplify_fraction64(&a,&b);
5717   tt_u64_op(a, OP_EQ, 0);
5718   tt_u64_op(b, OP_EQ, 1);
5719 
5720  done:
5721   ;
5722 }
5723 
5724 static void
test_util_round_to_next_multiple_of(void * arg)5725 test_util_round_to_next_multiple_of(void *arg)
5726 {
5727   (void)arg;
5728 
5729   tt_u64_op(round_uint64_to_next_multiple_of(0,1), OP_EQ, 0);
5730   tt_u64_op(round_uint64_to_next_multiple_of(0,7), OP_EQ, 0);
5731 
5732   tt_u64_op(round_uint64_to_next_multiple_of(99,1), OP_EQ, 99);
5733   tt_u64_op(round_uint64_to_next_multiple_of(99,7), OP_EQ, 105);
5734   tt_u64_op(round_uint64_to_next_multiple_of(99,9), OP_EQ, 99);
5735 
5736   tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX,2), OP_EQ,
5737             UINT64_MAX);
5738 
5739   tt_int_op(round_uint32_to_next_multiple_of(0,1), OP_EQ, 0);
5740   tt_int_op(round_uint32_to_next_multiple_of(0,7), OP_EQ, 0);
5741 
5742   tt_int_op(round_uint32_to_next_multiple_of(99,1), OP_EQ, 99);
5743   tt_int_op(round_uint32_to_next_multiple_of(99,7), OP_EQ, 105);
5744   tt_int_op(round_uint32_to_next_multiple_of(99,9), OP_EQ, 99);
5745 
5746   tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX,2), OP_EQ,
5747             UINT32_MAX);
5748 
5749   tt_uint_op(round_to_next_multiple_of(0,1), OP_EQ, 0);
5750   tt_uint_op(round_to_next_multiple_of(0,7), OP_EQ, 0);
5751 
5752   tt_uint_op(round_to_next_multiple_of(99,1), OP_EQ, 99);
5753   tt_uint_op(round_to_next_multiple_of(99,7), OP_EQ, 105);
5754   tt_uint_op(round_to_next_multiple_of(99,9), OP_EQ, 99);
5755 
5756   tt_uint_op(round_to_next_multiple_of(UINT_MAX,2), OP_EQ,
5757             UINT_MAX);
5758  done:
5759   ;
5760 }
5761 
5762 static void
test_util_laplace(void * arg)5763 test_util_laplace(void *arg)
5764 {
5765   /* Sample values produced using Python's SciPy:
5766    *
5767    * >>> from scipy.stats import laplace
5768    * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
5769      ...             loc = 24, scale = 24)
5770    * array([          nan,          -inf,  -69.88855213,   24.        ,
5771    *          24.48486498,  117.88855213,           inf,           nan])
5772    */
5773   const double mu = 24.0, b = 24.0;
5774   const double delta_f = 15.0, epsilon = 0.3; /* b = 15.0 / 0.3 = 50.0 */
5775   (void)arg;
5776 
5777   tt_i64_op(INT64_MIN, OP_EQ, sample_laplace_distribution(mu, b, 0.0));
5778   tt_i64_op(-69, OP_EQ, sample_laplace_distribution(mu, b, 0.01));
5779   tt_i64_op(24, OP_EQ, sample_laplace_distribution(mu, b, 0.5));
5780   tt_i64_op(24, OP_EQ, sample_laplace_distribution(mu, b, 0.51));
5781   tt_i64_op(117, OP_EQ, sample_laplace_distribution(mu, b, 0.99));
5782 
5783   /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
5784    * ...             loc = 0, scale = 50)
5785    * array([         -inf,  -80.47189562,  -34.65735903,    0.        ,
5786    *          34.65735903,   80.47189562,  195.60115027])
5787    */
5788   tt_i64_op(INT64_MIN + 20, OP_EQ,
5789             add_laplace_noise(20, 0.0, delta_f, epsilon));
5790 
5791   tt_i64_op(-60, OP_EQ, add_laplace_noise(20, 0.1, delta_f, epsilon));
5792   tt_i64_op(-14, OP_EQ, add_laplace_noise(20, 0.25, delta_f, epsilon));
5793   tt_i64_op(20, OP_EQ, add_laplace_noise(20, 0.5, delta_f, epsilon));
5794   tt_i64_op(54, OP_EQ, add_laplace_noise(20, 0.75, delta_f, epsilon));
5795   tt_i64_op(100, OP_EQ, add_laplace_noise(20, 0.9, delta_f, epsilon));
5796   tt_i64_op(215, OP_EQ, add_laplace_noise(20, 0.99, delta_f, epsilon));
5797 
5798   /* Test extreme values of signal with maximally negative values of noise
5799    * 1.0000000000000002 is the smallest number > 1
5800    * 0.0000000000000002 is the double epsilon (error when calculating near 1)
5801    * this is approximately 1/(2^52)
5802    * per https://en.wikipedia.org/wiki/Double_precision
5803    * (let's not descend into the world of subnormals)
5804    * >>> laplace.ppf([0, 0.0000000000000002], loc = 0, scale = 1)
5805    * array([        -inf, -35.45506713])
5806    */
5807   const double noscale_df = 1.0, noscale_eps = 1.0;
5808 
5809   tt_i64_op(INT64_MIN, OP_EQ,
5810             add_laplace_noise(0, 0.0, noscale_df, noscale_eps));
5811 
5812   /* is it clipped to INT64_MIN? */
5813   tt_i64_op(INT64_MIN, OP_EQ,
5814             add_laplace_noise(-1, 0.0, noscale_df, noscale_eps));
5815   tt_i64_op(INT64_MIN, OP_EQ,
5816             add_laplace_noise(INT64_MIN, 0.0,
5817                               noscale_df, noscale_eps));
5818   /* ... even when scaled? */
5819   tt_i64_op(INT64_MIN, OP_EQ,
5820             add_laplace_noise(0, 0.0, delta_f, epsilon));
5821   tt_i64_op(INT64_MIN, OP_EQ,
5822             add_laplace_noise(0, 0.0,
5823                               DBL_MAX, 1));
5824   tt_i64_op(INT64_MIN, OP_EQ,
5825             add_laplace_noise(INT64_MIN, 0.0,
5826                               DBL_MAX, 1));
5827 
5828   /* does it play nice with INT64_MAX? */
5829   tt_i64_op((INT64_MIN + INT64_MAX), OP_EQ,
5830             add_laplace_noise(INT64_MAX, 0.0,
5831                               noscale_df, noscale_eps));
5832 
5833   /* do near-zero fractional values work? */
5834   const double min_dbl_error = 0.0000000000000002;
5835 
5836   tt_i64_op(-35, OP_EQ,
5837             add_laplace_noise(0, min_dbl_error,
5838                               noscale_df, noscale_eps));
5839   tt_i64_op(INT64_MIN, OP_EQ,
5840             add_laplace_noise(INT64_MIN, min_dbl_error,
5841                               noscale_df, noscale_eps));
5842   tt_i64_op((-35 + INT64_MAX), OP_EQ,
5843             add_laplace_noise(INT64_MAX, min_dbl_error,
5844                               noscale_df, noscale_eps));
5845   tt_i64_op(INT64_MIN, OP_EQ,
5846             add_laplace_noise(0, min_dbl_error,
5847                               DBL_MAX, 1));
5848   tt_i64_op((INT64_MAX + INT64_MIN), OP_EQ,
5849             add_laplace_noise(INT64_MAX, min_dbl_error,
5850                               DBL_MAX, 1));
5851   tt_i64_op(INT64_MIN, OP_EQ,
5852             add_laplace_noise(INT64_MIN, min_dbl_error,
5853                               DBL_MAX, 1));
5854 
5855   /* does it play nice with INT64_MAX? */
5856   tt_i64_op((INT64_MAX - 35), OP_EQ,
5857             add_laplace_noise(INT64_MAX, min_dbl_error,
5858                               noscale_df, noscale_eps));
5859 
5860   /* Test extreme values of signal with maximally positive values of noise
5861    * 1.0000000000000002 is the smallest number > 1
5862    * 0.9999999999999998 is the greatest number < 1 by calculation
5863    * per https://en.wikipedia.org/wiki/Double_precision
5864    * >>> laplace.ppf([1.0, 0.9999999999999998], loc = 0, scale = 1)
5865    * array([inf,  35.35050621])
5866    * but the function rejects p == 1.0, so we just use max_dbl_lt_one
5867    */
5868   const double max_dbl_lt_one = 0.9999999999999998;
5869 
5870   /* do near-one fractional values work? */
5871   tt_i64_op(35, OP_EQ,
5872             add_laplace_noise(0, max_dbl_lt_one, noscale_df, noscale_eps));
5873 
5874   /* is it clipped to INT64_MAX? */
5875   tt_i64_op(INT64_MAX, OP_EQ,
5876             add_laplace_noise(INT64_MAX - 35, max_dbl_lt_one,
5877                               noscale_df, noscale_eps));
5878   tt_i64_op(INT64_MAX, OP_EQ,
5879             add_laplace_noise(INT64_MAX - 34, max_dbl_lt_one,
5880                               noscale_df, noscale_eps));
5881   tt_i64_op(INT64_MAX, OP_EQ,
5882             add_laplace_noise(INT64_MAX, max_dbl_lt_one,
5883                               noscale_df, noscale_eps));
5884   /* ... even when scaled? */
5885   tt_i64_op(INT64_MAX, OP_EQ,
5886             add_laplace_noise(INT64_MAX, max_dbl_lt_one,
5887                               delta_f, epsilon));
5888   tt_i64_op((INT64_MIN + INT64_MAX), OP_EQ,
5889             add_laplace_noise(INT64_MIN, max_dbl_lt_one,
5890                               DBL_MAX, 1));
5891   tt_i64_op(INT64_MAX, OP_EQ,
5892             add_laplace_noise(INT64_MAX, max_dbl_lt_one,
5893                               DBL_MAX, 1));
5894   /* does it play nice with INT64_MIN? */
5895   tt_i64_op((INT64_MIN + 35), OP_EQ,
5896             add_laplace_noise(INT64_MIN, max_dbl_lt_one,
5897                               noscale_df, noscale_eps));
5898 
5899  done:
5900   ;
5901 }
5902 
5903 static void
test_util_clamp_double_to_int64(void * arg)5904 test_util_clamp_double_to_int64(void *arg)
5905 {
5906   (void)arg;
5907 
5908   tt_i64_op(INT64_MIN, OP_EQ, clamp_double_to_int64(-INFINITY_DBL));
5909   tt_i64_op(INT64_MIN, OP_EQ,
5910             clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0));
5911   tt_i64_op(INT64_MIN, OP_EQ,
5912             clamp_double_to_int64(-1.0 * pow(2.0, 63.0) - 1.0));
5913   tt_i64_op(((uint64_t) -1) << 53, OP_EQ,
5914             clamp_double_to_int64(-1.0 * pow(2.0, 53.0)));
5915   tt_i64_op((((uint64_t) -1) << 53) + 1, OP_EQ,
5916             clamp_double_to_int64(-1.0 * pow(2.0, 53.0) + 1.0));
5917   tt_i64_op(-1, OP_EQ, clamp_double_to_int64(-1.0));
5918   tt_i64_op(0, OP_EQ, clamp_double_to_int64(-0.9));
5919   tt_i64_op(0, OP_EQ, clamp_double_to_int64(-0.1));
5920   tt_i64_op(0, OP_EQ, clamp_double_to_int64(0.0));
5921   tt_i64_op(0, OP_EQ, clamp_double_to_int64(NAN_DBL));
5922   tt_i64_op(0, OP_EQ, clamp_double_to_int64(0.1));
5923   tt_i64_op(0, OP_EQ, clamp_double_to_int64(0.9));
5924   tt_i64_op(1, OP_EQ, clamp_double_to_int64(1.0));
5925   tt_i64_op((((int64_t) 1) << 53) - 1, OP_EQ,
5926             clamp_double_to_int64(pow(2.0, 53.0) - 1.0));
5927   tt_i64_op(((int64_t) 1) << 53, OP_EQ,
5928             clamp_double_to_int64(pow(2.0, 53.0)));
5929   tt_i64_op(INT64_MAX, OP_EQ,
5930             clamp_double_to_int64(pow(2.0, 63.0)));
5931   tt_i64_op(INT64_MAX, OP_EQ,
5932             clamp_double_to_int64(pow(2.0, 64.0)));
5933   tt_i64_op(INT64_MAX, OP_EQ, clamp_double_to_int64(INFINITY_DBL));
5934 
5935  done:
5936   ;
5937 }
5938 
5939 #ifdef FD_CLOEXEC
5940 #define CAN_CHECK_CLOEXEC
5941 static int
fd_is_cloexec(tor_socket_t fd)5942 fd_is_cloexec(tor_socket_t fd)
5943 {
5944   int flags = fcntl(fd, F_GETFD, 0);
5945   return (flags & FD_CLOEXEC) != 0;
5946 }
5947 #endif /* defined(FD_CLOEXEC) */
5948 
5949 #ifndef _WIN32
5950 #define CAN_CHECK_NONBLOCK
5951 static int
fd_is_nonblocking(tor_socket_t fd)5952 fd_is_nonblocking(tor_socket_t fd)
5953 {
5954   int flags = fcntl(fd, F_GETFL, 0);
5955   return (flags & O_NONBLOCK) != 0;
5956 }
5957 #endif /* !defined(_WIN32) */
5958 
5959 #define ERRNO_IS_EPROTO(e)    (e == SOCK_ERRNO(EPROTONOSUPPORT))
5960 #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s))
5961 
5962 /* Test for tor_open_socket*, using IPv4 or IPv6 depending on arg. */
5963 static void
test_util_socket(void * arg)5964 test_util_socket(void *arg)
5965 {
5966   const int domain = !strcmp(arg, "4") ? AF_INET : AF_INET6;
5967   tor_socket_t fd1 = TOR_INVALID_SOCKET;
5968   tor_socket_t fd2 = TOR_INVALID_SOCKET;
5969   tor_socket_t fd3 = TOR_INVALID_SOCKET;
5970   tor_socket_t fd4 = TOR_INVALID_SOCKET;
5971   int n = get_n_open_sockets();
5972 
5973   TT_BLATHER(("Starting with %d open sockets.", n));
5974 
5975   (void)arg;
5976 
5977   fd1 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 0, 0);
5978   int err = tor_socket_errno(fd1);
5979   if (fd1 < 0 && (err == SOCK_ERRNO(EPROTONOSUPPORT) ||
5980                   err == SOCK_ERRNO(EAFNOSUPPORT))) {
5981     /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */
5982     goto done;
5983   }
5984   fd2 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 0, 1);
5985   tt_assert(SOCKET_OK(fd1));
5986   tt_assert(SOCKET_OK(fd2));
5987   tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
5988   //fd3 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 0);
5989   //fd4 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 1);
5990   fd3 = tor_open_socket(domain, SOCK_STREAM, 0);
5991   fd4 = tor_open_socket_nonblocking(domain, SOCK_STREAM, 0);
5992   tt_assert(SOCKET_OK(fd3));
5993   tt_assert(SOCKET_OK(fd4));
5994   tt_int_op(get_n_open_sockets(), OP_EQ, n + 4);
5995 
5996 #ifdef CAN_CHECK_CLOEXEC
5997   tt_int_op(fd_is_cloexec(fd1), OP_EQ, 0);
5998   tt_int_op(fd_is_cloexec(fd2), OP_EQ, 0);
5999   tt_int_op(fd_is_cloexec(fd3), OP_EQ, 1);
6000   tt_int_op(fd_is_cloexec(fd4), OP_EQ, 1);
6001 #endif /* defined(CAN_CHECK_CLOEXEC) */
6002 #ifdef CAN_CHECK_NONBLOCK
6003   tt_int_op(fd_is_nonblocking(fd1), OP_EQ, 0);
6004   tt_int_op(fd_is_nonblocking(fd2), OP_EQ, 1);
6005   tt_int_op(fd_is_nonblocking(fd3), OP_EQ, 0);
6006   tt_int_op(fd_is_nonblocking(fd4), OP_EQ, 1);
6007 #endif /* defined(CAN_CHECK_NONBLOCK) */
6008 
6009   tor_assert(tor_close_socket == tor_close_socket__real);
6010 
6011   /* we use close_socket__real here so that coverity can tell that we are
6012    * really closing these sockets. */
6013   tor_close_socket__real(fd1);
6014   tor_close_socket__real(fd2);
6015   fd1 = fd2 = TOR_INVALID_SOCKET;
6016   tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
6017   tor_close_socket__real(fd3);
6018   tor_close_socket__real(fd4);
6019   fd3 = fd4 = TOR_INVALID_SOCKET;
6020   tt_int_op(get_n_open_sockets(), OP_EQ, n);
6021 
6022  done:
6023   if (SOCKET_OK(fd1))
6024     tor_close_socket__real(fd1);
6025   if (SOCKET_OK(fd2))
6026     tor_close_socket__real(fd2);
6027   if (SOCKET_OK(fd3))
6028     tor_close_socket__real(fd3);
6029   if (SOCKET_OK(fd4))
6030     tor_close_socket__real(fd4);
6031 }
6032 
6033 #if 0
6034 static int
6035 is_there_a_localhost(int family)
6036 {
6037   tor_socket_t s;
6038   s = tor_open_socket(family, SOCK_STREAM, IPPROTO_TCP);
6039   tor_assert(SOCKET_OK(s));
6040 
6041   int result = 0;
6042   if (family == AF_INET) {
6043     struct sockaddr_in s_in;
6044     memset(&s_in, 0, sizeof(s_in));
6045     s_in.sin_family = AF_INET;
6046     s_in.sin_addr.s_addr = htonl(0x7f000001);
6047     s_in.sin_port = 0;
6048 
6049     if (bind(s, (void*)&s_in, sizeof(s_in)) == 0) {
6050       result = 1;
6051     }
6052   } else if (family == AF_INET6) {
6053     struct sockaddr_in6 sin6;
6054     memset(&sin6, 0, sizeof(sin6));
6055     sin6.sin6_family = AF_INET6;
6056     sin6.sin6_addr.s6_addr[15] = 1;
6057     sin6.sin6_port = 0;
6058   }
6059   tor_close_socket(s);
6060 
6061   return result;
6062 }
6063 #endif /* 0 */
6064 
6065 /* Test for socketpair and ersatz_socketpair().  We test them both, since
6066  * the latter is a tolerably good way to exercise tor_accept_socket(). */
6067 static void
test_util_socketpair(void * arg)6068 test_util_socketpair(void *arg)
6069 {
6070   const int ersatz = !strcmp(arg, "1");
6071   int (*const tor_socketpair_fn)(int, int, int, tor_socket_t[2]) =
6072     ersatz ? tor_ersatz_socketpair : tor_socketpair;
6073   int n = get_n_open_sockets();
6074   tor_socket_t fds[2] = {TOR_INVALID_SOCKET, TOR_INVALID_SOCKET};
6075   const int family = AF_UNIX;
6076   int socketpair_result = 0;
6077 
6078   socketpair_result = tor_socketpair_fn(family, SOCK_STREAM, 0, fds);
6079 
6080 #ifdef __FreeBSD__
6081   /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
6082    * Otherwise, we risk exposing a socketpair on a routable IP address. (Some
6083    * BSD jails use a routable address for localhost. Fortunately, they have
6084    * the real AF_UNIX socketpair.) */
6085   if (ersatz && socketpair_result < 0) {
6086     /* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
6087      * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
6088     tt_skip();
6089   }
6090 #endif /* defined(__FreeBSD__) */
6091 #ifdef ENETUNREACH
6092   if (ersatz && socketpair_result == -ENETUNREACH) {
6093     /* We can also fail with -ENETUNREACH if we have no network stack at
6094      * all. */
6095     tt_skip();
6096   }
6097 #endif /* defined(ENETUNREACH) */
6098   tt_int_op(0, OP_EQ, socketpair_result);
6099 
6100   tt_assert(SOCKET_OK(fds[0]));
6101   tt_assert(SOCKET_OK(fds[1]));
6102   if (ersatz)
6103     tt_int_op(get_n_open_sockets(), OP_EQ, n);
6104   else
6105     tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
6106 #ifdef CAN_CHECK_CLOEXEC
6107   tt_int_op(fd_is_cloexec(fds[0]), OP_EQ, !ersatz);
6108   tt_int_op(fd_is_cloexec(fds[1]), OP_EQ, !ersatz);
6109 #endif
6110 #ifdef CAN_CHECK_NONBLOCK
6111   tt_int_op(fd_is_nonblocking(fds[0]), OP_EQ, 0);
6112   tt_int_op(fd_is_nonblocking(fds[1]), OP_EQ, 0);
6113 #endif
6114 
6115  done:
6116   if (ersatz) {
6117     if (SOCKET_OK(fds[0]))
6118       tor_close_socket_simple(fds[0]);
6119     if (SOCKET_OK(fds[1]))
6120       tor_close_socket_simple(fds[1]);
6121   } else {
6122     if (SOCKET_OK(fds[0]))
6123       tor_close_socket(fds[0]);
6124     if (SOCKET_OK(fds[1]))
6125       tor_close_socket(fds[1]);
6126   }
6127 }
6128 
6129 #undef SOCKET_EPROTO
6130 
6131 static void
test_util_max_mem(void * arg)6132 test_util_max_mem(void *arg)
6133 {
6134   size_t memory1, memory2;
6135   int r, r2;
6136   (void) arg;
6137 
6138   r = get_total_system_memory(&memory1);
6139   r2 = get_total_system_memory(&memory2);
6140   tt_int_op(r, OP_EQ, r2);
6141   tt_uint_op(memory2, OP_EQ, memory1);
6142 
6143   TT_BLATHER(("System memory: %"TOR_PRIuSZ, (memory1)));
6144 
6145   if (r==0) {
6146     /* You have at least a megabyte. */
6147     tt_uint_op(memory1, OP_GT, (1<<20));
6148   } else {
6149     /* You do not have a petabyte. */
6150 #if SIZEOF_SIZE_T >= 8
6151     tt_u64_op(memory1, OP_LT, (UINT64_C(1)<<50));
6152 #endif
6153   }
6154 
6155  done:
6156   ;
6157 }
6158 
6159 static void
test_util_dest_validation_edgecase(void * arg)6160 test_util_dest_validation_edgecase(void *arg)
6161 {
6162   (void)arg;
6163 
6164   tt_assert(!string_is_valid_dest(NULL));
6165   tt_assert(!string_is_valid_dest(""));
6166 
6167   done:
6168   return;
6169 }
6170 
6171 static void
test_util_hostname_validation(void * arg)6172 test_util_hostname_validation(void *arg)
6173 {
6174   (void)arg;
6175 
6176   // Lets try valid hostnames first.
6177   tt_assert(string_is_valid_nonrfc_hostname("torproject.org"));
6178   tt_assert(string_is_valid_nonrfc_hostname("ocw.mit.edu"));
6179   tt_assert(string_is_valid_nonrfc_hostname("i.4cdn.org"));
6180   tt_assert(string_is_valid_nonrfc_hostname("stanford.edu"));
6181   tt_assert(string_is_valid_nonrfc_hostname("multiple-words-with-hypens.jp"));
6182 
6183   // Subdomain name cannot start with '-' or '_'.
6184   tt_assert(!string_is_valid_nonrfc_hostname("-torproject.org"));
6185   tt_assert(!string_is_valid_nonrfc_hostname("subdomain.-domain.org"));
6186   tt_assert(!string_is_valid_nonrfc_hostname("-subdomain.domain.org"));
6187   tt_assert(!string_is_valid_nonrfc_hostname("___abc.org"));
6188 
6189   // Hostnames cannot contain non-alphanumeric characters.
6190   tt_assert(!string_is_valid_nonrfc_hostname("%%domain.\\org."));
6191   tt_assert(!string_is_valid_nonrfc_hostname("***x.net"));
6192   tt_assert(!string_is_valid_nonrfc_hostname("\xff\xffxyz.org"));
6193   tt_assert(!string_is_valid_nonrfc_hostname("word1 word2.net"));
6194 
6195   // Test workaround for nytimes.com stupidity, technically invalid,
6196   // but we allow it since they are big, even though they are failing to
6197   // comply with a ~30 year old standard.
6198   tt_assert(string_is_valid_nonrfc_hostname("core3_euw1.fabrik.nytimes.com"));
6199 
6200   // Firefox passes FQDNs with trailing '.'s  directly to the SOCKS proxy,
6201   // which is redundant since the spec states DOMAINNAME addresses are fully
6202   // qualified.  While unusual, this should be tollerated.
6203   tt_assert(string_is_valid_nonrfc_hostname("core9_euw1.fabrik.nytimes.com."));
6204   tt_assert(!string_is_valid_nonrfc_hostname(
6205                                          "..washingtonpost.is.better.com"));
6206   tt_assert(!string_is_valid_nonrfc_hostname("so.is..ft.com"));
6207   tt_assert(!string_is_valid_nonrfc_hostname("..."));
6208 
6209   // XXX: do we allow single-label DNS names?
6210   // We shouldn't for SOCKS (spec says "contains a fully-qualified domain name"
6211   // but only test pathologically malformed trailing '.' cases for now.
6212   tt_assert(!string_is_valid_nonrfc_hostname("."));
6213   tt_assert(!string_is_valid_nonrfc_hostname(".."));
6214 
6215   // IP address strings are not hostnames.
6216   tt_assert(!string_is_valid_nonrfc_hostname("8.8.8.8"));
6217   tt_assert(!string_is_valid_nonrfc_hostname("[2a00:1450:401b:800::200e]"));
6218   tt_assert(!string_is_valid_nonrfc_hostname("2a00:1450:401b:800::200e"));
6219 
6220   // We allow alphanumeric TLDs. For discussion, see ticket #25055.
6221   tt_assert(string_is_valid_nonrfc_hostname("lucky.13"));
6222   tt_assert(string_is_valid_nonrfc_hostname("luck.y13"));
6223   tt_assert(string_is_valid_nonrfc_hostname("luck.y13."));
6224 
6225   // We allow punycode TLDs. For examples, see
6226   // https://data.iana.org/TLD/tlds-alpha-by-domain.txt
6227   tt_assert(string_is_valid_nonrfc_hostname("example.xn--l1acc"));
6228 
6229   done:
6230   return;
6231 }
6232 
6233 static void
test_util_ipv4_validation(void * arg)6234 test_util_ipv4_validation(void *arg)
6235 {
6236   (void)arg;
6237 
6238   tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
6239   tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
6240 
6241   tt_assert(!string_is_valid_ipv4_address("abcd"));
6242   tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
6243   tt_assert(!string_is_valid_ipv4_address("8.8."));
6244 
6245   done:
6246   return;
6247 }
6248 
6249 static void
test_util_ipv6_validation(void * arg)6250 test_util_ipv6_validation(void *arg)
6251 {
6252   (void)arg;
6253 
6254   tt_assert(string_is_valid_ipv6_address("2a00:1450:401b:800::200e"));
6255   tt_assert(!string_is_valid_ipv6_address("11:22::33:44:"));
6256 
6257   done:
6258   return;
6259 }
6260 
6261 static void
test_util_writepid(void * arg)6262 test_util_writepid(void *arg)
6263 {
6264   (void) arg;
6265 
6266   char *contents = NULL;
6267   const char *fname = get_fname("tmp_pid");
6268   unsigned long pid;
6269   char c;
6270 
6271   write_pidfile(fname);
6272 
6273   contents = read_file_to_str(fname, 0, NULL);
6274   tt_assert(contents);
6275 
6276   int n = tor_sscanf(contents, "%lu\n%c", &pid, &c);
6277   tt_int_op(n, OP_EQ, 1);
6278 
6279 #ifdef _WIN32
6280   tt_uint_op(pid, OP_EQ, _getpid());
6281 #else
6282   tt_uint_op(pid, OP_EQ, getpid());
6283 #endif
6284 
6285  done:
6286   tor_free(contents);
6287 }
6288 
6289 static void
test_util_get_avail_disk_space(void * arg)6290 test_util_get_avail_disk_space(void *arg)
6291 {
6292   (void) arg;
6293   int64_t val;
6294 
6295   /* No answer for nonexistent directory */
6296   val = tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
6297   tt_i64_op(val, OP_EQ, -1);
6298 
6299   /* Try the current directory */
6300   val = tor_get_avail_disk_space(".");
6301 
6302 #if !defined(HAVE_STATVFS) && !defined(_WIN32)
6303   tt_i64_op(val, OP_EQ, -1); /* You don't have an implementation for this */
6304 #else
6305   tt_i64_op(val, OP_GT, 0); /* You have some space. */
6306   tt_i64_op(val, OP_LT, ((int64_t)1)<<56); /* You don't have a zebibyte */
6307 #endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */
6308 
6309  done:
6310   ;
6311 }
6312 
6313 /** Helper: Change the atime and mtime of a file. */
6314 static void
set_file_mtime(const char * fname,time_t when)6315 set_file_mtime(const char *fname, time_t when)
6316 {
6317   struct utimbuf u = { when, when };
6318   struct stat st;
6319   tt_int_op(0, OP_EQ, utime(fname, &u));
6320   tt_int_op(0, OP_EQ, stat(fname, &st));
6321   /* Let's hope that utime/stat give the same second as a round-trip? */
6322   tt_i64_op(st.st_mtime, OP_EQ, when);
6323 done:
6324   ;
6325 }
6326 
6327 static void
test_util_touch_file(void * arg)6328 test_util_touch_file(void *arg)
6329 {
6330   (void) arg;
6331   const char *fname = get_fname("touch");
6332 
6333   const time_t now = time(NULL);
6334   struct stat st;
6335   write_bytes_to_file(fname, "abc", 3, 1);
6336   tt_int_op(0, OP_EQ, stat(fname, &st));
6337   /* A subtle point: the filesystem time is not necessarily equal to the
6338    * system clock time, since one can be using a monotonic clock, or coarse
6339    * monotonic clock, or whatever.  So we might wind up with an mtime a few
6340    * microseconds ago.  Let's just give it a lot of wiggle room. */
6341   tt_i64_op(st.st_mtime, OP_GE, now - 1);
6342 
6343   const time_t five_sec_ago = now - 5;
6344   set_file_mtime(fname, five_sec_ago);
6345 
6346   /* Finally we can touch the file */
6347   tt_int_op(0, OP_EQ, touch_file(fname));
6348   tt_int_op(0, OP_EQ, stat(fname, &st));
6349   tt_i64_op(st.st_mtime, OP_GE, now-1);
6350 
6351  done:
6352   ;
6353 }
6354 
6355 #ifndef DISABLE_PWDB_TESTS
6356 static void
test_util_pwdb(void * arg)6357 test_util_pwdb(void *arg)
6358 {
6359   (void) arg;
6360   const struct passwd *me = NULL, *me2, *me3;
6361   char *name = NULL;
6362   char *dir = NULL;
6363 
6364   /* Uncached case. */
6365   /* Let's assume that we exist. */
6366   me = tor_getpwuid(getuid());
6367   tt_ptr_op(me, OP_NE, NULL);
6368   name = tor_strdup(me->pw_name);
6369 
6370   /* Uncached case */
6371   me2 = tor_getpwnam(name);
6372   tt_ptr_op(me2, OP_NE, NULL);
6373   tt_int_op(me2->pw_uid, OP_EQ, getuid());
6374 
6375   /* Cached case */
6376   me3 = tor_getpwuid(getuid());
6377   tt_ptr_op(me3, OP_NE, NULL);
6378   tt_str_op(me3->pw_name, OP_EQ, name);
6379 
6380   me3 = tor_getpwnam(name);
6381   tt_ptr_op(me3, OP_NE, NULL);
6382   tt_int_op(me3->pw_uid, OP_EQ, getuid());
6383 
6384   dir = get_user_homedir(name);
6385   tt_ptr_op(dir, OP_NE, NULL);
6386 
6387   /* Try failing cases.  First find a user that doesn't exist by name */
6388   char randbytes[4];
6389   char badname[9];
6390   int i, found=0;
6391   for (i = 0; i < 100; ++i) {
6392     crypto_rand(randbytes, sizeof(randbytes));
6393     base16_encode(badname, sizeof(badname), randbytes, sizeof(randbytes));
6394     if (tor_getpwnam(badname) == NULL) {
6395       found = 1;
6396       break;
6397     }
6398   }
6399   tt_assert(found);
6400   tor_free(dir);
6401 
6402   /* We should do a LOG_ERR */
6403   setup_full_capture_of_logs(LOG_ERR);
6404   dir = get_user_homedir(badname);
6405   tt_ptr_op(dir, OP_EQ, NULL);
6406   expect_log_msg_containing("not found");
6407   tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
6408   teardown_capture_of_logs();
6409 
6410   /* Now try to find a user that doesn't exist by ID. */
6411   found = 0;
6412   for (i = 0; i < 1000; ++i) {
6413     uid_t u;
6414     crypto_rand((char*)&u, sizeof(u));
6415     if (tor_getpwuid(u) == NULL) {
6416       found = 1;
6417       break;
6418     }
6419   }
6420   tt_assert(found);
6421 
6422  done:
6423   tor_free(name);
6424   tor_free(dir);
6425   teardown_capture_of_logs();
6426 }
6427 #endif /* !defined(DISABLE_PWDB_TESTS) */
6428 
6429 static void
test_util_calloc_check(void * arg)6430 test_util_calloc_check(void *arg)
6431 {
6432   (void) arg;
6433   /* Easy cases that are good. */
6434   tt_assert(size_mul_check(0,0));
6435   tt_assert(size_mul_check(0,100));
6436   tt_assert(size_mul_check(100,0));
6437   tt_assert(size_mul_check(100,100));
6438 
6439   /* Harder cases that are still good. */
6440   tt_assert(size_mul_check(SIZE_MAX, 1));
6441   tt_assert(size_mul_check(1, SIZE_MAX));
6442   tt_assert(size_mul_check(SIZE_MAX / 10, 9));
6443   tt_assert(size_mul_check(11, SIZE_MAX / 12));
6444   const size_t sqrt_size_max_p1 = ((size_t)1) << (sizeof(size_t) * 4);
6445   tt_assert(size_mul_check(sqrt_size_max_p1, sqrt_size_max_p1 - 1));
6446 
6447   /* Cases that overflow */
6448   tt_assert(! size_mul_check(SIZE_MAX, 2));
6449   tt_assert(! size_mul_check(2, SIZE_MAX));
6450   tt_assert(! size_mul_check(SIZE_MAX / 10, 11));
6451   tt_assert(! size_mul_check(11, SIZE_MAX / 10));
6452   tt_assert(! size_mul_check(SIZE_MAX / 8, 9));
6453   tt_assert(! size_mul_check(sqrt_size_max_p1, sqrt_size_max_p1));
6454 
6455  done:
6456   ;
6457 }
6458 
6459 static void
test_util_monotonic_time(void * arg)6460 test_util_monotonic_time(void *arg)
6461 {
6462   (void)arg;
6463 
6464   monotime_t mt1, mt2;
6465   monotime_coarse_t mtc1, mtc2;
6466   uint64_t nsec1, nsec2, usec1, msec1;
6467   uint64_t nsecc1, nsecc2, usecc1, msecc1;
6468   uint32_t stamp1, stamp2;
6469 
6470   monotime_init();
6471 
6472   monotime_get(&mt1);
6473   monotime_coarse_get(&mtc1);
6474   nsec1 = monotime_absolute_nsec();
6475   usec1 = monotime_absolute_usec();
6476   msec1 = monotime_absolute_msec();
6477   nsecc1 = monotime_coarse_absolute_nsec();
6478   usecc1 = monotime_coarse_absolute_usec();
6479   msecc1 = monotime_coarse_absolute_msec();
6480   stamp1 = monotime_coarse_to_stamp(&mtc1);
6481 
6482   tor_sleep_msec(200);
6483 
6484   monotime_get(&mt2);
6485   monotime_coarse_get(&mtc2);
6486   nsec2 = monotime_absolute_nsec();
6487   nsecc2 = monotime_coarse_absolute_nsec();
6488   stamp2 = monotime_coarse_to_stamp(&mtc2);
6489 
6490   /* We need to be a little careful here since we don't know the system load.
6491    */
6492   tt_i64_op(monotime_diff_msec(&mt1, &mt2), OP_GE, 175);
6493   tt_i64_op(monotime_diff_msec(&mt1, &mt2), OP_LT, 1000);
6494   tt_i64_op(monotime_coarse_diff_msec(&mtc1, &mtc2), OP_GE, 125);
6495   tt_i64_op(monotime_coarse_diff_msec(&mtc1, &mtc2), OP_LT, 1000);
6496   tt_u64_op(nsec2-nsec1, OP_GE, 175000000);
6497   tt_u64_op(nsec2-nsec1, OP_LT, 1000000000);
6498   tt_u64_op(nsecc2-nsecc1, OP_GE, 125000000);
6499   tt_u64_op(nsecc2-nsecc1, OP_LT, 1000000000);
6500 
6501   tt_u64_op(msec1, OP_GE, nsec1 / 1000000);
6502   tt_u64_op(usec1, OP_GE, nsec1 / 1000);
6503   tt_u64_op(msecc1, OP_GE, nsecc1 / 1000000);
6504   tt_u64_op(usecc1, OP_GE, nsecc1 / 1000);
6505   tt_u64_op(msec1, OP_LE, nsec1 / 1000000 + 10);
6506   tt_u64_op(usec1, OP_LE, nsec1 / 1000 + 10000);
6507   tt_u64_op(msecc1, OP_LE, nsecc1 / 1000000 + 10);
6508   tt_u64_op(usecc1, OP_LE, nsecc1 / 1000 + 10000);
6509 
6510   uint64_t coarse_stamp_diff =
6511     monotime_coarse_stamp_units_to_approx_msec(stamp2-stamp1);
6512   tt_u64_op(coarse_stamp_diff, OP_GE, 120);
6513   tt_u64_op(coarse_stamp_diff, OP_LE, 1200);
6514 
6515   {
6516     uint64_t units = monotime_msec_to_approx_coarse_stamp_units(5000);
6517     uint64_t ms = monotime_coarse_stamp_units_to_approx_msec(units);
6518     tt_u64_op(ms, OP_GE, 4950);
6519     tt_u64_op(ms, OP_LT, 5050);
6520   }
6521 
6522  done:
6523   ;
6524 }
6525 
6526 static void
test_util_monotonic_time_ratchet(void * arg)6527 test_util_monotonic_time_ratchet(void *arg)
6528 {
6529   (void)arg;
6530   monotime_init();
6531   monotime_reset_ratchets_for_testing();
6532 
6533   /* win32, performance counter ratchet. */
6534   tt_i64_op(100, OP_EQ, ratchet_performance_counter(100));
6535   tt_i64_op(101, OP_EQ, ratchet_performance_counter(101));
6536   tt_i64_op(2000, OP_EQ, ratchet_performance_counter(2000));
6537   tt_i64_op(2000, OP_EQ, ratchet_performance_counter(100));
6538   tt_i64_op(2005, OP_EQ, ratchet_performance_counter(105));
6539   tt_i64_op(3005, OP_EQ, ratchet_performance_counter(1105));
6540   tt_i64_op(3005, OP_EQ, ratchet_performance_counter(1000));
6541   tt_i64_op(3010, OP_EQ, ratchet_performance_counter(1005));
6542 
6543   /* win32, GetTickCounts32 ratchet-and-rollover-detector. */
6544   const int64_t R = ((int64_t)1) << 32;
6545   tt_i64_op(5, OP_EQ, ratchet_coarse_performance_counter(5));
6546   tt_i64_op(1000, OP_EQ, ratchet_coarse_performance_counter(1000));
6547   tt_i64_op(5+R, OP_EQ, ratchet_coarse_performance_counter(5));
6548   tt_i64_op(10+R, OP_EQ, ratchet_coarse_performance_counter(10));
6549   tt_i64_op(4+R*2, OP_EQ, ratchet_coarse_performance_counter(4));
6550 
6551   /* gettimeofday regular ratchet. */
6552   struct timeval tv_in = {0,0}, tv_out;
6553   tv_in.tv_usec = 9000;
6554 
6555   ratchet_timeval(&tv_in, &tv_out);
6556   tt_int_op(tv_out.tv_usec, OP_EQ, 9000);
6557   tt_i64_op(tv_out.tv_sec, OP_EQ, 0);
6558 
6559   tv_in.tv_sec = 1337;
6560   tv_in.tv_usec = 0;
6561   ratchet_timeval(&tv_in, &tv_out);
6562   tt_int_op(tv_out.tv_usec, OP_EQ, 0);
6563   tt_i64_op(tv_out.tv_sec, OP_EQ, 1337);
6564 
6565   tv_in.tv_sec = 1336;
6566   tv_in.tv_usec = 500000;
6567   ratchet_timeval(&tv_in, &tv_out);
6568   tt_int_op(tv_out.tv_usec, OP_EQ, 0);
6569   tt_i64_op(tv_out.tv_sec, OP_EQ, 1337);
6570 
6571   tv_in.tv_sec = 1337;
6572   tv_in.tv_usec = 0;
6573   ratchet_timeval(&tv_in, &tv_out);
6574   tt_int_op(tv_out.tv_usec, OP_EQ, 500000);
6575   tt_i64_op(tv_out.tv_sec, OP_EQ, 1337);
6576 
6577   tv_in.tv_sec = 1337;
6578   tv_in.tv_usec = 600000;
6579   ratchet_timeval(&tv_in, &tv_out);
6580   tt_int_op(tv_out.tv_usec, OP_EQ, 100000);
6581   tt_i64_op(tv_out.tv_sec, OP_EQ, 1338);
6582 
6583   tv_in.tv_sec = 1000;
6584   tv_in.tv_usec = 1000;
6585   ratchet_timeval(&tv_in, &tv_out);
6586   tt_int_op(tv_out.tv_usec, OP_EQ, 100000);
6587   tt_i64_op(tv_out.tv_sec, OP_EQ, 1338);
6588 
6589   tv_in.tv_sec = 2000;
6590   tv_in.tv_usec = 2000;
6591   ratchet_timeval(&tv_in, &tv_out);
6592   tt_int_op(tv_out.tv_usec, OP_EQ, 101000);
6593   tt_i64_op(tv_out.tv_sec, OP_EQ, 2338);
6594 
6595  done:
6596   ;
6597 }
6598 
6599 static void
test_util_monotonic_time_zero(void * arg)6600 test_util_monotonic_time_zero(void *arg)
6601 {
6602   (void) arg;
6603   monotime_t t1;
6604   monotime_coarse_t ct1;
6605   monotime_init();
6606   /* Check 1: The current time is not zero. */
6607   monotime_get(&t1);
6608   monotime_coarse_get(&ct1);
6609   tt_assert(!monotime_is_zero(&t1));
6610   tt_assert(!monotime_coarse_is_zero(&ct1));
6611 
6612   /* Check 2: The _zero() makes the time zero. */
6613   monotime_zero(&t1);
6614   monotime_coarse_zero(&ct1);
6615   tt_assert(monotime_is_zero(&t1));
6616   tt_assert(monotime_coarse_is_zero(&ct1));
6617  done:
6618   ;
6619 }
6620 
6621 static void
test_util_monotonic_time_add_msec(void * arg)6622 test_util_monotonic_time_add_msec(void *arg)
6623 {
6624   (void) arg;
6625   monotime_t t1, t2;
6626   monotime_coarse_t ct1, ct2;
6627   monotime_init();
6628 
6629   monotime_get(&t1);
6630   monotime_coarse_get(&ct1);
6631 
6632   /* adding zero does nothing */
6633   monotime_add_msec(&t2, &t1, 0);
6634   monotime_coarse_add_msec(&ct2, &ct1, 0);
6635   tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 0);
6636   tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 0);
6637 
6638   /* Add 1337 msec; see if the diff function agree */
6639   monotime_add_msec(&t2, &t1, 1337);
6640   monotime_coarse_add_msec(&ct2, &ct1, 1337);
6641   tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337);
6642   tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337);
6643   // The 32-bit variant must be within 1% of the regular one.
6644   tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_GT, 1323);
6645   tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_LT, 1350);
6646 
6647   /* Add 1337 msec twice more; make sure that any second rollover issues
6648    * worked. */
6649   monotime_add_msec(&t2, &t2, 1337);
6650   monotime_coarse_add_msec(&ct2, &ct2, 1337);
6651   monotime_add_msec(&t2, &t2, 1337);
6652   monotime_coarse_add_msec(&ct2, &ct2, 1337);
6653   tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337*3);
6654   tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337*3);
6655   tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_GT, 3970);
6656   tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_LT, 4051);
6657 
6658  done:
6659   ;
6660 }
6661 
6662 static void
test_util_nowrap_math(void * arg)6663 test_util_nowrap_math(void *arg)
6664 {
6665   (void)arg;
6666 
6667   tt_u64_op(0, OP_EQ, tor_add_u32_nowrap(0, 0));
6668   tt_u64_op(1, OP_EQ, tor_add_u32_nowrap(0, 1));
6669   tt_u64_op(1, OP_EQ, tor_add_u32_nowrap(1, 0));
6670   tt_u64_op(4, OP_EQ, tor_add_u32_nowrap(2, 2));
6671   tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(UINT32_MAX-1, 2));
6672   tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(2, UINT32_MAX-1));
6673   tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(UINT32_MAX, UINT32_MAX));
6674 
6675   tt_u64_op(0, OP_EQ, tor_mul_u64_nowrap(0, 0));
6676   tt_u64_op(1, OP_EQ, tor_mul_u64_nowrap(1, 1));
6677   tt_u64_op(2, OP_EQ, tor_mul_u64_nowrap(2, 1));
6678   tt_u64_op(4, OP_EQ, tor_mul_u64_nowrap(2, 2));
6679   tt_u64_op(UINT64_MAX, OP_EQ, tor_mul_u64_nowrap(UINT64_MAX, 1));
6680   tt_u64_op(UINT64_MAX, OP_EQ, tor_mul_u64_nowrap(2, UINT64_MAX));
6681   tt_u64_op(UINT64_MAX, OP_EQ, tor_mul_u64_nowrap(UINT64_MAX, UINT64_MAX));
6682 
6683  done:
6684   ;
6685 }
6686 
6687 static void
test_util_htonll(void * arg)6688 test_util_htonll(void *arg)
6689 {
6690   (void)arg;
6691 #ifdef WORDS_BIGENDIAN
6692   const uint64_t res_be = 0x8877665544332211;
6693 #else
6694   const uint64_t res_le = 0x1122334455667788;
6695 #endif
6696 
6697   tt_u64_op(0, OP_EQ, tor_htonll(0));
6698   tt_u64_op(0, OP_EQ, tor_ntohll(0));
6699   tt_u64_op(UINT64_MAX, OP_EQ, tor_htonll(UINT64_MAX));
6700   tt_u64_op(UINT64_MAX, OP_EQ, tor_ntohll(UINT64_MAX));
6701 
6702 #ifdef WORDS_BIGENDIAN
6703   tt_u64_op(res_be, OP_EQ, tor_htonll(0x8877665544332211));
6704   tt_u64_op(res_be, OP_EQ, tor_ntohll(0x8877665544332211));
6705 #else
6706   tt_u64_op(res_le, OP_EQ, tor_htonll(0x8877665544332211));
6707   tt_u64_op(res_le, OP_EQ, tor_ntohll(0x8877665544332211));
6708 #endif /* defined(WORDS_BIGENDIAN) */
6709 
6710  done:
6711   ;
6712 }
6713 
6714 static void
test_util_get_unquoted_path(void * arg)6715 test_util_get_unquoted_path(void *arg)
6716 {
6717   (void)arg;
6718 
6719   char *r = NULL;
6720 
6721   r = get_unquoted_path("\""); // "
6722   tt_ptr_op(r, OP_EQ, NULL);
6723   tor_free(r);
6724 
6725   r = get_unquoted_path("\"\"\""); // """
6726   tt_ptr_op(r, OP_EQ, NULL);
6727   tor_free(r);
6728 
6729   r = get_unquoted_path("\\\""); // \"
6730   tt_ptr_op(r, OP_EQ, NULL);
6731   tor_free(r);
6732 
6733   r = get_unquoted_path("\\\"\\\""); // \"\"
6734   tt_ptr_op(r, OP_EQ, NULL);
6735   tor_free(r);
6736 
6737   r = get_unquoted_path("A\\B\\C\""); // A\B\C"
6738   tt_ptr_op(r, OP_EQ, NULL);
6739   tor_free(r);
6740 
6741   r = get_unquoted_path("\"A\\B\\C"); // "A\B\C
6742   tt_ptr_op(r, OP_EQ, NULL);
6743   tor_free(r);
6744 
6745   r = get_unquoted_path("\"A\\B\"C\""); // "A\B"C"
6746   tt_ptr_op(r, OP_EQ, NULL);
6747   tor_free(r);
6748 
6749   r = get_unquoted_path("A\\B\"C"); // A\B"C
6750   tt_ptr_op(r, OP_EQ, NULL);
6751   tor_free(r);
6752 
6753   r = get_unquoted_path("");
6754   tt_str_op(r, OP_EQ, "");
6755   tor_free(r);
6756 
6757   r = get_unquoted_path("\"\""); // ""
6758   tt_str_op(r, OP_EQ, "");
6759   tor_free(r);
6760 
6761   r = get_unquoted_path("A\\B\\C"); // A\B\C
6762   tt_str_op(r, OP_EQ, "A\\B\\C"); // A\B\C
6763   tor_free(r);
6764 
6765   r = get_unquoted_path("\"A\\B\\C\""); // "A\B\C"
6766   tt_str_op(r, OP_EQ, "A\\B\\C"); // A\B\C
6767   tor_free(r);
6768 
6769   r = get_unquoted_path("\"\\\""); // "\"
6770   tt_str_op(r, OP_EQ, "\\"); // \ /* comment to prevent line continuation */
6771   tor_free(r);
6772 
6773   r = get_unquoted_path("\"\\\"\""); // "\""
6774   tt_str_op(r, OP_EQ, "\""); // "
6775   tor_free(r);
6776 
6777   r = get_unquoted_path("\"A\\B\\C\\\"\""); // "A\B\C\""
6778   tt_str_op(r, OP_EQ, "A\\B\\C\""); // A\B\C"
6779   tor_free(r);
6780 
6781   r = get_unquoted_path("A\\B\\\"C"); // A\B\"C
6782   tt_str_op(r, OP_EQ, "A\\B\"C"); // A\B"C
6783   tor_free(r);
6784 
6785   r = get_unquoted_path("\"A\\B\\\"C\""); // "A\B\"C"
6786   tt_str_op(r, OP_EQ, "A\\B\"C"); // A\B"C
6787 
6788  done:
6789   tor_free(r);
6790 }
6791 
6792 static void
test_util_map_anon(void * arg)6793 test_util_map_anon(void *arg)
6794 {
6795   (void)arg;
6796   char *ptr = NULL;
6797   size_t sz = 16384;
6798   unsigned inherit=0;
6799 
6800   /* Basic checks. */
6801   ptr = tor_mmap_anonymous(sz, 0, &inherit);
6802   tt_ptr_op(ptr, OP_NE, 0);
6803   tt_int_op(inherit, OP_EQ, INHERIT_RES_KEEP);
6804   ptr[sz-1] = 3;
6805   tt_int_op(ptr[0], OP_EQ, 0);
6806   tt_int_op(ptr[sz-2], OP_EQ, 0);
6807   tt_int_op(ptr[sz-1], OP_EQ, 3);
6808 
6809   /* Try again, with a private (non-swappable) mapping. */
6810   tor_munmap_anonymous(ptr, sz);
6811   ptr = tor_mmap_anonymous(sz, ANONMAP_PRIVATE, &inherit);
6812   tt_ptr_op(ptr, OP_NE, 0);
6813   tt_int_op(inherit, OP_EQ, INHERIT_RES_KEEP);
6814   ptr[sz-1] = 10;
6815   tt_int_op(ptr[0], OP_EQ, 0);
6816   tt_int_op(ptr[sz/2], OP_EQ, 0);
6817   tt_int_op(ptr[sz-1], OP_EQ, 10);
6818 
6819   /* Now let's test a drop-on-fork mapping. */
6820   tor_munmap_anonymous(ptr, sz);
6821   ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT, &inherit);
6822   tt_ptr_op(ptr, OP_NE, 0);
6823   ptr[sz-1] = 10;
6824   tt_int_op(ptr[0], OP_EQ, 0);
6825   tt_int_op(ptr[sz/2], OP_EQ, 0);
6826   tt_int_op(ptr[sz-1], OP_EQ, 10);
6827 
6828  done:
6829   tor_munmap_anonymous(ptr, sz);
6830 }
6831 
6832 static void
test_util_map_anon_nofork(void * arg)6833 test_util_map_anon_nofork(void *arg)
6834 {
6835   (void)arg;
6836 #ifdef _WIN32
6837   /* The operating system doesn't support forking. */
6838   tt_skip();
6839  done:
6840   ;
6841 #else /* !defined(_WIN32) */
6842   /* We have the right OS support.  We're going to try marking the buffer as
6843    * either zero-on-fork or as drop-on-fork, whichever is supported.  Then we
6844    * will fork and send a byte back to the parent process.  This will either
6845    * crash, or send zero. */
6846 
6847   char *ptr = NULL;
6848   const char TEST_VALUE = 0xd0;
6849   size_t sz = 16384;
6850   int pipefd[2] = {-1, -1};
6851   unsigned inherit=0;
6852 
6853   tor_munmap_anonymous(ptr, sz);
6854   ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT, &inherit);
6855   tt_ptr_op(ptr, OP_NE, 0);
6856   memset(ptr, (uint8_t)TEST_VALUE, sz);
6857 
6858   tt_int_op(0, OP_EQ, pipe(pipefd));
6859   pid_t child = fork();
6860   if (child == 0) {
6861     /* We're in the child. */
6862     close(pipefd[0]);
6863     ssize_t r = write(pipefd[1], &ptr[sz-1], 1); /* This may crash. */
6864     close(pipefd[1]);
6865     if (r < 0)
6866       exit(1);
6867     exit(0);
6868   }
6869   tt_int_op(child, OP_GT, 0);
6870   /* In the parent. */
6871   close(pipefd[1]);
6872   pipefd[1] = -1;
6873   char buf[1];
6874   ssize_t r = read(pipefd[0], buf, 1);
6875 
6876   if (inherit == INHERIT_RES_ZERO) {
6877     // We should be seeing clear-on-fork behavior.
6878     tt_int_op((int)r, OP_EQ, 1); // child should send us a byte.
6879     tt_int_op(buf[0], OP_EQ, 0); // that byte should be zero.
6880   } else if (inherit == INHERIT_RES_DROP) {
6881     // We should be seeing noinherit behavior.
6882     tt_int_op(r, OP_LE, 0); // child said nothing; it should have crashed.
6883   } else {
6884     // noinherit isn't implemented.
6885     tt_int_op(inherit, OP_EQ, INHERIT_RES_KEEP);
6886     tt_int_op((int)r, OP_EQ, 1); // child should send us a byte.
6887     tt_int_op(buf[0], OP_EQ, TEST_VALUE); // that byte should be TEST_VALUE.
6888   }
6889 
6890   int ws;
6891   waitpid(child, &ws, 0);
6892 
6893 #ifndef NOINHERIT_CAN_FAIL
6894   /* Only if NOINHERIT_CAN_FAIL should it be possible for us to get
6895    * INHERIT_KEEP behavior in this case. */
6896   tt_int_op(inherit, OP_NE, INHERIT_RES_KEEP);
6897 #else
6898   if (inherit == INHERIT_RES_KEEP) {
6899     /* Call this test "skipped", not "passed", since noinherit wasn't
6900      * implemented. */
6901     tt_skip();
6902   }
6903 #endif /* !defined(NOINHERIT_CAN_FAIL) */
6904 
6905  done:
6906   tor_munmap_anonymous(ptr, sz);
6907   if (pipefd[0] >= 0) {
6908     close(pipefd[0]);
6909   }
6910   if (pipefd[1] >= 0) {
6911     close(pipefd[1]);
6912   }
6913 #endif /* defined(_WIN32) */
6914 }
6915 
6916 #ifndef COCCI
6917 #define UTIL_LEGACY(name)                                               \
6918   { (#name), test_util_ ## name , 0, NULL, NULL }
6919 
6920 #define UTIL_TEST(name, flags)                          \
6921   { (#name), test_util_ ## name, flags, NULL, NULL }
6922 
6923 #define COMPRESS(name, identifier)              \
6924   { ("compress/" #name), test_util_compress, 0, &compress_setup,        \
6925     (char*)(identifier) }
6926 
6927 #define COMPRESS_CONCAT(name, identifier)                               \
6928   { ("compress_concat/" #name), test_util_decompress_concatenated, 0,   \
6929     &compress_setup,                                                    \
6930     (char*)(identifier) }
6931 
6932 #define COMPRESS_JUNK(name, identifier)                                 \
6933   { ("compress_junk/" #name), test_util_decompress_junk, 0,             \
6934     &compress_setup,                                                    \
6935     (char*)(identifier) }
6936 
6937 #define COMPRESS_DOS(name, identifier)                                  \
6938   { ("compress_dos/" #name), test_util_decompress_dos, 0,               \
6939     &compress_setup,                                                    \
6940     (char*)(identifier) }
6941 
6942 #ifdef _WIN32
6943 #define UTIL_TEST_WIN_ONLY(n, f) UTIL_TEST(n, (f))
6944 #else
6945 #define UTIL_TEST_WIN_ONLY(n, f) { (#n), NULL, TT_SKIP, NULL, NULL }
6946 #endif
6947 
6948 #ifdef DISABLE_PWDB_TESTS
6949 #define UTIL_TEST_PWDB(n, f) { (#n), NULL, TT_SKIP, NULL, NULL }
6950 #else
6951 #define UTIL_TEST_PWDB(n, f) UTIL_TEST(n, (f))
6952 #endif
6953 #endif /* !defined(COCCI) */
6954 
6955 struct testcase_t util_tests[] = {
6956   UTIL_LEGACY(time),
6957   UTIL_TEST(parse_http_time, 0),
6958   UTIL_LEGACY(config_line),
6959   UTIL_LEGACY(config_line_quotes),
6960   UTIL_LEGACY(config_line_comment_character),
6961   UTIL_LEGACY(config_line_escaped_content),
6962   UTIL_LEGACY(config_line_crlf),
6963   UTIL_TEST(config_line_partition, 0),
6964   UTIL_TEST_PWDB(expand_filename, 0),
6965   UTIL_LEGACY(escape_string_socks),
6966   UTIL_LEGACY(string_is_key_value),
6967   UTIL_LEGACY(strmisc),
6968   UTIL_TEST(parse_integer, 0),
6969   UTIL_LEGACY(pow2),
6970   COMPRESS(zlib, "deflate"),
6971   COMPRESS(gzip, "gzip"),
6972   COMPRESS(lzma, "x-tor-lzma"),
6973   COMPRESS(zstd, "x-zstd"),
6974   COMPRESS(zstd_nostatic, "x-zstd:nostatic"),
6975   COMPRESS(none, "identity"),
6976   COMPRESS_CONCAT(zlib, "deflate"),
6977   COMPRESS_CONCAT(gzip, "gzip"),
6978   COMPRESS_CONCAT(lzma, "x-tor-lzma"),
6979   COMPRESS_CONCAT(zstd, "x-zstd"),
6980   COMPRESS_CONCAT(zstd_nostatic, "x-zstd:nostatic"),
6981   COMPRESS_CONCAT(none, "identity"),
6982   COMPRESS_JUNK(zlib, "deflate"),
6983   COMPRESS_JUNK(gzip, "gzip"),
6984   COMPRESS_JUNK(lzma, "x-tor-lzma"),
6985   COMPRESS_DOS(zlib, "deflate"),
6986   COMPRESS_DOS(gzip, "gzip"),
6987   COMPRESS_DOS(lzma, "x-tor-lzma"),
6988   COMPRESS_DOS(zstd, "x-zstd"),
6989   COMPRESS_DOS(zstd_nostatic, "x-zstd:nostatic"),
6990   UTIL_TEST(gzip_compression_bomb, TT_FORK),
6991   UTIL_LEGACY(datadir),
6992   UTIL_LEGACY(memarea),
6993   UTIL_LEGACY(control_formats),
6994   UTIL_LEGACY(mmap),
6995   UTIL_TEST(sscanf, TT_FORK),
6996   UTIL_LEGACY(format_time_interval),
6997   UTIL_LEGACY(path_is_relative),
6998   UTIL_LEGACY(strtok),
6999   UTIL_LEGACY(di_ops),
7000   UTIL_TEST(memcpy_iftrue_timei, 0),
7001   UTIL_TEST(di_map, 0),
7002   UTIL_TEST(round_to_next_multiple_of, 0),
7003   UTIL_TEST(laplace, 0),
7004   UTIL_TEST(clamp_double_to_int64, 0),
7005   UTIL_TEST(find_str_at_start_of_line, 0),
7006   UTIL_TEST(tor_strreplacechar, 0),
7007   UTIL_TEST(string_is_C_identifier, 0),
7008   UTIL_TEST(string_is_utf8, 0),
7009   UTIL_TEST(asprintf, 0),
7010   UTIL_TEST(listdir, 0),
7011   UTIL_TEST(glob, 0),
7012   UTIL_TEST(get_glob_opened_files, 0),
7013   UTIL_TEST(parent_dir, 0),
7014   UTIL_TEST(ftruncate, 0),
7015   UTIL_TEST(nowrap_math, 0),
7016   UTIL_TEST(num_cpus, 0),
7017   UTIL_TEST_WIN_ONLY(load_win_lib, 0),
7018   UTIL_TEST(format_hex_number, 0),
7019   UTIL_TEST(format_dec_number, 0),
7020   UTIL_TEST(n_bits_set, 0),
7021   UTIL_TEST(eat_whitespace, 0),
7022   UTIL_TEST(sl_new_from_text_lines, 0),
7023   UTIL_TEST(envnames, 0),
7024   UTIL_TEST(make_environment, 0),
7025   UTIL_TEST(set_env_var_in_sl, 0),
7026   UTIL_TEST(read_file_eof_tiny_limit, 0),
7027   UTIL_TEST(read_file_eof_one_loop_a, 0),
7028   UTIL_TEST(read_file_eof_one_loop_b, 0),
7029   UTIL_TEST(read_file_eof_two_loops, 0),
7030   UTIL_TEST(read_file_eof_two_loops_b, 0),
7031   UTIL_TEST(read_file_eof_zero_bytes, 0),
7032   UTIL_TEST(read_file_endlines, 0),
7033   UTIL_TEST(write_chunks_to_file, 0),
7034   UTIL_TEST(write_str_if_changed, 0),
7035   UTIL_TEST(mathlog, 0),
7036   UTIL_TEST(fraction, 0),
7037   UTIL_TEST(weak_random, 0),
7038   { "tor_isinf", test_tor_isinf, TT_FORK, NULL, NULL },
7039   { "socket_ipv4", test_util_socket, TT_FORK, &passthrough_setup,
7040     (void*)"4" },
7041   { "socket_ipv6", test_util_socket, TT_FORK,
7042     &passthrough_setup, (void*)"6" },
7043   { "socketpair", test_util_socketpair, TT_FORK, &passthrough_setup,
7044     (void*)"0" },
7045   { "socketpair_ersatz", test_util_socketpair, TT_FORK,
7046     &passthrough_setup, (void*)"1" },
7047   UTIL_TEST(max_mem, 0),
7048   UTIL_TEST(hostname_validation, 0),
7049   UTIL_TEST(dest_validation_edgecase, 0),
7050   UTIL_TEST(ipv4_validation, 0),
7051   UTIL_TEST(ipv6_validation, 0),
7052   UTIL_TEST(writepid, 0),
7053   UTIL_TEST(get_avail_disk_space, 0),
7054   UTIL_TEST(touch_file, 0),
7055   UTIL_TEST_PWDB(pwdb, TT_FORK),
7056   UTIL_TEST(calloc_check, 0),
7057   UTIL_TEST(monotonic_time, 0),
7058   UTIL_TEST(monotonic_time_ratchet, TT_FORK),
7059   UTIL_TEST(monotonic_time_zero, 0),
7060   UTIL_TEST(monotonic_time_add_msec, 0),
7061   UTIL_TEST(timegm_real, 0),
7062   UTIL_TEST(htonll, 0),
7063   UTIL_TEST(get_unquoted_path, 0),
7064   UTIL_TEST(map_anon, 0),
7065   UTIL_TEST(map_anon_nofork, 0),
7066   END_OF_TESTCASES
7067 };
7068