1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2019, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
8 #define COMPAT_TIME_PRIVATE
9 #define CONTROL_PRIVATE
11 #define UTIL_MALLOC_PRIVATE
12 #define SOCKET_PRIVATE
13 #define PROCESS_WIN32_PRIVATE
14 #include "lib/testsupport/testsupport.h"
15 #include "core/or/or.h"
16 #include "lib/buf/buffers.h"
17 #include "app/config/config.h"
18 #include "feature/control/control.h"
19 #include "feature/client/transports.h"
20 #include "lib/crypt_ops/crypto_format.h"
21 #include "lib/crypt_ops/crypto_rand.h"
22 #include "lib/defs/time.h"
23 #include "test/test.h"
24 #include "lib/memarea/memarea.h"
25 #include "lib/process/waitpid.h"
26 #include "lib/process/process_win32.h"
27 #include "test/log_test_helpers.h"
28 #include "lib/compress/compress.h"
29 #include "lib/compress/compress_zstd.h"
30 #include "lib/encoding/keyval.h"
31 #include "lib/fdio/fdio.h"
32 #include "lib/fs/winlib.h"
33 #include "lib/process/env.h"
34 #include "lib/process/pidfile.h"
35 #include "lib/intmath/weakrng.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"
48 #ifdef HAVE_SYS_UTIME_H
49 #include <sys/utime.h>
54 #ifdef HAVE_SYS_STAT_H
63 #ifdef HAVE_SYS_MMAN_H
66 #ifdef HAVE_SYS_WAIT_H
77 #define INFINITY_DBL ((double)INFINITY)
78 #define NAN_DBL ((double)NAN)
80 /** Test the tor_isinf() wrapper */
82 test_tor_isinf(void *arg
)
86 tt_assert(tor_isinf(INFINITY_DBL
));
88 tt_assert(!tor_isinf(NAN_DBL
));
89 tt_assert(!tor_isinf(DBL_EPSILON
));
90 tt_assert(!tor_isinf(DBL_MAX
));
91 tt_assert(!tor_isinf(DBL_MIN
));
93 tt_assert(!tor_isinf(0.0));
94 tt_assert(!tor_isinf(0.1));
95 tt_assert(!tor_isinf(3));
96 tt_assert(!tor_isinf(3.14));
102 /* XXXX this is a minimal wrapper to make the unit tests compile with the
103 * changed tor_timegm interface. */
105 tor_timegm_wrapper(const struct tm
*tm
)
108 if (tor_timegm(tm
, &t
) < 0)
113 #define tor_timegm tor_timegm_wrapper
116 test_util_read_until_eof_impl(const char *fname
, size_t file_len
,
119 char *fifo_name
= NULL
;
120 char *test_str
= NULL
;
126 fifo_name
= tor_strdup(get_fname(fname
));
127 test_str
= tor_malloc(file_len
);
128 crypto_rand(test_str
, file_len
);
130 r
= write_bytes_to_file(fifo_name
, test_str
, file_len
, 1);
131 tt_int_op(r
, OP_EQ
, 0);
133 fd
= open(fifo_name
, O_RDONLY
|O_BINARY
);
134 tt_int_op(fd
, OP_GE
, 0);
135 str
= read_file_to_str_until_eof(fd
, read_limit
, &sz
);
136 tt_ptr_op(str
, OP_NE
, NULL
);
138 if (read_limit
< file_len
)
139 tt_int_op(sz
, OP_EQ
, read_limit
);
141 tt_int_op(sz
, OP_EQ
, file_len
);
143 tt_mem_op(test_str
, OP_EQ
, str
, sz
);
144 tt_int_op(str
[sz
], OP_EQ
, '\0');
156 test_util_read_file_eof_tiny_limit(void *arg
)
159 // purposely set limit shorter than what we wrote to the FIFO to
160 // test the maximum, and that it puts the NUL in the right spot
162 test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
166 test_util_read_file_eof_one_loop_a(void *arg
)
169 test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
173 test_util_read_file_eof_one_loop_b(void *arg
)
176 test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
180 test_util_read_file_eof_two_loops(void *arg
)
183 // write more than 1024 bytes to the FIFO to test two passes through
184 // the loop in the method; if the re-alloc size is changed this
185 // should be updated as well.
187 test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
191 test_util_read_file_eof_two_loops_b(void *arg
)
195 test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
199 test_util_read_file_eof_zero_bytes(void *arg
)
203 test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
206 /* Test the basic expected behaviour for write_chunks_to_file.
207 * NOTE: This will need to be updated if we ever change the tempfile location
210 test_util_write_chunks_to_file(void *arg
)
213 char *tempname
= NULL
;
218 /* These should be two different sizes to ensure the data is different
219 * between the data file and the temp file's 'known string' */
220 int temp_str_len
= 1024;
221 int data_str_len
= 512;
222 char *data_str
= tor_malloc(data_str_len
);
223 char *temp_str
= tor_malloc(temp_str_len
);
225 smartlist_t
*chunks
= smartlist_new();
226 sized_chunk_t c
= {data_str
, data_str_len
/2};
227 sized_chunk_t c2
= {data_str
+ data_str_len
/2, data_str_len
/2};
230 crypto_rand(temp_str
, temp_str_len
);
231 crypto_rand(data_str
, data_str_len
);
233 // Ensure it can write multiple chunks
235 smartlist_add(chunks
, &c
);
236 smartlist_add(chunks
, &c2
);
239 * Check if it writes using a tempfile
241 fname
= tor_strdup(get_fname("write_chunks_with_tempfile"));
242 tor_asprintf(&tempname
, "%s.tmp", fname
);
244 // write a known string to a file where the tempfile will be
245 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
246 tt_int_op(r
, OP_EQ
, 0);
248 // call write_chunks_to_file
249 r
= write_chunks_to_file(fname
, chunks
, 1, 0);
250 tt_int_op(r
, OP_EQ
, 0);
252 // assert the file has been written (expected size)
253 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
254 tt_assert(str
!= NULL
);
255 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
256 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
259 // assert that the tempfile is removed (should not leave artifacts)
260 str
= read_file_to_str(tempname
, RFTS_BIN
|RFTS_IGNORE_MISSING
, &st
);
261 tt_assert(str
== NULL
);
263 // Remove old testfile for second test
265 tt_int_op(r
, OP_EQ
, 0);
270 * Check if it skips using a tempfile with flags
272 fname
= tor_strdup(get_fname("write_chunks_with_no_tempfile"));
273 tor_asprintf(&tempname
, "%s.tmp", fname
);
275 // write a known string to a file where the tempfile will be
276 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
277 tt_int_op(r
, OP_EQ
, 0);
279 // call write_chunks_to_file with no_tempfile = true
280 r
= write_chunks_to_file(fname
, chunks
, 1, 1);
281 tt_int_op(r
, OP_EQ
, 0);
283 // assert the file has been written (expected size)
284 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
285 tt_assert(str
!= NULL
);
286 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
287 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
290 // assert the tempfile still contains the known string
291 str
= read_file_to_str(tempname
, RFTS_BIN
, &st
);
292 tt_assert(str
!= NULL
);
293 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, temp_str_len
);
294 tt_mem_op(temp_str
, OP_EQ
, str
, temp_str_len
);
299 smartlist_free(chunks
);
307 #define _TFE(a, b, f) tt_int_op((a).f, OP_EQ, (b).f)
308 /** test the minimum set of struct tm fields needed for a unique epoch value
309 * this is also the set we use to test tor_timegm */
310 #define TM_EQUAL(a, b) \
312 _TFE(a, b, tm_year); \
313 _TFE(a, b, tm_mon ); \
314 _TFE(a, b, tm_mday); \
315 _TFE(a, b, tm_hour); \
316 _TFE(a, b, tm_min ); \
317 _TFE(a, b, tm_sec ); \
321 test_util_time(void *arg
)
323 struct timeval start
, end
;
324 struct tm a_time
, b_time
;
330 /* Test tv_udiff and tv_mdiff */
334 start
.tv_usec
= 5000;
339 tt_int_op(0L,OP_EQ
, tv_udiff(&start
, &end
));
340 tt_int_op(0L,OP_EQ
, tv_mdiff(&start
, &end
));
341 tt_int_op(0L,OP_EQ
, tv_udiff(&end
, &start
));
342 tt_int_op(0L,OP_EQ
, tv_mdiff(&end
, &start
));
346 tt_int_op(2000L,OP_EQ
, tv_udiff(&start
, &end
));
347 tt_int_op(2L,OP_EQ
, tv_mdiff(&start
, &end
));
348 tt_int_op(-2000L,OP_EQ
, tv_udiff(&end
, &start
));
349 tt_int_op(-2L,OP_EQ
, tv_mdiff(&end
, &start
));
353 tt_int_op(1002000L,OP_EQ
, tv_udiff(&start
, &end
));
354 tt_int_op(1002L,OP_EQ
, tv_mdiff(&start
, &end
));
355 tt_int_op(-1002000L,OP_EQ
, tv_udiff(&end
, &start
));
356 tt_int_op(-1002L,OP_EQ
, tv_mdiff(&end
, &start
));
360 tt_int_op(995000L,OP_EQ
, tv_udiff(&start
, &end
));
361 tt_int_op(995L,OP_EQ
, tv_mdiff(&start
, &end
));
362 tt_int_op(-995000L,OP_EQ
, tv_udiff(&end
, &start
));
363 tt_int_op(-995L,OP_EQ
, tv_mdiff(&end
, &start
));
367 tt_int_op(-1005000L,OP_EQ
, tv_udiff(&start
, &end
));
368 tt_int_op(-1005L,OP_EQ
, tv_mdiff(&start
, &end
));
369 tt_int_op(1005000L,OP_EQ
, tv_udiff(&end
, &start
));
370 tt_int_op(1005L,OP_EQ
, tv_mdiff(&end
, &start
));
372 /* Negative tv_sec values, these will break on platforms where tv_sec is
377 tt_int_op(-15005000L,OP_EQ
, tv_udiff(&start
, &end
));
378 tt_int_op(-15005L,OP_EQ
, tv_mdiff(&start
, &end
));
379 tt_int_op(15005000L,OP_EQ
, tv_udiff(&end
, &start
));
380 tt_int_op(15005L,OP_EQ
, tv_mdiff(&end
, &start
));
384 tt_int_op(89995000L,OP_EQ
, tv_udiff(&start
, &end
));
385 tt_int_op(89995L,OP_EQ
, tv_mdiff(&start
, &end
));
386 tt_int_op(-89995000L,OP_EQ
, tv_udiff(&end
, &start
));
387 tt_int_op(-89995L,OP_EQ
, tv_mdiff(&end
, &start
));
389 /* Test that tv_usec values round away from zero when converted to msec */
395 tt_int_op(10000499L, OP_EQ
, tv_udiff(&start
, &end
));
396 tt_int_op(10000L, OP_EQ
, tv_mdiff(&start
, &end
));
397 tt_int_op(-10000499L, OP_EQ
, tv_udiff(&end
, &start
));
398 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
405 tt_int_op(10000500L, OP_EQ
, tv_udiff(&start
, &end
));
406 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
407 tt_int_op(-10000500L, OP_EQ
, tv_udiff(&end
, &start
));
408 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
415 tt_int_op(10000501L, OP_EQ
, tv_udiff(&start
, &end
));
416 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
417 tt_int_op(-10000501L, OP_EQ
, tv_udiff(&end
, &start
));
418 tt_int_op(-10001L, OP_EQ
, tv_mdiff(&end
, &start
));
420 /* Overflow conditions */
423 /* Would you believe that tv_sec is a long on windows? Of course you would.*/
424 #define TV_SEC_MAX LONG_MAX
425 #define TV_SEC_MIN LONG_MIN
427 /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
428 * Which means TIME_MAX is not actually the maximum value of tv_sec.
429 * But that's ok for the moment, because the code correctly performs 64-bit
430 * calculations internally, then catches the overflow. */
431 #define TV_SEC_MAX TIME_MAX
432 #define TV_SEC_MIN TIME_MIN
433 #endif /* defined(_WIN32) */
435 /* Assume tv_usec is an unsigned integer until proven otherwise */
436 #define TV_USEC_MAX UINT_MAX
438 /* Overflows in the result type */
440 /* All comparisons work */
443 end
.tv_sec
= LONG_MAX
/1000 - 2;
446 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
447 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
448 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
449 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
453 end
.tv_sec
= LONG_MAX
/1000000 - 1;
456 tt_int_op(end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&start
, &end
));
457 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
458 tt_int_op(-end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&end
, &start
));
459 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
461 /* No comparisons work */
464 end
.tv_sec
= LONG_MAX
/1000 + 1;
467 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
468 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
469 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
470 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
474 end
.tv_sec
= LONG_MAX
/1000000 + 1;
477 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
478 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
479 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
480 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
484 end
.tv_sec
= LONG_MAX
/1000;
485 end
.tv_usec
= TOR_USEC_PER_SEC
;
487 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
488 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
489 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
490 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
494 end
.tv_sec
= LONG_MAX
/1000000;
495 end
.tv_usec
= TOR_USEC_PER_SEC
;
497 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
498 tt_int_op((end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
499 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
500 tt_int_op(-(end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
502 /* Overflows on comparison to zero */
507 end
.tv_sec
= TV_SEC_MAX
;
510 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
511 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
512 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
513 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
515 end
.tv_sec
= TV_SEC_MAX
;
516 end
.tv_usec
= TOR_USEC_PER_SEC
;
518 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
519 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
520 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
521 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
524 end
.tv_usec
= TV_USEC_MAX
;
526 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
527 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
528 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
529 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
531 end
.tv_sec
= TV_SEC_MAX
;
532 end
.tv_usec
= TV_USEC_MAX
;
534 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
535 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
536 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
537 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
542 start
.tv_sec
= TV_SEC_MIN
;
545 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
546 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
547 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
548 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
550 start
.tv_sec
= TV_SEC_MIN
;
551 start
.tv_usec
= TOR_USEC_PER_SEC
;
553 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
554 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
555 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
556 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
558 start
.tv_sec
= TV_SEC_MIN
;
559 start
.tv_usec
= TV_USEC_MAX
;
561 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
562 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
563 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
564 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
566 /* overflows on comparison to maxima / minima */
568 start
.tv_sec
= TV_SEC_MIN
;
571 end
.tv_sec
= TV_SEC_MAX
;
574 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
575 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
576 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
577 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
579 end
.tv_sec
= TV_SEC_MAX
;
580 end
.tv_usec
= TOR_USEC_PER_SEC
;
582 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
583 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
584 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
585 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
587 end
.tv_sec
= TV_SEC_MAX
;
590 start
.tv_sec
= TV_SEC_MIN
;
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
));
598 start
.tv_sec
= TV_SEC_MIN
;
599 start
.tv_usec
= TOR_USEC_PER_SEC
;
601 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
602 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
603 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
604 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
606 /* overflows on comparison to maxima / minima with extra usec */
608 start
.tv_sec
= TV_SEC_MIN
;
609 start
.tv_usec
= TOR_USEC_PER_SEC
;
611 end
.tv_sec
= TV_SEC_MAX
;
614 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
615 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
616 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
617 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
619 end
.tv_sec
= TV_SEC_MAX
;
620 end
.tv_usec
= TOR_USEC_PER_SEC
;
622 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
623 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
624 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
625 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
627 end
.tv_sec
= TV_SEC_MAX
;
628 end
.tv_usec
= TOR_USEC_PER_SEC
;
630 start
.tv_sec
= TV_SEC_MIN
;
633 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
634 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
635 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
636 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
638 start
.tv_sec
= TV_SEC_MIN
;
639 start
.tv_usec
= TOR_USEC_PER_SEC
;
641 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
642 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
643 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
644 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
646 /* Test tor_timegm & tor_gmtime_r */
648 /* The test values here are confirmed to be correct on a platform
649 * with a working timegm & gmtime_r. */
651 /* Start with known-zero a_time and b_time.
652 * This avoids passing uninitialised values to TM_EQUAL in a_time.
653 * Zeroing may not be needed for b_time, as long as tor_gmtime_r
654 * never reads the existing values in the structure.
655 * But we really don't want intermittently failing tests. */
656 memset(&a_time
, 0, sizeof(struct tm
));
657 memset(&b_time
, 0, sizeof(struct tm
));
659 a_time
.tm_year
= 2003-1900;
665 t_res
= 1062224095UL;
666 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
667 tor_gmtime_r(&t_res
, &b_time
);
668 TM_EQUAL(a_time
, b_time
);
670 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
671 t_res
= 1093846495UL;
672 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
673 tor_gmtime_r(&t_res
, &b_time
);
674 TM_EQUAL(a_time
, b_time
);
676 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
678 t_res
= 1076393695UL;
679 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
680 tor_gmtime_r(&t_res
, &b_time
);
681 TM_EQUAL(a_time
, b_time
);
684 t_res
= 1073715295UL;
685 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
686 tor_gmtime_r(&t_res
, &b_time
);
687 TM_EQUAL(a_time
, b_time
);
689 /* This value is in range with 32 bit and 64 bit time_t */
690 a_time
.tm_year
= 2037-1900;
691 t_res
= 2115180895UL;
692 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
693 tor_gmtime_r(&t_res
, &b_time
);
694 TM_EQUAL(a_time
, b_time
);
696 /* This value is out of range with 32 bit time_t, but in range for 64 bit
698 a_time
.tm_year
= 2039-1900;
699 #if SIZEOF_TIME_T == 4
700 setup_full_capture_of_logs(LOG_WARN
);
701 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
702 expect_single_log_msg_containing("Result does not fit in tor_timegm");
703 teardown_capture_of_logs();
704 #elif SIZEOF_TIME_T == 8
705 t_res
= 2178252895UL;
706 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
707 tor_gmtime_r(&t_res
, &b_time
);
708 TM_EQUAL(a_time
, b_time
);
709 #endif /* SIZEOF_TIME_T == 4 || ... */
711 /* Test tor_timegm out of range */
713 /* The below tests will all cause a BUG message, so we capture, suppress,
715 #define CAPTURE() do { \
716 setup_full_capture_of_logs(LOG_WARN); \
718 #define CHECK_TIMEGM_WARNING(msg) do { \
719 expect_single_log_msg_containing(msg); \
720 teardown_capture_of_logs(); \
722 #define CHECK_POSSIBLE_EINVAL() do { \
723 if (mock_saved_log_n_entries()) { \
724 expect_single_log_msg_containing("Invalid argument"); \
726 teardown_capture_of_logs(); \
729 #define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
730 CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
734 /* Wrong year < 1970 */
735 a_time
.tm_year
= 1969-1900;
737 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
738 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
740 a_time
.tm_year
= -1-1900;
742 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
743 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
745 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
746 a_time
.tm_year
= -1*(1 << 16);
748 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
749 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
751 /* one of the smallest tm_year values my 64 bit system supports:
752 * t_res = -9223372036854775LL without clamping */
753 a_time
.tm_year
= -292275055-1900;
755 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
756 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
758 a_time
.tm_year
= INT32_MIN
;
760 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
761 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
762 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
765 a_time
.tm_year
= -1*(1 << 48);
767 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
768 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
770 /* while unlikely, the system's gmtime(_r) could return
771 * a "correct" retrospective gregorian negative year value,
772 * which I'm pretty sure is:
773 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
774 * 730485 is the number of days in two millennia, including leap days */
775 a_time
.tm_year
= -292277022657-1900;
777 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
778 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
780 a_time
.tm_year
= INT64_MIN
;
782 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
783 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
784 #endif /* SIZEOF_INT == 8 */
786 /* Wrong year >= INT32_MAX - 1900 */
787 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
788 a_time
.tm_year
= INT32_MAX
-1900;
790 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
791 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
793 a_time
.tm_year
= INT32_MAX
;
795 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
796 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
797 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
800 /* one of the largest tm_year values my 64 bit system supports */
801 a_time
.tm_year
= 292278994-1900;
803 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
804 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
806 /* while unlikely, the system's gmtime(_r) could return
807 * a "correct" proleptic gregorian year value,
808 * which I'm pretty sure is:
809 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
810 * 730485 is the number of days in two millennia, including leap days */
811 a_time
.tm_year
= 292277026596-1900;
813 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
814 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
816 a_time
.tm_year
= INT64_MAX
-1900;
818 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
819 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
821 a_time
.tm_year
= INT64_MAX
;
823 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
824 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
825 #endif /* SIZEOF_INT == 8 */
828 a_time
.tm_year
= 2007-1900; /* restore valid year */
830 a_time
.tm_mon
= 12; /* Wrong month, it's 0-based */
832 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
833 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
835 a_time
.tm_mon
= -1; /* Wrong month */
837 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
838 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
841 a_time
.tm_mon
= 6; /* Try July */
842 a_time
.tm_mday
= 32; /* Wrong day */
844 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
845 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
847 a_time
.tm_mon
= 5; /* Try June */
848 a_time
.tm_mday
= 31; /* Wrong day */
850 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
851 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
853 a_time
.tm_year
= 2008-1900; /* Try a leap year */
854 a_time
.tm_mon
= 1; /* in feb. */
855 a_time
.tm_mday
= 30; /* Wrong day */
857 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
858 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
860 a_time
.tm_year
= 2011-1900; /* Try a non-leap year */
861 a_time
.tm_mon
= 1; /* in feb. */
862 a_time
.tm_mday
= 29; /* Wrong day */
864 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
865 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
867 a_time
.tm_mday
= 0; /* Wrong day, it's 1-based (to be different) */
869 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
870 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
873 a_time
.tm_mday
= 3; /* restore valid month day */
875 a_time
.tm_hour
= 24; /* Wrong hour, it's 0-based */
877 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
878 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
880 a_time
.tm_hour
= -1; /* Wrong hour */
882 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
883 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
886 a_time
.tm_hour
= 22; /* restore valid hour */
888 a_time
.tm_min
= 60; /* Wrong minute, it's 0-based */
890 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
891 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
893 a_time
.tm_min
= -1; /* Wrong minute */
895 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
896 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
899 a_time
.tm_min
= 37; /* restore valid minute */
901 a_time
.tm_sec
= 61; /* Wrong second: 0-based with leap seconds */
903 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
904 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
906 a_time
.tm_sec
= -1; /* Wrong second */
908 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
909 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
911 /* Test tor_gmtime_r out of range */
913 /* time_t < 0 yields a year clamped to 1 or 1970,
914 * depending on whether the implementation of the system gmtime(_r)
915 * sets struct tm (1) or not (1970) */
917 tor_gmtime_r(&t_res
, &b_time
);
918 tt_assert(b_time
.tm_year
== (1970-1900) ||
919 b_time
.tm_year
== (1969-1900));
921 if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
922 t_res
= -1*(1 << 30);
924 tor_gmtime_r(&t_res
, &b_time
);
925 CHECK_POSSIBLE_EINVAL();
926 tt_assert(b_time
.tm_year
== (1970-1900) ||
927 b_time
.tm_year
== (1935-1900));
931 tor_gmtime_r(&t_res
, &b_time
);
932 CHECK_POSSIBLE_EINVAL();
933 tt_assert(b_time
.tm_year
== (1970-1900) ||
934 b_time
.tm_year
== (1901-1900));
937 #if SIZEOF_TIME_T == 8
939 /* one of the smallest tm_year values my 64 bit system supports:
940 * b_time.tm_year == (-292275055LL-1900LL) without clamping */
941 t_res
= -9223372036854775LL;
943 tor_gmtime_r(&t_res
, &b_time
);
944 CHECK_POSSIBLE_EINVAL();
945 tt_assert(b_time
.tm_year
== (1970-1900) ||
946 b_time
.tm_year
== (1-1900));
948 /* while unlikely, the system's gmtime(_r) could return
949 * a "correct" retrospective gregorian negative year value,
950 * which I'm pretty sure is:
951 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
952 * 730485 is the number of days in two millennia, including leap days
953 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
956 tor_gmtime_r(&t_res
, &b_time
);
957 if (! (b_time
.tm_year
== (1970-1900) ||
958 b_time
.tm_year
== (1-1900))) {
959 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
961 if (b_time
.tm_year
!= 1970-1900) {
962 CHECK_TIMEGM_WARNING("Rounding up to ");
964 teardown_capture_of_logs();
968 /* As above, but with localtime. */
969 t_res
= -9223372036854775LL;
971 tor_localtime_r(&t_res
, &b_time
);
972 CHECK_POSSIBLE_EINVAL();
973 tt_assert(b_time
.tm_year
== (1970-1900) ||
974 b_time
.tm_year
== (1-1900));
976 /* while unlikely, the system's gmtime(_r) could return
977 * a "correct" retrospective gregorian negative year value,
978 * which I'm pretty sure is:
979 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
980 * 730485 is the number of days in two millennia, including leap days
981 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
984 tor_localtime_r(&t_res
, &b_time
);
985 if (! (b_time
.tm_year
== (1970-1900) ||
986 b_time
.tm_year
== (1-1900))) {
987 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
989 if (b_time
.tm_year
!= 1970-1900) {
990 CHECK_TIMEGM_WARNING("Rounding up to ");
992 teardown_capture_of_logs();
995 #endif /* SIZEOF_TIME_T == 8 */
997 /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
998 * depending on whether the implementation of the system gmtime(_r)
999 * sets struct tm (9999) or not (2037) */
1000 #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
1002 t_res
= 3*(1 << 29);
1003 tor_gmtime_r(&t_res
, &b_time
);
1004 tt_assert(b_time
.tm_year
== (2021-1900));
1007 tor_gmtime_r(&t_res
, &b_time
);
1008 tt_assert(b_time
.tm_year
== (2037-1900) ||
1009 b_time
.tm_year
== (2038-1900));
1012 /* as above but with localtime. */
1013 t_res
= 3*(1 << 29);
1014 tor_localtime_r(&t_res
, &b_time
);
1015 tt_assert(b_time
.tm_year
== (2021-1900));
1018 tor_localtime_r(&t_res
, &b_time
);
1019 tt_assert(b_time
.tm_year
== (2037-1900) ||
1020 b_time
.tm_year
== (2038-1900));
1022 #endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
1024 #if SIZEOF_TIME_T == 8
1026 /* one of the largest tm_year values my 64 bit system supports:
1027 * b_time.tm_year == (292278994L-1900L) without clamping */
1028 t_res
= 9223372036854775LL;
1030 tor_gmtime_r(&t_res
, &b_time
);
1031 CHECK_POSSIBLE_EINVAL();
1032 tt_assert(b_time
.tm_year
== (2037-1900) ||
1033 b_time
.tm_year
== (9999-1900));
1035 /* while unlikely, the system's gmtime(_r) could return
1036 * a "correct" proleptic gregorian year value,
1037 * which I'm pretty sure is:
1038 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1039 * 730485 is the number of days in two millennia, including leap days
1040 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1043 tor_gmtime_r(&t_res
, &b_time
);
1044 CHECK_TIMEGM_WARNING("Rounding down to ");
1046 tt_assert(b_time
.tm_year
== (2037-1900) ||
1047 b_time
.tm_year
== (9999-1900));
1050 /* As above but with localtime. */
1051 t_res
= 9223372036854775LL;
1053 tor_localtime_r(&t_res
, &b_time
);
1054 CHECK_POSSIBLE_EINVAL();
1055 tt_assert(b_time
.tm_year
== (2037-1900) ||
1056 b_time
.tm_year
== (9999-1900));
1058 /* while unlikely, the system's gmtime(_r) could return
1059 * a "correct" proleptic gregorian year value,
1060 * which I'm pretty sure is:
1061 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1062 * 730485 is the number of days in two millennia, including leap days
1063 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1066 tor_localtime_r(&t_res
, &b_time
);
1067 CHECK_TIMEGM_WARNING("Rounding down to ");
1069 tt_assert(b_time
.tm_year
== (2037-1900) ||
1070 b_time
.tm_year
== (9999-1900));
1072 #endif /* SIZEOF_TIME_T == 8 */
1074 /* Test {format,parse}_rfc1123_time */
1076 format_rfc1123_time(timestr
, 0);
1077 tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ
, timestr
);
1078 format_rfc1123_time(timestr
, (time_t)1091580502UL);
1079 tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ
, timestr
);
1082 i
= parse_rfc1123_time(timestr
, &t_res
);
1083 tt_int_op(0,OP_EQ
, i
);
1084 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1086 /* This value is in range with 32 bit and 64 bit time_t */
1087 format_rfc1123_time(timestr
, (time_t)2080000000UL);
1088 tt_str_op("Fri, 30 Nov 2035 01:46:40 GMT",OP_EQ
, timestr
);
1091 i
= parse_rfc1123_time(timestr
, &t_res
);
1092 tt_int_op(0,OP_EQ
, i
);
1093 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1095 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1098 format_rfc1123_time(timestr
, (time_t)2150000000UL);
1099 CHECK_POSSIBLE_EINVAL();
1101 #if SIZEOF_TIME_T == 4
1103 /* Wrapping around will have made it this. */
1104 /* On windows, at least, this is clipped to 1 Jan 1970. ??? */
1105 tt_str_op("Sat, 11 Jan 1902 23:45:04 GMT",OP_EQ
, timestr
);
1107 /* Make sure that the right date doesn't parse. */
1108 strlcpy(timestr
, "Wed, 17 Feb 2038 06:13:20 GMT", sizeof(timestr
));
1112 i
= parse_rfc1123_time(timestr
, &t_res
);
1113 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1114 tt_int_op(-1,OP_EQ
, i
);
1115 #elif SIZEOF_TIME_T == 8
1116 tt_str_op("Wed, 17 Feb 2038 06:13:20 GMT",OP_EQ
, timestr
);
1119 i
= parse_rfc1123_time(timestr
, &t_res
);
1120 tt_int_op(0,OP_EQ
, i
);
1121 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1122 #endif /* SIZEOF_TIME_T == 4 || ... */
1124 /* The timezone doesn't matter */
1127 parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res
));
1128 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1130 parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
1132 parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res
));
1134 parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res
));
1136 parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res
));
1138 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res
));
1140 parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res
));
1142 parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res
));
1144 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res
));
1146 parse_rfc1123_time("Wed, 30 Mar 1900 23:59:59 GMT", &t_res
));
1150 parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res
));
1152 parse_rfc1123_time("Wed, 29 Feb 2012 16:00:00 GMT", &t_res
));
1154 /* Leap second plus one */
1156 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res
));
1158 /* Test parse_iso_time */
1161 i
= parse_iso_time("", &t_res
);
1162 tt_int_op(-1,OP_EQ
, i
);
1164 i
= parse_iso_time("2004-08-32 00:48:22", &t_res
);
1165 tt_int_op(-1,OP_EQ
, i
);
1167 i
= parse_iso_time("1969-08-03 00:48:22", &t_res
);
1168 tt_int_op(-1,OP_EQ
, i
);
1171 i
= parse_iso_time("2004-08-04 00:48:22", &t_res
);
1172 tt_int_op(0,OP_EQ
, i
);
1173 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1175 i
= parse_iso_time("2004-8-4 0:48:22", &t_res
);
1176 tt_int_op(0,OP_EQ
, i
);
1177 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1179 /* This value is in range with 32 bit and 64 bit time_t */
1181 i
= parse_iso_time("2035-11-30 01:46:40", &t_res
);
1182 tt_int_op(0,OP_EQ
, i
);
1183 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1185 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1188 #if SIZEOF_TIME_T == 4
1190 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1191 tt_int_op(-1,OP_EQ
, i
);
1192 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1193 #elif SIZEOF_TIME_T == 8
1194 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1195 tt_int_op(0,OP_EQ
, i
);
1196 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1197 #endif /* SIZEOF_TIME_T == 4 || ... */
1199 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-zz 99-99x99", &t_res
));
1200 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-32 00:00:00", &t_res
));
1201 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 24:00:00", &t_res
));
1202 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:60:00", &t_res
));
1203 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59:62", &t_res
));
1204 tt_int_op(-1,OP_EQ
, parse_iso_time("1969-03-30 23:59:59", &t_res
));
1205 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-00-30 23:59:59", &t_res
));
1206 tt_int_op(-1,OP_EQ
, parse_iso_time("2147483647-08-29 14:00:00", &t_res
));
1207 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59", &t_res
));
1208 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22.100", &t_res
));
1209 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res
));
1211 /* but... that _is_ acceptable if we aren't being strict. */
1213 i
= parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res
, 0, 0);
1214 tt_int_op(0,OP_EQ
, i
);
1215 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1217 /* try nospace variant. */
1219 i
= parse_iso_time_nospace("2004-08-04T00:48:22", &t_res
);
1220 tt_int_op(0,OP_EQ
, i
);
1221 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1223 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04T00:48:22", &t_res
));
1224 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res
));
1225 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04x00:48:22", &t_res
));
1226 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res
));
1228 /* Test tor_gettimeofday */
1231 end
.tv_usec
= 999990;
1233 start
.tv_usec
= 500;
1235 tor_gettimeofday(&start
);
1236 /* now make sure time works. */
1237 tor_gettimeofday(&end
);
1238 /* We might've timewarped a little. */
1239 tt_int_op(tv_udiff(&start
, &end
), OP_GE
, -5000);
1241 /* Test format_iso_time */
1243 tv
.tv_sec
= (time_t)1326296338UL;
1245 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1246 tt_str_op("2012-01-11 15:38:58",OP_EQ
, timestr
);
1247 /* The output of format_local_iso_time will vary by timezone, and setting
1248 our timezone for testing purposes would be a nontrivial flaky pain.
1249 Skip this test for now.
1250 format_local_iso_time(timestr, tv.tv_sec);
1251 test_streq("2012-01-11 10:38:58", timestr);
1253 format_iso_time_nospace(timestr
, (time_t)tv
.tv_sec
);
1254 tt_str_op("2012-01-11T15:38:58",OP_EQ
, timestr
);
1255 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_LEN
);
1256 format_iso_time_nospace_usec(timestr
, &tv
);
1257 tt_str_op("2012-01-11T15:38:58.003060",OP_EQ
, timestr
);
1258 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_USEC_LEN
);
1261 /* This value is in range with 32 bit and 64 bit time_t */
1262 tv
.tv_sec
= (time_t)2080000000UL;
1263 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1264 tt_str_op("2035-11-30 01:46:40",OP_EQ
, timestr
);
1266 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1268 tv
.tv_sec
= (time_t)2150000000UL;
1270 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1271 CHECK_POSSIBLE_EINVAL();
1272 #if SIZEOF_TIME_T == 4
1273 /* format_iso_time should indicate failure on overflow, but it doesn't yet.
1274 * Hopefully #18480 will improve the failure semantics in this case.
1275 tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
1277 #elif SIZEOF_TIME_T == 8
1279 /* This SHOULD work on windows too; see bug #18665 */
1280 tt_str_op("2038-02-17 06:13:20",OP_EQ
, timestr
);
1282 #endif /* SIZEOF_TIME_T == 4 || ... */
1285 #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
1286 #undef CHECK_POSSIBLE_EINVAL
1289 teardown_capture_of_logs();
1293 test_util_parse_http_time(void *arg
)
1296 char b
[ISO_TIME_LEN
+1];
1300 format_iso_time(b, tor_timegm(&a_time)); \
1301 tt_str_op(b, OP_EQ, (s)); \
1305 /* Test parse_http_time */
1308 parse_http_time("", &a_time
));
1310 parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time
));
1312 parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time
));
1314 parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time
));
1316 parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time
));
1318 parse_http_time("Sunday, August the third", &a_time
));
1320 parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time
));
1323 parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time
));
1324 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1325 T("1994-08-04 00:48:22");
1327 parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time
));
1328 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1329 T("1994-08-04 00:48:22");
1331 parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time
));
1332 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1333 T("1994-08-04 00:48:22");
1335 parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time
));
1336 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1337 T("1994-08-04 00:48:22");
1339 parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time
));
1340 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1341 T("1994-08-04 00:48:22");
1343 parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time
));
1344 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1345 T("1994-08-04 00:48:22");
1346 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time
));
1347 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1348 T("1994-08-04 00:48:22");
1349 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time
));
1350 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1351 T("1994-08-04 00:48:22");
1352 tt_int_op(0,OP_EQ
, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time
));
1353 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1354 T("1994-08-04 00:48:22");
1355 tt_int_op(0,OP_EQ
,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time
));
1356 tt_int_op((time_t)1325376000UL,OP_EQ
, tor_timegm(&a_time
));
1357 T("2012-01-01 00:00:00");
1358 tt_int_op(0,OP_EQ
,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time
));
1359 tt_int_op((time_t)1356912000UL,OP_EQ
, tor_timegm(&a_time
));
1360 T("2012-12-31 00:00:00");
1362 /* This value is in range with 32 bit and 64 bit time_t */
1363 tt_int_op(0,OP_EQ
,parse_http_time("Fri, 30 Nov 2035 01:46:40 GMT", &a_time
));
1364 tt_int_op((time_t)2080000000UL,OP_EQ
, tor_timegm(&a_time
));
1365 T("2035-11-30 01:46:40");
1367 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1369 #if SIZEOF_TIME_T == 4
1370 /* parse_http_time should indicate failure on overflow, but it doesn't yet.
1371 * Hopefully #18480 will improve the failure semantics in this case. */
1372 setup_full_capture_of_logs(LOG_WARN
);
1373 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1374 tt_int_op((time_t)-1,OP_EQ
, tor_timegm(&a_time
));
1375 expect_single_log_msg_containing("does not fit in tor_timegm");
1376 teardown_capture_of_logs();
1377 #elif SIZEOF_TIME_T == 8
1378 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1379 tt_int_op((time_t)2150000000UL,OP_EQ
, tor_timegm(&a_time
));
1380 T("2038-02-17 06:13:20");
1381 #endif /* SIZEOF_TIME_T == 4 || ... */
1383 tt_int_op(-1,OP_EQ
, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time
));
1384 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-32 00:00:00 GMT", &a_time
));
1385 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 24:00:00 GMT", &a_time
));
1386 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:60:00 GMT", &a_time
));
1387 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59:62 GMT", &a_time
));
1388 tt_int_op(-1,OP_EQ
, parse_http_time("1969-03-30 23:59:59 GMT", &a_time
));
1389 tt_int_op(-1,OP_EQ
, parse_http_time("2011-00-30 23:59:59 GMT", &a_time
));
1390 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59", &a_time
));
1394 teardown_capture_of_logs();
1398 test_util_config_line(void *arg
)
1401 char *k
=NULL
, *v
=NULL
;
1404 /* Test parse_config_line_from_str */
1406 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
1408 "k3 \n" "\n" " \n" "#comment\n"
1409 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
1410 "kseven \"a quoted 'string\"\n"
1411 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
1412 "k9 a line that\\\n spans two lines.\n\n"
1413 "k10 more than\\\n one contin\\\nuation\n"
1414 "k11 \\\ncontinuation at the start\n"
1415 "k12 line with a\\\n#comment\n embedded\n"
1416 "k13\\\ncontinuation at the very start\n"
1417 "k14 a line that has a comment and # ends with a slash \\\n"
1418 "k15 this should be the next new line\n"
1419 "k16 a line that has a comment and # ends without a slash \n"
1420 "k17 this should be the next new line\n"
1424 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1425 tt_str_op(k
,OP_EQ
, "k");
1426 tt_str_op(v
,OP_EQ
, "v");
1427 tor_free(k
); tor_free(v
);
1428 tt_assert(!strcmpstart(str
, "key value with"));
1430 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1431 tt_str_op(k
,OP_EQ
, "key");
1432 tt_str_op(v
,OP_EQ
, "value with spaces");
1433 tor_free(k
); tor_free(v
);
1434 tt_assert(!strcmpstart(str
, "keykey"));
1436 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1437 tt_str_op(k
,OP_EQ
, "keykey");
1438 tt_str_op(v
,OP_EQ
, "val");
1439 tor_free(k
); tor_free(v
);
1440 tt_assert(!strcmpstart(str
, "k2\n"));
1442 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1443 tt_str_op(k
,OP_EQ
, "k2");
1444 tt_str_op(v
,OP_EQ
, "");
1445 tor_free(k
); tor_free(v
);
1446 tt_assert(!strcmpstart(str
, "k3 \n"));
1448 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1449 tt_str_op(k
,OP_EQ
, "k3");
1450 tt_str_op(v
,OP_EQ
, "");
1451 tor_free(k
); tor_free(v
);
1452 tt_assert(!strcmpstart(str
, "#comment"));
1454 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1455 tt_str_op(k
,OP_EQ
, "k4");
1456 tt_str_op(v
,OP_EQ
, "");
1457 tor_free(k
); tor_free(v
);
1458 tt_assert(!strcmpstart(str
, "k5#abc"));
1460 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1461 tt_str_op(k
,OP_EQ
, "k5");
1462 tt_str_op(v
,OP_EQ
, "");
1463 tor_free(k
); tor_free(v
);
1464 tt_assert(!strcmpstart(str
, "k6"));
1466 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1467 tt_str_op(k
,OP_EQ
, "k6");
1468 tt_str_op(v
,OP_EQ
, "val");
1469 tor_free(k
); tor_free(v
);
1470 tt_assert(!strcmpstart(str
, "kseven"));
1472 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1473 tt_str_op(k
,OP_EQ
, "kseven");
1474 tt_str_op(v
,OP_EQ
, "a quoted \'string");
1475 tor_free(k
); tor_free(v
);
1476 tt_assert(!strcmpstart(str
, "k8 "));
1478 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1479 tt_str_op(k
,OP_EQ
, "k8");
1480 tt_str_op(v
,OP_EQ
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
1481 tor_free(k
); tor_free(v
);
1483 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1484 tt_str_op(k
,OP_EQ
, "k9");
1485 tt_str_op(v
,OP_EQ
, "a line that spans two lines.");
1486 tor_free(k
); tor_free(v
);
1488 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1489 tt_str_op(k
,OP_EQ
, "k10");
1490 tt_str_op(v
,OP_EQ
, "more than one continuation");
1491 tor_free(k
); tor_free(v
);
1493 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1494 tt_str_op(k
,OP_EQ
, "k11");
1495 tt_str_op(v
,OP_EQ
, "continuation at the start");
1496 tor_free(k
); tor_free(v
);
1498 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1499 tt_str_op(k
,OP_EQ
, "k12");
1500 tt_str_op(v
,OP_EQ
, "line with a embedded");
1501 tor_free(k
); tor_free(v
);
1503 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1504 tt_str_op(k
,OP_EQ
, "k13");
1505 tt_str_op(v
,OP_EQ
, "continuation at the very start");
1506 tor_free(k
); tor_free(v
);
1508 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1509 tt_str_op(k
,OP_EQ
, "k14");
1510 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1511 tor_free(k
); tor_free(v
);
1513 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1514 tt_str_op(k
,OP_EQ
, "k15");
1515 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1516 tor_free(k
); tor_free(v
);
1518 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1519 tt_str_op(k
,OP_EQ
, "k16");
1520 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1521 tor_free(k
); tor_free(v
);
1523 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1524 tt_str_op(k
,OP_EQ
, "k17");
1525 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1526 tor_free(k
); tor_free(v
);
1528 tt_str_op(str
,OP_EQ
, "");
1536 test_util_config_line_quotes(void *arg
)
1542 char *k
=NULL
, *v
=NULL
;
1545 /* Test parse_config_line_from_str */
1547 strlcpy(buf1
, "kTrailingSpace \"quoted value\" \n"
1548 "kTrailingGarbage \"quoted value\"trailing garbage\n"
1550 strlcpy(buf2
, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
1552 strlcpy(buf3
, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
1554 strlcpy(buf4
, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
1558 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1559 tt_str_op(k
,OP_EQ
, "kTrailingSpace");
1560 tt_str_op(v
,OP_EQ
, "quoted value");
1561 tor_free(k
); tor_free(v
);
1563 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1564 tt_ptr_op(str
,OP_EQ
, NULL
);
1565 tor_free(k
); tor_free(v
);
1569 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1570 tt_ptr_op(str
,OP_EQ
, NULL
);
1571 tor_free(k
); tor_free(v
);
1575 const char *err
= NULL
;
1576 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1577 tt_ptr_op(str
,OP_EQ
, NULL
);
1578 tor_free(k
); tor_free(v
);
1579 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1584 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1585 tt_ptr_op(str
,OP_EQ
, NULL
);
1586 tor_free(k
); tor_free(v
);
1587 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1595 test_util_config_line_comment_character(void *arg
)
1598 char *k
=NULL
, *v
=NULL
;
1601 /* Test parse_config_line_from_str */
1603 strlcpy(buf
, "k1 \"# in quotes\"\n"
1604 "k2 some value # some comment\n"
1605 "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
1609 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1610 tt_str_op(k
,OP_EQ
, "k1");
1611 tt_str_op(v
,OP_EQ
, "# in quotes");
1612 tor_free(k
); tor_free(v
);
1614 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1615 tt_str_op(k
,OP_EQ
, "k2");
1616 tt_str_op(v
,OP_EQ
, "some value");
1617 tor_free(k
); tor_free(v
);
1619 tt_str_op(str
,OP_EQ
, "k3 /home/user/myTorNetwork#2\n");
1622 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1623 test_streq(k
, "k3");
1624 test_streq(v
, "/home/user/myTorNetwork#2");
1625 tor_free(k
); tor_free(v
);
1627 test_streq(str
, "");
1636 test_util_config_line_escaped_content(void *arg
)
1644 char *k
=NULL
, *v
=NULL
;
1647 /* Test parse_config_line_from_str */
1649 strlcpy(buf1
, "HexadecimalLower \"\\x2a\"\n"
1650 "HexadecimalUpper \"\\x2A\"\n"
1651 "HexadecimalUpperX \"\\X2A\"\n"
1655 "CarriageReturn \"\\r\"\n"
1656 "DoubleQuote \"\\\"\"\n"
1657 "SimpleQuote \"\\'\"\n"
1658 "Backslash \"\\\\\"\n"
1659 "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
1662 strlcpy(buf2
, "BrokenEscapedContent \"\\a\"\n"
1665 strlcpy(buf3
, "BrokenEscapedContent \"\\x\"\n"
1668 strlcpy(buf4
, "BrokenOctal \"\\8\"\n"
1671 strlcpy(buf5
, "BrokenHex \"\\xg4\"\n"
1674 strlcpy(buf6
, "BrokenEscape \"\\"
1679 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1680 tt_str_op(k
,OP_EQ
, "HexadecimalLower");
1681 tt_str_op(v
,OP_EQ
, "*");
1682 tor_free(k
); tor_free(v
);
1684 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1685 tt_str_op(k
,OP_EQ
, "HexadecimalUpper");
1686 tt_str_op(v
,OP_EQ
, "*");
1687 tor_free(k
); tor_free(v
);
1689 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1690 tt_str_op(k
,OP_EQ
, "HexadecimalUpperX");
1691 tt_str_op(v
,OP_EQ
, "*");
1692 tor_free(k
); tor_free(v
);
1694 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1695 tt_str_op(k
,OP_EQ
, "Octal");
1696 tt_str_op(v
,OP_EQ
, "*");
1697 tor_free(k
); tor_free(v
);
1699 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1700 tt_str_op(k
,OP_EQ
, "Newline");
1701 tt_str_op(v
,OP_EQ
, "\n");
1702 tor_free(k
); tor_free(v
);
1704 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1705 tt_str_op(k
,OP_EQ
, "Tab");
1706 tt_str_op(v
,OP_EQ
, "\t");
1707 tor_free(k
); tor_free(v
);
1709 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1710 tt_str_op(k
,OP_EQ
, "CarriageReturn");
1711 tt_str_op(v
,OP_EQ
, "\r");
1712 tor_free(k
); tor_free(v
);
1714 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1715 tt_str_op(k
,OP_EQ
, "DoubleQuote");
1716 tt_str_op(v
,OP_EQ
, "\"");
1717 tor_free(k
); tor_free(v
);
1719 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1720 tt_str_op(k
,OP_EQ
, "SimpleQuote");
1721 tt_str_op(v
,OP_EQ
, "'");
1722 tor_free(k
); tor_free(v
);
1724 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1725 tt_str_op(k
,OP_EQ
, "Backslash");
1726 tt_str_op(v
,OP_EQ
, "\\");
1727 tor_free(k
); tor_free(v
);
1729 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1730 tt_str_op(k
,OP_EQ
, "Mix");
1731 tt_str_op(v
,OP_EQ
, "This is a \"star\":\t'*'\nAnd second line");
1732 tor_free(k
); tor_free(v
);
1733 tt_str_op(str
,OP_EQ
, "");
1737 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1738 tt_ptr_op(str
,OP_EQ
, NULL
);
1739 tor_free(k
); tor_free(v
);
1743 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1744 tt_ptr_op(str
,OP_EQ
, NULL
);
1745 tor_free(k
); tor_free(v
);
1749 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1750 tt_ptr_op(str
,OP_EQ
, NULL
);
1751 tor_free(k
); tor_free(v
);
1756 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1757 tt_ptr_op(str
, OP_EQ
, NULL
);
1758 tor_free(k
); tor_free(v
);
1763 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1764 tt_ptr_op(str
,OP_EQ
, NULL
);
1765 tor_free(k
); tor_free(v
);
1767 /* more things to try. */
1769 strlcpy(buf1
, "Foo \"\\x9g\"\n", sizeof(buf1
));
1770 strlcpy(buf2
, "Foo \"\\xg0\"\n", sizeof(buf2
));
1771 strlcpy(buf3
, "Foo \"\\xf\"\n", sizeof(buf3
));
1773 strlcpy(buf4
, "Foo \"\\q\"\n", sizeof(buf4
));
1774 /* missing endquote */
1775 strlcpy(buf5
, "Foo \"hello\n", sizeof(buf5
));
1777 strlcpy(buf6
, "Foo \"hello\" world\n", sizeof(buf6
));
1780 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1781 tt_ptr_op(str
,OP_EQ
, NULL
);
1782 tor_free(k
); tor_free(v
);
1785 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1786 tt_ptr_op(str
,OP_EQ
, NULL
);
1787 tor_free(k
); tor_free(v
);
1790 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1791 tt_ptr_op(str
,OP_EQ
, NULL
);
1792 tor_free(k
); tor_free(v
);
1795 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1796 tt_ptr_op(str
,OP_EQ
, NULL
);
1797 tor_free(k
); tor_free(v
);
1801 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1802 tt_ptr_op(str
,OP_EQ
, NULL
);
1803 tor_free(k
); tor_free(v
);
1806 const char *err
= NULL
;
1807 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1808 tt_ptr_op(str
,OP_EQ
, NULL
);
1809 tor_free(k
); tor_free(v
);
1810 tt_str_op(err
,OP_EQ
, "Excess data after quoted string");
1818 test_util_config_line_crlf(void *arg
)
1820 char *k
=NULL
, *v
=NULL
;
1821 const char *err
= NULL
;
1825 "Hello \"nice big world\"\r\n";
1827 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1829 tt_str_op(k
,OP_EQ
,"Hello");
1830 tt_str_op(v
,OP_EQ
,"world");
1831 tt_ptr_op(err
, OP_EQ
, NULL
);
1832 tor_free(k
); tor_free(v
);
1834 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1836 tt_str_op(k
,OP_EQ
,"Hello");
1837 tt_str_op(v
,OP_EQ
,"nice big world");
1838 tt_ptr_op(err
, OP_EQ
, NULL
);
1839 tor_free(k
); tor_free(v
);
1840 tt_str_op(str
,OP_EQ
, "");
1843 tor_free(k
); tor_free(v
);
1848 test_util_expand_filename(void *arg
)
1853 setenv("HOME", "/home/itv", 1); /* For "internal test value" */
1855 str
= expand_filename("");
1856 tt_str_op("",OP_EQ
, str
);
1859 str
= expand_filename("/normal/path");
1860 tt_str_op("/normal/path",OP_EQ
, str
);
1863 str
= expand_filename("/normal/trailing/path/");
1864 tt_str_op("/normal/trailing/path/",OP_EQ
, str
);
1867 str
= expand_filename("~");
1868 tt_str_op("/home/itv/",OP_EQ
, str
);
1871 str
= expand_filename("$HOME/nodice");
1872 tt_str_op("$HOME/nodice",OP_EQ
, str
);
1875 str
= expand_filename("~/");
1876 tt_str_op("/home/itv/",OP_EQ
, str
);
1879 str
= expand_filename("~/foobarqux");
1880 tt_str_op("/home/itv/foobarqux",OP_EQ
, str
);
1883 str
= expand_filename("~/../../etc/passwd");
1884 tt_str_op("/home/itv/../../etc/passwd",OP_EQ
, str
);
1887 str
= expand_filename("~/trailing/");
1888 tt_str_op("/home/itv/trailing/",OP_EQ
, str
);
1890 /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
1891 have to somehow inject/fake the get_user_homedir call) */
1893 /* $HOME ending in a trailing slash */
1894 setenv("HOME", "/home/itv/", 1);
1896 str
= expand_filename("~");
1897 tt_str_op("/home/itv/",OP_EQ
, str
);
1900 str
= expand_filename("~/");
1901 tt_str_op("/home/itv/",OP_EQ
, str
);
1904 str
= expand_filename("~/foo");
1905 tt_str_op("/home/itv/foo",OP_EQ
, str
);
1908 /* Try with empty $HOME */
1910 setenv("HOME", "", 1);
1912 str
= expand_filename("~");
1913 tt_str_op("/",OP_EQ
, str
);
1916 str
= expand_filename("~/");
1917 tt_str_op("/",OP_EQ
, str
);
1920 str
= expand_filename("~/foobar");
1921 tt_str_op("/foobar",OP_EQ
, str
);
1924 /* Try with $HOME unset */
1928 str
= expand_filename("~");
1929 tt_str_op("/",OP_EQ
, str
);
1932 str
= expand_filename("~/");
1933 tt_str_op("/",OP_EQ
, str
);
1936 str
= expand_filename("~/foobar");
1937 tt_str_op("/foobar",OP_EQ
, str
);
1943 #endif /* !defined(_WIN32) */
1945 /** Test tor_escape_str_for_pt_args(). */
1947 test_util_escape_string_socks(void *arg
)
1949 char *escaped_string
= NULL
;
1951 /** Simple backslash escape. */
1953 escaped_string
= tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
1954 tt_assert(escaped_string
);
1955 tt_str_op(escaped_string
,OP_EQ
, "This is a backslash: \\\\");
1956 tor_free(escaped_string
);
1958 /** Simple semicolon escape. */
1959 escaped_string
= tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
1960 tt_assert(escaped_string
);
1961 tt_str_op(escaped_string
,OP_EQ
, "First rule:Do not use \\;");
1962 tor_free(escaped_string
);
1964 /** Empty string. */
1965 escaped_string
= tor_escape_str_for_pt_args("", ";\\");
1966 tt_assert(escaped_string
);
1967 tt_str_op(escaped_string
,OP_EQ
, "");
1968 tor_free(escaped_string
);
1970 /** Escape all characters. */
1971 escaped_string
= tor_escape_str_for_pt_args(";\\;\\", ";\\");
1972 tt_assert(escaped_string
);
1973 tt_str_op(escaped_string
,OP_EQ
, "\\;\\\\\\;\\\\");
1974 tor_free(escaped_string
);
1976 escaped_string
= tor_escape_str_for_pt_args(";", ";\\");
1977 tt_assert(escaped_string
);
1978 tt_str_op(escaped_string
,OP_EQ
, "\\;");
1979 tor_free(escaped_string
);
1982 tor_free(escaped_string
);
1986 test_util_string_is_key_value(void *ptr
)
1989 tt_assert(string_is_key_value(LOG_WARN
, "key=value"));
1990 tt_assert(string_is_key_value(LOG_WARN
, "k=v"));
1991 tt_assert(string_is_key_value(LOG_WARN
, "key="));
1992 tt_assert(string_is_key_value(LOG_WARN
, "x="));
1993 tt_assert(string_is_key_value(LOG_WARN
, "xx="));
1994 tt_assert(!string_is_key_value(LOG_WARN
, "=value"));
1995 tt_assert(!string_is_key_value(LOG_WARN
, "=x"));
1996 tt_assert(!string_is_key_value(LOG_WARN
, "="));
1999 /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
2004 /** Test basic string functionality. */
2006 test_util_strmisc(void *arg
)
2009 char *cp_tmp
= NULL
;
2011 /* Test strl operations */
2013 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 0));
2014 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 10));
2015 tt_str_op(buf
,OP_EQ
, "Hello");
2016 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 6));
2017 tt_str_op(buf
,OP_EQ
, "Hello");
2018 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 5));
2019 tt_str_op(buf
,OP_EQ
, "Hell");
2020 strlcpy(buf
, "Hello", sizeof(buf
));
2021 tt_int_op(10,OP_EQ
, strlcat(buf
, "Hello", 5));
2023 /* Test strstrip() */
2024 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
2025 tor_strstrip(buf
, ",!");
2026 tt_str_op(buf
,OP_EQ
, "Testing 1 2 3");
2027 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
2028 tor_strstrip(buf
, "!? ");
2029 tt_str_op(buf
,OP_EQ
, "Testing123");
2030 strlcpy(buf
, "!!!Testing 1 2 3??", sizeof(buf
));
2031 tor_strstrip(buf
, "!? ");
2032 tt_str_op(buf
,OP_EQ
, "Testing123");
2035 /* Returning -1 when there's not enough room in the output buffer */
2036 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 0, "Foo"));
2037 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 2, "Foo"));
2038 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 3, "Foo"));
2039 tt_int_op(-1,OP_NE
, tor_snprintf(buf
, 4, "Foo"));
2040 /* Always NUL-terminate the output */
2041 tor_snprintf(buf
, 5, "abcdef");
2042 tt_int_op(0,OP_EQ
, buf
[4]);
2043 tor_snprintf(buf
, 10, "abcdef");
2044 tt_int_op(0,OP_EQ
, buf
[6]);
2046 tor_snprintf(buf
, sizeof(buf
), "x!%"PRIu64
"!x",
2047 (UINT64_C(12345678901)));
2048 tt_str_op("x!12345678901!x",OP_EQ
, buf
);
2050 /* Test str{,case}cmpstart */
2051 tt_assert(strcmpstart("abcdef", "abcdef")==0);
2052 tt_assert(strcmpstart("abcdef", "abc")==0);
2053 tt_assert(strcmpstart("abcdef", "abd")<0);
2054 tt_assert(strcmpstart("abcdef", "abb")>0);
2055 tt_assert(strcmpstart("ab", "abb")<0);
2056 tt_assert(strcmpstart("ab", "")==0);
2057 tt_assert(strcmpstart("ab", "ab ")<0);
2058 tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
2059 tt_assert(strcasecmpstart("abcDeF", "abc")==0);
2060 tt_assert(strcasecmpstart("abcdef", "Abd")<0);
2061 tt_assert(strcasecmpstart("Abcdef", "abb")>0);
2062 tt_assert(strcasecmpstart("ab", "Abb")<0);
2063 tt_assert(strcasecmpstart("ab", "")==0);
2064 tt_assert(strcasecmpstart("ab", "ab ")<0);
2066 /* Test str{,case}cmpend */
2067 tt_assert(strcmpend("abcdef", "abcdef")==0);
2068 tt_assert(strcmpend("abcdef", "def")==0);
2069 tt_assert(strcmpend("abcdef", "deg")<0);
2070 tt_assert(strcmpend("abcdef", "dee")>0);
2071 tt_assert(strcmpend("ab", "aab")>0);
2072 tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
2073 tt_assert(strcasecmpend("abcdef", "dEF")==0);
2074 tt_assert(strcasecmpend("abcdef", "Deg")<0);
2075 tt_assert(strcasecmpend("abcDef", "dee")>0);
2076 tt_assert(strcasecmpend("AB", "abb")<0);
2078 /* Test digest_is_zero */
2081 tt_assert(tor_digest_is_zero(buf
));
2083 tt_assert(!tor_digest_is_zero(buf
));
2085 /* Test mem_is_zero */
2088 tt_assert(tor_mem_is_zero(buf
, 10));
2089 tt_assert(tor_mem_is_zero(buf
, 20));
2090 tt_assert(tor_mem_is_zero(buf
, 128));
2091 tt_assert(!tor_mem_is_zero(buf
, 129));
2092 buf
[60] = (char)255;
2093 tt_assert(!tor_mem_is_zero(buf
, 128));
2095 tt_assert(!tor_mem_is_zero(buf
, 10));
2097 /* Test 'escaped' */
2098 tt_ptr_op(escaped(NULL
), OP_EQ
, NULL
);
2099 tt_str_op("\"\"",OP_EQ
, escaped(""));
2100 tt_str_op("\"abcd\"",OP_EQ
, escaped("abcd"));
2101 tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ
, escaped("\\ \n\r\t\"'"));
2102 tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ
,
2103 escaped("unnecessary \'backslashes\'"));
2104 /* Non-printable characters appear as octal */
2105 tt_str_op("\"z\\001abc\\277d\"",OP_EQ
, escaped("z\001abc\277d"));
2106 tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ
, escaped("z\xde\xad\x20;foo"));
2108 /* Other cases of esc_for_log{,_len} */
2109 cp_tmp
= esc_for_log(NULL
);
2110 tt_str_op(cp_tmp
, OP_EQ
, "(null)");
2112 cp_tmp
= esc_for_log_len("abcdefg", 3);
2113 tt_str_op(cp_tmp
, OP_EQ
, "\"abc\"");
2115 cp_tmp
= esc_for_log_len("abcdefg", 100);
2116 tt_str_op(cp_tmp
, OP_EQ
, "\"abcdefg\"");
2119 /* Test strndup and memdup */
2121 const char *s
= "abcdefghijklmnopqrstuvwxyz";
2122 cp_tmp
= tor_strndup(s
, 30);
2123 tt_str_op(cp_tmp
,OP_EQ
, s
); /* same string, */
2124 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2127 cp_tmp
= tor_strndup(s
, 5);
2128 tt_str_op(cp_tmp
,OP_EQ
, "abcde");
2131 s
= "a\0b\0c\0d\0e\0";
2132 cp_tmp
= tor_memdup(s
,10);
2133 tt_mem_op(cp_tmp
,OP_EQ
, s
, 10); /* same ram, */
2134 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2138 /* Test str-foo functions */
2139 cp_tmp
= tor_strdup("abcdef");
2140 tt_assert(tor_strisnonupper(cp_tmp
));
2142 tt_assert(!tor_strisnonupper(cp_tmp
));
2143 tor_strupper(cp_tmp
);
2144 tt_str_op(cp_tmp
,OP_EQ
, "ABCDEF");
2145 tor_strlower(cp_tmp
);
2146 tt_str_op(cp_tmp
,OP_EQ
, "abcdef");
2147 tt_assert(tor_strisnonupper(cp_tmp
));
2148 tt_assert(tor_strisprint(cp_tmp
));
2150 tt_assert(!tor_strisprint(cp_tmp
));
2153 /* Test memmem and memstr */
2155 const char *haystack
= "abcde";
2156 tt_ptr_op(tor_memmem(haystack
, 5, "ef", 2), OP_EQ
, NULL
);
2157 tt_ptr_op(tor_memmem(haystack
, 5, "cd", 2),OP_EQ
, haystack
+ 2);
2158 tt_ptr_op(tor_memmem(haystack
, 5, "cde", 3),OP_EQ
, haystack
+ 2);
2159 tt_ptr_op(tor_memmem(haystack
, 4, "cde", 3), OP_EQ
, NULL
);
2160 haystack
= "ababcad";
2161 tt_ptr_op(tor_memmem(haystack
, 7, "abc", 3),OP_EQ
, haystack
+ 2);
2162 tt_ptr_op(tor_memmem(haystack
, 7, "ad", 2),OP_EQ
, haystack
+ 5);
2163 tt_ptr_op(tor_memmem(haystack
, 7, "cad", 3),OP_EQ
, haystack
+ 4);
2164 tt_ptr_op(tor_memmem(haystack
, 7, "dadad", 5), OP_EQ
, NULL
);
2165 tt_ptr_op(tor_memmem(haystack
, 7, "abcdefghij", 10), OP_EQ
, NULL
);
2167 tt_ptr_op(tor_memstr(haystack
, 7, "abc"),OP_EQ
, haystack
+ 2);
2168 tt_ptr_op(tor_memstr(haystack
, 7, "cad"),OP_EQ
, haystack
+ 4);
2169 tt_ptr_op(tor_memstr(haystack
, 6, "cad"), OP_EQ
, NULL
);
2170 tt_ptr_op(tor_memstr(haystack
, 7, "cadd"), OP_EQ
, NULL
);
2171 tt_ptr_op(tor_memstr(haystack
, 7, "fe"), OP_EQ
, NULL
);
2172 tt_ptr_op(tor_memstr(haystack
, 7, "ababcade"), OP_EQ
, NULL
);
2177 char binary_data
[68];
2179 for (idx
= 0; idx
< sizeof(binary_data
); ++idx
)
2180 binary_data
[idx
] = idx
;
2181 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2182 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2183 tt_str_op(hex_str(binary_data
, 17),OP_EQ
,
2184 "000102030405060708090A0B0C0D0E0F10");
2185 tt_str_op(hex_str(binary_data
, 32),OP_EQ
,
2186 "000102030405060708090A0B0C0D0E0F"
2187 "101112131415161718191A1B1C1D1E1F");
2188 tt_str_op(hex_str(binary_data
, 34),OP_EQ
,
2189 "000102030405060708090A0B0C0D0E0F"
2190 "101112131415161718191A1B1C1D1E1F");
2191 /* Repeat these tests for shorter strings after longer strings
2192 have been tried, to make sure we're correctly terminating strings */
2193 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2194 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2197 /* Test strcmp_opt */
2198 tt_int_op(strcmp_opt("", "foo"), OP_LT
, 0);
2199 tt_int_op(strcmp_opt("", ""), OP_EQ
, 0);
2200 tt_int_op(strcmp_opt("foo", ""), OP_GT
, 0);
2202 tt_int_op(strcmp_opt(NULL
, ""), OP_LT
, 0);
2203 tt_int_op(strcmp_opt(NULL
, NULL
), OP_EQ
, 0);
2204 tt_int_op(strcmp_opt("", NULL
), OP_GT
, 0);
2206 tt_int_op(strcmp_opt(NULL
, "foo"), OP_LT
, 0);
2207 tt_int_op(strcmp_opt("foo", NULL
), OP_GT
, 0);
2214 test_util_parse_integer(void *arg
)
2220 /* Test parse_long */
2221 /* Empty/zero input */
2222 tt_int_op(0L,OP_EQ
, tor_parse_long("",10,0,100,&i
,NULL
));
2223 tt_int_op(0,OP_EQ
, i
);
2224 tt_int_op(0L,OP_EQ
, tor_parse_long("0",10,0,100,&i
,NULL
));
2225 tt_int_op(1,OP_EQ
, i
);
2227 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,100,&i
,NULL
));
2228 tt_int_op(1,OP_EQ
, i
);
2229 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,10,&i
,NULL
));
2230 tt_int_op(1,OP_EQ
, i
);
2231 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,10,100,&i
,NULL
));
2232 tt_int_op(1,OP_EQ
, i
);
2233 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,100,&i
,NULL
));
2234 tt_int_op(1,OP_EQ
, i
);
2235 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,0,&i
,NULL
));
2236 tt_int_op(1,OP_EQ
, i
);
2237 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-50,0,&i
,NULL
));
2238 tt_int_op(1,OP_EQ
, i
);
2240 tt_int_op(0L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,NULL
));
2241 tt_int_op(0,OP_EQ
, i
);
2242 tt_int_op(0L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,NULL
));
2243 tt_int_op(0,OP_EQ
, i
);
2244 tt_int_op(10L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,&cp
));
2245 tt_int_op(1,OP_EQ
, i
);
2246 tt_str_op(cp
,OP_EQ
, "m");
2247 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,&cp
));
2248 tt_int_op(1,OP_EQ
, i
);
2249 tt_str_op(cp
,OP_EQ
, " plus garbage");
2250 /* Illogical min max */
2251 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,4,&i
,NULL
));
2252 tt_int_op(0,OP_EQ
, i
);
2253 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,100,-100,&i
,NULL
));
2254 tt_int_op(0,OP_EQ
, i
);
2256 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,100,&i
,NULL
));
2257 tt_int_op(0,OP_EQ
, i
);
2258 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,0,100,&i
,NULL
));
2259 tt_int_op(0,OP_EQ
, i
);
2260 /* Base different than 10 */
2261 tt_int_op(2L,OP_EQ
, tor_parse_long("10",2,0,100,NULL
,NULL
));
2262 tt_int_op(0L,OP_EQ
, tor_parse_long("2",2,0,100,NULL
,NULL
));
2263 tt_int_op(68284L,OP_EQ
, tor_parse_long("10abc",16,0,70000,NULL
,NULL
));
2264 tt_int_op(68284L,OP_EQ
, tor_parse_long("10ABC",16,0,70000,NULL
,NULL
));
2265 tt_int_op(0L,OP_EQ
, tor_parse_long("10",-2,0,100,NULL
,NULL
));
2266 tt_int_op(0,OP_EQ
, tor_parse_long("10ABC",-1,0,70000,&i
,NULL
));
2267 tt_int_op(i
,OP_EQ
, 0);
2269 /* Test parse_ulong */
2270 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("",10,0,100,NULL
,NULL
));
2271 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("0",10,0,100,NULL
,NULL
));
2272 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
2273 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
2274 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,10,NULL
,NULL
));
2275 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,10,100,NULL
,NULL
));
2276 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("8",8,0,100,NULL
,NULL
));
2277 tt_int_op(50UL,OP_EQ
, tor_parse_ulong("50",10,50,100,NULL
,NULL
));
2278 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,NULL
,NULL
));
2279 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("50",-1,50,100,&i
,NULL
));
2280 tt_int_op(0,OP_EQ
, i
);
2281 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,&i
,NULL
));
2282 tt_int_op(0,OP_EQ
, i
);
2284 /* Test parse_uint64 */
2285 tt_assert(UINT64_C(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
2286 tt_int_op(1,OP_EQ
, i
);
2287 tt_str_op(cp
,OP_EQ
, " x");
2288 tt_assert(UINT64_C(12345678901) ==
2289 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
2290 tt_int_op(1,OP_EQ
, i
);
2291 tt_str_op(cp
,OP_EQ
, "");
2292 tt_assert(UINT64_C(0) ==
2293 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
2294 tt_int_op(0,OP_EQ
, i
);
2295 tt_assert(UINT64_C(0) ==
2296 tor_parse_uint64("123",-1,0,INT32_MAX
, &i
, &cp
));
2297 tt_int_op(0,OP_EQ
, i
);
2300 /* Test parse_double */
2301 double d
= tor_parse_double("10", 0, (double)UINT64_MAX
,&i
,NULL
);
2302 tt_int_op(1,OP_EQ
, i
);
2303 tt_assert(((uint64_t)d
) == 10);
2304 d
= tor_parse_double("0", 0, (double)UINT64_MAX
,&i
,NULL
);
2305 tt_int_op(1,OP_EQ
, i
);
2306 tt_assert(((uint64_t)d
) == 0);
2307 d
= tor_parse_double(" ", 0, (double)UINT64_MAX
,&i
,NULL
);
2308 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2309 tt_int_op(0,OP_EQ
, i
);
2310 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,NULL
);
2311 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2312 tt_int_op(0,OP_EQ
, i
);
2313 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,&cp
);
2314 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2315 tt_int_op(1,OP_EQ
, i
);
2316 d
= tor_parse_double("-.0", 0, (double)UINT64_MAX
,&i
,NULL
);
2317 tt_int_op(1,OP_EQ
, i
);
2318 tt_assert(((uint64_t)d
) == 0);
2319 d
= tor_parse_double("-10", -100.0, 100.0,&i
,NULL
);
2320 tt_int_op(1,OP_EQ
, i
);
2321 tt_double_op(fabs(d
- -10.0),OP_LT
, 1E-12);
2325 /* Test tor_parse_* where we overflow/underflow the underlying type. */
2326 /* This string should overflow 64-bit ints. */
2327 #define TOOBIG "100000000000000000000000000"
2328 tt_int_op(0L, OP_EQ
,
2329 tor_parse_long(TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2330 tt_int_op(i
,OP_EQ
, 0);
2332 tor_parse_long("-"TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2333 tt_int_op(i
,OP_EQ
, 0);
2334 tt_int_op(0UL,OP_EQ
, tor_parse_ulong(TOOBIG
, 10, 0, ULONG_MAX
, &i
, NULL
));
2335 tt_int_op(i
,OP_EQ
, 0);
2336 tt_u64_op(UINT64_C(0), OP_EQ
, tor_parse_uint64(TOOBIG
, 10,
2337 0, UINT64_MAX
, &i
, NULL
));
2338 tt_int_op(i
,OP_EQ
, 0);
2345 test_util_pow2(void *arg
)
2347 /* Test tor_log2(). */
2349 tt_int_op(tor_log2(64),OP_EQ
, 6);
2350 tt_int_op(tor_log2(65),OP_EQ
, 6);
2351 tt_int_op(tor_log2(63),OP_EQ
, 5);
2352 /* incorrect mathematically, but as specified: */
2353 tt_int_op(tor_log2(0),OP_EQ
, 0);
2354 tt_int_op(tor_log2(1),OP_EQ
, 0);
2355 tt_int_op(tor_log2(2),OP_EQ
, 1);
2356 tt_int_op(tor_log2(3),OP_EQ
, 1);
2357 tt_int_op(tor_log2(4),OP_EQ
, 2);
2358 tt_int_op(tor_log2(5),OP_EQ
, 2);
2359 tt_int_op(tor_log2(UINT64_C(40000000000000000)),OP_EQ
, 55);
2360 tt_int_op(tor_log2(UINT64_MAX
),OP_EQ
, 63);
2362 /* Test round_to_power_of_2 */
2363 tt_u64_op(round_to_power_of_2(120), OP_EQ
, 128);
2364 tt_u64_op(round_to_power_of_2(128), OP_EQ
, 128);
2365 tt_u64_op(round_to_power_of_2(130), OP_EQ
, 128);
2366 tt_u64_op(round_to_power_of_2(UINT64_C(40000000000000000)), OP_EQ
,
2368 tt_u64_op(round_to_power_of_2(UINT64_C(0xffffffffffffffff)), OP_EQ
,
2370 tt_u64_op(round_to_power_of_2(0), OP_EQ
, 1);
2371 tt_u64_op(round_to_power_of_2(1), OP_EQ
, 1);
2372 tt_u64_op(round_to_power_of_2(2), OP_EQ
, 2);
2373 tt_u64_op(round_to_power_of_2(3), OP_EQ
, 2);
2374 tt_u64_op(round_to_power_of_2(4), OP_EQ
, 4);
2375 tt_u64_op(round_to_power_of_2(5), OP_EQ
, 4);
2376 tt_u64_op(round_to_power_of_2(6), OP_EQ
, 4);
2377 tt_u64_op(round_to_power_of_2(7), OP_EQ
, 8);
2384 test_util_compress_impl(compress_method_t method
)
2386 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
;
2389 tt_assert(tor_compress_supports_method(method
));
2391 if (method
!= NO_METHOD
) {
2392 tt_ptr_op(tor_compress_version_str(method
), OP_NE
, NULL
);
2393 tt_ptr_op(tor_compress_header_version_str(method
), OP_NE
, NULL
);
2396 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
2397 tt_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
2399 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1, method
));
2400 tt_ptr_op(buf2
, OP_NE
, NULL
);
2401 if (method
== NO_METHOD
) {
2402 // The identity transform doesn't actually compress, and it isn't
2403 // detectable as "the identity transform."
2404 tt_int_op(len1
, OP_EQ
, strlen(buf1
)+1);
2405 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, UNKNOWN_METHOD
);
2407 tt_int_op(len1
, OP_LT
, strlen(buf1
));
2408 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, method
);
2411 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
, method
, 1, LOG_INFO
));
2412 tt_ptr_op(buf3
, OP_NE
, NULL
);
2413 tt_int_op(strlen(buf1
) + 1, OP_EQ
, len2
);
2414 tt_str_op(buf1
, OP_EQ
, buf3
);
2415 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2417 /* Check whether we can uncompress concatenated, compressed strings. */
2419 buf2
= tor_reallocarray(buf2
, len1
, 2);
2420 memcpy(buf2
+len1
, buf2
, len1
);
2421 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
*2, method
, 1, LOG_INFO
));
2422 tt_int_op((strlen(buf1
)+1)*2, OP_EQ
, len2
);
2423 tt_mem_op(buf3
, OP_EQ
,
2424 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
2425 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
2426 (strlen(buf1
)+1)*2);
2427 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2429 /* Check whether we can uncompress partial strings */
2435 size_t b1len
= 1<<10;
2436 if (method
== ZSTD_METHOD
) {
2437 // zstd needs a big input before it starts generating output that it
2438 // can partially decompress.
2441 buf1
= tor_malloc(b1len
);
2442 crypto_rand(buf1
, b1len
);
2443 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, b1len
, method
));
2444 tt_int_op(len1
, OP_GT
, 16);
2445 /* when we allow an incomplete output we should succeed.*/
2446 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2447 method
, 0, LOG_INFO
));
2448 tt_int_op(len2
, OP_GT
, 5);
2449 tt_int_op(len2
, OP_LE
, len1
);
2450 tt_assert(fast_memeq(buf1
, buf3
, len2
));
2451 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2453 /* when we demand a complete output from a real compression method, this
2456 if (method
!= NO_METHOD
) {
2457 tt_assert(tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2458 method
, 1, LOG_INFO
));
2459 tt_ptr_op(buf3
, OP_EQ
, NULL
);
2469 test_util_compress_stream_impl(compress_method_t method
,
2470 compression_level_t level
)
2472 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
2476 tor_compress_state_t
*state
= NULL
;
2477 state
= tor_compress_new(1, method
, level
);
2479 cp1
= buf1
= tor_malloc(1024);
2481 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
2483 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0),
2484 OP_EQ
, TOR_COMPRESS_OK
);
2485 tt_int_op(0, OP_EQ
, len2
); /* Make sure we compressed it all. */
2486 tt_assert(cp1
> buf1
);
2490 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1),
2491 OP_EQ
, TOR_COMPRESS_DONE
);
2492 tt_int_op(0, OP_EQ
, len2
);
2493 if (method
== NO_METHOD
) {
2494 tt_ptr_op(cp1
, OP_EQ
, cp2
);
2496 tt_assert(cp1
> cp2
); /* Make sure we really added something. */
2499 tt_int_op(tor_compress_state_size(state
), OP_GT
, 0);
2501 tt_assert(!tor_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
2502 method
, 1, LOG_WARN
));
2503 /* Make sure it compressed right. */
2504 tt_str_op(buf3
, OP_EQ
, "ABCDEFGHIJABCDEFGHIJ");
2505 tt_int_op(21, OP_EQ
, len2
);
2509 tor_compress_free(state
);
2515 /** Setup function for compression tests: handles x-zstd:nostatic
2518 compression_test_setup(const struct testcase_t
*testcase
)
2520 tor_assert(testcase
->setup_data
);
2521 tor_assert(testcase
->setup_data
!= (void*)TT_SKIP
);
2522 const char *methodname
= testcase
->setup_data
;
2524 if (!strcmp(methodname
, "x-zstd:nostatic")) {
2525 methodname
= "x-zstd";
2526 tor_zstd_set_static_apis_disabled_for_testing(1);
2529 return (void *)methodname
;
2532 /** Cleanup for compression tests: disables nostatic */
2534 compression_test_cleanup(const struct testcase_t
*testcase
, void *ptr
)
2538 tor_zstd_set_static_apis_disabled_for_testing(0);
2542 static const struct testcase_setup_t compress_setup
= {
2543 compression_test_setup
, compression_test_cleanup
2546 /** Run unit tests for compression functions */
2548 test_util_compress(void *arg
)
2550 const char *methodname
= arg
;
2551 tt_assert(methodname
);
2553 compress_method_t method
= compression_method_get_by_name(methodname
);
2554 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2556 if (! tor_compress_supports_method(method
)) {
2560 compression_level_t levels
[] = {
2567 test_util_compress_impl(method
);
2569 for (unsigned l
= 0; l
< ARRAY_LENGTH(levels
); ++l
) {
2570 compression_level_t level
= levels
[l
];
2571 test_util_compress_stream_impl(method
, level
);
2578 test_util_decompress_concatenated_impl(compress_method_t method
)
2581 char *c1
= NULL
, *c2
= NULL
, *c3
= NULL
;
2582 char *result
= NULL
;
2583 size_t sz1
, sz2
, sz3
, szr
;
2586 crypto_rand(input
, sizeof(input
));
2588 /* Compress the input in two chunks. */
2589 r
= tor_compress(&c1
, &sz1
, input
, 2048, method
);
2590 tt_int_op(r
, OP_EQ
, 0);
2591 r
= tor_compress(&c2
, &sz2
, input
+2048, 2048, method
);
2592 tt_int_op(r
, OP_EQ
, 0);
2594 /* concatenate the chunks. */
2596 c3
= tor_malloc(sz3
);
2597 memcpy(c3
, c1
, sz1
);
2598 memcpy(c3
+sz1
, c2
, sz2
);
2600 /* decompress the concatenated result */
2601 r
= tor_uncompress(&result
, &szr
, c3
, sz3
, method
, 0, LOG_WARN
);
2602 tt_int_op(r
, OP_EQ
, 0);
2603 tt_int_op(szr
, OP_EQ
, sizeof(input
));
2604 tt_mem_op(result
, OP_EQ
, input
, sizeof(input
));
2614 test_util_decompress_concatenated(void *arg
)
2616 const char *methodname
= arg
;
2617 tt_assert(methodname
);
2619 compress_method_t method
= compression_method_get_by_name(methodname
);
2620 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2621 if (! tor_compress_supports_method(method
)) {
2625 test_util_decompress_concatenated_impl(method
);
2631 test_util_decompress_junk_impl(compress_method_t method
)
2634 char *result
= NULL
, *result2
= NULL
;
2635 size_t szr
, szr2
, sz
;
2638 /* This shouldn't be a compressed string according to any method. */
2639 strlcpy(input
, "This shouldn't be a compressed string by any means.",
2642 setup_capture_of_logs(LOG_WARN
);
2643 r
= tor_uncompress(&result
, &szr
, input
, sz
, method
, 0, LOG_WARN
);
2644 tt_int_op(r
, OP_EQ
, -1);
2645 tt_ptr_op(result
, OP_EQ
, NULL
);
2646 expect_log_msg_containing("Error while uncompressing data: bad input?");
2647 mock_clean_saved_logs();
2649 /* Now try again, with a compressed object that starts out good and turns to
2651 crypto_rand(input
, sizeof(input
));
2652 r
= tor_compress(&result
, &szr
, input
, sizeof(input
), method
);
2653 tt_int_op(r
, OP_EQ
, 0);
2654 crypto_rand(result
+szr
/2, szr
-(szr
/2)); // trash the 2nd half of the result
2655 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2656 tt_int_op(r
, OP_EQ
, -1);
2657 expect_log_msg_containing("Error while uncompressing data: bad input?");
2660 teardown_capture_of_logs();
2666 test_util_decompress_junk(void *arg
)
2668 const char *methodname
= arg
;
2669 tt_assert(methodname
);
2671 compress_method_t method
= compression_method_get_by_name(methodname
);
2672 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2673 if (! tor_compress_supports_method(method
)) {
2677 test_util_decompress_junk_impl(method
);
2682 /* mock replacement for tor_compress_is_compression_bomb that doesn't
2683 * believe in compression bombs. */
2685 mock_is_never_compression_bomb(size_t in
, size_t out
)
2693 test_util_decompress_dos_impl(compress_method_t method
)
2696 char *result
= NULL
, *result2
= NULL
;
2700 const size_t big
= 1024*1024;
2701 /* one megabyte of 0s. */
2702 input
= tor_malloc_zero(big
);
2704 /* Compress it into "result": it should fail. */
2705 setup_full_capture_of_logs(LOG_WARN
);
2706 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2707 tt_int_op(r
, OP_EQ
, -1);
2708 expect_log_msg_containing(
2709 "other Tors would think this was a compression bomb");
2710 teardown_capture_of_logs();
2712 /* Try again, but this time suppress compression-bomb detection */
2713 MOCK(tor_compress_is_compression_bomb
, mock_is_never_compression_bomb
);
2714 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2715 UNMOCK(tor_compress_is_compression_bomb
);
2716 tt_int_op(r
, OP_EQ
, 0);
2717 tt_ptr_op(result
, OP_NE
, NULL
);
2719 /* We should refuse to uncomrpess it again, since it looks like a
2720 * compression bomb. */
2721 setup_capture_of_logs(LOG_WARN
);
2722 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2723 tt_int_op(r
, OP_EQ
, -1);
2724 expect_log_msg_containing("bomb; abandoning stream");
2727 teardown_capture_of_logs();
2734 test_util_decompress_dos(void *arg
)
2736 const char *methodname
= arg
;
2737 tt_assert(methodname
);
2739 compress_method_t method
= compression_method_get_by_name(methodname
);
2740 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2741 if (! tor_compress_supports_method(method
)) {
2745 test_util_decompress_dos_impl(method
);
2751 test_util_gzip_compression_bomb(void *arg
)
2753 /* A 'compression bomb' is a very small object that uncompresses to a huge
2754 * one. Most compression formats support them, but they can be a DOS vector.
2755 * In Tor we try not to generate them, and we don't accept them.
2758 size_t one_million
= 1<<20;
2759 char *one_mb
= tor_malloc_zero(one_million
);
2760 char *result
= NULL
;
2761 size_t result_len
= 0;
2762 tor_compress_state_t
*state
= NULL
;
2764 /* Make sure we can't produce a compression bomb */
2765 setup_full_capture_of_logs(LOG_WARN
);
2766 tt_int_op(-1, OP_EQ
, tor_compress(&result
, &result_len
,
2767 one_mb
, one_million
,
2769 expect_single_log_msg_containing(
2770 "We compressed something and got an insanely high "
2771 "compression factor; other Tors would think this "
2772 "was a compression bomb.");
2773 teardown_capture_of_logs();
2775 /* Here's a compression bomb that we made manually. */
2776 const char compression_bomb
[1039] =
2777 { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2,
2778 0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ };
2779 tt_int_op(-1, OP_EQ
, tor_uncompress(&result
, &result_len
,
2780 compression_bomb
, 1039,
2781 ZLIB_METHOD
, 0, LOG_WARN
));
2783 /* Now try streaming that. */
2784 state
= tor_compress_new(0, ZLIB_METHOD
, HIGH_COMPRESSION
);
2785 tor_compress_output_t r
;
2786 const char *inp
= compression_bomb
;
2787 size_t inlen
= 1039;
2789 char *outp
= one_mb
;
2790 size_t outleft
= 4096; /* small on purpose */
2791 r
= tor_compress_process(state
, &outp
, &outleft
, &inp
, &inlen
, 0);
2792 tt_int_op(inlen
, OP_NE
, 0);
2793 } while (r
== TOR_COMPRESS_BUFFER_FULL
);
2795 tt_int_op(r
, OP_EQ
, TOR_COMPRESS_ERROR
);
2799 tor_compress_free(state
);
2802 /** Run unit tests for mmap() wrapper functionality. */
2804 test_util_mmap(void *arg
)
2806 char *fname1
= tor_strdup(get_fname("mapped_1"));
2807 char *fname2
= tor_strdup(get_fname("mapped_2"));
2808 char *fname3
= tor_strdup(get_fname("mapped_3"));
2809 const size_t buflen
= 17000;
2810 char *buf
= tor_malloc(17000);
2811 tor_mmap_t
*mapping
= NULL
;
2814 crypto_rand(buf
, buflen
);
2816 mapping
= tor_mmap_file(fname1
);
2817 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2819 write_str_to_file(fname1
, "Short file.", 1);
2821 mapping
= tor_mmap_file(fname1
);
2823 tt_int_op(mapping
->size
,OP_EQ
, strlen("Short file."));
2824 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
2826 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2828 tt_assert(unlink(fname1
) == 0);
2830 /* make sure we can unlink. */
2831 tt_assert(unlink(fname1
) == 0);
2832 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
2833 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2835 #endif /* defined(_WIN32) */
2837 /* Now a zero-length file. */
2838 write_str_to_file(fname1
, "", 1);
2839 mapping
= tor_mmap_file(fname1
);
2840 tt_ptr_op(mapping
,OP_EQ
, NULL
);
2841 tt_int_op(ERANGE
,OP_EQ
, errno
);
2844 /* Make sure that we fail to map a no-longer-existent file. */
2845 mapping
= tor_mmap_file(fname1
);
2846 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2848 /* Now try a big file that stretches across a few pages and isn't aligned */
2849 write_bytes_to_file(fname2
, buf
, buflen
, 1);
2850 mapping
= tor_mmap_file(fname2
);
2852 tt_int_op(mapping
->size
,OP_EQ
, buflen
);
2853 tt_mem_op(mapping
->data
,OP_EQ
, buf
, buflen
);
2854 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2857 /* Now try a big aligned file. */
2858 write_bytes_to_file(fname3
, buf
, 16384, 1);
2859 mapping
= tor_mmap_file(fname3
);
2861 tt_int_op(mapping
->size
,OP_EQ
, 16384);
2862 tt_mem_op(mapping
->data
,OP_EQ
, buf
, 16384);
2863 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2876 tor_munmap_file(mapping
);
2879 /** Run unit tests for escaping/unescaping data for use by controllers. */
2881 test_util_control_formats(void *arg
)
2885 "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
2889 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
2890 tt_str_op(out
,OP_EQ
,
2891 ".This is a test\nof the emergency \n.system.\n\rZ.\n");
2892 tt_int_op(sz
,OP_EQ
, strlen(out
));
2898 #define test_feq(value1,value2) do { \
2899 double v1 = (value1), v2=(value2); \
2900 double tf_diff = v1-v2; \
2901 double tf_tolerance = ((v1+v2)/2.0)/1e8; \
2902 if (tf_diff<0) tf_diff=-tf_diff; \
2903 if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
2904 if (tf_diff<tf_tolerance) { \
2905 TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
2907 TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
2912 test_util_sscanf(void *arg
)
2914 unsigned u1
, u2
, u3
;
2916 char s1
[20], s2
[10], s3
[10], ch
, *huge
= NULL
;
2922 /* Simple tests (malformed patterns, literal matching, ...) */
2924 tt_int_op(-1,OP_EQ
, tor_sscanf("123", "%i", &r
)); /* %i is not supported */
2926 tor_sscanf("wrong", "%5c", s1
)); /* %c cannot have a number. */
2927 tt_int_op(-1,OP_EQ
, tor_sscanf("hello", "%s", s1
)); /* %s needs a number. */
2928 /* this will fail because we don't allow widths longer than 9999 */
2930 huge
= tor_malloc(1000000);
2931 r
= tor_sscanf("prettylongstring", "%99999s", huge
);
2933 tt_int_op(-1,OP_EQ
, r
);
2936 /* GCC thinks these two are illegal. */
2937 test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1
));
2938 test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL
));
2940 /* No '%'-strings: always "success" */
2941 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "hello world"));
2942 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "good bye"));
2945 tor_sscanf("hello 3", "%u", &u1
)); /* have to match the start */
2946 tt_int_op(0,OP_EQ
, tor_sscanf(" 3 hello", "%u", &u1
));
2948 tor_sscanf(" 3 hello", "%2u", &u1
)); /* not even in this case */
2950 tor_sscanf("3 hello", "%u", &u1
)); /* but trailing is alright */
2952 /* Numbers (ie. %u) */
2954 tor_sscanf("hello world 3", "hello worlb %u", &u1
)); /* d vs b */
2955 tt_int_op(1,OP_EQ
, tor_sscanf("12345", "%u", &u1
));
2956 tt_int_op(12345u,OP_EQ
, u1
);
2957 tt_int_op(1,OP_EQ
, tor_sscanf("12346 ", "%u", &u1
));
2958 tt_int_op(12346u,OP_EQ
, u1
);
2959 tt_int_op(0,OP_EQ
, tor_sscanf(" 12347", "%u", &u1
));
2960 tt_int_op(1,OP_EQ
, tor_sscanf(" 12348", " %u", &u1
));
2961 tt_int_op(12348u,OP_EQ
, u1
);
2962 tt_int_op(1,OP_EQ
, tor_sscanf("0", "%u", &u1
));
2963 tt_int_op(0u,OP_EQ
, u1
);
2964 tt_int_op(1,OP_EQ
, tor_sscanf("0000", "%u", &u2
));
2965 tt_int_op(0u,OP_EQ
, u2
);
2966 tt_int_op(0,OP_EQ
, tor_sscanf("", "%u", &u1
)); /* absent number */
2967 tt_int_op(0,OP_EQ
, tor_sscanf("A", "%u", &u1
)); /* bogus number */
2968 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%u", &u1
)); /* negative number */
2970 /* Numbers with size (eg. %2u) */
2971 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%2u", &u1
));
2972 tt_int_op(2,OP_EQ
, tor_sscanf("123456", "%2u%u", &u1
, &u2
));
2973 tt_int_op(12u,OP_EQ
, u1
);
2974 tt_int_op(3456u,OP_EQ
, u2
);
2975 tt_int_op(1,OP_EQ
, tor_sscanf("123456", "%8u", &u1
));
2976 tt_int_op(123456u,OP_EQ
, u1
);
2977 tt_int_op(1,OP_EQ
, tor_sscanf("123457 ", "%8u", &u1
));
2978 tt_int_op(123457u,OP_EQ
, u1
);
2979 tt_int_op(0,OP_EQ
, tor_sscanf(" 123456", "%8u", &u1
));
2980 tt_int_op(3,OP_EQ
, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
));
2981 tt_int_op(12u,OP_EQ
, u1
);
2982 tt_int_op(3u,OP_EQ
, u2
);
2983 tt_int_op(456u,OP_EQ
, u3
);
2985 tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1
, &u2
, &u3
)); /* 0s */
2986 tt_int_op(67u,OP_EQ
, u1
);
2987 tt_int_op(8u,OP_EQ
, u2
);
2988 tt_int_op(99u,OP_EQ
, u3
);
2989 /* %u does not match space.*/
2990 tt_int_op(2,OP_EQ
, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
2991 tt_int_op(12u,OP_EQ
, u1
);
2992 tt_int_op(3u,OP_EQ
, u2
);
2993 /* %u does not match negative numbers. */
2994 tt_int_op(2,OP_EQ
, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
2995 tt_int_op(67u,OP_EQ
, u1
);
2996 tt_int_op(8u,OP_EQ
, u2
);
2997 /* Arbitrary amounts of 0-padding are okay */
2998 tt_int_op(3,OP_EQ
, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
3000 tt_int_op(12u,OP_EQ
, u1
);
3001 tt_int_op(3u,OP_EQ
, u2
);
3002 tt_int_op(99u,OP_EQ
, u3
);
3006 tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1
, &u2
, &u3
));
3007 tt_int_op(0x1234,OP_EQ
, u1
);
3008 tt_int_op(0x2ABCDEF,OP_EQ
, u2
);
3009 tt_int_op(0xFF,OP_EQ
, u3
);
3010 /* Width works on %x */
3011 tt_int_op(3,OP_EQ
, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1
, &u2
, &u3
));
3012 tt_int_op(0xf00d,OP_EQ
, u1
);
3013 tt_int_op(0xcafe,OP_EQ
, u2
);
3014 tt_int_op(444,OP_EQ
, u3
);
3016 /* Literal '%' (ie. '%%') */
3017 tt_int_op(1,OP_EQ
, tor_sscanf("99% fresh", "%3u%% fresh", &u1
));
3018 tt_int_op(99,OP_EQ
, u1
);
3019 tt_int_op(0,OP_EQ
, tor_sscanf("99 fresh", "%% %3u %s", &u1
, s1
));
3020 tt_int_op(1,OP_EQ
, tor_sscanf("99 fresh", "%3u%% %s", &u1
, s1
));
3021 tt_int_op(2,OP_EQ
, tor_sscanf("99 fresh", "%3u %5s %%", &u1
, s1
));
3022 tt_int_op(99,OP_EQ
, u1
);
3023 tt_str_op(s1
,OP_EQ
, "fresh");
3024 tt_int_op(1,OP_EQ
, tor_sscanf("% boo", "%% %3s", s1
));
3025 tt_str_op("boo",OP_EQ
, s1
);
3027 /* Strings (ie. %s) */
3028 tt_int_op(2,OP_EQ
, tor_sscanf("hello", "%3s%7s", s1
, s2
));
3029 tt_str_op(s1
,OP_EQ
, "hel");
3030 tt_str_op(s2
,OP_EQ
, "lo");
3031 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%2s%u", s3
, &u1
)); /* %s%u */
3032 tt_str_op(s3
,OP_EQ
, "WD");
3033 tt_int_op(40,OP_EQ
, u1
);
3034 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%3s%u", s3
, &u1
)); /* %s%u */
3035 tt_str_op(s3
,OP_EQ
, "WD4");
3036 tt_int_op(0,OP_EQ
, u1
);
3037 tt_int_op(2,OP_EQ
, tor_sscanf("76trombones", "%6u%9s", &u1
, s1
)); /* %u%s */
3038 tt_int_op(76,OP_EQ
, u1
);
3039 tt_str_op(s1
,OP_EQ
, "trombones");
3041 huge
= tor_malloc(1000);
3042 r
= tor_sscanf("prettylongstring", "%999s", huge
);
3043 tt_int_op(1,OP_EQ
, r
);
3044 tt_str_op(huge
,OP_EQ
, "prettylongstring");
3047 /* %s doesn't eat spaces */
3048 tt_int_op(2,OP_EQ
, tor_sscanf("hello world", "%9s %9s", s1
, s2
));
3049 tt_str_op(s1
,OP_EQ
, "hello");
3050 tt_str_op(s2
,OP_EQ
, "world");
3051 tt_int_op(2,OP_EQ
, tor_sscanf("bye world?", "%9s %9s", s1
, s2
));
3052 tt_str_op(s1
,OP_EQ
, "bye");
3053 tt_str_op(s2
,OP_EQ
, "");
3055 tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
)); /* %s can be empty. */
3056 tt_str_op(s1
,OP_EQ
, "hi");
3057 tt_str_op(s2
,OP_EQ
, "");
3058 tt_str_op(s3
,OP_EQ
, "");
3060 tt_int_op(3,OP_EQ
, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3062 tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3063 tt_int_op(' ',OP_EQ
, ch
);
3065 r
= tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1
, &lng1
, &int2
);
3066 tt_int_op(r
,OP_EQ
, 3);
3067 tt_int_op(int1
,OP_EQ
, 12345);
3068 tt_int_op(lng1
,OP_EQ
, -67890);
3069 tt_int_op(int2
,OP_EQ
, -1);
3073 /* UINT32_MAX should work */
3074 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%u", &u1
));
3075 tt_int_op(4294967295U,OP_EQ
, u1
);
3077 /* But UINT32_MAX + 1 shouldn't work */
3078 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%u", &u1
));
3079 /* but parsing only 9... */
3080 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9u", &u1
));
3081 tt_int_op(429496729U,OP_EQ
, u1
);
3084 /* UINT32_MAX should work */
3085 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%x", &u1
));
3086 tt_int_op(0xFFFFFFFF,OP_EQ
, u1
);
3088 /* But UINT32_MAX + 1 shouldn't work */
3089 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%x", &u1
));
3092 /* INT32_MIN and INT32_MAX should work */
3093 r
= tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1
, &int2
);
3094 tt_int_op(r
,OP_EQ
, 2);
3095 tt_int_op(int1
,OP_EQ
, -2147483647 - 1);
3096 tt_int_op(int2
,OP_EQ
, 2147483647);
3098 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3099 r
= tor_sscanf("-2147483649.", "%d.", &int1
);
3100 tt_int_op(r
,OP_EQ
, 0);
3102 r
= tor_sscanf("2147483648.", "%d.", &int1
);
3103 tt_int_op(r
,OP_EQ
, 0);
3105 /* and the first failure stops further processing */
3106 r
= tor_sscanf("-2147483648. 2147483648.",
3107 "%d. %d.", &int1
, &int2
);
3108 tt_int_op(r
,OP_EQ
, 1);
3110 r
= tor_sscanf("-2147483649. 2147483647.",
3111 "%d. %d.", &int1
, &int2
);
3112 tt_int_op(r
,OP_EQ
, 0);
3114 r
= tor_sscanf("2147483648. -2147483649.",
3115 "%d. %d.", &int1
, &int2
);
3116 tt_int_op(r
,OP_EQ
, 0);
3117 #elif SIZEOF_INT == 8
3119 /* UINT64_MAX should work */
3120 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%u", &u1
));
3121 tt_int_op(18446744073709551615U,OP_EQ
, u1
);
3123 /* But UINT64_MAX + 1 shouldn't work */
3124 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%u", &u1
));
3125 /* but parsing only 19... */
3126 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19u", &u1
));
3127 tt_int_op(1844674407370955161U,OP_EQ
, u1
);
3130 /* UINT64_MAX should work */
3131 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1
));
3132 tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ
, u1
);
3134 /* But UINT64_MAX + 1 shouldn't work */
3135 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%x", &u1
));
3138 /* INT64_MIN and INT64_MAX should work */
3139 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3140 "%d. %d.", &int1
, &int2
);
3141 tt_int_op(r
,OP_EQ
, 2);
3142 tt_int_op(int1
,OP_EQ
, -9223372036854775807 - 1);
3143 tt_int_op(int2
,OP_EQ
, 9223372036854775807);
3145 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3146 r
= tor_sscanf("-9223372036854775809.", "%d.", &int1
);
3147 tt_int_op(r
,OP_EQ
, 0);
3149 r
= tor_sscanf("9223372036854775808.", "%d.", &int1
);
3150 tt_int_op(r
,OP_EQ
, 0);
3152 /* and the first failure stops further processing */
3153 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3154 "%d. %d.", &int1
, &int2
);
3155 tt_int_op(r
,OP_EQ
, 1);
3157 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3158 "%d. %d.", &int1
, &int2
);
3159 tt_int_op(r
,OP_EQ
, 0);
3161 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3162 "%d. %d.", &int1
, &int2
);
3163 tt_int_op(r
,OP_EQ
, 0);
3164 #endif /* SIZEOF_INT == 4 || ... */
3166 #if SIZEOF_LONG == 4
3168 /* UINT32_MAX should work */
3169 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%lu", &ulng
));
3170 tt_int_op(4294967295UL,OP_EQ
, ulng
);
3172 /* But UINT32_MAX + 1 shouldn't work */
3173 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%lu", &ulng
));
3174 /* but parsing only 9... */
3175 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9lu", &ulng
));
3176 tt_int_op(429496729UL,OP_EQ
, ulng
);
3179 /* UINT32_MAX should work */
3180 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%lx", &ulng
));
3181 tt_int_op(0xFFFFFFFFUL
,OP_EQ
, ulng
);
3183 /* But UINT32_MAX + 1 shouldn't work */
3184 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%lx", &ulng
));
3187 /* INT32_MIN and INT32_MAX should work */
3188 r
= tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1
, &lng2
);
3189 tt_int_op(r
,OP_EQ
, 2);
3190 tt_int_op(lng1
,OP_EQ
, -2147483647L - 1L);
3191 tt_int_op(lng2
,OP_EQ
, 2147483647L);
3193 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3194 r
= tor_sscanf("-2147483649.", "%ld.", &lng1
);
3195 tt_int_op(r
,OP_EQ
, 0);
3197 r
= tor_sscanf("2147483648.", "%ld.", &lng1
);
3198 tt_int_op(r
,OP_EQ
, 0);
3200 /* and the first failure stops further processing */
3201 r
= tor_sscanf("-2147483648. 2147483648.",
3202 "%ld. %ld.", &lng1
, &lng2
);
3203 tt_int_op(r
,OP_EQ
, 1);
3205 r
= tor_sscanf("-2147483649. 2147483647.",
3206 "%ld. %ld.", &lng1
, &lng2
);
3207 tt_int_op(r
,OP_EQ
, 0);
3209 r
= tor_sscanf("2147483648. -2147483649.",
3210 "%ld. %ld.", &lng1
, &lng2
);
3211 tt_int_op(r
,OP_EQ
, 0);
3212 #elif SIZEOF_LONG == 8
3214 /* UINT64_MAX should work */
3215 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%lu", &ulng
));
3216 tt_int_op(18446744073709551615UL,OP_EQ
, ulng
);
3218 /* But UINT64_MAX + 1 shouldn't work */
3219 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%lu", &ulng
));
3220 /* but parsing only 19... */
3221 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19lu", &ulng
));
3222 tt_int_op(1844674407370955161UL,OP_EQ
, ulng
);
3225 /* UINT64_MAX should work */
3226 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng
));
3227 tt_int_op(0xFFFFFFFFFFFFFFFFUL
,OP_EQ
, ulng
);
3229 /* But UINT64_MAX + 1 shouldn't work */
3230 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%lx", &ulng
));
3233 /* INT64_MIN and INT64_MAX should work */
3234 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3235 "%ld. %ld.", &lng1
, &lng2
);
3236 tt_int_op(r
,OP_EQ
, 2);
3237 tt_int_op(lng1
,OP_EQ
, -9223372036854775807L - 1L);
3238 tt_int_op(lng2
,OP_EQ
, 9223372036854775807L);
3240 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3241 r
= tor_sscanf("-9223372036854775809.", "%ld.", &lng1
);
3242 tt_int_op(r
,OP_EQ
, 0);
3244 r
= tor_sscanf("9223372036854775808.", "%ld.", &lng1
);
3245 tt_int_op(r
,OP_EQ
, 0);
3247 /* and the first failure stops further processing */
3248 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3249 "%ld. %ld.", &lng1
, &lng2
);
3250 tt_int_op(r
,OP_EQ
, 1);
3252 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3253 "%ld. %ld.", &lng1
, &lng2
);
3254 tt_int_op(r
,OP_EQ
, 0);
3256 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3257 "%ld. %ld.", &lng1
, &lng2
);
3258 tt_int_op(r
,OP_EQ
, 0);
3259 #endif /* SIZEOF_LONG == 4 || ... */
3261 r
= tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
3262 "%lf %lf %lf %lf", &d1
,&d2
,&d3
,&d4
);
3263 tt_int_op(r
,OP_EQ
, 4);
3264 test_feq(d1
, 123.456);
3265 test_feq(d2
, .000007);
3266 test_feq(d3
, -900123123.2000787);
3270 r
= tor_sscanf("3 ", "%d %lf", &int1
, &d1
);
3271 tt_int_op(r
, OP_EQ
, 1);
3272 tt_int_op(int1
, OP_EQ
, 3);
3275 r
= tor_sscanf("999 notafloat", "%d %lf", &int1
, &d1
);
3276 tt_int_op(r
, OP_EQ
, 1);
3277 tt_int_op(int1
, OP_EQ
, 999);
3279 /* %s but no buffer. */
3280 char *nullbuf
= NULL
;
3281 r
= tor_sscanf("hello", "%3s", nullbuf
);
3282 tt_int_op(r
, OP_EQ
, 0);
3288 #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
3289 #define tt_ci_char_op(a,op,b) \
3290 tt_char_op(TOR_TOLOWER((int)a),op,TOR_TOLOWER((int)b))
3292 #ifndef HAVE_STRNLEN
3294 strnlen(const char *s
, size_t len
)
3296 const char *p
= memchr(s
, 0, len
);
3301 #endif /* !defined(HAVE_STRNLEN) */
3304 test_util_format_time_interval(void *arg
)
3306 /* use the same sized buffer and integers as tor uses */
3307 #define DBUF_SIZE 64
3308 char dbuf
[DBUF_SIZE
];
3310 long sec
, min
, hour
, day
;
3312 /* we don't care about the exact spelling of the
3313 * second(s), minute(s), hour(s), day(s) labels */
3314 #define LABEL_SIZE 21
3316 char label_s
[LABEL_SIZE
];
3317 char label_m
[LABEL_SIZE
];
3318 char label_h
[LABEL_SIZE
];
3319 char label_d
[LABEL_SIZE
];
3321 #define TL_ T_ " " L_
3327 /* In these tests, we're not picky about
3328 * spelling or abbreviations */
3330 /* seconds: 0, 1, 9, 10, 59 */
3332 /* ignore exact spelling of "second(s)"*/
3333 format_time_interval(dbuf
, sizeof(dbuf
), 0);
3334 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3335 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3336 tt_int_op(r
,OP_EQ
, 2);
3337 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3338 tt_int_op(sec
,OP_EQ
, 0);
3340 format_time_interval(dbuf
, sizeof(dbuf
), 1);
3341 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3342 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3343 tt_int_op(r
,OP_EQ
, 2);
3344 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3345 tt_int_op(sec
,OP_EQ
, 1);
3347 format_time_interval(dbuf
, sizeof(dbuf
), 10);
3348 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3349 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3350 tt_int_op(r
,OP_EQ
, 2);
3351 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3352 tt_int_op(sec
,OP_EQ
, 10);
3354 format_time_interval(dbuf
, sizeof(dbuf
), 59);
3355 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3356 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3357 tt_int_op(r
,OP_EQ
, 2);
3358 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3359 tt_int_op(sec
,OP_EQ
, 59);
3361 /* negative seconds are reported as their absolute value */
3363 format_time_interval(dbuf
, sizeof(dbuf
), -4);
3364 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3365 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3366 tt_int_op(r
,OP_EQ
, 2);
3367 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3368 tt_int_op(sec
,OP_EQ
, 4);
3369 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3371 format_time_interval(dbuf
, sizeof(dbuf
), -32);
3372 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3373 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3374 tt_int_op(r
,OP_EQ
, 2);
3375 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3376 tt_int_op(sec
,OP_EQ
, 32);
3377 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3379 /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
3381 /* ignore trailing "0 second(s)", if present */
3382 format_time_interval(dbuf
, sizeof(dbuf
), 60);
3383 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3384 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3385 tt_int_op(r
,OP_EQ
, 2);
3386 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3387 tt_int_op(min
,OP_EQ
, 1);
3388 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3390 /* ignore exact spelling of "minute(s)," and "second(s)" */
3391 format_time_interval(dbuf
, sizeof(dbuf
), 60 + 1);
3392 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3393 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3394 &min
, label_m
, &sec
, label_s
);
3395 tt_int_op(r
,OP_EQ
, 4);
3396 tt_int_op(min
,OP_EQ
, 1);
3397 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3398 tt_int_op(sec
,OP_EQ
, 1);
3399 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3400 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3402 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 - 1);
3403 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3404 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3405 &min
, label_m
, &sec
, label_s
);
3406 tt_int_op(r
,OP_EQ
, 4);
3407 tt_int_op(min
,OP_EQ
, 1);
3408 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3409 tt_int_op(sec
,OP_EQ
, 59);
3410 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3412 /* ignore trailing "0 second(s)", if present */
3413 format_time_interval(dbuf
, sizeof(dbuf
), 60*2);
3414 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3415 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3416 tt_int_op(r
,OP_EQ
, 2);
3417 tt_int_op(min
,OP_EQ
, 2);
3418 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3420 /* ignore exact spelling of "minute(s)," and "second(s)" */
3421 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 + 1);
3422 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3423 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3424 &min
, label_m
, &sec
, label_s
);
3425 tt_int_op(r
,OP_EQ
, 4);
3426 tt_int_op(min
,OP_EQ
, 2);
3427 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3428 tt_int_op(sec
,OP_EQ
, 1);
3429 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3431 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 - 1);
3432 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3433 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3434 &min
, label_m
, &sec
, label_s
);
3435 tt_int_op(r
,OP_EQ
, 4);
3436 tt_int_op(min
,OP_EQ
, 59);
3437 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3438 tt_int_op(sec
,OP_EQ
, 59);
3439 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3441 /* negative minutes are reported as their absolute value */
3443 /* ignore trailing "0 second(s)", if present */
3444 format_time_interval(dbuf
, sizeof(dbuf
), -3*60);
3445 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3446 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3447 tt_int_op(r
,OP_EQ
, 2);
3448 tt_int_op(min
,OP_EQ
, 3);
3449 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3451 /* ignore exact spelling of "minute(s)," and "second(s)" */
3452 format_time_interval(dbuf
, sizeof(dbuf
), -96);
3453 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3454 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3455 &min
, label_m
, &sec
, label_s
);
3456 tt_int_op(r
,OP_EQ
, 4);
3457 tt_int_op(min
,OP_EQ
, 1);
3458 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3459 tt_int_op(sec
,OP_EQ
, 36);
3460 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3462 format_time_interval(dbuf
, sizeof(dbuf
), -2815);
3463 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3464 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3465 &min
, label_m
, &sec
, label_s
);
3466 tt_int_op(r
,OP_EQ
, 4);
3467 tt_int_op(min
,OP_EQ
, 46);
3468 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3469 tt_int_op(sec
,OP_EQ
, 55);
3470 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3472 /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
3473 /* always ignore trailing seconds, if present */
3475 /* ignore trailing "0 minute(s)" etc., if present */
3476 format_time_interval(dbuf
, sizeof(dbuf
), 60*60);
3477 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3478 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3479 tt_int_op(r
,OP_EQ
, 2);
3480 tt_int_op(hour
,OP_EQ
, 1);
3481 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3483 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 1);
3484 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3485 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3486 tt_int_op(r
,OP_EQ
, 2);
3487 tt_int_op(hour
,OP_EQ
, 1);
3488 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3490 /* ignore exact spelling of "hour(s)," etc. */
3491 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 60);
3492 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3493 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3494 &hour
, label_h
, &min
, label_m
);
3495 tt_int_op(r
,OP_EQ
, 4);
3496 tt_int_op(hour
,OP_EQ
, 1);
3497 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3498 tt_int_op(min
,OP_EQ
, 1);
3499 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3501 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 60);
3502 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3503 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3504 &hour
, label_h
, &min
, label_m
);
3505 tt_int_op(r
,OP_EQ
, 4);
3506 tt_int_op(hour
,OP_EQ
, 23);
3507 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3508 tt_int_op(min
,OP_EQ
, 59);
3509 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3511 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 1);
3512 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3513 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3514 &hour
, label_h
, &min
, label_m
);
3515 tt_int_op(r
,OP_EQ
, 4);
3516 tt_int_op(hour
,OP_EQ
, 23);
3517 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3518 tt_int_op(min
,OP_EQ
, 59);
3519 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3521 /* negative hours are reported as their absolute value */
3523 /* ignore exact spelling of "hour(s)," etc., if present */
3524 format_time_interval(dbuf
, sizeof(dbuf
), -2*60*60);
3525 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3526 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3527 tt_int_op(r
,OP_EQ
, 2);
3528 tt_int_op(hour
,OP_EQ
, 2);
3529 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3531 format_time_interval(dbuf
, sizeof(dbuf
), -75804);
3532 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3533 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3534 &hour
, label_h
, &min
, label_m
);
3535 tt_int_op(r
,OP_EQ
, 4);
3536 tt_int_op(hour
,OP_EQ
, 21);
3537 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3538 tt_int_op(min
,OP_EQ
, 3);
3539 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3541 /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
3542 /* always ignore trailing seconds, if present */
3544 /* ignore trailing "0 hours(s)" etc., if present */
3545 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60);
3546 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3547 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3548 tt_int_op(r
,OP_EQ
, 2);
3549 tt_int_op(day
,OP_EQ
, 1);
3550 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3552 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 1);
3553 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3554 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3555 tt_int_op(r
,OP_EQ
, 2);
3556 tt_int_op(day
,OP_EQ
, 1);
3557 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3559 /* ignore exact spelling of "days(s)," etc. */
3560 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60);
3561 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3562 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3563 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3565 /* ignore 0 hours(s), if present */
3566 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3567 &day
, label_d
, &min
, label_m
);
3569 tt_assert(r
== 4 || r
== 6);
3570 tt_int_op(day
,OP_EQ
, 1);
3571 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3573 tt_int_op(hour
,OP_EQ
, 0);
3574 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3576 tt_int_op(min
,OP_EQ
, 1);
3577 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3579 /* ignore trailing "0 minutes(s)" etc., if present */
3580 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60*60);
3581 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3582 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3583 &day
, label_d
, &hour
, label_h
);
3584 tt_int_op(r
,OP_EQ
, 4);
3585 tt_int_op(day
,OP_EQ
, 1);
3586 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3587 tt_int_op(hour
,OP_EQ
, 1);
3588 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3590 /* negative days are reported as their absolute value */
3592 format_time_interval(dbuf
, sizeof(dbuf
), -21936184);
3593 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3594 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3595 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3596 tt_int_op(r
,OP_EQ
, 6);
3597 tt_int_op(day
,OP_EQ
, 253);
3598 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3599 tt_int_op(hour
,OP_EQ
, 21);
3600 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3601 tt_int_op(min
,OP_EQ
, 23);
3602 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3604 /* periods > 1 year are reported in days (warn?) */
3606 /* ignore exact spelling of "days(s)," etc., if present */
3607 format_time_interval(dbuf
, sizeof(dbuf
), 758635154);
3608 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3609 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3610 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3611 tt_int_op(r
,OP_EQ
, 6);
3612 tt_int_op(day
,OP_EQ
, 8780);
3613 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3614 tt_int_op(hour
,OP_EQ
, 11);
3615 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3616 tt_int_op(min
,OP_EQ
, 59);
3617 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3619 /* negative periods > 1 year are reported in days (warn?) */
3621 format_time_interval(dbuf
, sizeof(dbuf
), -1427014922);
3622 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3623 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3624 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3625 tt_int_op(r
,OP_EQ
, 6);
3626 tt_int_op(day
,OP_EQ
, 16516);
3627 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3628 tt_int_op(hour
,OP_EQ
, 9);
3629 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3630 tt_int_op(min
,OP_EQ
, 2);
3631 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3633 #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
3635 /* We can try INT32_MIN/MAX */
3636 /* Always ignore second(s) */
3639 format_time_interval(dbuf
, sizeof(dbuf
), 2147483647);
3640 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3641 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3642 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3643 tt_int_op(r
,OP_EQ
, 6);
3644 tt_int_op(day
,OP_EQ
, 24855);
3645 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3646 tt_int_op(hour
,OP_EQ
, 3);
3647 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3648 tt_int_op(min
,OP_EQ
, 14);
3649 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3650 /* and 7 seconds - ignored */
3652 /* INT32_MIN: check that we get the absolute value of interval,
3653 * which doesn't actually fit in int32_t.
3654 * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
3655 format_time_interval(dbuf
, sizeof(dbuf
), -2147483647L - 1L);
3656 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3657 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3658 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3659 tt_int_op(r
,OP_EQ
, 6);
3660 tt_int_op(day
,OP_EQ
, 24855);
3661 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3662 tt_int_op(hour
,OP_EQ
, 3);
3663 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3664 tt_int_op(min
,OP_EQ
, 14);
3665 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3666 /* and 7 or 8 seconds - ignored */
3668 #endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */
3670 #if SIZEOF_LONG == 8
3672 /* We can try INT64_MIN/MAX */
3673 /* Always ignore second(s) */
3676 format_time_interval(dbuf
, sizeof(dbuf
), 9223372036854775807L);
3677 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3678 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3679 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3680 tt_int_op(r
,OP_EQ
, 6);
3681 tt_int_op(day
,OP_EQ
, 106751991167300L);
3682 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3683 tt_int_op(hour
,OP_EQ
, 15);
3684 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3685 tt_int_op(min
,OP_EQ
, 30);
3686 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3687 /* and 7 seconds - ignored */
3689 /* INT64_MIN: check that we get the absolute value of interval,
3690 * which doesn't actually fit in int64_t.
3691 * We expect INT64_MAX */
3692 format_time_interval(dbuf
, sizeof(dbuf
),
3693 -9223372036854775807L - 1L);
3694 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3695 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3696 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3697 tt_int_op(r
,OP_EQ
, 6);
3698 tt_int_op(day
,OP_EQ
, 106751991167300L);
3699 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3700 tt_int_op(hour
,OP_EQ
, 15);
3701 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3702 tt_int_op(min
,OP_EQ
, 30);
3703 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3704 /* and 7 or 8 seconds - ignored */
3706 #endif /* SIZEOF_LONG == 8 */
3713 #undef tt_ci_char_op
3721 test_util_path_is_relative(void *arg
)
3723 /* OS-independent tests */
3725 tt_int_op(1,OP_EQ
, path_is_relative(""));
3726 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3727 tt_int_op(1,OP_EQ
, path_is_relative("dir/"));
3728 tt_int_op(1,OP_EQ
, path_is_relative("./dir"));
3729 tt_int_op(1,OP_EQ
, path_is_relative("../dir"));
3731 tt_int_op(0,OP_EQ
, path_is_relative("/"));
3732 tt_int_op(0,OP_EQ
, path_is_relative("/dir"));
3733 tt_int_op(0,OP_EQ
, path_is_relative("/dir/"));
3737 /* I don't have Windows so I can't test this, hence the "#ifdef
3738 0". These are tests that look useful, so please try to get them
3739 running and uncomment if it all works as it should */
3740 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3741 tt_int_op(1,OP_EQ
, path_is_relative("dir\\"));
3742 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:"));
3743 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:\\"));
3744 tt_int_op(1,OP_EQ
, path_is_relative("http:\\dir"));
3746 tt_int_op(0,OP_EQ
, path_is_relative("\\dir"));
3747 tt_int_op(0,OP_EQ
, path_is_relative("a:\\dir"));
3748 tt_int_op(0,OP_EQ
, path_is_relative("z:\\dir"));
3749 #endif /* defined(_WIN32) */
3755 /** Run unittests for memory area allocator */
3757 test_util_memarea(void *arg
)
3759 memarea_t
*area
= memarea_new();
3760 char *p1
, *p2
, *p3
, *p1_orig
;
3761 void *malloced_ptr
= NULL
;
3764 #ifdef DISABLE_MEMORY_SENTINELS
3765 /* If memory sentinels are disabled, this whole module is just an alias for
3766 malloc(), which is free to lay out memory most any way it wants. */
3769 #endif /* defined(DISABLE_MEMORY_SENTINELS) */
3774 p1_orig
= p1
= memarea_alloc(area
,64);
3775 p2
= memarea_alloc_zero(area
,52);
3776 p3
= memarea_alloc(area
,11);
3778 tt_assert(memarea_owns_ptr(area
, p1
));
3779 tt_assert(memarea_owns_ptr(area
, p2
));
3780 tt_assert(memarea_owns_ptr(area
, p3
));
3781 /* Make sure we left enough space. */
3782 tt_assert(p1
+64 <= p2
);
3783 tt_assert(p2
+52 <= p3
);
3784 /* Make sure we aligned. */
3785 tt_int_op(((uintptr_t)p1
) % sizeof(void*),OP_EQ
, 0);
3786 tt_int_op(((uintptr_t)p2
) % sizeof(void*),OP_EQ
, 0);
3787 tt_int_op(((uintptr_t)p3
) % sizeof(void*),OP_EQ
, 0);
3788 tt_assert(!memarea_owns_ptr(area
, p3
+8192));
3789 tt_assert(!memarea_owns_ptr(area
, p3
+30));
3790 tt_assert(tor_mem_is_zero(p2
, 52));
3791 /* Make sure we don't overalign. */
3792 p1
= memarea_alloc(area
, 1);
3793 p2
= memarea_alloc(area
, 1);
3794 tt_ptr_op(p1
+sizeof(void*),OP_EQ
, p2
);
3796 malloced_ptr
= tor_malloc(64);
3797 tt_assert(!memarea_owns_ptr(area
, malloced_ptr
));
3798 tor_free(malloced_ptr
);
3801 /* memarea_memdup */
3803 malloced_ptr
= tor_malloc(64);
3804 crypto_rand((char*)malloced_ptr
, 64);
3805 p1
= memarea_memdup(area
, malloced_ptr
, 64);
3806 tt_assert(p1
!= malloced_ptr
);
3807 tt_mem_op(p1
,OP_EQ
, malloced_ptr
, 64);
3808 tor_free(malloced_ptr
);
3811 /* memarea_strdup. */
3812 p1
= memarea_strdup(area
,"");
3813 p2
= memarea_strdup(area
, "abcd");
3816 tt_str_op(p1
,OP_EQ
, "");
3817 tt_str_op(p2
,OP_EQ
, "abcd");
3819 /* memarea_strndup. */
3821 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
3822 /* (From Turandot, act 3.) */
3823 size_t len
= strlen(s
);
3824 p1
= memarea_strndup(area
, s
, 1000);
3825 p2
= memarea_strndup(area
, s
, 10);
3826 tt_str_op(p1
,OP_EQ
, s
);
3827 tt_assert(p2
>= p1
+ len
+ 1);
3828 tt_mem_op(s
,OP_EQ
, p2
, 10);
3829 tt_int_op(p2
[10],OP_EQ
, '\0');
3830 p3
= memarea_strndup(area
, s
, len
);
3831 tt_str_op(p3
,OP_EQ
, s
);
3832 p3
= memarea_strndup(area
, s
, len
-1);
3833 tt_mem_op(s
,OP_EQ
, p3
, len
-1);
3834 tt_int_op(p3
[len
-1],OP_EQ
, '\0');
3837 memarea_clear(area
);
3838 p1
= memarea_alloc(area
, 1);
3839 tt_ptr_op(p1
,OP_EQ
, p1_orig
);
3840 memarea_clear(area
);
3841 size_t total
= 0, initial_allocation
, allocation2
, dummy
;
3842 memarea_get_stats(area
, &initial_allocation
, &dummy
);
3844 /* Check for running over an area's size. */
3845 for (i
= 0; i
< 4096; ++i
) {
3846 size_t n
= crypto_rand_int(6);
3847 p1
= memarea_alloc(area
, n
);
3849 tt_assert(memarea_owns_ptr(area
, p1
));
3851 memarea_assert_ok(area
);
3852 memarea_get_stats(area
, &allocation2
, &dummy
);
3853 /* Make sure we can allocate a too-big object. */
3854 p1
= memarea_alloc_zero(area
, 9000);
3855 p2
= memarea_alloc_zero(area
, 16);
3858 tt_assert(memarea_owns_ptr(area
, p1
));
3859 tt_assert(memarea_owns_ptr(area
, p2
));
3861 /* Now test stats... */
3862 size_t allocated
= 0, used
= 0;
3863 memarea_get_stats(area
, &allocated
, &used
);
3864 tt_int_op(used
, OP_LE
, allocated
);
3865 tt_int_op(used
, OP_GE
, total
); /* not EQ, because of alignment and headers*/
3866 tt_int_op(allocated
, OP_GT
, allocation2
);
3868 tt_int_op(allocation2
, OP_GT
, initial_allocation
);
3870 memarea_clear(area
);
3871 memarea_get_stats(area
, &allocated
, &used
);
3872 tt_int_op(used
, OP_LT
, 128); /* Not 0, because of header */
3873 tt_int_op(allocated
, OP_EQ
, initial_allocation
);
3876 memarea_drop_all(area
);
3877 tor_free(malloced_ptr
);
3880 /** Run unit tests for utility functions to get file names relative to
3881 * the data directory. */
3883 test_util_datadir(void *arg
)
3887 char *temp_dir
= NULL
;
3890 temp_dir
= get_datadir_fname(NULL
);
3891 f
= get_datadir_fname("state");
3892 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
3893 tt_str_op(f
,OP_EQ
, buf
);
3895 f
= get_datadir_fname2("cache", "thingy");
3896 tor_snprintf(buf
, sizeof(buf
),
3897 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
3898 tt_str_op(f
,OP_EQ
, buf
);
3900 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
3901 tor_snprintf(buf
, sizeof(buf
),
3902 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
3903 tt_str_op(f
,OP_EQ
, buf
);
3905 f
= get_datadir_fname_suffix("cache", ".foo");
3906 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
3908 tt_str_op(f
,OP_EQ
, buf
);
3916 test_util_strtok(void *arg
)
3924 for (i
= 0; i
< 3; i
++) {
3925 const char *pad1
="", *pad2
="";
3938 tor_snprintf(buf
, sizeof(buf
), "%s", pad1
);
3939 tor_snprintf(buf2
, sizeof(buf2
), "%s", pad2
);
3940 tt_ptr_op(tor_strtok_r_impl(buf
, " ", &cp1
), OP_EQ
, NULL
);
3941 tt_ptr_op(tor_strtok_r_impl(buf2
, ".!..;!", &cp2
), OP_EQ
, NULL
);
3943 tor_snprintf(buf
, sizeof(buf
),
3944 "%sGraved on the dark in gestures of descent%s", pad1
, pad1
);
3945 tor_snprintf(buf2
, sizeof(buf2
),
3946 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2
,pad2
);
3947 /* -- "Year's End", Richard Wilbur */
3949 tt_str_op("Graved",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3950 tt_str_op("they",OP_EQ
, tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
3951 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
3952 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
3953 tt_str_op("on",OP_EQ
, S1());
3954 tt_str_op("the",OP_EQ
, S1());
3955 tt_str_op("dark",OP_EQ
, S1());
3956 tt_str_op("seemed",OP_EQ
, S2());
3957 tt_str_op("their",OP_EQ
, S2());
3958 tt_str_op("own",OP_EQ
, S2());
3959 tt_str_op("in",OP_EQ
, S1());
3960 tt_str_op("gestures",OP_EQ
, S1());
3961 tt_str_op("of",OP_EQ
, S1());
3962 tt_str_op("most",OP_EQ
, S2());
3963 tt_str_op("perfect",OP_EQ
, S2());
3964 tt_str_op("descent",OP_EQ
, S1());
3965 tt_str_op("monument",OP_EQ
, S2());
3966 tt_ptr_op(NULL
,OP_EQ
, S1());
3967 tt_ptr_op(NULL
,OP_EQ
, S2());
3971 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3972 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
3974 strlcpy(buf
, "Howdy!", sizeof(buf
));
3975 tt_str_op("Howdy",OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
3976 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, "!", &cp1
));
3978 strlcpy(buf
, " ", sizeof(buf
));
3979 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3980 strlcpy(buf
, " ", sizeof(buf
));
3981 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3983 strlcpy(buf
, "something ", sizeof(buf
));
3984 tt_str_op("something",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3985 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, ";", &cp1
));
3991 test_util_find_str_at_start_of_line(void *ptr
)
3993 const char *long_string
=
3994 "howdy world. how are you? i hope it's fine.\n"
3997 char *line2
= strchr(long_string
,'\n')+1;
3998 char *line3
= strchr(line2
,'\n')+1;
3999 const char *short_string
= "hello kitty\n"
4001 char *short_line2
= strchr(short_string
,'\n')+1;
4005 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, ""));
4006 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(short_string
, "nonsense"));
4007 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "nonsense"));
4008 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "\n"));
4009 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "how "));
4010 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "kitty"));
4011 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "h"));
4012 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "how"));
4013 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "he"));
4014 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hell"));
4015 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hello k"));
4016 tt_ptr_op(line2
,OP_EQ
,
4017 find_str_at_start_of_line(long_string
, "hello kitty\n"));
4018 tt_ptr_op(line2
,OP_EQ
,
4019 find_str_at_start_of_line(long_string
, "hello kitty\nt"));
4020 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third"));
4021 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third line"));
4022 tt_ptr_op(NULL
, OP_EQ
,
4023 find_str_at_start_of_line(long_string
, "third line\n"));
4024 tt_ptr_op(short_line2
,OP_EQ
, find_str_at_start_of_line(short_string
,
4031 test_util_string_is_C_identifier(void *ptr
)
4035 tt_int_op(1,OP_EQ
, string_is_C_identifier("string_is_C_identifier"));
4036 tt_int_op(1,OP_EQ
, string_is_C_identifier("_string_is_C_identifier"));
4037 tt_int_op(1,OP_EQ
, string_is_C_identifier("_"));
4038 tt_int_op(1,OP_EQ
, string_is_C_identifier("i"));
4039 tt_int_op(1,OP_EQ
, string_is_C_identifier("_____"));
4040 tt_int_op(1,OP_EQ
, string_is_C_identifier("__00__"));
4041 tt_int_op(1,OP_EQ
, string_is_C_identifier("__init__"));
4042 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4043 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0string_is_C_identifier"));
4044 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4046 tt_int_op(0,OP_EQ
, string_is_C_identifier("0_string_is_C_identifier"));
4047 tt_int_op(0,OP_EQ
, string_is_C_identifier("0"));
4048 tt_int_op(0,OP_EQ
, string_is_C_identifier(""));
4049 tt_int_op(0,OP_EQ
, string_is_C_identifier(";"));
4050 tt_int_op(0,OP_EQ
, string_is_C_identifier("i;"));
4051 tt_int_op(0,OP_EQ
, string_is_C_identifier("_;"));
4052 tt_int_op(0,OP_EQ
, string_is_C_identifier("Ã"));
4053 tt_int_op(0,OP_EQ
, string_is_C_identifier("ñ"));
4060 test_util_string_is_utf8(void *ptr
)
4064 tt_int_op(1, OP_EQ
, string_is_utf8(NULL
, 0));
4065 tt_int_op(1, OP_EQ
, string_is_utf8("", 1));
4066 tt_int_op(1, OP_EQ
, string_is_utf8("\uFEFF", 3));
4067 tt_int_op(1, OP_EQ
, string_is_utf8("\uFFFE", 3));
4068 tt_int_op(1, OP_EQ
, string_is_utf8("ascii\x7f\n", 7));
4069 tt_int_op(1, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 9));
4071 /* Test the utf8_no_bom function */
4072 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFEFF", 3));
4073 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFFFE", 3));
4074 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFEFFlove", 7));
4075 tt_int_op(1, OP_EQ
, string_is_utf8_no_bom("loveandrespect",
4076 strlen("loveandrespect")));
4078 // Validate exactly 'len' bytes.
4079 tt_int_op(0, OP_EQ
, string_is_utf8("\0\x80", 2));
4080 tt_int_op(0, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 6));
4082 // Reject sequences with missing bytes.
4083 tt_int_op(0, OP_EQ
, string_is_utf8("\x80", 1));
4084 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2", 1));
4085 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2 ", 2));
4086 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80", 2));
4087 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80 ", 3));
4088 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80", 3));
4089 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80 ", 4));
4091 // Reject encodings that are overly long.
4092 tt_int_op(0, OP_EQ
, string_is_utf8("\xc1\xbf", 2));
4093 tt_int_op(1, OP_EQ
, string_is_utf8("\xc2\x80", 2));
4094 tt_int_op(0, OP_EQ
, string_is_utf8("\xe0\x9f\xbf", 3));
4095 tt_int_op(1, OP_EQ
, string_is_utf8("\xe0\xa0\x80", 3));
4096 tt_int_op(0, OP_EQ
, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
4097 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\x90\x80\x80", 4));
4099 // Reject UTF-16 surrogate halves.
4100 tt_int_op(1, OP_EQ
, string_is_utf8("\xed\x9f\xbf", 3));
4101 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xa0\x80", 3));
4102 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xbf\xbf", 3));
4103 tt_int_op(1, OP_EQ
, string_is_utf8("\xee\x80\x80", 3));
4105 // The maximum legal codepoint, 10FFFF.
4106 tt_int_op(1, OP_EQ
, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
4107 tt_int_op(0, OP_EQ
, string_is_utf8("\xf4\x90\x80\x80", 4));
4114 test_util_asprintf(void *ptr
)
4116 #define LOREMIPSUM \
4117 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
4118 char *cp
=NULL
, *cp2
=NULL
;
4123 r
= tor_asprintf(&cp
, "simple string 100%% safe");
4125 tt_str_op("simple string 100% safe",OP_EQ
, cp
);
4126 tt_int_op(strlen(cp
),OP_EQ
, r
);
4130 r
= tor_asprintf(&cp
, "%s", "");
4132 tt_str_op("",OP_EQ
, cp
);
4133 tt_int_op(strlen(cp
),OP_EQ
, r
);
4137 r
= tor_asprintf(&cp
, "I like numbers-%2i, %i, etc.", -1, 2);
4139 tt_str_op("I like numbers--1, 2, etc.",OP_EQ
, cp
);
4140 tt_int_op(strlen(cp
),OP_EQ
, r
);
4141 /* don't free cp; next test uses it. */
4144 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
4146 tt_int_op(strlen(cp2
),OP_EQ
, r
);
4147 tt_str_op("First=101, Second=202",OP_EQ
, cp2
);
4148 tt_assert(cp
!= cp2
);
4152 /* Glass-box test: a string exactly 128 characters long. */
4153 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
4155 tt_int_op(128,OP_EQ
, r
);
4156 tt_int_op(cp
[128], OP_EQ
, '\0');
4157 tt_str_op("Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
,OP_EQ
, cp
);
4160 /* String longer than 128 characters */
4161 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
4162 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
4164 tt_int_op(strlen(cp
),OP_EQ
, r
);
4165 tt_str_op("1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
,OP_EQ
, cp
);
4173 test_util_listdir(void *ptr
)
4175 smartlist_t
*dir_contents
= NULL
;
4176 char *fname1
=NULL
, *fname2
=NULL
, *fname3
=NULL
, *dir1
=NULL
, *dirname
=NULL
;
4180 fname1
= tor_strdup(get_fname("hopscotch"));
4181 fname2
= tor_strdup(get_fname("mumblety-peg"));
4182 fname3
= tor_strdup(get_fname(".hidden-file"));
4183 dir1
= tor_strdup(get_fname("some-directory"));
4184 dirname
= tor_strdup(get_fname(NULL
));
4186 tt_int_op(0,OP_EQ
, write_str_to_file(fname1
, "X\n", 0));
4187 tt_int_op(0,OP_EQ
, write_str_to_file(fname2
, "Y\n", 0));
4188 tt_int_op(0,OP_EQ
, write_str_to_file(fname3
, "Z\n", 0));
4192 r
= mkdir(dir1
, 0700);
4195 fprintf(stderr
, "Can't create directory %s:", dir1
);
4200 dir_contents
= tor_listdir(dirname
);
4201 tt_assert(dir_contents
);
4202 /* make sure that each filename is listed. */
4203 tt_assert(smartlist_contains_string_case(dir_contents
, "hopscotch"));
4204 tt_assert(smartlist_contains_string_case(dir_contents
, "mumblety-peg"));
4205 tt_assert(smartlist_contains_string_case(dir_contents
, ".hidden-file"));
4206 tt_assert(smartlist_contains_string_case(dir_contents
, "some-directory"));
4208 tt_assert(!smartlist_contains_string(dir_contents
, "."));
4209 tt_assert(!smartlist_contains_string(dir_contents
, ".."));
4218 SMARTLIST_FOREACH(dir_contents
, char *, cp
, tor_free(cp
));
4219 smartlist_free(dir_contents
);
4224 test_util_parent_dir(void *ptr
)
4229 #define T(output,expect_ok,input) \
4232 cp = tor_strdup(input); \
4233 ok = get_parent_directory(cp); \
4234 tt_int_op(expect_ok, OP_EQ, ok); \
4236 tt_str_op(output, OP_EQ, cp); \
4240 T("/home/wombat", 0, "/home/wombat/knish");
4241 T("/home/wombat", 0, "/home/wombat/knish/");
4242 T("/home/wombat", 0, "/home/wombat/knish///");
4243 T("./home/wombat", 0, "./home/wombat/knish/");
4245 T("/", 0, "/home//");
4246 T(".", 0, "./wombat");
4247 T(".", 0, "./wombat/");
4248 T(".", 0, "./wombat//");
4249 T("wombat", 0, "wombat/foo");
4250 T("wombat/..", 0, "wombat/../foo");
4251 T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
4252 T("wombat/.", 0, "wombat/./foo");
4253 T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
4254 T("wombat", 0, "wombat/..//");
4255 T("wombat", 0, "wombat/foo/");
4256 T("wombat", 0, "wombat/.foo");
4257 T("wombat", 0, "wombat/.foo/");
4259 T("wombat", -1, "");
4261 T("wombat", 0, "wombat/knish");
4271 test_util_ftruncate(void *ptr
)
4276 const char *message
= "Hello world";
4277 const char *message2
= "Hola mundo";
4282 fname
= get_fname("ftruncate");
4284 fd
= tor_open_cloexec(fname
, O_WRONLY
|O_CREAT
, 0600);
4285 tt_int_op(fd
, OP_GE
, 0);
4287 /* Make the file be there. */
4288 tt_int_op(strlen(message
), OP_EQ
,
4289 write_all_to_fd(fd
, message
, strlen(message
)));
4290 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message
));
4291 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4292 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message
));
4294 /* Truncate and see if it got truncated */
4295 tt_int_op(0, OP_EQ
, tor_ftruncate(fd
));
4296 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, 0);
4297 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4298 tt_int_op((int)st
.st_size
, OP_EQ
, 0);
4300 /* Replace, and see if it got replaced */
4301 tt_int_op(strlen(message2
), OP_EQ
,
4302 write_all_to_fd(fd
, message2
, strlen(message2
)));
4303 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message2
));
4304 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4305 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message2
));
4310 buf
= read_file_to_str(fname
, 0, NULL
);
4311 tt_str_op(message2
, OP_EQ
, buf
);
4320 test_util_num_cpus(void *arg
)
4323 int num
= compute_num_cpus();
4327 tt_int_op(num
, OP_GE
, 1);
4328 tt_int_op(num
, OP_LE
, 16);
4336 test_util_load_win_lib(void *ptr
)
4338 HANDLE h
= load_windows_system_library(_T("advapi32.dll"));
4346 #endif /* defined(_WIN32) */
4349 * Test for format_hex_number_sigsafe()
4353 test_util_format_hex_number(void *ptr
)
4365 {"7FFFFFFF", 0x7fffffff},
4366 {"FFFFFFFF", 0xffffffff},
4367 #if UINT_MAX >= 0xffffffff
4368 {"31BC421D", 0x31bc421d},
4369 {"FFFFFFFF", 0xffffffff},
4376 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
4377 len
= format_hex_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
4378 tt_int_op(len
,OP_NE
, 0);
4379 tt_int_op(len
,OP_EQ
, strlen(buf
));
4380 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4383 tt_int_op(4,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 5));
4384 tt_str_op(buf
,OP_EQ
, "FFFF");
4385 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 4));
4386 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0, buf
, 1));
4393 * Test for format_hex_number_sigsafe()
4397 test_util_format_dec_number(void *ptr
)
4408 {"12345678", 12345678},
4409 {"99999999", 99999999},
4410 {"100000000", 100000000},
4411 {"4294967295", 4294967295u},
4412 #if UINT_MAX > 0xffffffff
4413 {"18446744073709551615", 18446744073709551615u },
4420 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
4421 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
4422 tt_int_op(len
,OP_NE
, 0);
4423 tt_int_op(len
,OP_EQ
, strlen(buf
));
4424 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4426 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
,
4427 (int)(strlen(test_data
[i
].str
) + 1));
4428 tt_int_op(len
,OP_EQ
, strlen(buf
));
4429 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4432 tt_int_op(4,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 5));
4433 tt_str_op(buf
,OP_EQ
, "7331");
4434 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 4));
4435 tt_int_op(1,OP_EQ
, format_dec_number_sigsafe(0, buf
, 2));
4436 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(0, buf
, 1));
4442 #define MAX_SPLIT_LINE_COUNT 4
4443 struct split_lines_test_t
{
4444 const char *orig_line
; // Line to be split (may contain \0's)
4445 int orig_length
; // Length of orig_line
4446 const char *split_line
[MAX_SPLIT_LINE_COUNT
]; // Split lines
4450 test_util_di_ops(void *arg
)
4456 const char *a
; int want_sign
; const char *b
;
4458 { "Foo", EQ
, "Foo" },
4459 { "foo", GT
, "bar", },
4460 { "foobar", EQ
,"foobar" },
4461 { "foobar", LT
, "foobaw" },
4462 { "foobar", GT
, "f00bar" },
4463 { "foobar", GT
, "boobar" },
4471 for (i
= 0; examples
[i
].a
; ++i
) {
4472 size_t len
= strlen(examples
[i
].a
);
4473 int eq1
, eq2
, neq1
, neq2
, cmp1
, cmp2
;
4474 tt_int_op(len
,OP_EQ
, strlen(examples
[i
].b
));
4475 /* We do all of the operations, with operands in both orders. */
4476 eq1
= tor_memeq(examples
[i
].a
, examples
[i
].b
, len
);
4477 eq2
= tor_memeq(examples
[i
].b
, examples
[i
].a
, len
);
4478 neq1
= tor_memneq(examples
[i
].a
, examples
[i
].b
, len
);
4479 neq2
= tor_memneq(examples
[i
].b
, examples
[i
].a
, len
);
4480 cmp1
= tor_memcmp(examples
[i
].a
, examples
[i
].b
, len
);
4481 cmp2
= tor_memcmp(examples
[i
].b
, examples
[i
].a
, len
);
4483 /* Check for correctness of cmp1 */
4484 if (cmp1
< 0 && examples
[i
].want_sign
!= LT
)
4485 TT_DIE(("Assertion failed."));
4486 else if (cmp1
> 0 && examples
[i
].want_sign
!= GT
)
4487 TT_DIE(("Assertion failed."));
4488 else if (cmp1
== 0 && examples
[i
].want_sign
!= EQ
)
4489 TT_DIE(("Assertion failed."));
4491 /* Check for consistency of everything else with cmp1 */
4492 tt_int_op(eq1
,OP_EQ
, eq2
);
4493 tt_int_op(neq1
,OP_EQ
, neq2
);
4494 tt_int_op(cmp1
,OP_EQ
, -cmp2
);
4495 tt_int_op(eq1
,OP_EQ
, cmp1
== 0);
4496 tt_int_op(neq1
,OP_EQ
, !eq1
);
4504 /* exhaustively test tor_memeq and tor_memcmp
4505 * against each possible single-byte numeric difference
4506 * some arithmetic bugs only appear with certain bit patterns */
4507 for (z
= 0; z
< 256; z
++) {
4508 for (i
= 0; i
< 256; i
++) {
4511 tt_int_op(tor_memeq(&zz
, &ii
, 1),OP_EQ
, zz
== ii
);
4512 tt_int_op(tor_memcmp(&zz
, &ii
, 1) > 0 ? GT
: EQ
,OP_EQ
,
4514 tt_int_op(tor_memcmp(&ii
, &zz
, 1) < 0 ? LT
: EQ
,OP_EQ
,
4520 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 0));
4521 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 1));
4522 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 1));
4523 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 2));
4524 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0a", 2));
4525 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0a", 2));
4526 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
4527 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
4528 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
4535 test_util_di_map(void *arg
)
4538 di_digest256_map_t
*dimap
= NULL
;
4539 uint8_t key1
[] = "Robert Anton Wilson ";
4540 uint8_t key2
[] = "Martin Gardner, _Fads&fallacies";
4541 uint8_t key3
[] = "Tom Lehrer, _Be Prepared_. ";
4542 uint8_t key4
[] = "Ursula Le Guin,_A Wizard of... ";
4544 char dflt_entry
[] = "'You have made a good beginning', but no more";
4546 tt_int_op(32, OP_EQ
, sizeof(key1
));
4547 tt_int_op(32, OP_EQ
, sizeof(key2
));
4548 tt_int_op(32, OP_EQ
, sizeof(key3
));
4550 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
4552 char *str1
= tor_strdup("You are precisely as big as what you love"
4553 " and precisely as small as what you allow"
4555 char *str2
= tor_strdup("Let us hope that Lysenko's success in Russia will"
4556 " serve for many generations to come as another"
4557 " reminder to the world of how quickly and easily"
4558 " a science can be corrupted when ignorant"
4559 " political leaders deem themselves competent"
4560 " to arbitrate scientific disputes");
4561 char *str3
= tor_strdup("Don't write naughty words on walls "
4562 "if you can't spell.");
4564 dimap_add_entry(&dimap
, key1
, str1
);
4565 dimap_add_entry(&dimap
, key2
, str2
);
4566 dimap_add_entry(&dimap
, key3
, str3
);
4568 tt_ptr_op(str1
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
4569 tt_ptr_op(str3
, OP_EQ
, dimap_search(dimap
, key3
, dflt_entry
));
4570 tt_ptr_op(str2
, OP_EQ
, dimap_search(dimap
, key2
, dflt_entry
));
4571 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key4
, dflt_entry
));
4574 dimap_free(dimap
, tor_free_
);
4578 * Test counting high bits
4581 test_util_n_bits_set(void *ptr
)
4584 tt_int_op(0,OP_EQ
, n_bits_set_u8(0));
4585 tt_int_op(1,OP_EQ
, n_bits_set_u8(1));
4586 tt_int_op(3,OP_EQ
, n_bits_set_u8(7));
4587 tt_int_op(1,OP_EQ
, n_bits_set_u8(8));
4588 tt_int_op(2,OP_EQ
, n_bits_set_u8(129));
4589 tt_int_op(8,OP_EQ
, n_bits_set_u8(255));
4595 * Test LHS whitespace (and comment) eater
4598 test_util_eat_whitespace(void *ptr
)
4600 const char ws
[] = { ' ', '\t', '\r' }; /* Except NL */
4606 /* Try one leading ws */
4607 strlcpy(str
, "fuubaar", sizeof(str
));
4608 for (i
= 0; i
< sizeof(ws
); ++i
) {
4610 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
4611 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4612 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
4613 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4616 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
4617 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4618 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4619 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4622 strlcpy(str
, "", sizeof(str
));
4623 tt_ptr_op(str
,OP_EQ
, eat_whitespace(str
));
4624 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos(str
, str
));
4625 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4626 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
));
4629 strlcpy(str
, " \t\r\n", sizeof(str
));
4630 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4631 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4632 eat_whitespace_eos(str
, str
+ strlen(str
)));
4633 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
4634 eat_whitespace_no_nl(str
));
4635 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
4636 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4638 strlcpy(str
, " \t\r ", sizeof(str
));
4639 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4640 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4641 eat_whitespace_eos(str
, str
+ strlen(str
)));
4642 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace_no_nl(str
));
4643 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4644 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4647 strlcpy(str
, "fuubaar", sizeof(str
));
4648 for (i
= 0; i
< sizeof(ws
); ++i
)
4650 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace(str
));
4651 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
4652 eat_whitespace_eos(str
, str
+ strlen(str
)));
4653 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace_no_nl(str
));
4654 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
4655 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4658 strlcpy(str
, "# Comment \n No Comment", sizeof(str
));
4659 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
4660 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4661 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4662 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4664 /* Eat comment & ws mix */
4665 strlcpy(str
, " # \t Comment \n\t\nNo Comment", sizeof(str
));
4666 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
4667 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4668 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
4669 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4671 /* Eat entire comment */
4672 strlcpy(str
, "#Comment", sizeof(str
));
4673 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4674 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4675 eat_whitespace_eos(str
, str
+ strlen(str
)));
4676 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4677 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4679 /* Blank line, then comment */
4680 strlcpy(str
, " \t\n # Comment", sizeof(str
));
4681 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4682 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4683 eat_whitespace_eos(str
, str
+ strlen(str
)));
4684 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_no_nl(str
));
4685 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4691 /** Return a newly allocated smartlist containing the lines of text in
4692 * <b>lines</b>. The returned strings are heap-allocated, and must be
4693 * freed by the caller.
4695 * XXXX? Move to container.[hc] ? */
4696 static smartlist_t
*
4697 smartlist_new_from_text_lines(const char *lines
)
4699 smartlist_t
*sl
= smartlist_new();
4702 smartlist_split_string(sl
, lines
, "\n", 0, 0);
4704 last_line
= smartlist_pop_last(sl
);
4705 if (last_line
!= NULL
&& *last_line
!= '\0') {
4706 smartlist_add(sl
, last_line
);
4708 tor_free(last_line
);
4714 /** Test smartlist_new_from_text_lines */
4716 test_util_sl_new_from_text_lines(void *ptr
)
4720 { /* Normal usage */
4721 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz\n");
4722 int sl_len
= smartlist_len(sl
);
4724 tt_want_int_op(sl_len
, OP_EQ
, 3);
4726 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
4727 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
4728 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
4730 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4734 { /* No final newline */
4735 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz");
4736 int sl_len
= smartlist_len(sl
);
4738 tt_want_int_op(sl_len
, OP_EQ
, 3);
4740 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
4741 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
4742 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
4744 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4749 smartlist_t
*sl
= smartlist_new_from_text_lines("foo");
4750 int sl_len
= smartlist_len(sl
);
4752 tt_want_int_op(sl_len
, OP_EQ
, 1);
4754 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
4756 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4760 { /* No text at all */
4761 smartlist_t
*sl
= smartlist_new_from_text_lines("");
4762 int sl_len
= smartlist_len(sl
);
4764 tt_want_int_op(sl_len
, OP_EQ
, 0);
4766 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4772 test_util_envnames(void *ptr
)
4776 tt_assert(environment_variable_names_equal("abc", "abc"));
4777 tt_assert(environment_variable_names_equal("abc", "abc="));
4778 tt_assert(environment_variable_names_equal("abc", "abc=def"));
4779 tt_assert(environment_variable_names_equal("abc=def", "abc"));
4780 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
4782 tt_assert(environment_variable_names_equal("abc", "abc"));
4783 tt_assert(environment_variable_names_equal("abc", "abc="));
4784 tt_assert(environment_variable_names_equal("abc", "abc=def"));
4785 tt_assert(environment_variable_names_equal("abc=def", "abc"));
4786 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
4788 tt_assert(!environment_variable_names_equal("abc", "abcd"));
4789 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
4790 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
4791 tt_assert(!environment_variable_names_equal("abc=", "def"));
4792 tt_assert(!environment_variable_names_equal("abc=", "def="));
4793 tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
4795 tt_assert(!environment_variable_names_equal("", "a=def"));
4796 /* A bit surprising. */
4797 tt_assert(environment_variable_names_equal("", "=def"));
4798 tt_assert(environment_variable_names_equal("=y", "=x"));
4804 /** Test process_environment_make */
4806 test_util_make_environment(void *ptr
)
4808 const char *env_vars_string
=
4809 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
4810 "HOME=/home/foozer\n";
4811 const char expected_windows_env_block
[] =
4812 "HOME=/home/foozer\000"
4813 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
4815 size_t expected_windows_env_block_len
=
4816 sizeof(expected_windows_env_block
) - 1;
4818 smartlist_t
*env_vars
= smartlist_new_from_text_lines(env_vars_string
);
4819 smartlist_t
*env_vars_sorted
= smartlist_new();
4820 smartlist_t
*env_vars_in_unixoid_env_block_sorted
= smartlist_new();
4822 process_environment_t
*env
;
4826 env
= process_environment_make(env_vars
);
4828 /* Check that the Windows environment block is correct. */
4829 tt_want(tor_memeq(expected_windows_env_block
, env
->windows_environment_block
,
4830 expected_windows_env_block_len
));
4832 /* Now for the Unixoid environment block. We don't care which order
4833 * these environment variables are in, so we sort both lists first. */
4835 smartlist_add_all(env_vars_sorted
, env_vars
);
4839 for (v
= env
->unixoid_environment_block
; *v
; ++v
) {
4840 smartlist_add(env_vars_in_unixoid_env_block_sorted
, *v
);
4844 smartlist_sort_strings(env_vars_sorted
);
4845 smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted
);
4847 tt_want_int_op(smartlist_len(env_vars_sorted
), OP_EQ
,
4848 smartlist_len(env_vars_in_unixoid_env_block_sorted
));
4850 int len
= smartlist_len(env_vars_sorted
);
4853 if (smartlist_len(env_vars_in_unixoid_env_block_sorted
) < len
) {
4854 len
= smartlist_len(env_vars_in_unixoid_env_block_sorted
);
4857 for (i
= 0; i
< len
; ++i
) {
4858 tt_want_str_op(smartlist_get(env_vars_sorted
, i
), OP_EQ
,
4859 smartlist_get(env_vars_in_unixoid_env_block_sorted
, i
));
4864 smartlist_free(env_vars_in_unixoid_env_block_sorted
);
4865 smartlist_free(env_vars_sorted
);
4867 SMARTLIST_FOREACH(env_vars
, char *, x
, tor_free(x
));
4868 smartlist_free(env_vars
);
4870 process_environment_free(env
);
4873 /** Test set_environment_variable_in_smartlist */
4875 test_util_set_env_var_in_sl(void *ptr
)
4877 /* The environment variables in these strings are in arbitrary
4878 * order; we sort the resulting lists before comparing them.
4880 * (They *will not* end up in the order shown in
4881 * expected_resulting_env_vars_string.) */
4883 const char *base_env_vars_string
=
4884 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
4885 "HOME=/home/foozer\n"
4894 const char *new_env_vars_string
=
4899 const char *expected_resulting_env_vars_string
=
4900 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
4901 "HOME=/home/foozer\n"
4911 smartlist_t
*merged_env_vars
=
4912 smartlist_new_from_text_lines(base_env_vars_string
);
4913 smartlist_t
*new_env_vars
=
4914 smartlist_new_from_text_lines(new_env_vars_string
);
4915 smartlist_t
*expected_resulting_env_vars
=
4916 smartlist_new_from_text_lines(expected_resulting_env_vars_string
);
4918 /* Elements of merged_env_vars are heap-allocated, and must be
4919 * freed. Some of them are (or should) be freed by
4920 * set_environment_variable_in_smartlist.
4922 * Elements of new_env_vars are heap-allocated, but are copied into
4923 * merged_env_vars, so they are not freed separately at the end of
4926 * Elements of expected_resulting_env_vars are heap-allocated, and
4931 SMARTLIST_FOREACH(new_env_vars
, char *, env_var
,
4932 set_environment_variable_in_smartlist(merged_env_vars
,
4937 smartlist_sort_strings(merged_env_vars
);
4938 smartlist_sort_strings(expected_resulting_env_vars
);
4940 tt_want_int_op(smartlist_len(merged_env_vars
), OP_EQ
,
4941 smartlist_len(expected_resulting_env_vars
));
4943 int len
= smartlist_len(merged_env_vars
);
4946 if (smartlist_len(expected_resulting_env_vars
) < len
) {
4947 len
= smartlist_len(expected_resulting_env_vars
);
4950 for (i
= 0; i
< len
; ++i
) {
4951 tt_want_str_op(smartlist_get(merged_env_vars
, i
), OP_EQ
,
4952 smartlist_get(expected_resulting_env_vars
, i
));
4957 SMARTLIST_FOREACH(merged_env_vars
, char *, x
, tor_free(x
));
4958 smartlist_free(merged_env_vars
);
4960 smartlist_free(new_env_vars
);
4962 SMARTLIST_FOREACH(expected_resulting_env_vars
, char *, x
, tor_free(x
));
4963 smartlist_free(expected_resulting_env_vars
);
4967 test_util_weak_random(void *arg
)
4973 tor_init_weak_random(&rng
, (unsigned)time(NULL
));
4975 for (i
= 1; i
<= 256; ++i
) {
4976 for (j
=0;j
<100;++j
) {
4977 int r
= tor_weak_random_range(&rng
, i
);
4978 tt_int_op(0, OP_LE
, r
);
4979 tt_int_op(r
, OP_LT
, i
);
4983 memset(n
,0,sizeof(n
));
4984 for (j
=0;j
<8192;++j
) {
4985 n
[tor_weak_random_range(&rng
, 16)]++;
4989 tt_int_op(n
[i
], OP_GT
, 0);
4995 test_util_mathlog(void *arg
)
5000 d
= tor_mathlog(2.718281828);
5001 tt_double_op(fabs(d
- 1.0), OP_LT
, .000001);
5002 d
= tor_mathlog(10);
5003 tt_double_op(fabs(d
- 2.30258509), OP_LT
, .000001);
5009 test_util_fraction(void *arg
)
5015 simplify_fraction64(&a
,&b
);
5016 tt_u64_op(a
, OP_EQ
, 33);
5017 tt_u64_op(b
, OP_EQ
, 10);
5019 a
= 3000000; b
= 10000000;
5020 simplify_fraction64(&a
,&b
);
5021 tt_u64_op(a
, OP_EQ
, 3);
5022 tt_u64_op(b
, OP_EQ
, 10);
5025 simplify_fraction64(&a
,&b
);
5026 tt_u64_op(a
, OP_EQ
, 0);
5027 tt_u64_op(b
, OP_EQ
, 1);
5034 test_util_round_to_next_multiple_of(void *arg
)
5038 tt_u64_op(round_uint64_to_next_multiple_of(0,1), OP_EQ
, 0);
5039 tt_u64_op(round_uint64_to_next_multiple_of(0,7), OP_EQ
, 0);
5041 tt_u64_op(round_uint64_to_next_multiple_of(99,1), OP_EQ
, 99);
5042 tt_u64_op(round_uint64_to_next_multiple_of(99,7), OP_EQ
, 105);
5043 tt_u64_op(round_uint64_to_next_multiple_of(99,9), OP_EQ
, 99);
5045 tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX
,2), OP_EQ
,
5048 tt_int_op(round_uint32_to_next_multiple_of(0,1), OP_EQ
, 0);
5049 tt_int_op(round_uint32_to_next_multiple_of(0,7), OP_EQ
, 0);
5051 tt_int_op(round_uint32_to_next_multiple_of(99,1), OP_EQ
, 99);
5052 tt_int_op(round_uint32_to_next_multiple_of(99,7), OP_EQ
, 105);
5053 tt_int_op(round_uint32_to_next_multiple_of(99,9), OP_EQ
, 99);
5055 tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX
,2), OP_EQ
,
5058 tt_uint_op(round_to_next_multiple_of(0,1), OP_EQ
, 0);
5059 tt_uint_op(round_to_next_multiple_of(0,7), OP_EQ
, 0);
5061 tt_uint_op(round_to_next_multiple_of(99,1), OP_EQ
, 99);
5062 tt_uint_op(round_to_next_multiple_of(99,7), OP_EQ
, 105);
5063 tt_uint_op(round_to_next_multiple_of(99,9), OP_EQ
, 99);
5065 tt_uint_op(round_to_next_multiple_of(UINT_MAX
,2), OP_EQ
,
5072 test_util_laplace(void *arg
)
5074 /* Sample values produced using Python's SciPy:
5076 * >>> from scipy.stats import laplace
5077 * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
5078 ... loc = 24, scale = 24)
5079 * array([ nan, -inf, -69.88855213, 24. ,
5080 * 24.48486498, 117.88855213, inf, nan])
5082 const double mu
= 24.0, b
= 24.0;
5083 const double delta_f
= 15.0, epsilon
= 0.3; /* b = 15.0 / 0.3 = 50.0 */
5086 tt_i64_op(INT64_MIN
, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.0));
5087 tt_i64_op(-69, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.01));
5088 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.5));
5089 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.51));
5090 tt_i64_op(117, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.99));
5092 /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
5093 * ... loc = 0, scale = 50)
5094 * array([ -inf, -80.47189562, -34.65735903, 0. ,
5095 * 34.65735903, 80.47189562, 195.60115027])
5097 tt_i64_op(INT64_MIN
+ 20, OP_EQ
,
5098 add_laplace_noise(20, 0.0, delta_f
, epsilon
));
5100 tt_i64_op(-60, OP_EQ
, add_laplace_noise(20, 0.1, delta_f
, epsilon
));
5101 tt_i64_op(-14, OP_EQ
, add_laplace_noise(20, 0.25, delta_f
, epsilon
));
5102 tt_i64_op(20, OP_EQ
, add_laplace_noise(20, 0.5, delta_f
, epsilon
));
5103 tt_i64_op(54, OP_EQ
, add_laplace_noise(20, 0.75, delta_f
, epsilon
));
5104 tt_i64_op(100, OP_EQ
, add_laplace_noise(20, 0.9, delta_f
, epsilon
));
5105 tt_i64_op(215, OP_EQ
, add_laplace_noise(20, 0.99, delta_f
, epsilon
));
5107 /* Test extreme values of signal with maximally negative values of noise
5108 * 1.0000000000000002 is the smallest number > 1
5109 * 0.0000000000000002 is the double epsilon (error when calculating near 1)
5110 * this is approximately 1/(2^52)
5111 * per https://en.wikipedia.org/wiki/Double_precision
5112 * (let's not descend into the world of subnormals)
5113 * >>> laplace.ppf([0, 0.0000000000000002], loc = 0, scale = 1)
5114 * array([ -inf, -35.45506713])
5116 const double noscale_df
= 1.0, noscale_eps
= 1.0;
5118 tt_i64_op(INT64_MIN
, OP_EQ
,
5119 add_laplace_noise(0, 0.0, noscale_df
, noscale_eps
));
5121 /* is it clipped to INT64_MIN? */
5122 tt_i64_op(INT64_MIN
, OP_EQ
,
5123 add_laplace_noise(-1, 0.0, noscale_df
, noscale_eps
));
5124 tt_i64_op(INT64_MIN
, OP_EQ
,
5125 add_laplace_noise(INT64_MIN
, 0.0,
5126 noscale_df
, noscale_eps
));
5127 /* ... even when scaled? */
5128 tt_i64_op(INT64_MIN
, OP_EQ
,
5129 add_laplace_noise(0, 0.0, delta_f
, epsilon
));
5130 tt_i64_op(INT64_MIN
, OP_EQ
,
5131 add_laplace_noise(0, 0.0,
5133 tt_i64_op(INT64_MIN
, OP_EQ
,
5134 add_laplace_noise(INT64_MIN
, 0.0,
5137 /* does it play nice with INT64_MAX? */
5138 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5139 add_laplace_noise(INT64_MAX
, 0.0,
5140 noscale_df
, noscale_eps
));
5142 /* do near-zero fractional values work? */
5143 const double min_dbl_error
= 0.0000000000000002;
5145 tt_i64_op(-35, OP_EQ
,
5146 add_laplace_noise(0, min_dbl_error
,
5147 noscale_df
, noscale_eps
));
5148 tt_i64_op(INT64_MIN
, OP_EQ
,
5149 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5150 noscale_df
, noscale_eps
));
5151 tt_i64_op((-35 + INT64_MAX
), OP_EQ
,
5152 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5153 noscale_df
, noscale_eps
));
5154 tt_i64_op(INT64_MIN
, OP_EQ
,
5155 add_laplace_noise(0, min_dbl_error
,
5157 tt_i64_op((INT64_MAX
+ INT64_MIN
), OP_EQ
,
5158 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5160 tt_i64_op(INT64_MIN
, OP_EQ
,
5161 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5164 /* does it play nice with INT64_MAX? */
5165 tt_i64_op((INT64_MAX
- 35), OP_EQ
,
5166 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5167 noscale_df
, noscale_eps
));
5169 /* Test extreme values of signal with maximally positive values of noise
5170 * 1.0000000000000002 is the smallest number > 1
5171 * 0.9999999999999998 is the greatest number < 1 by calculation
5172 * per https://en.wikipedia.org/wiki/Double_precision
5173 * >>> laplace.ppf([1.0, 0.9999999999999998], loc = 0, scale = 1)
5174 * array([inf, 35.35050621])
5175 * but the function rejects p == 1.0, so we just use max_dbl_lt_one
5177 const double max_dbl_lt_one
= 0.9999999999999998;
5179 /* do near-one fractional values work? */
5180 tt_i64_op(35, OP_EQ
,
5181 add_laplace_noise(0, max_dbl_lt_one
, noscale_df
, noscale_eps
));
5183 /* is it clipped to INT64_MAX? */
5184 tt_i64_op(INT64_MAX
, OP_EQ
,
5185 add_laplace_noise(INT64_MAX
- 35, max_dbl_lt_one
,
5186 noscale_df
, noscale_eps
));
5187 tt_i64_op(INT64_MAX
, OP_EQ
,
5188 add_laplace_noise(INT64_MAX
- 34, max_dbl_lt_one
,
5189 noscale_df
, noscale_eps
));
5190 tt_i64_op(INT64_MAX
, OP_EQ
,
5191 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5192 noscale_df
, noscale_eps
));
5193 /* ... even when scaled? */
5194 tt_i64_op(INT64_MAX
, OP_EQ
,
5195 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5197 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5198 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5200 tt_i64_op(INT64_MAX
, OP_EQ
,
5201 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5203 /* does it play nice with INT64_MIN? */
5204 tt_i64_op((INT64_MIN
+ 35), OP_EQ
,
5205 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5206 noscale_df
, noscale_eps
));
5213 test_util_clamp_double_to_int64(void *arg
)
5217 tt_i64_op(INT64_MIN
, OP_EQ
, clamp_double_to_int64(-INFINITY_DBL
));
5218 tt_i64_op(INT64_MIN
, OP_EQ
,
5219 clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0));
5220 tt_i64_op(INT64_MIN
, OP_EQ
,
5221 clamp_double_to_int64(-1.0 * pow(2.0, 63.0) - 1.0));
5222 tt_i64_op(((uint64_t) -1) << 53, OP_EQ
,
5223 clamp_double_to_int64(-1.0 * pow(2.0, 53.0)));
5224 tt_i64_op((((uint64_t) -1) << 53) + 1, OP_EQ
,
5225 clamp_double_to_int64(-1.0 * pow(2.0, 53.0) + 1.0));
5226 tt_i64_op(-1, OP_EQ
, clamp_double_to_int64(-1.0));
5227 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.9));
5228 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.1));
5229 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.0));
5230 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(NAN_DBL
));
5231 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.1));
5232 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.9));
5233 tt_i64_op(1, OP_EQ
, clamp_double_to_int64(1.0));
5234 tt_i64_op((((int64_t) 1) << 53) - 1, OP_EQ
,
5235 clamp_double_to_int64(pow(2.0, 53.0) - 1.0));
5236 tt_i64_op(((int64_t) 1) << 53, OP_EQ
,
5237 clamp_double_to_int64(pow(2.0, 53.0)));
5238 tt_i64_op(INT64_MAX
, OP_EQ
,
5239 clamp_double_to_int64(pow(2.0, 63.0)));
5240 tt_i64_op(INT64_MAX
, OP_EQ
,
5241 clamp_double_to_int64(pow(2.0, 64.0)));
5242 tt_i64_op(INT64_MAX
, OP_EQ
, clamp_double_to_int64(INFINITY_DBL
));
5249 #define CAN_CHECK_CLOEXEC
5251 fd_is_cloexec(tor_socket_t fd
)
5253 int flags
= fcntl(fd
, F_GETFD
, 0);
5254 return (flags
& FD_CLOEXEC
) == FD_CLOEXEC
;
5256 #endif /* defined(FD_CLOEXEC) */
5259 #define CAN_CHECK_NONBLOCK
5261 fd_is_nonblocking(tor_socket_t fd
)
5263 int flags
= fcntl(fd
, F_GETFL
, 0);
5264 return (flags
& O_NONBLOCK
) == O_NONBLOCK
;
5266 #endif /* !defined(_WIN32) */
5268 #define ERRNO_IS_EPROTO(e) (e == SOCK_ERRNO(EPROTONOSUPPORT))
5269 #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s))
5271 /* Test for tor_open_socket*, using IPv4 or IPv6 depending on arg. */
5273 test_util_socket(void *arg
)
5275 const int domain
= !strcmp(arg
, "4") ? AF_INET
: AF_INET6
;
5276 tor_socket_t fd1
= TOR_INVALID_SOCKET
;
5277 tor_socket_t fd2
= TOR_INVALID_SOCKET
;
5278 tor_socket_t fd3
= TOR_INVALID_SOCKET
;
5279 tor_socket_t fd4
= TOR_INVALID_SOCKET
;
5280 int n
= get_n_open_sockets();
5282 TT_BLATHER(("Starting with %d open sockets.", n
));
5286 fd1
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 0);
5287 int err
= tor_socket_errno(fd1
);
5288 if (fd1
< 0 && (err
== SOCK_ERRNO(EPROTONOSUPPORT
) ||
5289 err
== SOCK_ERRNO(EAFNOSUPPORT
))) {
5290 /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */
5293 fd2
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 1);
5294 tt_assert(SOCKET_OK(fd1
));
5295 tt_assert(SOCKET_OK(fd2
));
5296 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5297 //fd3 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 0);
5298 //fd4 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 1);
5299 fd3
= tor_open_socket(domain
, SOCK_STREAM
, 0);
5300 fd4
= tor_open_socket_nonblocking(domain
, SOCK_STREAM
, 0);
5301 tt_assert(SOCKET_OK(fd3
));
5302 tt_assert(SOCKET_OK(fd4
));
5303 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 4);
5305 #ifdef CAN_CHECK_CLOEXEC
5306 tt_int_op(fd_is_cloexec(fd1
), OP_EQ
, 0);
5307 tt_int_op(fd_is_cloexec(fd2
), OP_EQ
, 0);
5308 tt_int_op(fd_is_cloexec(fd3
), OP_EQ
, 1);
5309 tt_int_op(fd_is_cloexec(fd4
), OP_EQ
, 1);
5310 #endif /* defined(CAN_CHECK_CLOEXEC) */
5311 #ifdef CAN_CHECK_NONBLOCK
5312 tt_int_op(fd_is_nonblocking(fd1
), OP_EQ
, 0);
5313 tt_int_op(fd_is_nonblocking(fd2
), OP_EQ
, 1);
5314 tt_int_op(fd_is_nonblocking(fd3
), OP_EQ
, 0);
5315 tt_int_op(fd_is_nonblocking(fd4
), OP_EQ
, 1);
5316 #endif /* defined(CAN_CHECK_NONBLOCK) */
5318 tor_assert(tor_close_socket
== tor_close_socket__real
);
5320 /* we use close_socket__real here so that coverity can tell that we are
5321 * really closing these sockets. */
5322 tor_close_socket__real(fd1
);
5323 tor_close_socket__real(fd2
);
5324 fd1
= fd2
= TOR_INVALID_SOCKET
;
5325 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5326 tor_close_socket__real(fd3
);
5327 tor_close_socket__real(fd4
);
5328 fd3
= fd4
= TOR_INVALID_SOCKET
;
5329 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
5333 tor_close_socket__real(fd1
);
5335 tor_close_socket__real(fd2
);
5337 tor_close_socket__real(fd3
);
5339 tor_close_socket__real(fd4
);
5344 is_there_a_localhost(int family
)
5347 s
= tor_open_socket(family
, SOCK_STREAM
, IPPROTO_TCP
);
5348 tor_assert(SOCKET_OK(s
));
5351 if (family
== AF_INET
) {
5352 struct sockaddr_in s_in
;
5353 memset(&s_in
, 0, sizeof(s_in
));
5354 s_in
.sin_family
= AF_INET
;
5355 s_in
.sin_addr
.s_addr
= htonl(0x7f000001);
5358 if (bind(s
, (void*)&s_in
, sizeof(s_in
)) == 0) {
5361 } else if (family
== AF_INET6
) {
5362 struct sockaddr_in6 sin6
;
5363 memset(&sin6
, 0, sizeof(sin6
));
5364 sin6
.sin6_family
= AF_INET6
;
5365 sin6
.sin6_addr
.s6_addr
[15] = 1;
5368 tor_close_socket(s
);
5374 /* Test for socketpair and ersatz_socketpair(). We test them both, since
5375 * the latter is a tolerably good way to exercise tor_accept_socket(). */
5377 test_util_socketpair(void *arg
)
5379 const int ersatz
= !strcmp(arg
, "1");
5380 int (*const tor_socketpair_fn
)(int, int, int, tor_socket_t
[2]) =
5381 ersatz
? tor_ersatz_socketpair
: tor_socketpair
;
5382 int n
= get_n_open_sockets();
5383 tor_socket_t fds
[2] = {TOR_INVALID_SOCKET
, TOR_INVALID_SOCKET
};
5384 const int family
= AF_UNIX
;
5385 int socketpair_result
= 0;
5387 socketpair_result
= tor_socketpair_fn(family
, SOCK_STREAM
, 0, fds
);
5390 /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
5391 * Otherwise, we risk exposing a socketpair on a routable IP address. (Some
5392 * BSD jails use a routable address for localhost. Fortunately, they have
5393 * the real AF_UNIX socketpair.) */
5394 if (ersatz
&& socketpair_result
< 0) {
5395 /* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
5396 * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
5399 #endif /* defined(__FreeBSD__) */
5400 tt_int_op(0, OP_EQ
, socketpair_result
);
5402 tt_assert(SOCKET_OK(fds
[0]));
5403 tt_assert(SOCKET_OK(fds
[1]));
5405 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
5407 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5408 #ifdef CAN_CHECK_CLOEXEC
5409 tt_int_op(fd_is_cloexec(fds
[0]), OP_EQ
, !ersatz
);
5410 tt_int_op(fd_is_cloexec(fds
[1]), OP_EQ
, !ersatz
);
5412 #ifdef CAN_CHECK_NONBLOCK
5413 tt_int_op(fd_is_nonblocking(fds
[0]), OP_EQ
, 0);
5414 tt_int_op(fd_is_nonblocking(fds
[1]), OP_EQ
, 0);
5419 if (SOCKET_OK(fds
[0]))
5420 tor_close_socket_simple(fds
[0]);
5421 if (SOCKET_OK(fds
[1]))
5422 tor_close_socket_simple(fds
[1]);
5424 if (SOCKET_OK(fds
[0]))
5425 tor_close_socket(fds
[0]);
5426 if (SOCKET_OK(fds
[1]))
5427 tor_close_socket(fds
[1]);
5431 #undef SOCKET_EPROTO
5434 test_util_max_mem(void *arg
)
5436 size_t memory1
, memory2
;
5440 r
= get_total_system_memory(&memory1
);
5441 r2
= get_total_system_memory(&memory2
);
5442 tt_int_op(r
, OP_EQ
, r2
);
5443 tt_uint_op(memory2
, OP_EQ
, memory1
);
5445 TT_BLATHER(("System memory: %"TOR_PRIuSZ
, (memory1
)));
5448 /* You have at least a megabyte. */
5449 tt_uint_op(memory1
, OP_GT
, (1<<20));
5451 /* You do not have a petabyte. */
5452 #if SIZEOF_SIZE_T >= 8
5453 tt_u64_op(memory1
, OP_LT
, (UINT64_C(1)<<50));
5462 test_util_dest_validation_edgecase(void *arg
)
5466 tt_assert(!string_is_valid_dest(NULL
));
5467 tt_assert(!string_is_valid_dest(""));
5474 test_util_hostname_validation(void *arg
)
5478 // Lets try valid hostnames first.
5479 tt_assert(string_is_valid_nonrfc_hostname("torproject.org"));
5480 tt_assert(string_is_valid_nonrfc_hostname("ocw.mit.edu"));
5481 tt_assert(string_is_valid_nonrfc_hostname("i.4cdn.org"));
5482 tt_assert(string_is_valid_nonrfc_hostname("stanford.edu"));
5483 tt_assert(string_is_valid_nonrfc_hostname("multiple-words-with-hypens.jp"));
5485 // Subdomain name cannot start with '-' or '_'.
5486 tt_assert(!string_is_valid_nonrfc_hostname("-torproject.org"));
5487 tt_assert(!string_is_valid_nonrfc_hostname("subdomain.-domain.org"));
5488 tt_assert(!string_is_valid_nonrfc_hostname("-subdomain.domain.org"));
5489 tt_assert(!string_is_valid_nonrfc_hostname("___abc.org"));
5491 // Hostnames cannot contain non-alphanumeric characters.
5492 tt_assert(!string_is_valid_nonrfc_hostname("%%domain.\\org."));
5493 tt_assert(!string_is_valid_nonrfc_hostname("***x.net"));
5494 tt_assert(!string_is_valid_nonrfc_hostname("\xff\xffxyz.org"));
5495 tt_assert(!string_is_valid_nonrfc_hostname("word1 word2.net"));
5497 // Test workaround for nytimes.com stupidity, technically invalid,
5498 // but we allow it since they are big, even though they are failing to
5499 // comply with a ~30 year old standard.
5500 tt_assert(string_is_valid_nonrfc_hostname("core3_euw1.fabrik.nytimes.com"));
5502 // Firefox passes FQDNs with trailing '.'s directly to the SOCKS proxy,
5503 // which is redundant since the spec states DOMAINNAME addresses are fully
5504 // qualified. While unusual, this should be tollerated.
5505 tt_assert(string_is_valid_nonrfc_hostname("core9_euw1.fabrik.nytimes.com."));
5506 tt_assert(!string_is_valid_nonrfc_hostname(
5507 "..washingtonpost.is.better.com"));
5508 tt_assert(!string_is_valid_nonrfc_hostname("so.is..ft.com"));
5509 tt_assert(!string_is_valid_nonrfc_hostname("..."));
5511 // XXX: do we allow single-label DNS names?
5512 // We shouldn't for SOCKS (spec says "contains a fully-qualified domain name"
5513 // but only test pathologically malformed traling '.' cases for now.
5514 tt_assert(!string_is_valid_nonrfc_hostname("."));
5515 tt_assert(!string_is_valid_nonrfc_hostname(".."));
5517 // IP address strings are not hostnames.
5518 tt_assert(!string_is_valid_nonrfc_hostname("8.8.8.8"));
5519 tt_assert(!string_is_valid_nonrfc_hostname("[2a00:1450:401b:800::200e]"));
5520 tt_assert(!string_is_valid_nonrfc_hostname("2a00:1450:401b:800::200e"));
5522 // We allow alphanumeric TLDs. For discussion, see ticket #25055.
5523 tt_assert(string_is_valid_nonrfc_hostname("lucky.13"));
5524 tt_assert(string_is_valid_nonrfc_hostname("luck.y13"));
5525 tt_assert(string_is_valid_nonrfc_hostname("luck.y13."));
5527 // We allow punycode TLDs. For examples, see
5528 // http://data.iana.org/TLD/tlds-alpha-by-domain.txt
5529 tt_assert(string_is_valid_nonrfc_hostname("example.xn--l1acc"));
5536 test_util_ipv4_validation(void *arg
)
5540 tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
5541 tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
5543 tt_assert(!string_is_valid_ipv4_address("abcd"));
5544 tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
5545 tt_assert(!string_is_valid_ipv4_address("8.8."));
5552 test_util_ipv6_validation(void *arg
)
5556 tt_assert(string_is_valid_ipv6_address("2a00:1450:401b:800::200e"));
5557 tt_assert(!string_is_valid_ipv6_address("11:22::33:44:"));
5564 test_util_writepid(void *arg
)
5568 char *contents
= NULL
;
5569 const char *fname
= get_fname("tmp_pid");
5573 write_pidfile(fname
);
5575 contents
= read_file_to_str(fname
, 0, NULL
);
5576 tt_assert(contents
);
5578 int n
= tor_sscanf(contents
, "%lu\n%c", &pid
, &c
);
5579 tt_int_op(n
, OP_EQ
, 1);
5582 tt_uint_op(pid
, OP_EQ
, _getpid());
5584 tt_uint_op(pid
, OP_EQ
, getpid());
5592 test_util_get_avail_disk_space(void *arg
)
5597 /* No answer for nonexistent directory */
5598 val
= tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
5599 tt_i64_op(val
, OP_EQ
, -1);
5601 /* Try the current directory */
5602 val
= tor_get_avail_disk_space(".");
5604 #if !defined(HAVE_STATVFS) && !defined(_WIN32)
5605 tt_i64_op(val
, OP_EQ
, -1); /* You don't have an implementation for this */
5607 tt_i64_op(val
, OP_GT
, 0); /* You have some space. */
5608 tt_i64_op(val
, OP_LT
, ((int64_t)1)<<56); /* You don't have a zebibyte */
5609 #endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */
5616 test_util_touch_file(void *arg
)
5619 const char *fname
= get_fname("touch");
5621 const time_t now
= time(NULL
);
5623 write_bytes_to_file(fname
, "abc", 3, 1);
5624 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5625 /* A subtle point: the filesystem time is not necessarily equal to the
5626 * system clock time, since one can be using a monotonic clock, or coarse
5627 * monotonic clock, or whatever. So we might wind up with an mtime a few
5628 * microseconds ago. Let's just give it a lot of wiggle room. */
5629 tt_i64_op(st
.st_mtime
, OP_GE
, now
- 1);
5631 const time_t five_sec_ago
= now
- 5;
5632 struct utimbuf u
= { five_sec_ago
, five_sec_ago
};
5633 tt_int_op(0, OP_EQ
, utime(fname
, &u
));
5634 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5635 /* Let's hope that utime/stat give the same second as a round-trip? */
5636 tt_i64_op(st
.st_mtime
, OP_EQ
, five_sec_ago
);
5638 /* Finally we can touch the file */
5639 tt_int_op(0, OP_EQ
, touch_file(fname
));
5640 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5641 tt_i64_op(st
.st_mtime
, OP_GE
, now
-1);
5649 test_util_pwdb(void *arg
)
5652 const struct passwd
*me
= NULL
, *me2
, *me3
;
5656 /* Uncached case. */
5657 /* Let's assume that we exist. */
5658 me
= tor_getpwuid(getuid());
5659 tt_ptr_op(me
, OP_NE
, NULL
);
5660 name
= tor_strdup(me
->pw_name
);
5663 me2
= tor_getpwnam(name
);
5664 tt_ptr_op(me2
, OP_NE
, NULL
);
5665 tt_int_op(me2
->pw_uid
, OP_EQ
, getuid());
5668 me3
= tor_getpwuid(getuid());
5669 tt_ptr_op(me3
, OP_NE
, NULL
);
5670 tt_str_op(me3
->pw_name
, OP_EQ
, name
);
5672 me3
= tor_getpwnam(name
);
5673 tt_ptr_op(me3
, OP_NE
, NULL
);
5674 tt_int_op(me3
->pw_uid
, OP_EQ
, getuid());
5676 dir
= get_user_homedir(name
);
5677 tt_ptr_op(dir
, OP_NE
, NULL
);
5679 /* Try failing cases. First find a user that doesn't exist by name */
5683 for (i
= 0; i
< 100; ++i
) {
5684 crypto_rand(randbytes
, sizeof(randbytes
));
5685 base16_encode(badname
, sizeof(badname
), randbytes
, sizeof(randbytes
));
5686 if (tor_getpwnam(badname
) == NULL
) {
5694 /* We should do a LOG_ERR */
5695 setup_full_capture_of_logs(LOG_ERR
);
5696 dir
= get_user_homedir(badname
);
5697 tt_ptr_op(dir
, OP_EQ
, NULL
);
5698 expect_log_msg_containing("not found");
5699 tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ
, 1);
5700 teardown_capture_of_logs();
5702 /* Now try to find a user that doesn't exist by ID. */
5704 for (i
= 0; i
< 1000; ++i
) {
5706 crypto_rand((char*)&u
, sizeof(u
));
5707 if (tor_getpwuid(u
) == NULL
) {
5717 teardown_capture_of_logs();
5719 #endif /* !defined(_WIN32) */
5722 test_util_calloc_check(void *arg
)
5725 /* Easy cases that are good. */
5726 tt_assert(size_mul_check(0,0));
5727 tt_assert(size_mul_check(0,100));
5728 tt_assert(size_mul_check(100,0));
5729 tt_assert(size_mul_check(100,100));
5731 /* Harder cases that are still good. */
5732 tt_assert(size_mul_check(SIZE_MAX
, 1));
5733 tt_assert(size_mul_check(1, SIZE_MAX
));
5734 tt_assert(size_mul_check(SIZE_MAX
/ 10, 9));
5735 tt_assert(size_mul_check(11, SIZE_MAX
/ 12));
5736 const size_t sqrt_size_max_p1
= ((size_t)1) << (sizeof(size_t) * 4);
5737 tt_assert(size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
- 1));
5739 /* Cases that overflow */
5740 tt_assert(! size_mul_check(SIZE_MAX
, 2));
5741 tt_assert(! size_mul_check(2, SIZE_MAX
));
5742 tt_assert(! size_mul_check(SIZE_MAX
/ 10, 11));
5743 tt_assert(! size_mul_check(11, SIZE_MAX
/ 10));
5744 tt_assert(! size_mul_check(SIZE_MAX
/ 8, 9));
5745 tt_assert(! size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
));
5752 test_util_monotonic_time(void *arg
)
5756 monotime_t mt1
, mt2
;
5757 monotime_coarse_t mtc1
, mtc2
;
5758 uint64_t nsec1
, nsec2
, usec1
, msec1
;
5759 uint64_t nsecc1
, nsecc2
, usecc1
, msecc1
;
5760 uint32_t stamp1
, stamp2
;
5765 monotime_coarse_get(&mtc1
);
5766 nsec1
= monotime_absolute_nsec();
5767 usec1
= monotime_absolute_usec();
5768 msec1
= monotime_absolute_msec();
5769 nsecc1
= monotime_coarse_absolute_nsec();
5770 usecc1
= monotime_coarse_absolute_usec();
5771 msecc1
= monotime_coarse_absolute_msec();
5772 stamp1
= monotime_coarse_to_stamp(&mtc1
);
5774 tor_sleep_msec(200);
5777 monotime_coarse_get(&mtc2
);
5778 nsec2
= monotime_absolute_nsec();
5779 nsecc2
= monotime_coarse_absolute_nsec();
5780 stamp2
= monotime_coarse_to_stamp(&mtc2
);
5782 /* We need to be a little careful here since we don't know the system load.
5784 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_GE
, 175);
5785 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_LT
, 1000);
5786 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_GE
, 125);
5787 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_LT
, 1000);
5788 tt_u64_op(nsec2
-nsec1
, OP_GE
, 175000000);
5789 tt_u64_op(nsec2
-nsec1
, OP_LT
, 1000000000);
5790 tt_u64_op(nsecc2
-nsecc1
, OP_GE
, 125000000);
5791 tt_u64_op(nsecc2
-nsecc1
, OP_LT
, 1000000000);
5793 tt_u64_op(msec1
, OP_GE
, nsec1
/ 1000000);
5794 tt_u64_op(usec1
, OP_GE
, nsec1
/ 1000);
5795 tt_u64_op(msecc1
, OP_GE
, nsecc1
/ 1000000);
5796 tt_u64_op(usecc1
, OP_GE
, nsecc1
/ 1000);
5797 tt_u64_op(msec1
, OP_LE
, nsec1
/ 1000000 + 10);
5798 tt_u64_op(usec1
, OP_LE
, nsec1
/ 1000 + 10000);
5799 tt_u64_op(msecc1
, OP_LE
, nsecc1
/ 1000000 + 10);
5800 tt_u64_op(usecc1
, OP_LE
, nsecc1
/ 1000 + 10000);
5802 uint64_t coarse_stamp_diff
=
5803 monotime_coarse_stamp_units_to_approx_msec(stamp2
-stamp1
);
5804 tt_u64_op(coarse_stamp_diff
, OP_GE
, 120);
5805 tt_u64_op(coarse_stamp_diff
, OP_LE
, 1200);
5808 uint64_t units
= monotime_msec_to_approx_coarse_stamp_units(5000);
5809 uint64_t ms
= monotime_coarse_stamp_units_to_approx_msec(units
);
5810 tt_u64_op(ms
, OP_GE
, 4950);
5811 tt_u64_op(ms
, OP_LT
, 5050);
5819 test_util_monotonic_time_ratchet(void *arg
)
5823 monotime_reset_ratchets_for_testing();
5825 /* win32, performance counter ratchet. */
5826 tt_i64_op(100, OP_EQ
, ratchet_performance_counter(100));
5827 tt_i64_op(101, OP_EQ
, ratchet_performance_counter(101));
5828 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(2000));
5829 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(100));
5830 tt_i64_op(2005, OP_EQ
, ratchet_performance_counter(105));
5831 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1105));
5832 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1000));
5833 tt_i64_op(3010, OP_EQ
, ratchet_performance_counter(1005));
5835 /* win32, GetTickCounts32 ratchet-and-rollover-detector. */
5836 const int64_t R
= ((int64_t)1) << 32;
5837 tt_i64_op(5, OP_EQ
, ratchet_coarse_performance_counter(5));
5838 tt_i64_op(1000, OP_EQ
, ratchet_coarse_performance_counter(1000));
5839 tt_i64_op(5+R
, OP_EQ
, ratchet_coarse_performance_counter(5));
5840 tt_i64_op(10+R
, OP_EQ
, ratchet_coarse_performance_counter(10));
5841 tt_i64_op(4+R
*2, OP_EQ
, ratchet_coarse_performance_counter(4));
5843 /* gettimeofday regular ratchet. */
5844 struct timeval tv_in
= {0,0}, tv_out
;
5845 tv_in
.tv_usec
= 9000;
5847 ratchet_timeval(&tv_in
, &tv_out
);
5848 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 9000);
5849 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 0);
5851 tv_in
.tv_sec
= 1337;
5853 ratchet_timeval(&tv_in
, &tv_out
);
5854 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
5855 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
5857 tv_in
.tv_sec
= 1336;
5858 tv_in
.tv_usec
= 500000;
5859 ratchet_timeval(&tv_in
, &tv_out
);
5860 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
5861 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
5863 tv_in
.tv_sec
= 1337;
5865 ratchet_timeval(&tv_in
, &tv_out
);
5866 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 500000);
5867 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
5869 tv_in
.tv_sec
= 1337;
5870 tv_in
.tv_usec
= 600000;
5871 ratchet_timeval(&tv_in
, &tv_out
);
5872 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
5873 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
5875 tv_in
.tv_sec
= 1000;
5876 tv_in
.tv_usec
= 1000;
5877 ratchet_timeval(&tv_in
, &tv_out
);
5878 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
5879 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
5881 tv_in
.tv_sec
= 2000;
5882 tv_in
.tv_usec
= 2000;
5883 ratchet_timeval(&tv_in
, &tv_out
);
5884 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 101000);
5885 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 2338);
5892 test_util_monotonic_time_zero(void *arg
)
5896 monotime_coarse_t ct1
;
5898 /* Check 1: The current time is not zero. */
5900 monotime_coarse_get(&ct1
);
5901 tt_assert(!monotime_is_zero(&t1
));
5902 tt_assert(!monotime_coarse_is_zero(&ct1
));
5904 /* Check 2: The _zero() makes the time zero. */
5906 monotime_coarse_zero(&ct1
);
5907 tt_assert(monotime_is_zero(&t1
));
5908 tt_assert(monotime_coarse_is_zero(&ct1
));
5914 test_util_monotonic_time_add_msec(void *arg
)
5918 monotime_coarse_t ct1
, ct2
;
5922 monotime_coarse_get(&ct1
);
5924 /* adding zero does nothing */
5925 monotime_add_msec(&t2
, &t1
, 0);
5926 monotime_coarse_add_msec(&ct2
, &ct1
, 0);
5927 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 0);
5928 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 0);
5930 /* Add 1337 msec; see if the diff function agree */
5931 monotime_add_msec(&t2
, &t1
, 1337);
5932 monotime_coarse_add_msec(&ct2
, &ct1
, 1337);
5933 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337);
5934 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337);
5935 // The 32-bit variant must be within 1% of the regular one.
5936 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 1323);
5937 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 1350);
5939 /* Add 1337 msec twice more; make sure that any second rollover issues
5941 monotime_add_msec(&t2
, &t2
, 1337);
5942 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
5943 monotime_add_msec(&t2
, &t2
, 1337);
5944 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
5945 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337*3);
5946 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337*3);
5947 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 3970);
5948 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 4051);
5955 test_util_nowrap_math(void *arg
)
5959 tt_u64_op(0, OP_EQ
, tor_add_u32_nowrap(0, 0));
5960 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(0, 1));
5961 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(1, 0));
5962 tt_u64_op(4, OP_EQ
, tor_add_u32_nowrap(2, 2));
5963 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
-1, 2));
5964 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(2, UINT32_MAX
-1));
5965 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
, UINT32_MAX
));
5972 test_util_htonll(void *arg
)
5975 #ifdef WORDS_BIGENDIAN
5976 const uint64_t res_be
= 0x8877665544332211;
5978 const uint64_t res_le
= 0x1122334455667788;
5981 tt_u64_op(0, OP_EQ
, tor_htonll(0));
5982 tt_u64_op(0, OP_EQ
, tor_ntohll(0));
5983 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_htonll(UINT64_MAX
));
5984 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_ntohll(UINT64_MAX
));
5986 #ifdef WORDS_BIGENDIAN
5987 tt_u64_op(res_be
, OP_EQ
, tor_htonll(0x8877665544332211));
5988 tt_u64_op(res_be
, OP_EQ
, tor_ntohll(0x8877665544332211));
5990 tt_u64_op(res_le
, OP_EQ
, tor_htonll(0x8877665544332211));
5991 tt_u64_op(res_le
, OP_EQ
, tor_ntohll(0x8877665544332211));
5992 #endif /* defined(WORDS_BIGENDIAN) */
5999 test_util_get_unquoted_path(void *arg
)
6005 r
= get_unquoted_path("\""); // "
6006 tt_ptr_op(r
, OP_EQ
, NULL
);
6009 r
= get_unquoted_path("\"\"\""); // """
6010 tt_ptr_op(r
, OP_EQ
, NULL
);
6013 r
= get_unquoted_path("\\\""); // \"
6014 tt_ptr_op(r
, OP_EQ
, NULL
);
6017 r
= get_unquoted_path("\\\"\\\""); // \"\"
6018 tt_ptr_op(r
, OP_EQ
, NULL
);
6021 r
= get_unquoted_path("A\\B\\C\""); // A\B\C"
6022 tt_ptr_op(r
, OP_EQ
, NULL
);
6025 r
= get_unquoted_path("\"A\\B\\C"); // "A\B\C
6026 tt_ptr_op(r
, OP_EQ
, NULL
);
6029 r
= get_unquoted_path("\"A\\B\"C\""); // "A\B"C"
6030 tt_ptr_op(r
, OP_EQ
, NULL
);
6033 r
= get_unquoted_path("A\\B\"C"); // A\B"C
6034 tt_ptr_op(r
, OP_EQ
, NULL
);
6037 r
= get_unquoted_path("");
6038 tt_str_op(r
, OP_EQ
, "");
6041 r
= get_unquoted_path("\"\""); // ""
6042 tt_str_op(r
, OP_EQ
, "");
6045 r
= get_unquoted_path("A\\B\\C"); // A\B\C
6046 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6049 r
= get_unquoted_path("\"A\\B\\C\""); // "A\B\C"
6050 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6053 r
= get_unquoted_path("\"\\\""); // "\"
6054 tt_str_op(r
, OP_EQ
, "\\"); // \ /* comment to prevent line continuation */
6057 r
= get_unquoted_path("\"\\\"\""); // "\""
6058 tt_str_op(r
, OP_EQ
, "\""); // "
6061 r
= get_unquoted_path("\"A\\B\\C\\\"\""); // "A\B\C\""
6062 tt_str_op(r
, OP_EQ
, "A\\B\\C\""); // A\B\C"
6065 r
= get_unquoted_path("A\\B\\\"C"); // A\B\"C
6066 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6069 r
= get_unquoted_path("\"A\\B\\\"C\""); // "A\B\"C"
6070 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6077 test_util_log_mallinfo(void *arg
)
6080 char *log1
= NULL
, *log2
= NULL
, *mem
= NULL
;
6081 #ifdef HAVE_MALLINFO
6082 setup_capture_of_logs(LOG_INFO
);
6083 tor_log_mallinfo(LOG_INFO
);
6084 expect_single_log_msg_containing("mallinfo() said: ");
6085 mock_saved_log_entry_t
*lg
= smartlist_get(mock_saved_logs(), 0);
6086 log1
= tor_strdup(lg
->generated_msg
);
6088 mock_clean_saved_logs();
6089 mem
= tor_malloc(8192);
6090 tor_log_mallinfo(LOG_INFO
);
6091 expect_single_log_msg_containing("mallinfo() said: ");
6092 lg
= smartlist_get(mock_saved_logs(), 0);
6093 log2
= tor_strdup(lg
->generated_msg
);
6095 /* Make sure that the amount of used memory increased. */
6096 const char *used1
= strstr(log1
, "uordblks=");
6097 const char *used2
= strstr(log2
, "uordblks=");
6100 used1
+= strlen("uordblks=");
6101 used2
+= strlen("uordblks=");
6104 char *next1
= NULL
, *next2
= NULL
;
6105 uint64_t mem1
= tor_parse_uint64(used1
, 10, 0, UINT64_MAX
, &ok1
, &next1
);
6106 uint64_t mem2
= tor_parse_uint64(used2
, 10, 0, UINT64_MAX
, &ok2
, &next2
);
6112 /* This is a fake mallinfo that doesn't actually fill in its outputs. */
6113 tt_u64_op(mem1
, OP_EQ
, 0);
6115 tt_u64_op(mem1
, OP_LT
, mem2
);
6121 teardown_capture_of_logs();
6128 test_util_map_anon(void *arg
)
6135 ptr
= tor_mmap_anonymous(sz
, 0);
6136 tt_ptr_op(ptr
, OP_NE
, 0);
6138 tt_int_op(ptr
[0], OP_EQ
, 0);
6139 tt_int_op(ptr
[sz
-2], OP_EQ
, 0);
6140 tt_int_op(ptr
[sz
-1], OP_EQ
, 3);
6142 /* Try again, with a private (non-swappable) mapping. */
6143 tor_munmap_anonymous(ptr
, sz
);
6144 ptr
= tor_mmap_anonymous(sz
, ANONMAP_PRIVATE
);
6145 tt_ptr_op(ptr
, OP_NE
, 0);
6147 tt_int_op(ptr
[0], OP_EQ
, 0);
6148 tt_int_op(ptr
[sz
/2], OP_EQ
, 0);
6149 tt_int_op(ptr
[sz
-1], OP_EQ
, 10);
6151 /* Now let's test a drop-on-fork mapping. */
6152 tor_munmap_anonymous(ptr
, sz
);
6153 ptr
= tor_mmap_anonymous(sz
, ANONMAP_NOINHERIT
);
6154 tt_ptr_op(ptr
, OP_NE
, 0);
6156 tt_int_op(ptr
[0], OP_EQ
, 0);
6157 tt_int_op(ptr
[sz
/2], OP_EQ
, 0);
6158 tt_int_op(ptr
[sz
-1], OP_EQ
, 10);
6161 tor_munmap_anonymous(ptr
, sz
);
6165 test_util_map_anon_nofork(void *arg
)
6168 #if !defined(HAVE_MADVISE) && !defined(HAVE_MINHERIT)
6169 /* The operating system doesn't support this. */
6174 /* We have the right OS support. We're going to try marking the buffer as
6175 * either zero-on-fork or as drop-on-fork, whichever is supported. Then we
6176 * will fork and send a byte back to the parent process. This will either
6177 * crash, or send zero. */
6181 int pipefd
[2] = {-1, -1};
6183 tor_munmap_anonymous(ptr
, sz
);
6184 ptr
= tor_mmap_anonymous(sz
, ANONMAP_NOINHERIT
);
6185 tt_ptr_op(ptr
, OP_NE
, 0);
6186 memset(ptr
, 0xd0, sz
);
6188 tt_int_op(0, OP_EQ
, pipe(pipefd
));
6189 pid_t child
= fork();
6191 /* We're in the child. */
6193 ssize_t r
= write(pipefd
[1], &ptr
[sz
-1], 1); /* This may crash. */
6199 tt_int_op(child
, OP_GT
, 0);
6200 /* In the parent. */
6204 ssize_t r
= read(pipefd
[0], buf
, 1);
6205 #if defined(INHERIT_ZERO) || defined(MADV_WIPEONFORK)
6206 tt_int_op((int)r
, OP_EQ
, 1); // child should send us a byte.
6207 tt_int_op(buf
[0], OP_EQ
, 0);
6209 tt_int_op(r
, OP_LE
, 0); // child said nothing; it should have crashed.
6212 waitpid(child
, &ws
, 0);
6215 tor_munmap_anonymous(ptr
, sz
);
6216 if (pipefd
[0] >= 0) {
6219 if (pipefd
[1] >= 0) {
6225 #define UTIL_LEGACY(name) \
6226 { #name, test_util_ ## name , 0, NULL, NULL }
6228 #define UTIL_TEST(name, flags) \
6229 { #name, test_util_ ## name, flags, NULL, NULL }
6231 #define COMPRESS(name, identifier) \
6232 { "compress/" #name, test_util_compress, 0, &compress_setup, \
6233 (char*)(identifier) }
6235 #define COMPRESS_CONCAT(name, identifier) \
6236 { "compress_concat/" #name, test_util_decompress_concatenated, 0, \
6238 (char*)(identifier) }
6240 #define COMPRESS_JUNK(name, identifier) \
6241 { "compress_junk/" #name, test_util_decompress_junk, 0, \
6243 (char*)(identifier) }
6245 #define COMPRESS_DOS(name, identifier) \
6246 { "compress_dos/" #name, test_util_decompress_dos, 0, \
6248 (char*)(identifier) }
6251 #define UTIL_TEST_NO_WIN(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
6252 #define UTIL_TEST_WIN_ONLY(n, f) UTIL_TEST(n, (f))
6253 #define UTIL_LEGACY_NO_WIN(n) UTIL_TEST_NO_WIN(n, 0)
6255 #define UTIL_TEST_NO_WIN(n, f) UTIL_TEST(n, (f))
6256 #define UTIL_TEST_WIN_ONLY(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
6257 #define UTIL_LEGACY_NO_WIN(n) UTIL_LEGACY(n)
6258 #endif /* defined(_WIN32) */
6260 struct testcase_t util_tests
[] = {
6262 UTIL_TEST(parse_http_time
, 0),
6263 UTIL_LEGACY(config_line
),
6264 UTIL_LEGACY(config_line_quotes
),
6265 UTIL_LEGACY(config_line_comment_character
),
6266 UTIL_LEGACY(config_line_escaped_content
),
6267 UTIL_LEGACY(config_line_crlf
),
6268 UTIL_LEGACY_NO_WIN(expand_filename
),
6269 UTIL_LEGACY(escape_string_socks
),
6270 UTIL_LEGACY(string_is_key_value
),
6271 UTIL_LEGACY(strmisc
),
6272 UTIL_TEST(parse_integer
, 0),
6274 COMPRESS(zlib
, "deflate"),
6275 COMPRESS(gzip
, "gzip"),
6276 COMPRESS(lzma
, "x-tor-lzma"),
6277 COMPRESS(zstd
, "x-zstd"),
6278 COMPRESS(zstd_nostatic
, "x-zstd:nostatic"),
6279 COMPRESS(none
, "identity"),
6280 COMPRESS_CONCAT(zlib
, "deflate"),
6281 COMPRESS_CONCAT(gzip
, "gzip"),
6282 COMPRESS_CONCAT(lzma
, "x-tor-lzma"),
6283 COMPRESS_CONCAT(zstd
, "x-zstd"),
6284 COMPRESS_CONCAT(zstd_nostatic
, "x-zstd:nostatic"),
6285 COMPRESS_CONCAT(none
, "identity"),
6286 COMPRESS_JUNK(zlib
, "deflate"),
6287 COMPRESS_JUNK(gzip
, "gzip"),
6288 COMPRESS_JUNK(lzma
, "x-tor-lzma"),
6289 COMPRESS_DOS(zlib
, "deflate"),
6290 COMPRESS_DOS(gzip
, "gzip"),
6291 COMPRESS_DOS(lzma
, "x-tor-lzma"),
6292 COMPRESS_DOS(zstd
, "x-zstd"),
6293 COMPRESS_DOS(zstd_nostatic
, "x-zstd:nostatic"),
6294 UTIL_TEST(gzip_compression_bomb
, TT_FORK
),
6295 UTIL_LEGACY(datadir
),
6296 UTIL_LEGACY(memarea
),
6297 UTIL_LEGACY(control_formats
),
6299 UTIL_TEST(sscanf
, TT_FORK
),
6300 UTIL_LEGACY(format_time_interval
),
6301 UTIL_LEGACY(path_is_relative
),
6302 UTIL_LEGACY(strtok
),
6303 UTIL_LEGACY(di_ops
),
6304 UTIL_TEST(di_map
, 0),
6305 UTIL_TEST(round_to_next_multiple_of
, 0),
6306 UTIL_TEST(laplace
, 0),
6307 UTIL_TEST(clamp_double_to_int64
, 0),
6308 UTIL_TEST(find_str_at_start_of_line
, 0),
6309 UTIL_TEST(string_is_C_identifier
, 0),
6310 UTIL_TEST(string_is_utf8
, 0),
6311 UTIL_TEST(asprintf
, 0),
6312 UTIL_TEST(listdir
, 0),
6313 UTIL_TEST(parent_dir
, 0),
6314 UTIL_TEST(ftruncate
, 0),
6315 UTIL_TEST(nowrap_math
, 0),
6316 UTIL_TEST(num_cpus
, 0),
6317 UTIL_TEST_WIN_ONLY(load_win_lib
, 0),
6318 UTIL_TEST(format_hex_number
, 0),
6319 UTIL_TEST(format_dec_number
, 0),
6320 UTIL_TEST(n_bits_set
, 0),
6321 UTIL_TEST(eat_whitespace
, 0),
6322 UTIL_TEST(sl_new_from_text_lines
, 0),
6323 UTIL_TEST(envnames
, 0),
6324 UTIL_TEST(make_environment
, 0),
6325 UTIL_TEST(set_env_var_in_sl
, 0),
6326 UTIL_TEST(read_file_eof_tiny_limit
, 0),
6327 UTIL_TEST(read_file_eof_one_loop_a
, 0),
6328 UTIL_TEST(read_file_eof_one_loop_b
, 0),
6329 UTIL_TEST(read_file_eof_two_loops
, 0),
6330 UTIL_TEST(read_file_eof_two_loops_b
, 0),
6331 UTIL_TEST(read_file_eof_zero_bytes
, 0),
6332 UTIL_TEST(write_chunks_to_file
, 0),
6333 UTIL_TEST(mathlog
, 0),
6334 UTIL_TEST(fraction
, 0),
6335 UTIL_TEST(weak_random
, 0),
6336 { "tor_isinf", test_tor_isinf
, TT_FORK
, NULL
, NULL
},
6337 { "socket_ipv4", test_util_socket
, TT_FORK
, &passthrough_setup
,
6339 { "socket_ipv6", test_util_socket
, TT_FORK
,
6340 &passthrough_setup
, (void*)"6" },
6341 { "socketpair", test_util_socketpair
, TT_FORK
, &passthrough_setup
,
6343 { "socketpair_ersatz", test_util_socketpair
, TT_FORK
,
6344 &passthrough_setup
, (void*)"1" },
6345 UTIL_TEST(max_mem
, 0),
6346 UTIL_TEST(hostname_validation
, 0),
6347 UTIL_TEST(dest_validation_edgecase
, 0),
6348 UTIL_TEST(ipv4_validation
, 0),
6349 UTIL_TEST(ipv6_validation
, 0),
6350 UTIL_TEST(writepid
, 0),
6351 UTIL_TEST(get_avail_disk_space
, 0),
6352 UTIL_TEST(touch_file
, 0),
6353 UTIL_TEST_NO_WIN(pwdb
, TT_FORK
),
6354 UTIL_TEST(calloc_check
, 0),
6355 UTIL_TEST(monotonic_time
, 0),
6356 UTIL_TEST(monotonic_time_ratchet
, TT_FORK
),
6357 UTIL_TEST(monotonic_time_zero
, 0),
6358 UTIL_TEST(monotonic_time_add_msec
, 0),
6359 UTIL_TEST(htonll
, 0),
6360 UTIL_TEST(get_unquoted_path
, 0),
6361 UTIL_TEST(log_mallinfo
, 0),
6362 UTIL_TEST(map_anon
, 0),
6363 UTIL_TEST(map_anon_nofork
, 0),