tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

test_util.c (221477B)


      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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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 *
   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
   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
   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
   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
   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
   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
   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
   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
   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 = 5*1024*1024;
   2880  /* five megabytes 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
   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
   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 six_megabytes = 6 * 1024 * 1024;
   2938  char *buffer = tor_malloc_zero(six_megabytes);
   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                                    buffer, six_megabytes,
   2947                                    ZLIB_METHOD));
   2948  expect_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  #include "test/compression_bomb.h"
   2956 
   2957  tt_int_op(-1, OP_EQ, tor_uncompress(&result, &result_len,
   2958                                      compression_bomb_gzip,
   2959                                      compression_bomb_gzip_len,
   2960                                      GZIP_METHOD, 0, LOG_WARN));
   2961 
   2962  /* Now try streaming that. */
   2963  state = tor_compress_new(0, GZIP_METHOD, HIGH_COMPRESSION);
   2964  tor_compress_output_t r;
   2965  const char *inp = compression_bomb_gzip;
   2966  size_t inlen = compression_bomb_gzip_len;
   2967  do {
   2968    char *outp = buffer;
   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(buffer);
   2978  tor_compress_free(state);
   2979 }
   2980 
   2981 /** Run unit tests for mmap() wrapper functionality. */
   2982 static void
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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  const char *line2 = strchr(long_string,'\n')+1;
   4177  const char *line3 = strchr(line2,'\n')+1;
   4178  const char *short_string = "hello kitty\n"
   4179    "second line\n";
   4180  const 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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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, 128);
   4991 
   4992 done:
   4993  ;
   4994 }
   4995 
   4996 #ifdef _WIN32
   4997 static void
   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
   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
   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
   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
   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
   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
   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
   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 *
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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 };