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 SUBPROCESS_PRIVATE
14 #include "lib/testsupport/testsupport.h"
15 #include "core/or/or.h"
16 #include "lib/container/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 "test/test.h"
23 #include "lib/memarea/memarea.h"
24 #include "lib/process/waitpid.h"
25 #include "test/log_test_helpers.h"
26 #include "lib/compress/compress.h"
27 #include "lib/compress/compress_zstd.h"
28 #include "lib/encoding/keyval.h"
29 #include "lib/fdio/fdio.h"
30 #include "lib/fs/winlib.h"
31 #include "lib/process/env.h"
32 #include "lib/process/pidfile.h"
33 #include "lib/process/subprocess.h"
34 #include "lib/intmath/weakrng.h"
35 #include "lib/thread/numcpus.h"
36 #include "lib/math/fp.h"
37 #include "lib/math/laplace.h"
38 #include "lib/meminfo/meminfo.h"
39 #include "lib/time/tvdiff.h"
40 #include "lib/encoding/confline.h"
41 #include "lib/net/socketpair.h"
46 #ifdef HAVE_SYS_UTIME_H
47 #include <sys/utime.h>
52 #ifdef HAVE_SYS_STAT_H
69 #define INFINITY_DBL ((double)INFINITY)
70 #define NAN_DBL ((double)NAN)
72 /* XXXX this is a minimal wrapper to make the unit tests compile with the
73 * changed tor_timegm interface. */
75 tor_timegm_wrapper(const struct tm
*tm
)
78 if (tor_timegm(tm
, &t
) < 0)
83 #define tor_timegm tor_timegm_wrapper
86 test_util_read_until_eof_impl(const char *fname
, size_t file_len
,
89 char *fifo_name
= NULL
;
90 char *test_str
= NULL
;
96 fifo_name
= tor_strdup(get_fname(fname
));
97 test_str
= tor_malloc(file_len
);
98 crypto_rand(test_str
, file_len
);
100 r
= write_bytes_to_file(fifo_name
, test_str
, file_len
, 1);
101 tt_int_op(r
, OP_EQ
, 0);
103 fd
= open(fifo_name
, O_RDONLY
|O_BINARY
);
104 tt_int_op(fd
, OP_GE
, 0);
105 str
= read_file_to_str_until_eof(fd
, read_limit
, &sz
);
106 tt_ptr_op(str
, OP_NE
, NULL
);
108 if (read_limit
< file_len
)
109 tt_int_op(sz
, OP_EQ
, read_limit
);
111 tt_int_op(sz
, OP_EQ
, file_len
);
113 tt_mem_op(test_str
, OP_EQ
, str
, sz
);
114 tt_int_op(str
[sz
], OP_EQ
, '\0');
126 test_util_read_file_eof_tiny_limit(void *arg
)
129 // purposely set limit shorter than what we wrote to the FIFO to
130 // test the maximum, and that it puts the NUL in the right spot
132 test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
136 test_util_read_file_eof_one_loop_a(void *arg
)
139 test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
143 test_util_read_file_eof_one_loop_b(void *arg
)
146 test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
150 test_util_read_file_eof_two_loops(void *arg
)
153 // write more than 1024 bytes to the FIFO to test two passes through
154 // the loop in the method; if the re-alloc size is changed this
155 // should be updated as well.
157 test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
161 test_util_read_file_eof_two_loops_b(void *arg
)
165 test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
169 test_util_read_file_eof_zero_bytes(void *arg
)
173 test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
177 test_util_read_file_endlines(void *arg
)
182 char *read_content
= NULL
;
185 /* Write a file that contains both \n and \r\n as line ending. */
186 const char *file_content
= "foo bar\n"
190 const char *expected_file_content
= "foo bar\n"
194 fname
= tor_strdup(get_fname("file_with_crlf_ending"));
196 r
= write_bytes_to_file(fname
, file_content
, strlen(file_content
), 1);
197 tt_int_op(r
, OP_EQ
, 0);
199 /* Read the file in text mode: we strip \r's from the files on both Windows
201 read_content
= read_file_to_str(fname
, 0, NULL
);
203 tt_ptr_op(read_content
, OP_NE
, NULL
);
204 tt_int_op(strlen(read_content
), OP_EQ
, strlen(expected_file_content
));
205 tt_str_op(read_content
, OP_EQ
, expected_file_content
);
207 tor_free(read_content
);
209 /* Read the file in binary mode: we should preserve the \r here. */
210 read_content
= read_file_to_str(fname
, RFTS_BIN
, NULL
);
212 tt_ptr_op(read_content
, OP_NE
, NULL
);
213 tt_int_op(strlen(read_content
), OP_EQ
, strlen(file_content
));
214 tt_str_op(read_content
, OP_EQ
, file_content
);
216 tor_free(read_content
);
221 tor_free(read_content
);
224 /* Test the basic expected behaviour for write_chunks_to_file.
225 * NOTE: This will need to be updated if we ever change the tempfile location
228 test_util_write_chunks_to_file(void *arg
)
231 char *tempname
= NULL
;
236 /* These should be two different sizes to ensure the data is different
237 * between the data file and the temp file's 'known string' */
238 int temp_str_len
= 1024;
239 int data_str_len
= 512;
240 char *data_str
= tor_malloc(data_str_len
);
241 char *temp_str
= tor_malloc(temp_str_len
);
243 smartlist_t
*chunks
= smartlist_new();
244 sized_chunk_t c
= {data_str
, data_str_len
/2};
245 sized_chunk_t c2
= {data_str
+ data_str_len
/2, data_str_len
/2};
248 crypto_rand(temp_str
, temp_str_len
);
249 crypto_rand(data_str
, data_str_len
);
251 // Ensure it can write multiple chunks
253 smartlist_add(chunks
, &c
);
254 smartlist_add(chunks
, &c2
);
257 * Check if it writes using a tempfile
259 fname
= tor_strdup(get_fname("write_chunks_with_tempfile"));
260 tor_asprintf(&tempname
, "%s.tmp", fname
);
262 // write a known string to a file where the tempfile will be
263 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
264 tt_int_op(r
, OP_EQ
, 0);
266 // call write_chunks_to_file
267 r
= write_chunks_to_file(fname
, chunks
, 1, 0);
268 tt_int_op(r
, OP_EQ
, 0);
270 // assert the file has been written (expected size)
271 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
272 tt_assert(str
!= NULL
);
273 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
274 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
277 // assert that the tempfile is removed (should not leave artifacts)
278 str
= read_file_to_str(tempname
, RFTS_BIN
|RFTS_IGNORE_MISSING
, &st
);
279 tt_assert(str
== NULL
);
281 // Remove old testfile for second test
283 tt_int_op(r
, OP_EQ
, 0);
288 * Check if it skips using a tempfile with flags
290 fname
= tor_strdup(get_fname("write_chunks_with_no_tempfile"));
291 tor_asprintf(&tempname
, "%s.tmp", fname
);
293 // write a known string to a file where the tempfile will be
294 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
295 tt_int_op(r
, OP_EQ
, 0);
297 // call write_chunks_to_file with no_tempfile = true
298 r
= write_chunks_to_file(fname
, chunks
, 1, 1);
299 tt_int_op(r
, OP_EQ
, 0);
301 // assert the file has been written (expected size)
302 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
303 tt_assert(str
!= NULL
);
304 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
305 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
308 // assert the tempfile still contains the known string
309 str
= read_file_to_str(tempname
, RFTS_BIN
, &st
);
310 tt_assert(str
!= NULL
);
311 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, temp_str_len
);
312 tt_mem_op(temp_str
, OP_EQ
, str
, temp_str_len
);
317 smartlist_free(chunks
);
325 #define _TFE(a, b, f) tt_int_op((a).f, OP_EQ, (b).f)
326 /** test the minimum set of struct tm fields needed for a unique epoch value
327 * this is also the set we use to test tor_timegm */
328 #define TM_EQUAL(a, b) \
330 _TFE(a, b, tm_year); \
331 _TFE(a, b, tm_mon ); \
332 _TFE(a, b, tm_mday); \
333 _TFE(a, b, tm_hour); \
334 _TFE(a, b, tm_min ); \
335 _TFE(a, b, tm_sec ); \
339 test_util_time(void *arg
)
341 struct timeval start
, end
;
342 struct tm a_time
, b_time
;
348 /* Test tv_udiff and tv_mdiff */
352 start
.tv_usec
= 5000;
357 tt_int_op(0L,OP_EQ
, tv_udiff(&start
, &end
));
358 tt_int_op(0L,OP_EQ
, tv_mdiff(&start
, &end
));
359 tt_int_op(0L,OP_EQ
, tv_udiff(&end
, &start
));
360 tt_int_op(0L,OP_EQ
, tv_mdiff(&end
, &start
));
364 tt_int_op(2000L,OP_EQ
, tv_udiff(&start
, &end
));
365 tt_int_op(2L,OP_EQ
, tv_mdiff(&start
, &end
));
366 tt_int_op(-2000L,OP_EQ
, tv_udiff(&end
, &start
));
367 tt_int_op(-2L,OP_EQ
, tv_mdiff(&end
, &start
));
371 tt_int_op(1002000L,OP_EQ
, tv_udiff(&start
, &end
));
372 tt_int_op(1002L,OP_EQ
, tv_mdiff(&start
, &end
));
373 tt_int_op(-1002000L,OP_EQ
, tv_udiff(&end
, &start
));
374 tt_int_op(-1002L,OP_EQ
, tv_mdiff(&end
, &start
));
378 tt_int_op(995000L,OP_EQ
, tv_udiff(&start
, &end
));
379 tt_int_op(995L,OP_EQ
, tv_mdiff(&start
, &end
));
380 tt_int_op(-995000L,OP_EQ
, tv_udiff(&end
, &start
));
381 tt_int_op(-995L,OP_EQ
, tv_mdiff(&end
, &start
));
385 tt_int_op(-1005000L,OP_EQ
, tv_udiff(&start
, &end
));
386 tt_int_op(-1005L,OP_EQ
, tv_mdiff(&start
, &end
));
387 tt_int_op(1005000L,OP_EQ
, tv_udiff(&end
, &start
));
388 tt_int_op(1005L,OP_EQ
, tv_mdiff(&end
, &start
));
390 /* Negative tv_sec values, these will break on platforms where tv_sec is
395 tt_int_op(-15005000L,OP_EQ
, tv_udiff(&start
, &end
));
396 tt_int_op(-15005L,OP_EQ
, tv_mdiff(&start
, &end
));
397 tt_int_op(15005000L,OP_EQ
, tv_udiff(&end
, &start
));
398 tt_int_op(15005L,OP_EQ
, tv_mdiff(&end
, &start
));
402 tt_int_op(89995000L,OP_EQ
, tv_udiff(&start
, &end
));
403 tt_int_op(89995L,OP_EQ
, tv_mdiff(&start
, &end
));
404 tt_int_op(-89995000L,OP_EQ
, tv_udiff(&end
, &start
));
405 tt_int_op(-89995L,OP_EQ
, tv_mdiff(&end
, &start
));
407 /* Test that tv_usec values round away from zero when converted to msec */
413 tt_int_op(10000499L, OP_EQ
, tv_udiff(&start
, &end
));
414 tt_int_op(10000L, OP_EQ
, tv_mdiff(&start
, &end
));
415 tt_int_op(-10000499L, OP_EQ
, tv_udiff(&end
, &start
));
416 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
423 tt_int_op(10000500L, OP_EQ
, tv_udiff(&start
, &end
));
424 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
425 tt_int_op(-10000500L, OP_EQ
, tv_udiff(&end
, &start
));
426 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
433 tt_int_op(10000501L, OP_EQ
, tv_udiff(&start
, &end
));
434 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
435 tt_int_op(-10000501L, OP_EQ
, tv_udiff(&end
, &start
));
436 tt_int_op(-10001L, OP_EQ
, tv_mdiff(&end
, &start
));
438 /* Overflow conditions */
441 /* Would you believe that tv_sec is a long on windows? Of course you would.*/
442 #define TV_SEC_MAX LONG_MAX
443 #define TV_SEC_MIN LONG_MIN
445 /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
446 * Which means TIME_MAX is not actually the maximum value of tv_sec.
447 * But that's ok for the moment, because the code correctly performs 64-bit
448 * calculations internally, then catches the overflow. */
449 #define TV_SEC_MAX TIME_MAX
450 #define TV_SEC_MIN TIME_MIN
451 #endif /* defined(_WIN32) */
453 /* Assume tv_usec is an unsigned integer until proven otherwise */
454 #define TV_USEC_MAX UINT_MAX
455 #define TOR_USEC_PER_SEC 1000000
457 /* Overflows in the result type */
459 /* All comparisons work */
462 end
.tv_sec
= LONG_MAX
/1000 - 2;
465 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
466 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
467 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
468 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
472 end
.tv_sec
= LONG_MAX
/1000000 - 1;
475 tt_int_op(end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&start
, &end
));
476 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
477 tt_int_op(-end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&end
, &start
));
478 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
480 /* No comparisons work */
483 end
.tv_sec
= LONG_MAX
/1000 + 1;
486 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
487 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
488 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
489 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
493 end
.tv_sec
= LONG_MAX
/1000000 + 1;
496 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
497 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
498 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
499 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
503 end
.tv_sec
= LONG_MAX
/1000;
504 end
.tv_usec
= TOR_USEC_PER_SEC
;
506 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
507 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
508 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
509 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
513 end
.tv_sec
= LONG_MAX
/1000000;
514 end
.tv_usec
= TOR_USEC_PER_SEC
;
516 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
517 tt_int_op((end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
518 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
519 tt_int_op(-(end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
521 /* Overflows on comparison to zero */
526 end
.tv_sec
= TV_SEC_MAX
;
529 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
530 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
531 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
532 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
534 end
.tv_sec
= TV_SEC_MAX
;
535 end
.tv_usec
= TOR_USEC_PER_SEC
;
537 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
538 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
539 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
540 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
543 end
.tv_usec
= TV_USEC_MAX
;
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 end
.tv_sec
= TV_SEC_MAX
;
551 end
.tv_usec
= TV_USEC_MAX
;
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
));
561 start
.tv_sec
= TV_SEC_MIN
;
564 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
565 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
566 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
567 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
569 start
.tv_sec
= TV_SEC_MIN
;
570 start
.tv_usec
= TOR_USEC_PER_SEC
;
572 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
573 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
574 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
575 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
577 start
.tv_sec
= TV_SEC_MIN
;
578 start
.tv_usec
= TV_USEC_MAX
;
580 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
581 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
582 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
583 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
585 /* overflows on comparison to maxima / minima */
587 start
.tv_sec
= TV_SEC_MIN
;
590 end
.tv_sec
= TV_SEC_MAX
;
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 end
.tv_sec
= TV_SEC_MAX
;
599 end
.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 end
.tv_sec
= TV_SEC_MAX
;
609 start
.tv_sec
= TV_SEC_MIN
;
612 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
613 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
614 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
615 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
617 start
.tv_sec
= TV_SEC_MIN
;
618 start
.tv_usec
= TOR_USEC_PER_SEC
;
620 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
621 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
622 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
623 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
625 /* overflows on comparison to maxima / minima with extra usec */
627 start
.tv_sec
= TV_SEC_MIN
;
628 start
.tv_usec
= TOR_USEC_PER_SEC
;
630 end
.tv_sec
= TV_SEC_MAX
;
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 end
.tv_sec
= TV_SEC_MAX
;
639 end
.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 end
.tv_sec
= TV_SEC_MAX
;
647 end
.tv_usec
= TOR_USEC_PER_SEC
;
649 start
.tv_sec
= TV_SEC_MIN
;
652 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
653 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
654 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
655 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
657 start
.tv_sec
= TV_SEC_MIN
;
658 start
.tv_usec
= TOR_USEC_PER_SEC
;
660 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
661 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
662 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
663 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
665 /* Test tor_timegm & tor_gmtime_r */
667 /* The test values here are confirmed to be correct on a platform
668 * with a working timegm & gmtime_r. */
670 /* Start with known-zero a_time and b_time.
671 * This avoids passing uninitialised values to TM_EQUAL in a_time.
672 * Zeroing may not be needed for b_time, as long as tor_gmtime_r
673 * never reads the existing values in the structure.
674 * But we really don't want intermittently failing tests. */
675 memset(&a_time
, 0, sizeof(struct tm
));
676 memset(&b_time
, 0, sizeof(struct tm
));
678 a_time
.tm_year
= 2003-1900;
684 t_res
= 1062224095UL;
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 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
690 t_res
= 1093846495UL;
691 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
692 tor_gmtime_r(&t_res
, &b_time
);
693 TM_EQUAL(a_time
, b_time
);
695 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
697 t_res
= 1076393695UL;
698 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
699 tor_gmtime_r(&t_res
, &b_time
);
700 TM_EQUAL(a_time
, b_time
);
703 t_res
= 1073715295UL;
704 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
705 tor_gmtime_r(&t_res
, &b_time
);
706 TM_EQUAL(a_time
, b_time
);
708 /* This value is in range with 32 bit and 64 bit time_t */
709 a_time
.tm_year
= 2037-1900;
710 t_res
= 2115180895UL;
711 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
712 tor_gmtime_r(&t_res
, &b_time
);
713 TM_EQUAL(a_time
, b_time
);
715 /* This value is out of range with 32 bit time_t, but in range for 64 bit
717 a_time
.tm_year
= 2039-1900;
718 #if SIZEOF_TIME_T == 4
719 setup_full_capture_of_logs(LOG_WARN
);
720 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
721 expect_single_log_msg_containing("Result does not fit in tor_timegm");
722 teardown_capture_of_logs();
723 #elif SIZEOF_TIME_T == 8
724 t_res
= 2178252895UL;
725 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
726 tor_gmtime_r(&t_res
, &b_time
);
727 TM_EQUAL(a_time
, b_time
);
728 #endif /* SIZEOF_TIME_T == 4 || ... */
730 /* Test tor_timegm out of range */
732 /* The below tests will all cause a BUG message, so we capture, suppress,
734 #define CAPTURE() do { \
735 setup_full_capture_of_logs(LOG_WARN); \
737 #define CHECK_TIMEGM_WARNING(msg) do { \
738 expect_single_log_msg_containing(msg); \
739 teardown_capture_of_logs(); \
741 #define CHECK_POSSIBLE_EINVAL() do { \
742 if (mock_saved_log_n_entries()) { \
743 expect_single_log_msg_containing("Invalid argument"); \
745 teardown_capture_of_logs(); \
748 #define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
749 CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
753 /* Wrong year < 1970 */
754 a_time
.tm_year
= 1969-1900;
756 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
757 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
759 a_time
.tm_year
= -1-1900;
761 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
762 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
764 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
765 a_time
.tm_year
= -1*(1 << 16);
767 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
768 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
770 /* one of the smallest tm_year values my 64 bit system supports:
771 * t_res = -9223372036854775LL without clamping */
772 a_time
.tm_year
= -292275055-1900;
774 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
775 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
777 a_time
.tm_year
= INT32_MIN
;
779 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
780 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
781 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
784 a_time
.tm_year
= -1*(1 << 48);
786 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
787 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
789 /* while unlikely, the system's gmtime(_r) could return
790 * a "correct" retrospective gregorian negative year value,
791 * which I'm pretty sure is:
792 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
793 * 730485 is the number of days in two millennia, including leap days */
794 a_time
.tm_year
= -292277022657-1900;
796 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
797 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
799 a_time
.tm_year
= INT64_MIN
;
801 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
802 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
803 #endif /* SIZEOF_INT == 8 */
805 /* Wrong year >= INT32_MAX - 1900 */
806 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
807 a_time
.tm_year
= INT32_MAX
-1900;
809 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
810 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
812 a_time
.tm_year
= INT32_MAX
;
814 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
815 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
816 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
819 /* one of the largest tm_year values my 64 bit system supports */
820 a_time
.tm_year
= 292278994-1900;
822 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
823 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
825 /* while unlikely, the system's gmtime(_r) could return
826 * a "correct" proleptic gregorian year value,
827 * which I'm pretty sure is:
828 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
829 * 730485 is the number of days in two millennia, including leap days */
830 a_time
.tm_year
= 292277026596-1900;
832 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
833 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
835 a_time
.tm_year
= INT64_MAX
-1900;
837 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
838 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
840 a_time
.tm_year
= INT64_MAX
;
842 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
843 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
844 #endif /* SIZEOF_INT == 8 */
847 a_time
.tm_year
= 2007-1900; /* restore valid year */
849 a_time
.tm_mon
= 12; /* Wrong month, it's 0-based */
851 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
852 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
854 a_time
.tm_mon
= -1; /* Wrong month */
856 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
857 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
860 a_time
.tm_mon
= 6; /* Try July */
861 a_time
.tm_mday
= 32; /* Wrong day */
863 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
864 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
866 a_time
.tm_mon
= 5; /* Try June */
867 a_time
.tm_mday
= 31; /* Wrong day */
869 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
870 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
872 a_time
.tm_year
= 2008-1900; /* Try a leap year */
873 a_time
.tm_mon
= 1; /* in feb. */
874 a_time
.tm_mday
= 30; /* Wrong day */
876 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
877 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
879 a_time
.tm_year
= 2011-1900; /* Try a non-leap year */
880 a_time
.tm_mon
= 1; /* in feb. */
881 a_time
.tm_mday
= 29; /* Wrong day */
883 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
884 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
886 a_time
.tm_mday
= 0; /* Wrong day, it's 1-based (to be different) */
888 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
889 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
892 a_time
.tm_mday
= 3; /* restore valid month day */
894 a_time
.tm_hour
= 24; /* Wrong hour, it's 0-based */
896 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
897 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
899 a_time
.tm_hour
= -1; /* Wrong hour */
901 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
902 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
905 a_time
.tm_hour
= 22; /* restore valid hour */
907 a_time
.tm_min
= 60; /* Wrong minute, it's 0-based */
909 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
910 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
912 a_time
.tm_min
= -1; /* Wrong minute */
914 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
915 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
918 a_time
.tm_min
= 37; /* restore valid minute */
920 a_time
.tm_sec
= 61; /* Wrong second: 0-based with leap seconds */
922 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
923 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
925 a_time
.tm_sec
= -1; /* Wrong second */
927 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
928 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
930 /* Test tor_gmtime_r out of range */
932 /* time_t < 0 yields a year clamped to 1 or 1970,
933 * depending on whether the implementation of the system gmtime(_r)
934 * sets struct tm (1) or not (1970) */
937 tor_gmtime_r(&t_res
, &b_time
);
938 CHECK_POSSIBLE_EINVAL();
939 tt_assert(b_time
.tm_year
== (1970-1900) ||
940 b_time
.tm_year
== (1969-1900));
942 if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
943 t_res
= -1*(1 << 30);
945 tor_gmtime_r(&t_res
, &b_time
);
946 CHECK_POSSIBLE_EINVAL();
947 tt_assert(b_time
.tm_year
== (1970-1900) ||
948 b_time
.tm_year
== (1935-1900));
952 tor_gmtime_r(&t_res
, &b_time
);
953 CHECK_POSSIBLE_EINVAL();
954 tt_assert(b_time
.tm_year
== (1970-1900) ||
955 b_time
.tm_year
== (1901-1900));
958 #if SIZEOF_TIME_T == 8
960 /* one of the smallest tm_year values my 64 bit system supports:
961 * b_time.tm_year == (-292275055LL-1900LL) without clamping */
962 t_res
= -9223372036854775LL;
964 tor_gmtime_r(&t_res
, &b_time
);
965 CHECK_POSSIBLE_EINVAL();
966 tt_assert(b_time
.tm_year
== (1970-1900) ||
967 b_time
.tm_year
== (1-1900));
969 /* while unlikely, the system's gmtime(_r) could return
970 * a "correct" retrospective gregorian negative year value,
971 * which I'm pretty sure is:
972 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
973 * 730485 is the number of days in two millennia, including leap days
974 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
977 tor_gmtime_r(&t_res
, &b_time
);
978 if (! (b_time
.tm_year
== (1970-1900) ||
979 b_time
.tm_year
== (1-1900))) {
980 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
982 if (b_time
.tm_year
!= 1970-1900) {
983 CHECK_TIMEGM_WARNING("Rounding up to ");
985 teardown_capture_of_logs();
989 /* As above, but with localtime. */
990 t_res
= -9223372036854775LL;
992 tor_localtime_r(&t_res
, &b_time
);
993 CHECK_POSSIBLE_EINVAL();
994 tt_assert(b_time
.tm_year
== (1970-1900) ||
995 b_time
.tm_year
== (1-1900));
997 /* while unlikely, the system's gmtime(_r) could return
998 * a "correct" retrospective gregorian negative year value,
999 * which I'm pretty sure is:
1000 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
1001 * 730485 is the number of days in two millennia, including leap days
1002 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
1005 tor_localtime_r(&t_res
, &b_time
);
1006 if (! (b_time
.tm_year
== (1970-1900) ||
1007 b_time
.tm_year
== (1-1900))) {
1008 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
1010 if (b_time
.tm_year
!= 1970-1900) {
1011 CHECK_TIMEGM_WARNING("Rounding up to ");
1013 teardown_capture_of_logs();
1016 #endif /* SIZEOF_TIME_T == 8 */
1018 /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
1019 * depending on whether the implementation of the system gmtime(_r)
1020 * sets struct tm (9999) or not (2037) */
1021 #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
1023 t_res
= 3*(1 << 29);
1024 tor_gmtime_r(&t_res
, &b_time
);
1025 tt_assert(b_time
.tm_year
== (2021-1900));
1028 tor_gmtime_r(&t_res
, &b_time
);
1029 tt_assert(b_time
.tm_year
== (2037-1900) ||
1030 b_time
.tm_year
== (2038-1900));
1033 /* as above but with localtime. */
1034 t_res
= 3*(1 << 29);
1035 tor_localtime_r(&t_res
, &b_time
);
1036 tt_assert(b_time
.tm_year
== (2021-1900));
1039 tor_localtime_r(&t_res
, &b_time
);
1040 tt_assert(b_time
.tm_year
== (2037-1900) ||
1041 b_time
.tm_year
== (2038-1900));
1043 #endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
1045 #if SIZEOF_TIME_T == 8
1047 /* one of the largest tm_year values my 64 bit system supports:
1048 * b_time.tm_year == (292278994L-1900L) without clamping */
1049 t_res
= 9223372036854775LL;
1051 tor_gmtime_r(&t_res
, &b_time
);
1052 CHECK_POSSIBLE_EINVAL();
1053 tt_assert(b_time
.tm_year
== (2037-1900) ||
1054 b_time
.tm_year
== (9999-1900));
1056 /* while unlikely, the system's gmtime(_r) could return
1057 * a "correct" proleptic gregorian year value,
1058 * which I'm pretty sure is:
1059 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1060 * 730485 is the number of days in two millennia, including leap days
1061 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1064 tor_gmtime_r(&t_res
, &b_time
);
1065 CHECK_TIMEGM_WARNING("Rounding down to ");
1067 tt_assert(b_time
.tm_year
== (2037-1900) ||
1068 b_time
.tm_year
== (9999-1900));
1071 /* As above but with localtime. */
1072 t_res
= 9223372036854775LL;
1074 tor_localtime_r(&t_res
, &b_time
);
1075 CHECK_POSSIBLE_EINVAL();
1076 tt_assert(b_time
.tm_year
== (2037-1900) ||
1077 b_time
.tm_year
== (9999-1900));
1079 /* while unlikely, the system's gmtime(_r) could return
1080 * a "correct" proleptic gregorian year value,
1081 * which I'm pretty sure is:
1082 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1083 * 730485 is the number of days in two millennia, including leap days
1084 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1087 tor_localtime_r(&t_res
, &b_time
);
1088 CHECK_TIMEGM_WARNING("Rounding down to ");
1090 tt_assert(b_time
.tm_year
== (2037-1900) ||
1091 b_time
.tm_year
== (9999-1900));
1093 #endif /* SIZEOF_TIME_T == 8 */
1095 /* Test {format,parse}_rfc1123_time */
1097 format_rfc1123_time(timestr
, 0);
1098 tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ
, timestr
);
1099 format_rfc1123_time(timestr
, (time_t)1091580502UL);
1100 tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ
, timestr
);
1103 i
= parse_rfc1123_time(timestr
, &t_res
);
1104 tt_int_op(0,OP_EQ
, i
);
1105 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1107 /* This value is in range with 32 bit and 64 bit time_t */
1108 format_rfc1123_time(timestr
, (time_t)2080000000UL);
1109 tt_str_op("Fri, 30 Nov 2035 01:46:40 GMT",OP_EQ
, timestr
);
1112 i
= parse_rfc1123_time(timestr
, &t_res
);
1113 tt_int_op(0,OP_EQ
, i
);
1114 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1116 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1119 format_rfc1123_time(timestr
, (time_t)2150000000UL);
1120 CHECK_POSSIBLE_EINVAL();
1122 #if SIZEOF_TIME_T == 4
1124 /* Wrapping around will have made it this. */
1125 /* On windows, at least, this is clipped to 1 Jan 1970. ??? */
1126 tt_str_op("Sat, 11 Jan 1902 23:45:04 GMT",OP_EQ
, timestr
);
1128 /* Make sure that the right date doesn't parse. */
1129 strlcpy(timestr
, "Wed, 17 Feb 2038 06:13:20 GMT", sizeof(timestr
));
1133 i
= parse_rfc1123_time(timestr
, &t_res
);
1134 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1135 tt_int_op(-1,OP_EQ
, i
);
1136 #elif SIZEOF_TIME_T == 8
1137 tt_str_op("Wed, 17 Feb 2038 06:13:20 GMT",OP_EQ
, timestr
);
1140 i
= parse_rfc1123_time(timestr
, &t_res
);
1141 tt_int_op(0,OP_EQ
, i
);
1142 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1143 #endif /* SIZEOF_TIME_T == 4 || ... */
1145 /* The timezone doesn't matter */
1148 parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res
));
1149 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1151 parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
1153 parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res
));
1155 parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res
));
1157 parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res
));
1159 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res
));
1161 parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res
));
1163 parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res
));
1165 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res
));
1167 parse_rfc1123_time("Wed, 30 Mar 1900 23:59:59 GMT", &t_res
));
1171 parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res
));
1173 parse_rfc1123_time("Wed, 29 Feb 2012 16:00:00 GMT", &t_res
));
1175 /* Leap second plus one */
1177 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res
));
1179 /* Test parse_iso_time */
1182 i
= parse_iso_time("", &t_res
);
1183 tt_int_op(-1,OP_EQ
, i
);
1185 i
= parse_iso_time("2004-08-32 00:48:22", &t_res
);
1186 tt_int_op(-1,OP_EQ
, i
);
1188 i
= parse_iso_time("1969-08-03 00:48:22", &t_res
);
1189 tt_int_op(-1,OP_EQ
, i
);
1192 i
= parse_iso_time("2004-08-04 00:48:22", &t_res
);
1193 tt_int_op(0,OP_EQ
, i
);
1194 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1196 i
= parse_iso_time("2004-8-4 0:48:22", &t_res
);
1197 tt_int_op(0,OP_EQ
, i
);
1198 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1200 /* This value is in range with 32 bit and 64 bit time_t */
1202 i
= parse_iso_time("2035-11-30 01:46:40", &t_res
);
1203 tt_int_op(0,OP_EQ
, i
);
1204 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1206 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1209 #if SIZEOF_TIME_T == 4
1211 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1212 tt_int_op(-1,OP_EQ
, i
);
1213 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1214 #elif SIZEOF_TIME_T == 8
1215 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1216 tt_int_op(0,OP_EQ
, i
);
1217 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1218 #endif /* SIZEOF_TIME_T == 4 || ... */
1220 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-zz 99-99x99", &t_res
));
1221 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-32 00:00:00", &t_res
));
1222 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 24:00:00", &t_res
));
1223 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:60:00", &t_res
));
1224 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59:62", &t_res
));
1225 tt_int_op(-1,OP_EQ
, parse_iso_time("1969-03-30 23:59:59", &t_res
));
1226 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-00-30 23:59:59", &t_res
));
1227 tt_int_op(-1,OP_EQ
, parse_iso_time("2147483647-08-29 14:00:00", &t_res
));
1228 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59", &t_res
));
1229 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22.100", &t_res
));
1230 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res
));
1232 /* but... that _is_ acceptable if we aren't being strict. */
1234 i
= parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res
, 0, 0);
1235 tt_int_op(0,OP_EQ
, i
);
1236 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1238 /* try nospace variant. */
1240 i
= parse_iso_time_nospace("2004-08-04T00:48:22", &t_res
);
1241 tt_int_op(0,OP_EQ
, i
);
1242 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1244 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04T00:48:22", &t_res
));
1245 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res
));
1246 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04x00:48:22", &t_res
));
1247 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res
));
1249 /* Test tor_gettimeofday */
1252 end
.tv_usec
= 999990;
1254 start
.tv_usec
= 500;
1256 tor_gettimeofday(&start
);
1257 /* now make sure time works. */
1258 tor_gettimeofday(&end
);
1259 /* We might've timewarped a little. */
1260 tt_int_op(tv_udiff(&start
, &end
), OP_GE
, -5000);
1262 /* Test format_iso_time */
1264 tv
.tv_sec
= (time_t)1326296338UL;
1266 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1267 tt_str_op("2012-01-11 15:38:58",OP_EQ
, timestr
);
1268 /* The output of format_local_iso_time will vary by timezone, and setting
1269 our timezone for testing purposes would be a nontrivial flaky pain.
1270 Skip this test for now.
1271 format_local_iso_time(timestr, tv.tv_sec);
1272 test_streq("2012-01-11 10:38:58", timestr);
1274 format_iso_time_nospace(timestr
, (time_t)tv
.tv_sec
);
1275 tt_str_op("2012-01-11T15:38:58",OP_EQ
, timestr
);
1276 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_LEN
);
1277 format_iso_time_nospace_usec(timestr
, &tv
);
1278 tt_str_op("2012-01-11T15:38:58.003060",OP_EQ
, timestr
);
1279 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_USEC_LEN
);
1282 /* This value is in range with 32 bit and 64 bit time_t */
1283 tv
.tv_sec
= (time_t)2080000000UL;
1284 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1285 tt_str_op("2035-11-30 01:46:40",OP_EQ
, timestr
);
1287 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1289 tv
.tv_sec
= (time_t)2150000000UL;
1291 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1292 CHECK_POSSIBLE_EINVAL();
1293 #if SIZEOF_TIME_T == 4
1294 /* format_iso_time should indicate failure on overflow, but it doesn't yet.
1295 * Hopefully #18480 will improve the failure semantics in this case.
1296 tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
1298 #elif SIZEOF_TIME_T == 8
1300 /* This SHOULD work on windows too; see bug #18665 */
1301 tt_str_op("2038-02-17 06:13:20",OP_EQ
, timestr
);
1303 #endif /* SIZEOF_TIME_T == 4 || ... */
1306 #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
1307 #undef CHECK_POSSIBLE_EINVAL
1310 teardown_capture_of_logs();
1314 test_util_parse_http_time(void *arg
)
1317 char b
[ISO_TIME_LEN
+1];
1321 format_iso_time(b, tor_timegm(&a_time)); \
1322 tt_str_op(b, OP_EQ, (s)); \
1326 /* Test parse_http_time */
1329 parse_http_time("", &a_time
));
1331 parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time
));
1333 parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time
));
1335 parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time
));
1337 parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time
));
1339 parse_http_time("Sunday, August the third", &a_time
));
1341 parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time
));
1344 parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time
));
1345 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1346 T("1994-08-04 00:48:22");
1348 parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time
));
1349 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1350 T("1994-08-04 00:48:22");
1352 parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time
));
1353 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1354 T("1994-08-04 00:48:22");
1356 parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time
));
1357 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1358 T("1994-08-04 00:48:22");
1360 parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time
));
1361 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1362 T("1994-08-04 00:48:22");
1364 parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time
));
1365 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1366 T("1994-08-04 00:48:22");
1367 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time
));
1368 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1369 T("1994-08-04 00:48:22");
1370 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time
));
1371 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1372 T("1994-08-04 00:48:22");
1373 tt_int_op(0,OP_EQ
, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time
));
1374 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1375 T("1994-08-04 00:48:22");
1376 tt_int_op(0,OP_EQ
,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time
));
1377 tt_int_op((time_t)1325376000UL,OP_EQ
, tor_timegm(&a_time
));
1378 T("2012-01-01 00:00:00");
1379 tt_int_op(0,OP_EQ
,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time
));
1380 tt_int_op((time_t)1356912000UL,OP_EQ
, tor_timegm(&a_time
));
1381 T("2012-12-31 00:00:00");
1383 /* This value is in range with 32 bit and 64 bit time_t */
1384 tt_int_op(0,OP_EQ
,parse_http_time("Fri, 30 Nov 2035 01:46:40 GMT", &a_time
));
1385 tt_int_op((time_t)2080000000UL,OP_EQ
, tor_timegm(&a_time
));
1386 T("2035-11-30 01:46:40");
1388 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1390 #if SIZEOF_TIME_T == 4
1391 /* parse_http_time should indicate failure on overflow, but it doesn't yet.
1392 * Hopefully #18480 will improve the failure semantics in this case. */
1393 setup_full_capture_of_logs(LOG_WARN
);
1394 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1395 tt_int_op((time_t)-1,OP_EQ
, tor_timegm(&a_time
));
1396 expect_single_log_msg_containing("does not fit in tor_timegm");
1397 teardown_capture_of_logs();
1398 #elif SIZEOF_TIME_T == 8
1399 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1400 tt_int_op((time_t)2150000000UL,OP_EQ
, tor_timegm(&a_time
));
1401 T("2038-02-17 06:13:20");
1402 #endif /* SIZEOF_TIME_T == 4 || ... */
1404 tt_int_op(-1,OP_EQ
, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time
));
1405 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-32 00:00:00 GMT", &a_time
));
1406 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 24:00:00 GMT", &a_time
));
1407 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:60:00 GMT", &a_time
));
1408 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59:62 GMT", &a_time
));
1409 tt_int_op(-1,OP_EQ
, parse_http_time("1969-03-30 23:59:59 GMT", &a_time
));
1410 tt_int_op(-1,OP_EQ
, parse_http_time("2011-00-30 23:59:59 GMT", &a_time
));
1411 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59", &a_time
));
1415 teardown_capture_of_logs();
1419 test_util_config_line(void *arg
)
1422 char *k
=NULL
, *v
=NULL
;
1425 /* Test parse_config_line_from_str */
1427 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
1429 "k3 \n" "\n" " \n" "#comment\n"
1430 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
1431 "kseven \"a quoted 'string\"\n"
1432 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
1433 "k9 a line that\\\n spans two lines.\n\n"
1434 "k10 more than\\\n one contin\\\nuation\n"
1435 "k11 \\\ncontinuation at the start\n"
1436 "k12 line with a\\\n#comment\n embedded\n"
1437 "k13\\\ncontinuation at the very start\n"
1438 "k14 a line that has a comment and # ends with a slash \\\n"
1439 "k15 this should be the next new line\n"
1440 "k16 a line that has a comment and # ends without a slash \n"
1441 "k17 this should be the next new line\n"
1445 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1446 tt_str_op(k
,OP_EQ
, "k");
1447 tt_str_op(v
,OP_EQ
, "v");
1448 tor_free(k
); tor_free(v
);
1449 tt_assert(!strcmpstart(str
, "key value with"));
1451 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1452 tt_str_op(k
,OP_EQ
, "key");
1453 tt_str_op(v
,OP_EQ
, "value with spaces");
1454 tor_free(k
); tor_free(v
);
1455 tt_assert(!strcmpstart(str
, "keykey"));
1457 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1458 tt_str_op(k
,OP_EQ
, "keykey");
1459 tt_str_op(v
,OP_EQ
, "val");
1460 tor_free(k
); tor_free(v
);
1461 tt_assert(!strcmpstart(str
, "k2\n"));
1463 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1464 tt_str_op(k
,OP_EQ
, "k2");
1465 tt_str_op(v
,OP_EQ
, "");
1466 tor_free(k
); tor_free(v
);
1467 tt_assert(!strcmpstart(str
, "k3 \n"));
1469 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1470 tt_str_op(k
,OP_EQ
, "k3");
1471 tt_str_op(v
,OP_EQ
, "");
1472 tor_free(k
); tor_free(v
);
1473 tt_assert(!strcmpstart(str
, "#comment"));
1475 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1476 tt_str_op(k
,OP_EQ
, "k4");
1477 tt_str_op(v
,OP_EQ
, "");
1478 tor_free(k
); tor_free(v
);
1479 tt_assert(!strcmpstart(str
, "k5#abc"));
1481 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1482 tt_str_op(k
,OP_EQ
, "k5");
1483 tt_str_op(v
,OP_EQ
, "");
1484 tor_free(k
); tor_free(v
);
1485 tt_assert(!strcmpstart(str
, "k6"));
1487 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1488 tt_str_op(k
,OP_EQ
, "k6");
1489 tt_str_op(v
,OP_EQ
, "val");
1490 tor_free(k
); tor_free(v
);
1491 tt_assert(!strcmpstart(str
, "kseven"));
1493 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1494 tt_str_op(k
,OP_EQ
, "kseven");
1495 tt_str_op(v
,OP_EQ
, "a quoted \'string");
1496 tor_free(k
); tor_free(v
);
1497 tt_assert(!strcmpstart(str
, "k8 "));
1499 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1500 tt_str_op(k
,OP_EQ
, "k8");
1501 tt_str_op(v
,OP_EQ
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
1502 tor_free(k
); tor_free(v
);
1504 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1505 tt_str_op(k
,OP_EQ
, "k9");
1506 tt_str_op(v
,OP_EQ
, "a line that spans two lines.");
1507 tor_free(k
); tor_free(v
);
1509 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1510 tt_str_op(k
,OP_EQ
, "k10");
1511 tt_str_op(v
,OP_EQ
, "more than one continuation");
1512 tor_free(k
); tor_free(v
);
1514 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1515 tt_str_op(k
,OP_EQ
, "k11");
1516 tt_str_op(v
,OP_EQ
, "continuation at the start");
1517 tor_free(k
); tor_free(v
);
1519 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1520 tt_str_op(k
,OP_EQ
, "k12");
1521 tt_str_op(v
,OP_EQ
, "line with a embedded");
1522 tor_free(k
); tor_free(v
);
1524 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1525 tt_str_op(k
,OP_EQ
, "k13");
1526 tt_str_op(v
,OP_EQ
, "continuation at the very start");
1527 tor_free(k
); tor_free(v
);
1529 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1530 tt_str_op(k
,OP_EQ
, "k14");
1531 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1532 tor_free(k
); tor_free(v
);
1534 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1535 tt_str_op(k
,OP_EQ
, "k15");
1536 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1537 tor_free(k
); tor_free(v
);
1539 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1540 tt_str_op(k
,OP_EQ
, "k16");
1541 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1542 tor_free(k
); tor_free(v
);
1544 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1545 tt_str_op(k
,OP_EQ
, "k17");
1546 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1547 tor_free(k
); tor_free(v
);
1549 tt_str_op(str
,OP_EQ
, "");
1557 test_util_config_line_quotes(void *arg
)
1563 char *k
=NULL
, *v
=NULL
;
1566 /* Test parse_config_line_from_str */
1568 strlcpy(buf1
, "kTrailingSpace \"quoted value\" \n"
1569 "kTrailingGarbage \"quoted value\"trailing garbage\n"
1571 strlcpy(buf2
, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
1573 strlcpy(buf3
, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
1575 strlcpy(buf4
, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
1579 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1580 tt_str_op(k
,OP_EQ
, "kTrailingSpace");
1581 tt_str_op(v
,OP_EQ
, "quoted value");
1582 tor_free(k
); tor_free(v
);
1584 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1585 tt_ptr_op(str
,OP_EQ
, NULL
);
1586 tor_free(k
); tor_free(v
);
1590 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1591 tt_ptr_op(str
,OP_EQ
, NULL
);
1592 tor_free(k
); tor_free(v
);
1596 const char *err
= NULL
;
1597 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1598 tt_ptr_op(str
,OP_EQ
, NULL
);
1599 tor_free(k
); tor_free(v
);
1600 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1605 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1606 tt_ptr_op(str
,OP_EQ
, NULL
);
1607 tor_free(k
); tor_free(v
);
1608 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1616 test_util_config_line_comment_character(void *arg
)
1619 char *k
=NULL
, *v
=NULL
;
1622 /* Test parse_config_line_from_str */
1624 strlcpy(buf
, "k1 \"# in quotes\"\n"
1625 "k2 some value # some comment\n"
1626 "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
1630 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1631 tt_str_op(k
,OP_EQ
, "k1");
1632 tt_str_op(v
,OP_EQ
, "# in quotes");
1633 tor_free(k
); tor_free(v
);
1635 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1636 tt_str_op(k
,OP_EQ
, "k2");
1637 tt_str_op(v
,OP_EQ
, "some value");
1638 tor_free(k
); tor_free(v
);
1640 tt_str_op(str
,OP_EQ
, "k3 /home/user/myTorNetwork#2\n");
1643 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1644 test_streq(k
, "k3");
1645 test_streq(v
, "/home/user/myTorNetwork#2");
1646 tor_free(k
); tor_free(v
);
1648 test_streq(str
, "");
1657 test_util_config_line_escaped_content(void *arg
)
1665 char *k
=NULL
, *v
=NULL
;
1668 /* Test parse_config_line_from_str */
1670 strlcpy(buf1
, "HexadecimalLower \"\\x2a\"\n"
1671 "HexadecimalUpper \"\\x2A\"\n"
1672 "HexadecimalUpperX \"\\X2A\"\n"
1676 "CarriageReturn \"\\r\"\n"
1677 "DoubleQuote \"\\\"\"\n"
1678 "SimpleQuote \"\\'\"\n"
1679 "Backslash \"\\\\\"\n"
1680 "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
1683 strlcpy(buf2
, "BrokenEscapedContent \"\\a\"\n"
1686 strlcpy(buf3
, "BrokenEscapedContent \"\\x\"\n"
1689 strlcpy(buf4
, "BrokenOctal \"\\8\"\n"
1692 strlcpy(buf5
, "BrokenHex \"\\xg4\"\n"
1695 strlcpy(buf6
, "BrokenEscape \"\\"
1700 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1701 tt_str_op(k
,OP_EQ
, "HexadecimalLower");
1702 tt_str_op(v
,OP_EQ
, "*");
1703 tor_free(k
); tor_free(v
);
1705 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1706 tt_str_op(k
,OP_EQ
, "HexadecimalUpper");
1707 tt_str_op(v
,OP_EQ
, "*");
1708 tor_free(k
); tor_free(v
);
1710 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1711 tt_str_op(k
,OP_EQ
, "HexadecimalUpperX");
1712 tt_str_op(v
,OP_EQ
, "*");
1713 tor_free(k
); tor_free(v
);
1715 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1716 tt_str_op(k
,OP_EQ
, "Octal");
1717 tt_str_op(v
,OP_EQ
, "*");
1718 tor_free(k
); tor_free(v
);
1720 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1721 tt_str_op(k
,OP_EQ
, "Newline");
1722 tt_str_op(v
,OP_EQ
, "\n");
1723 tor_free(k
); tor_free(v
);
1725 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1726 tt_str_op(k
,OP_EQ
, "Tab");
1727 tt_str_op(v
,OP_EQ
, "\t");
1728 tor_free(k
); tor_free(v
);
1730 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1731 tt_str_op(k
,OP_EQ
, "CarriageReturn");
1732 tt_str_op(v
,OP_EQ
, "\r");
1733 tor_free(k
); tor_free(v
);
1735 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1736 tt_str_op(k
,OP_EQ
, "DoubleQuote");
1737 tt_str_op(v
,OP_EQ
, "\"");
1738 tor_free(k
); tor_free(v
);
1740 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1741 tt_str_op(k
,OP_EQ
, "SimpleQuote");
1742 tt_str_op(v
,OP_EQ
, "'");
1743 tor_free(k
); tor_free(v
);
1745 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1746 tt_str_op(k
,OP_EQ
, "Backslash");
1747 tt_str_op(v
,OP_EQ
, "\\");
1748 tor_free(k
); tor_free(v
);
1750 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1751 tt_str_op(k
,OP_EQ
, "Mix");
1752 tt_str_op(v
,OP_EQ
, "This is a \"star\":\t'*'\nAnd second line");
1753 tor_free(k
); tor_free(v
);
1754 tt_str_op(str
,OP_EQ
, "");
1758 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1759 tt_ptr_op(str
,OP_EQ
, NULL
);
1760 tor_free(k
); tor_free(v
);
1764 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1765 tt_ptr_op(str
,OP_EQ
, NULL
);
1766 tor_free(k
); tor_free(v
);
1770 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1771 tt_ptr_op(str
,OP_EQ
, NULL
);
1772 tor_free(k
); tor_free(v
);
1777 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1778 tt_ptr_op(str
, OP_EQ
, NULL
);
1779 tor_free(k
); tor_free(v
);
1784 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1785 tt_ptr_op(str
,OP_EQ
, NULL
);
1786 tor_free(k
); tor_free(v
);
1788 /* more things to try. */
1790 strlcpy(buf1
, "Foo \"\\x9g\"\n", sizeof(buf1
));
1791 strlcpy(buf2
, "Foo \"\\xg0\"\n", sizeof(buf2
));
1792 strlcpy(buf3
, "Foo \"\\xf\"\n", sizeof(buf3
));
1794 strlcpy(buf4
, "Foo \"\\q\"\n", sizeof(buf4
));
1795 /* missing endquote */
1796 strlcpy(buf5
, "Foo \"hello\n", sizeof(buf5
));
1798 strlcpy(buf6
, "Foo \"hello\" world\n", sizeof(buf6
));
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 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1807 tt_ptr_op(str
,OP_EQ
, NULL
);
1808 tor_free(k
); tor_free(v
);
1811 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1812 tt_ptr_op(str
,OP_EQ
, NULL
);
1813 tor_free(k
); tor_free(v
);
1816 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1817 tt_ptr_op(str
,OP_EQ
, NULL
);
1818 tor_free(k
); tor_free(v
);
1822 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1823 tt_ptr_op(str
,OP_EQ
, NULL
);
1824 tor_free(k
); tor_free(v
);
1827 const char *err
= NULL
;
1828 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1829 tt_ptr_op(str
,OP_EQ
, NULL
);
1830 tor_free(k
); tor_free(v
);
1831 tt_str_op(err
,OP_EQ
, "Excess data after quoted string");
1839 test_util_config_line_crlf(void *arg
)
1841 char *k
=NULL
, *v
=NULL
;
1842 const char *err
= NULL
;
1846 "Hello \"nice big world\"\r\n";
1848 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1850 tt_str_op(k
,OP_EQ
,"Hello");
1851 tt_str_op(v
,OP_EQ
,"world");
1852 tt_ptr_op(err
, OP_EQ
, NULL
);
1853 tor_free(k
); tor_free(v
);
1855 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1857 tt_str_op(k
,OP_EQ
,"Hello");
1858 tt_str_op(v
,OP_EQ
,"nice big world");
1859 tt_ptr_op(err
, OP_EQ
, NULL
);
1860 tor_free(k
); tor_free(v
);
1861 tt_str_op(str
,OP_EQ
, "");
1864 tor_free(k
); tor_free(v
);
1869 test_util_expand_filename(void *arg
)
1874 setenv("HOME", "/home/itv", 1); /* For "internal test value" */
1876 str
= expand_filename("");
1877 tt_str_op("",OP_EQ
, str
);
1880 str
= expand_filename("/normal/path");
1881 tt_str_op("/normal/path",OP_EQ
, str
);
1884 str
= expand_filename("/normal/trailing/path/");
1885 tt_str_op("/normal/trailing/path/",OP_EQ
, str
);
1888 str
= expand_filename("~");
1889 tt_str_op("/home/itv/",OP_EQ
, str
);
1892 str
= expand_filename("$HOME/nodice");
1893 tt_str_op("$HOME/nodice",OP_EQ
, str
);
1896 str
= expand_filename("~/");
1897 tt_str_op("/home/itv/",OP_EQ
, str
);
1900 str
= expand_filename("~/foobarqux");
1901 tt_str_op("/home/itv/foobarqux",OP_EQ
, str
);
1904 str
= expand_filename("~/../../etc/passwd");
1905 tt_str_op("/home/itv/../../etc/passwd",OP_EQ
, str
);
1908 str
= expand_filename("~/trailing/");
1909 tt_str_op("/home/itv/trailing/",OP_EQ
, str
);
1911 /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
1912 have to somehow inject/fake the get_user_homedir call) */
1914 /* $HOME ending in a trailing slash */
1915 setenv("HOME", "/home/itv/", 1);
1917 str
= expand_filename("~");
1918 tt_str_op("/home/itv/",OP_EQ
, str
);
1921 str
= expand_filename("~/");
1922 tt_str_op("/home/itv/",OP_EQ
, str
);
1925 str
= expand_filename("~/foo");
1926 tt_str_op("/home/itv/foo",OP_EQ
, str
);
1929 /* Try with empty $HOME */
1931 setenv("HOME", "", 1);
1933 str
= expand_filename("~");
1934 tt_str_op("/",OP_EQ
, str
);
1937 str
= expand_filename("~/");
1938 tt_str_op("/",OP_EQ
, str
);
1941 str
= expand_filename("~/foobar");
1942 tt_str_op("/foobar",OP_EQ
, str
);
1945 /* Try with $HOME unset */
1949 str
= expand_filename("~");
1950 tt_str_op("/",OP_EQ
, str
);
1953 str
= expand_filename("~/");
1954 tt_str_op("/",OP_EQ
, str
);
1957 str
= expand_filename("~/foobar");
1958 tt_str_op("/foobar",OP_EQ
, str
);
1964 #endif /* !defined(_WIN32) */
1966 /** Test tor_escape_str_for_pt_args(). */
1968 test_util_escape_string_socks(void *arg
)
1970 char *escaped_string
= NULL
;
1972 /** Simple backslash escape. */
1974 escaped_string
= tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
1975 tt_assert(escaped_string
);
1976 tt_str_op(escaped_string
,OP_EQ
, "This is a backslash: \\\\");
1977 tor_free(escaped_string
);
1979 /** Simple semicolon escape. */
1980 escaped_string
= tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
1981 tt_assert(escaped_string
);
1982 tt_str_op(escaped_string
,OP_EQ
, "First rule:Do not use \\;");
1983 tor_free(escaped_string
);
1985 /** Empty string. */
1986 escaped_string
= tor_escape_str_for_pt_args("", ";\\");
1987 tt_assert(escaped_string
);
1988 tt_str_op(escaped_string
,OP_EQ
, "");
1989 tor_free(escaped_string
);
1991 /** Escape all characters. */
1992 escaped_string
= tor_escape_str_for_pt_args(";\\;\\", ";\\");
1993 tt_assert(escaped_string
);
1994 tt_str_op(escaped_string
,OP_EQ
, "\\;\\\\\\;\\\\");
1995 tor_free(escaped_string
);
1997 escaped_string
= tor_escape_str_for_pt_args(";", ";\\");
1998 tt_assert(escaped_string
);
1999 tt_str_op(escaped_string
,OP_EQ
, "\\;");
2000 tor_free(escaped_string
);
2003 tor_free(escaped_string
);
2007 test_util_string_is_key_value(void *ptr
)
2010 tt_assert(string_is_key_value(LOG_WARN
, "key=value"));
2011 tt_assert(string_is_key_value(LOG_WARN
, "k=v"));
2012 tt_assert(string_is_key_value(LOG_WARN
, "key="));
2013 tt_assert(string_is_key_value(LOG_WARN
, "x="));
2014 tt_assert(string_is_key_value(LOG_WARN
, "xx="));
2015 tt_assert(!string_is_key_value(LOG_WARN
, "=value"));
2016 tt_assert(!string_is_key_value(LOG_WARN
, "=x"));
2017 tt_assert(!string_is_key_value(LOG_WARN
, "="));
2020 /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
2025 /** Test basic string functionality. */
2027 test_util_strmisc(void *arg
)
2030 char *cp_tmp
= NULL
;
2032 /* Test strl operations */
2034 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 0));
2035 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 10));
2036 tt_str_op(buf
,OP_EQ
, "Hello");
2037 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 6));
2038 tt_str_op(buf
,OP_EQ
, "Hello");
2039 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 5));
2040 tt_str_op(buf
,OP_EQ
, "Hell");
2041 strlcpy(buf
, "Hello", sizeof(buf
));
2042 tt_int_op(10,OP_EQ
, strlcat(buf
, "Hello", 5));
2044 /* Test strstrip() */
2045 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
2046 tor_strstrip(buf
, ",!");
2047 tt_str_op(buf
,OP_EQ
, "Testing 1 2 3");
2048 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
2049 tor_strstrip(buf
, "!? ");
2050 tt_str_op(buf
,OP_EQ
, "Testing123");
2051 strlcpy(buf
, "!!!Testing 1 2 3??", sizeof(buf
));
2052 tor_strstrip(buf
, "!? ");
2053 tt_str_op(buf
,OP_EQ
, "Testing123");
2056 /* Returning -1 when there's not enough room in the output buffer */
2057 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 0, "Foo"));
2058 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 2, "Foo"));
2059 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 3, "Foo"));
2060 tt_int_op(-1,OP_NE
, tor_snprintf(buf
, 4, "Foo"));
2061 /* Always NUL-terminate the output */
2062 tor_snprintf(buf
, 5, "abcdef");
2063 tt_int_op(0,OP_EQ
, buf
[4]);
2064 tor_snprintf(buf
, 10, "abcdef");
2065 tt_int_op(0,OP_EQ
, buf
[6]);
2067 tor_snprintf(buf
, sizeof(buf
), "x!%"PRIu64
"!x",
2068 (UINT64_C(12345678901)));
2069 tt_str_op("x!12345678901!x",OP_EQ
, buf
);
2071 /* Test str{,case}cmpstart */
2072 tt_assert(strcmpstart("abcdef", "abcdef")==0);
2073 tt_assert(strcmpstart("abcdef", "abc")==0);
2074 tt_assert(strcmpstart("abcdef", "abd")<0);
2075 tt_assert(strcmpstart("abcdef", "abb")>0);
2076 tt_assert(strcmpstart("ab", "abb")<0);
2077 tt_assert(strcmpstart("ab", "")==0);
2078 tt_assert(strcmpstart("ab", "ab ")<0);
2079 tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
2080 tt_assert(strcasecmpstart("abcDeF", "abc")==0);
2081 tt_assert(strcasecmpstart("abcdef", "Abd")<0);
2082 tt_assert(strcasecmpstart("Abcdef", "abb")>0);
2083 tt_assert(strcasecmpstart("ab", "Abb")<0);
2084 tt_assert(strcasecmpstart("ab", "")==0);
2085 tt_assert(strcasecmpstart("ab", "ab ")<0);
2087 /* Test str{,case}cmpend */
2088 tt_assert(strcmpend("abcdef", "abcdef")==0);
2089 tt_assert(strcmpend("abcdef", "def")==0);
2090 tt_assert(strcmpend("abcdef", "deg")<0);
2091 tt_assert(strcmpend("abcdef", "dee")>0);
2092 tt_assert(strcmpend("ab", "aab")>0);
2093 tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
2094 tt_assert(strcasecmpend("abcdef", "dEF")==0);
2095 tt_assert(strcasecmpend("abcdef", "Deg")<0);
2096 tt_assert(strcasecmpend("abcDef", "dee")>0);
2097 tt_assert(strcasecmpend("AB", "abb")<0);
2099 /* Test digest_is_zero */
2102 tt_assert(tor_digest_is_zero(buf
));
2104 tt_assert(!tor_digest_is_zero(buf
));
2106 /* Test mem_is_zero */
2109 tt_assert(tor_mem_is_zero(buf
, 10));
2110 tt_assert(tor_mem_is_zero(buf
, 20));
2111 tt_assert(tor_mem_is_zero(buf
, 128));
2112 tt_assert(!tor_mem_is_zero(buf
, 129));
2113 buf
[60] = (char)255;
2114 tt_assert(!tor_mem_is_zero(buf
, 128));
2116 tt_assert(!tor_mem_is_zero(buf
, 10));
2118 /* Test 'escaped' */
2119 tt_ptr_op(escaped(NULL
), OP_EQ
, NULL
);
2120 tt_str_op("\"\"",OP_EQ
, escaped(""));
2121 tt_str_op("\"abcd\"",OP_EQ
, escaped("abcd"));
2122 tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ
, escaped("\\ \n\r\t\"'"));
2123 tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ
,
2124 escaped("unnecessary \'backslashes\'"));
2125 /* Non-printable characters appear as octal */
2126 tt_str_op("\"z\\001abc\\277d\"",OP_EQ
, escaped("z\001abc\277d"));
2127 tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ
, escaped("z\xde\xad\x20;foo"));
2129 /* Other cases of esc_for_log{,_len} */
2130 cp_tmp
= esc_for_log(NULL
);
2131 tt_str_op(cp_tmp
, OP_EQ
, "(null)");
2133 cp_tmp
= esc_for_log_len("abcdefg", 3);
2134 tt_str_op(cp_tmp
, OP_EQ
, "\"abc\"");
2136 cp_tmp
= esc_for_log_len("abcdefg", 100);
2137 tt_str_op(cp_tmp
, OP_EQ
, "\"abcdefg\"");
2140 /* Test strndup and memdup */
2142 const char *s
= "abcdefghijklmnopqrstuvwxyz";
2143 cp_tmp
= tor_strndup(s
, 30);
2144 tt_str_op(cp_tmp
,OP_EQ
, s
); /* same string, */
2145 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2148 cp_tmp
= tor_strndup(s
, 5);
2149 tt_str_op(cp_tmp
,OP_EQ
, "abcde");
2152 s
= "a\0b\0c\0d\0e\0";
2153 cp_tmp
= tor_memdup(s
,10);
2154 tt_mem_op(cp_tmp
,OP_EQ
, s
, 10); /* same ram, */
2155 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2159 /* Test str-foo functions */
2160 cp_tmp
= tor_strdup("abcdef");
2161 tt_assert(tor_strisnonupper(cp_tmp
));
2163 tt_assert(!tor_strisnonupper(cp_tmp
));
2164 tor_strupper(cp_tmp
);
2165 tt_str_op(cp_tmp
,OP_EQ
, "ABCDEF");
2166 tor_strlower(cp_tmp
);
2167 tt_str_op(cp_tmp
,OP_EQ
, "abcdef");
2168 tt_assert(tor_strisnonupper(cp_tmp
));
2169 tt_assert(tor_strisprint(cp_tmp
));
2171 tt_assert(!tor_strisprint(cp_tmp
));
2174 /* Test memmem and memstr */
2176 const char *haystack
= "abcde";
2177 tt_ptr_op(tor_memmem(haystack
, 5, "ef", 2), OP_EQ
, NULL
);
2178 tt_ptr_op(tor_memmem(haystack
, 5, "cd", 2),OP_EQ
, haystack
+ 2);
2179 tt_ptr_op(tor_memmem(haystack
, 5, "cde", 3),OP_EQ
, haystack
+ 2);
2180 tt_ptr_op(tor_memmem(haystack
, 4, "cde", 3), OP_EQ
, NULL
);
2181 haystack
= "ababcad";
2182 tt_ptr_op(tor_memmem(haystack
, 7, "abc", 3),OP_EQ
, haystack
+ 2);
2183 tt_ptr_op(tor_memmem(haystack
, 7, "ad", 2),OP_EQ
, haystack
+ 5);
2184 tt_ptr_op(tor_memmem(haystack
, 7, "cad", 3),OP_EQ
, haystack
+ 4);
2185 tt_ptr_op(tor_memmem(haystack
, 7, "dadad", 5), OP_EQ
, NULL
);
2186 tt_ptr_op(tor_memmem(haystack
, 7, "abcdefghij", 10), OP_EQ
, NULL
);
2188 tt_ptr_op(tor_memstr(haystack
, 7, "abc"),OP_EQ
, haystack
+ 2);
2189 tt_ptr_op(tor_memstr(haystack
, 7, "cad"),OP_EQ
, haystack
+ 4);
2190 tt_ptr_op(tor_memstr(haystack
, 6, "cad"), OP_EQ
, NULL
);
2191 tt_ptr_op(tor_memstr(haystack
, 7, "cadd"), OP_EQ
, NULL
);
2192 tt_ptr_op(tor_memstr(haystack
, 7, "fe"), OP_EQ
, NULL
);
2193 tt_ptr_op(tor_memstr(haystack
, 7, "ababcade"), OP_EQ
, NULL
);
2198 char binary_data
[68];
2200 for (idx
= 0; idx
< sizeof(binary_data
); ++idx
)
2201 binary_data
[idx
] = idx
;
2202 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2203 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2204 tt_str_op(hex_str(binary_data
, 17),OP_EQ
,
2205 "000102030405060708090A0B0C0D0E0F10");
2206 tt_str_op(hex_str(binary_data
, 32),OP_EQ
,
2207 "000102030405060708090A0B0C0D0E0F"
2208 "101112131415161718191A1B1C1D1E1F");
2209 tt_str_op(hex_str(binary_data
, 34),OP_EQ
,
2210 "000102030405060708090A0B0C0D0E0F"
2211 "101112131415161718191A1B1C1D1E1F");
2212 /* Repeat these tests for shorter strings after longer strings
2213 have been tried, to make sure we're correctly terminating strings */
2214 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2215 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2218 /* Test strcmp_opt */
2219 tt_int_op(strcmp_opt("", "foo"), OP_LT
, 0);
2220 tt_int_op(strcmp_opt("", ""), OP_EQ
, 0);
2221 tt_int_op(strcmp_opt("foo", ""), OP_GT
, 0);
2223 tt_int_op(strcmp_opt(NULL
, ""), OP_LT
, 0);
2224 tt_int_op(strcmp_opt(NULL
, NULL
), OP_EQ
, 0);
2225 tt_int_op(strcmp_opt("", NULL
), OP_GT
, 0);
2227 tt_int_op(strcmp_opt(NULL
, "foo"), OP_LT
, 0);
2228 tt_int_op(strcmp_opt("foo", NULL
), OP_GT
, 0);
2230 /* Test strcmp_len */
2231 tt_int_op(strcmp_len("foo", "bar", 3), OP_GT
, 0);
2232 tt_int_op(strcmp_len("foo", "bar", 2), OP_LT
, 0);
2233 tt_int_op(strcmp_len("foo2", "foo1", 4), OP_GT
, 0);
2234 tt_int_op(strcmp_len("foo2", "foo1", 3), OP_LT
, 0); /* Really stop at len */
2235 tt_int_op(strcmp_len("foo2", "foo", 3), OP_EQ
, 0); /* Really stop at len */
2236 tt_int_op(strcmp_len("blah", "", 4), OP_GT
, 0);
2237 tt_int_op(strcmp_len("blah", "", 0), OP_EQ
, 0);
2244 test_util_parse_integer(void *arg
)
2250 /* Test parse_long */
2251 /* Empty/zero input */
2252 tt_int_op(0L,OP_EQ
, tor_parse_long("",10,0,100,&i
,NULL
));
2253 tt_int_op(0,OP_EQ
, i
);
2254 tt_int_op(0L,OP_EQ
, tor_parse_long("0",10,0,100,&i
,NULL
));
2255 tt_int_op(1,OP_EQ
, i
);
2257 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,100,&i
,NULL
));
2258 tt_int_op(1,OP_EQ
, i
);
2259 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,10,&i
,NULL
));
2260 tt_int_op(1,OP_EQ
, i
);
2261 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,10,100,&i
,NULL
));
2262 tt_int_op(1,OP_EQ
, i
);
2263 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,100,&i
,NULL
));
2264 tt_int_op(1,OP_EQ
, i
);
2265 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,0,&i
,NULL
));
2266 tt_int_op(1,OP_EQ
, i
);
2267 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-50,0,&i
,NULL
));
2268 tt_int_op(1,OP_EQ
, i
);
2270 tt_int_op(0L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,NULL
));
2271 tt_int_op(0,OP_EQ
, i
);
2272 tt_int_op(0L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,NULL
));
2273 tt_int_op(0,OP_EQ
, i
);
2274 tt_int_op(10L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,&cp
));
2275 tt_int_op(1,OP_EQ
, i
);
2276 tt_str_op(cp
,OP_EQ
, "m");
2277 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,&cp
));
2278 tt_int_op(1,OP_EQ
, i
);
2279 tt_str_op(cp
,OP_EQ
, " plus garbage");
2280 /* Illogical min max */
2281 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,4,&i
,NULL
));
2282 tt_int_op(0,OP_EQ
, i
);
2283 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,100,-100,&i
,NULL
));
2284 tt_int_op(0,OP_EQ
, i
);
2286 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,100,&i
,NULL
));
2287 tt_int_op(0,OP_EQ
, i
);
2288 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,0,100,&i
,NULL
));
2289 tt_int_op(0,OP_EQ
, i
);
2290 /* Base different than 10 */
2291 tt_int_op(2L,OP_EQ
, tor_parse_long("10",2,0,100,NULL
,NULL
));
2292 tt_int_op(0L,OP_EQ
, tor_parse_long("2",2,0,100,NULL
,NULL
));
2293 tt_int_op(68284L,OP_EQ
, tor_parse_long("10abc",16,0,70000,NULL
,NULL
));
2294 tt_int_op(68284L,OP_EQ
, tor_parse_long("10ABC",16,0,70000,NULL
,NULL
));
2295 tt_int_op(0L,OP_EQ
, tor_parse_long("10",-2,0,100,NULL
,NULL
));
2296 tt_int_op(0,OP_EQ
, tor_parse_long("10ABC",-1,0,70000,&i
,NULL
));
2297 tt_int_op(i
,OP_EQ
, 0);
2299 /* Test parse_ulong */
2300 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("",10,0,100,NULL
,NULL
));
2301 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("0",10,0,100,NULL
,NULL
));
2302 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
2303 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
2304 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,10,NULL
,NULL
));
2305 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,10,100,NULL
,NULL
));
2306 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("8",8,0,100,NULL
,NULL
));
2307 tt_int_op(50UL,OP_EQ
, tor_parse_ulong("50",10,50,100,NULL
,NULL
));
2308 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,NULL
,NULL
));
2309 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("50",-1,50,100,&i
,NULL
));
2310 tt_int_op(0,OP_EQ
, i
);
2311 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,&i
,NULL
));
2312 tt_int_op(0,OP_EQ
, i
);
2314 /* Test parse_uint64 */
2315 tt_assert(UINT64_C(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
2316 tt_int_op(1,OP_EQ
, i
);
2317 tt_str_op(cp
,OP_EQ
, " x");
2318 tt_assert(UINT64_C(12345678901) ==
2319 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
2320 tt_int_op(1,OP_EQ
, i
);
2321 tt_str_op(cp
,OP_EQ
, "");
2322 tt_assert(UINT64_C(0) ==
2323 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
2324 tt_int_op(0,OP_EQ
, i
);
2325 tt_assert(UINT64_C(0) ==
2326 tor_parse_uint64("123",-1,0,INT32_MAX
, &i
, &cp
));
2327 tt_int_op(0,OP_EQ
, i
);
2330 /* Test parse_double */
2331 double d
= tor_parse_double("10", 0, (double)UINT64_MAX
,&i
,NULL
);
2332 tt_int_op(1,OP_EQ
, i
);
2333 tt_assert(((uint64_t)d
) == 10);
2334 d
= tor_parse_double("0", 0, (double)UINT64_MAX
,&i
,NULL
);
2335 tt_int_op(1,OP_EQ
, i
);
2336 tt_assert(((uint64_t)d
) == 0);
2337 d
= tor_parse_double(" ", 0, (double)UINT64_MAX
,&i
,NULL
);
2338 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2339 tt_int_op(0,OP_EQ
, i
);
2340 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,NULL
);
2341 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2342 tt_int_op(0,OP_EQ
, i
);
2343 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,&cp
);
2344 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2345 tt_int_op(1,OP_EQ
, i
);
2346 d
= tor_parse_double("-.0", 0, (double)UINT64_MAX
,&i
,NULL
);
2347 tt_int_op(1,OP_EQ
, i
);
2348 tt_assert(((uint64_t)d
) == 0);
2349 d
= tor_parse_double("-10", -100.0, 100.0,&i
,NULL
);
2350 tt_int_op(1,OP_EQ
, i
);
2351 tt_double_op(fabs(d
- -10.0),OP_LT
, 1E-12);
2355 /* Test tor_parse_* where we overflow/underflow the underlying type. */
2356 /* This string should overflow 64-bit ints. */
2357 #define TOOBIG "100000000000000000000000000"
2358 tt_int_op(0L, OP_EQ
,
2359 tor_parse_long(TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2360 tt_int_op(i
,OP_EQ
, 0);
2362 tor_parse_long("-"TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2363 tt_int_op(i
,OP_EQ
, 0);
2364 tt_int_op(0UL,OP_EQ
, tor_parse_ulong(TOOBIG
, 10, 0, ULONG_MAX
, &i
, NULL
));
2365 tt_int_op(i
,OP_EQ
, 0);
2366 tt_u64_op(UINT64_C(0), OP_EQ
, tor_parse_uint64(TOOBIG
, 10,
2367 0, UINT64_MAX
, &i
, NULL
));
2368 tt_int_op(i
,OP_EQ
, 0);
2375 test_util_pow2(void *arg
)
2377 /* Test tor_log2(). */
2379 tt_int_op(tor_log2(64),OP_EQ
, 6);
2380 tt_int_op(tor_log2(65),OP_EQ
, 6);
2381 tt_int_op(tor_log2(63),OP_EQ
, 5);
2382 /* incorrect mathematically, but as specified: */
2383 tt_int_op(tor_log2(0),OP_EQ
, 0);
2384 tt_int_op(tor_log2(1),OP_EQ
, 0);
2385 tt_int_op(tor_log2(2),OP_EQ
, 1);
2386 tt_int_op(tor_log2(3),OP_EQ
, 1);
2387 tt_int_op(tor_log2(4),OP_EQ
, 2);
2388 tt_int_op(tor_log2(5),OP_EQ
, 2);
2389 tt_int_op(tor_log2(UINT64_C(40000000000000000)),OP_EQ
, 55);
2390 tt_int_op(tor_log2(UINT64_MAX
),OP_EQ
, 63);
2392 /* Test round_to_power_of_2 */
2393 tt_u64_op(round_to_power_of_2(120), OP_EQ
, 128);
2394 tt_u64_op(round_to_power_of_2(128), OP_EQ
, 128);
2395 tt_u64_op(round_to_power_of_2(130), OP_EQ
, 128);
2396 tt_u64_op(round_to_power_of_2(UINT64_C(40000000000000000)), OP_EQ
,
2398 tt_u64_op(round_to_power_of_2(UINT64_C(0xffffffffffffffff)), OP_EQ
,
2400 tt_u64_op(round_to_power_of_2(0), OP_EQ
, 1);
2401 tt_u64_op(round_to_power_of_2(1), OP_EQ
, 1);
2402 tt_u64_op(round_to_power_of_2(2), OP_EQ
, 2);
2403 tt_u64_op(round_to_power_of_2(3), OP_EQ
, 2);
2404 tt_u64_op(round_to_power_of_2(4), OP_EQ
, 4);
2405 tt_u64_op(round_to_power_of_2(5), OP_EQ
, 4);
2406 tt_u64_op(round_to_power_of_2(6), OP_EQ
, 4);
2407 tt_u64_op(round_to_power_of_2(7), OP_EQ
, 8);
2414 test_util_compress_impl(compress_method_t method
)
2416 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
;
2419 tt_assert(tor_compress_supports_method(method
));
2421 if (method
!= NO_METHOD
) {
2422 tt_ptr_op(tor_compress_version_str(method
), OP_NE
, NULL
);
2423 tt_ptr_op(tor_compress_header_version_str(method
), OP_NE
, NULL
);
2426 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
2427 tt_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
2429 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1, method
));
2430 tt_ptr_op(buf2
, OP_NE
, NULL
);
2431 if (method
== NO_METHOD
) {
2432 // The identity transform doesn't actually compress, and it isn't
2433 // detectable as "the identity transform."
2434 tt_int_op(len1
, OP_EQ
, strlen(buf1
)+1);
2435 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, UNKNOWN_METHOD
);
2437 tt_int_op(len1
, OP_LT
, strlen(buf1
));
2438 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, method
);
2441 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
, method
, 1, LOG_INFO
));
2442 tt_ptr_op(buf3
, OP_NE
, NULL
);
2443 tt_int_op(strlen(buf1
) + 1, OP_EQ
, len2
);
2444 tt_str_op(buf1
, OP_EQ
, buf3
);
2445 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2447 /* Check whether we can uncompress concatenated, compressed strings. */
2449 buf2
= tor_reallocarray(buf2
, len1
, 2);
2450 memcpy(buf2
+len1
, buf2
, len1
);
2451 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
*2, method
, 1, LOG_INFO
));
2452 tt_int_op((strlen(buf1
)+1)*2, OP_EQ
, len2
);
2453 tt_mem_op(buf3
, OP_EQ
,
2454 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
2455 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
2456 (strlen(buf1
)+1)*2);
2457 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2459 /* Check whether we can uncompress partial strings */
2465 size_t b1len
= 1<<10;
2466 if (method
== ZSTD_METHOD
) {
2467 // zstd needs a big input before it starts generating output that it
2468 // can partially decompress.
2471 buf1
= tor_malloc(b1len
);
2472 crypto_rand(buf1
, b1len
);
2473 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, b1len
, method
));
2474 tt_int_op(len1
, OP_GT
, 16);
2475 /* when we allow an incomplete output we should succeed.*/
2476 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2477 method
, 0, LOG_INFO
));
2478 tt_int_op(len2
, OP_GT
, 5);
2479 tt_int_op(len2
, OP_LE
, len1
);
2480 tt_assert(fast_memeq(buf1
, buf3
, len2
));
2481 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2483 /* when we demand a complete output from a real compression method, this
2486 if (method
!= NO_METHOD
) {
2487 tt_assert(tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2488 method
, 1, LOG_INFO
));
2489 tt_ptr_op(buf3
, OP_EQ
, NULL
);
2499 test_util_compress_stream_impl(compress_method_t method
,
2500 compression_level_t level
)
2502 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
2506 tor_compress_state_t
*state
= NULL
;
2507 state
= tor_compress_new(1, method
, level
);
2509 cp1
= buf1
= tor_malloc(1024);
2511 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
2513 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0),
2514 OP_EQ
, TOR_COMPRESS_OK
);
2515 tt_int_op(0, OP_EQ
, len2
); /* Make sure we compressed it all. */
2516 tt_assert(cp1
> buf1
);
2520 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1),
2521 OP_EQ
, TOR_COMPRESS_DONE
);
2522 tt_int_op(0, OP_EQ
, len2
);
2523 if (method
== NO_METHOD
) {
2524 tt_ptr_op(cp1
, OP_EQ
, cp2
);
2526 tt_assert(cp1
> cp2
); /* Make sure we really added something. */
2529 tt_int_op(tor_compress_state_size(state
), OP_GT
, 0);
2531 tt_assert(!tor_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
2532 method
, 1, LOG_WARN
));
2533 /* Make sure it compressed right. */
2534 tt_str_op(buf3
, OP_EQ
, "ABCDEFGHIJABCDEFGHIJ");
2535 tt_int_op(21, OP_EQ
, len2
);
2539 tor_compress_free(state
);
2545 /** Setup function for compression tests: handles x-zstd:nostatic
2548 compression_test_setup(const struct testcase_t
*testcase
)
2550 tor_assert(testcase
->setup_data
);
2551 tor_assert(testcase
->setup_data
!= (void*)TT_SKIP
);
2552 const char *methodname
= testcase
->setup_data
;
2554 if (!strcmp(methodname
, "x-zstd:nostatic")) {
2555 methodname
= "x-zstd";
2556 tor_zstd_set_static_apis_disabled_for_testing(1);
2559 return (void *)methodname
;
2562 /** Cleanup for compression tests: disables nostatic */
2564 compression_test_cleanup(const struct testcase_t
*testcase
, void *ptr
)
2568 tor_zstd_set_static_apis_disabled_for_testing(0);
2572 static const struct testcase_setup_t compress_setup
= {
2573 compression_test_setup
, compression_test_cleanup
2576 /** Run unit tests for compression functions */
2578 test_util_compress(void *arg
)
2580 const char *methodname
= arg
;
2581 tt_assert(methodname
);
2583 compress_method_t method
= compression_method_get_by_name(methodname
);
2584 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2586 if (! tor_compress_supports_method(method
)) {
2590 compression_level_t levels
[] = {
2597 test_util_compress_impl(method
);
2599 for (unsigned l
= 0; l
< ARRAY_LENGTH(levels
); ++l
) {
2600 compression_level_t level
= levels
[l
];
2601 test_util_compress_stream_impl(method
, level
);
2608 test_util_decompress_concatenated_impl(compress_method_t method
)
2611 char *c1
= NULL
, *c2
= NULL
, *c3
= NULL
;
2612 char *result
= NULL
;
2613 size_t sz1
, sz2
, sz3
, szr
;
2616 crypto_rand(input
, sizeof(input
));
2618 /* Compress the input in two chunks. */
2619 r
= tor_compress(&c1
, &sz1
, input
, 2048, method
);
2620 tt_int_op(r
, OP_EQ
, 0);
2621 r
= tor_compress(&c2
, &sz2
, input
+2048, 2048, method
);
2622 tt_int_op(r
, OP_EQ
, 0);
2624 /* concatenate the chunks. */
2626 c3
= tor_malloc(sz3
);
2627 memcpy(c3
, c1
, sz1
);
2628 memcpy(c3
+sz1
, c2
, sz2
);
2630 /* decompress the concatenated result */
2631 r
= tor_uncompress(&result
, &szr
, c3
, sz3
, method
, 0, LOG_WARN
);
2632 tt_int_op(r
, OP_EQ
, 0);
2633 tt_int_op(szr
, OP_EQ
, sizeof(input
));
2634 tt_mem_op(result
, OP_EQ
, input
, sizeof(input
));
2644 test_util_decompress_concatenated(void *arg
)
2646 const char *methodname
= arg
;
2647 tt_assert(methodname
);
2649 compress_method_t method
= compression_method_get_by_name(methodname
);
2650 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2651 if (! tor_compress_supports_method(method
)) {
2655 test_util_decompress_concatenated_impl(method
);
2661 test_util_decompress_junk_impl(compress_method_t method
)
2664 char *result
= NULL
, *result2
= NULL
;
2665 size_t szr
, szr2
, sz
;
2668 /* This shouldn't be a compressed string according to any method. */
2669 strlcpy(input
, "This shouldn't be a compressed string by any means.",
2672 setup_capture_of_logs(LOG_WARN
);
2673 r
= tor_uncompress(&result
, &szr
, input
, sz
, method
, 0, LOG_WARN
);
2674 tt_int_op(r
, OP_EQ
, -1);
2675 tt_ptr_op(result
, OP_EQ
, NULL
);
2676 expect_log_msg_containing("Error while uncompressing data: bad input?");
2677 mock_clean_saved_logs();
2679 /* Now try again, with a compressed object that starts out good and turns to
2681 crypto_rand(input
, sizeof(input
));
2682 r
= tor_compress(&result
, &szr
, input
, sizeof(input
), method
);
2683 tt_int_op(r
, OP_EQ
, 0);
2684 crypto_rand(result
+szr
/2, szr
-(szr
/2)); // trash the 2nd half of the result
2685 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2686 tt_int_op(r
, OP_EQ
, -1);
2687 expect_log_msg_containing("Error while uncompressing data: bad input?");
2690 teardown_capture_of_logs();
2696 test_util_decompress_junk(void *arg
)
2698 const char *methodname
= arg
;
2699 tt_assert(methodname
);
2701 compress_method_t method
= compression_method_get_by_name(methodname
);
2702 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2703 if (! tor_compress_supports_method(method
)) {
2707 test_util_decompress_junk_impl(method
);
2712 /* mock replacement for tor_compress_is_compression_bomb that doesn't
2713 * believe in compression bombs. */
2715 mock_is_never_compression_bomb(size_t in
, size_t out
)
2723 test_util_decompress_dos_impl(compress_method_t method
)
2726 char *result
= NULL
, *result2
= NULL
;
2730 const size_t big
= 1024*1024;
2731 /* one megabyte of 0s. */
2732 input
= tor_malloc_zero(big
);
2734 /* Compress it into "result": it should fail. */
2735 setup_full_capture_of_logs(LOG_WARN
);
2736 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2737 tt_int_op(r
, OP_EQ
, -1);
2738 expect_log_msg_containing(
2739 "other Tors would think this was a compression bomb");
2740 teardown_capture_of_logs();
2742 /* Try again, but this time suppress compression-bomb detection */
2743 MOCK(tor_compress_is_compression_bomb
, mock_is_never_compression_bomb
);
2744 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2745 UNMOCK(tor_compress_is_compression_bomb
);
2746 tt_int_op(r
, OP_EQ
, 0);
2747 tt_ptr_op(result
, OP_NE
, NULL
);
2749 /* We should refuse to uncomrpess it again, since it looks like a
2750 * compression bomb. */
2751 setup_capture_of_logs(LOG_WARN
);
2752 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2753 tt_int_op(r
, OP_EQ
, -1);
2754 expect_log_msg_containing("bomb; abandoning stream");
2757 teardown_capture_of_logs();
2764 test_util_decompress_dos(void *arg
)
2766 const char *methodname
= arg
;
2767 tt_assert(methodname
);
2769 compress_method_t method
= compression_method_get_by_name(methodname
);
2770 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2771 if (! tor_compress_supports_method(method
)) {
2775 test_util_decompress_dos_impl(method
);
2781 test_util_gzip_compression_bomb(void *arg
)
2783 /* A 'compression bomb' is a very small object that uncompresses to a huge
2784 * one. Most compression formats support them, but they can be a DOS vector.
2785 * In Tor we try not to generate them, and we don't accept them.
2788 size_t one_million
= 1<<20;
2789 char *one_mb
= tor_malloc_zero(one_million
);
2790 char *result
= NULL
;
2791 size_t result_len
= 0;
2792 tor_compress_state_t
*state
= NULL
;
2794 /* Make sure we can't produce a compression bomb */
2795 setup_full_capture_of_logs(LOG_WARN
);
2796 tt_int_op(-1, OP_EQ
, tor_compress(&result
, &result_len
,
2797 one_mb
, one_million
,
2799 expect_single_log_msg_containing(
2800 "We compressed something and got an insanely high "
2801 "compression factor; other Tors would think this "
2802 "was a compression bomb.");
2803 teardown_capture_of_logs();
2805 /* Here's a compression bomb that we made manually. */
2806 const char compression_bomb
[1039] =
2807 { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2,
2808 0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ };
2809 tt_int_op(-1, OP_EQ
, tor_uncompress(&result
, &result_len
,
2810 compression_bomb
, 1039,
2811 ZLIB_METHOD
, 0, LOG_WARN
));
2813 /* Now try streaming that. */
2814 state
= tor_compress_new(0, ZLIB_METHOD
, HIGH_COMPRESSION
);
2815 tor_compress_output_t r
;
2816 const char *inp
= compression_bomb
;
2817 size_t inlen
= 1039;
2819 char *outp
= one_mb
;
2820 size_t outleft
= 4096; /* small on purpose */
2821 r
= tor_compress_process(state
, &outp
, &outleft
, &inp
, &inlen
, 0);
2822 tt_int_op(inlen
, OP_NE
, 0);
2823 } while (r
== TOR_COMPRESS_BUFFER_FULL
);
2825 tt_int_op(r
, OP_EQ
, TOR_COMPRESS_ERROR
);
2829 tor_compress_free(state
);
2832 /** Run unit tests for mmap() wrapper functionality. */
2834 test_util_mmap(void *arg
)
2836 char *fname1
= tor_strdup(get_fname("mapped_1"));
2837 char *fname2
= tor_strdup(get_fname("mapped_2"));
2838 char *fname3
= tor_strdup(get_fname("mapped_3"));
2839 const size_t buflen
= 17000;
2840 char *buf
= tor_malloc(17000);
2841 tor_mmap_t
*mapping
= NULL
;
2844 crypto_rand(buf
, buflen
);
2846 mapping
= tor_mmap_file(fname1
);
2847 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2849 write_str_to_file(fname1
, "Short file.", 1);
2851 mapping
= tor_mmap_file(fname1
);
2853 tt_int_op(mapping
->size
,OP_EQ
, strlen("Short file."));
2854 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
2856 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2858 tt_assert(unlink(fname1
) == 0);
2860 /* make sure we can unlink. */
2861 tt_assert(unlink(fname1
) == 0);
2862 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
2863 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2865 #endif /* defined(_WIN32) */
2867 /* Now a zero-length file. */
2868 write_str_to_file(fname1
, "", 1);
2869 mapping
= tor_mmap_file(fname1
);
2870 tt_ptr_op(mapping
,OP_EQ
, NULL
);
2871 tt_int_op(ERANGE
,OP_EQ
, errno
);
2874 /* Make sure that we fail to map a no-longer-existent file. */
2875 mapping
= tor_mmap_file(fname1
);
2876 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2878 /* Now try a big file that stretches across a few pages and isn't aligned */
2879 write_bytes_to_file(fname2
, buf
, buflen
, 1);
2880 mapping
= tor_mmap_file(fname2
);
2882 tt_int_op(mapping
->size
,OP_EQ
, buflen
);
2883 tt_mem_op(mapping
->data
,OP_EQ
, buf
, buflen
);
2884 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2887 /* Now try a big aligned file. */
2888 write_bytes_to_file(fname3
, buf
, 16384, 1);
2889 mapping
= tor_mmap_file(fname3
);
2891 tt_int_op(mapping
->size
,OP_EQ
, 16384);
2892 tt_mem_op(mapping
->data
,OP_EQ
, buf
, 16384);
2893 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2906 tor_munmap_file(mapping
);
2909 /** Run unit tests for escaping/unescaping data for use by controllers. */
2911 test_util_control_formats(void *arg
)
2915 "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
2919 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
2920 tt_str_op(out
,OP_EQ
,
2921 ".This is a test\nof the emergency \n.system.\n\rZ.\n");
2922 tt_int_op(sz
,OP_EQ
, strlen(out
));
2928 #define test_feq(value1,value2) do { \
2929 double v1 = (value1), v2=(value2); \
2930 double tf_diff = v1-v2; \
2931 double tf_tolerance = ((v1+v2)/2.0)/1e8; \
2932 if (tf_diff<0) tf_diff=-tf_diff; \
2933 if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
2934 if (tf_diff<tf_tolerance) { \
2935 TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
2937 TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
2942 test_util_sscanf(void *arg
)
2944 unsigned u1
, u2
, u3
;
2946 char s1
[20], s2
[10], s3
[10], ch
, *huge
= NULL
;
2952 /* Simple tests (malformed patterns, literal matching, ...) */
2954 tt_int_op(-1,OP_EQ
, tor_sscanf("123", "%i", &r
)); /* %i is not supported */
2956 tor_sscanf("wrong", "%5c", s1
)); /* %c cannot have a number. */
2957 tt_int_op(-1,OP_EQ
, tor_sscanf("hello", "%s", s1
)); /* %s needs a number. */
2958 /* this will fail because we don't allow widths longer than 9999 */
2960 huge
= tor_malloc(1000000);
2961 r
= tor_sscanf("prettylongstring", "%99999s", huge
);
2963 tt_int_op(-1,OP_EQ
, r
);
2966 /* GCC thinks these two are illegal. */
2967 test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1
));
2968 test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL
));
2970 /* No '%'-strings: always "success" */
2971 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "hello world"));
2972 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "good bye"));
2975 tor_sscanf("hello 3", "%u", &u1
)); /* have to match the start */
2976 tt_int_op(0,OP_EQ
, tor_sscanf(" 3 hello", "%u", &u1
));
2978 tor_sscanf(" 3 hello", "%2u", &u1
)); /* not even in this case */
2980 tor_sscanf("3 hello", "%u", &u1
)); /* but trailing is alright */
2982 /* Numbers (ie. %u) */
2984 tor_sscanf("hello world 3", "hello worlb %u", &u1
)); /* d vs b */
2985 tt_int_op(1,OP_EQ
, tor_sscanf("12345", "%u", &u1
));
2986 tt_int_op(12345u,OP_EQ
, u1
);
2987 tt_int_op(1,OP_EQ
, tor_sscanf("12346 ", "%u", &u1
));
2988 tt_int_op(12346u,OP_EQ
, u1
);
2989 tt_int_op(0,OP_EQ
, tor_sscanf(" 12347", "%u", &u1
));
2990 tt_int_op(1,OP_EQ
, tor_sscanf(" 12348", " %u", &u1
));
2991 tt_int_op(12348u,OP_EQ
, u1
);
2992 tt_int_op(1,OP_EQ
, tor_sscanf("0", "%u", &u1
));
2993 tt_int_op(0u,OP_EQ
, u1
);
2994 tt_int_op(1,OP_EQ
, tor_sscanf("0000", "%u", &u2
));
2995 tt_int_op(0u,OP_EQ
, u2
);
2996 tt_int_op(0,OP_EQ
, tor_sscanf("", "%u", &u1
)); /* absent number */
2997 tt_int_op(0,OP_EQ
, tor_sscanf("A", "%u", &u1
)); /* bogus number */
2998 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%u", &u1
)); /* negative number */
3000 /* Numbers with size (eg. %2u) */
3001 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%2u", &u1
));
3002 tt_int_op(2,OP_EQ
, tor_sscanf("123456", "%2u%u", &u1
, &u2
));
3003 tt_int_op(12u,OP_EQ
, u1
);
3004 tt_int_op(3456u,OP_EQ
, u2
);
3005 tt_int_op(1,OP_EQ
, tor_sscanf("123456", "%8u", &u1
));
3006 tt_int_op(123456u,OP_EQ
, u1
);
3007 tt_int_op(1,OP_EQ
, tor_sscanf("123457 ", "%8u", &u1
));
3008 tt_int_op(123457u,OP_EQ
, u1
);
3009 tt_int_op(0,OP_EQ
, tor_sscanf(" 123456", "%8u", &u1
));
3010 tt_int_op(3,OP_EQ
, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
));
3011 tt_int_op(12u,OP_EQ
, u1
);
3012 tt_int_op(3u,OP_EQ
, u2
);
3013 tt_int_op(456u,OP_EQ
, u3
);
3015 tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1
, &u2
, &u3
)); /* 0s */
3016 tt_int_op(67u,OP_EQ
, u1
);
3017 tt_int_op(8u,OP_EQ
, u2
);
3018 tt_int_op(99u,OP_EQ
, u3
);
3019 /* %u does not match space.*/
3020 tt_int_op(2,OP_EQ
, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
3021 tt_int_op(12u,OP_EQ
, u1
);
3022 tt_int_op(3u,OP_EQ
, u2
);
3023 /* %u does not match negative numbers. */
3024 tt_int_op(2,OP_EQ
, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
3025 tt_int_op(67u,OP_EQ
, u1
);
3026 tt_int_op(8u,OP_EQ
, u2
);
3027 /* Arbitrary amounts of 0-padding are okay */
3028 tt_int_op(3,OP_EQ
, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
3030 tt_int_op(12u,OP_EQ
, u1
);
3031 tt_int_op(3u,OP_EQ
, u2
);
3032 tt_int_op(99u,OP_EQ
, u3
);
3036 tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1
, &u2
, &u3
));
3037 tt_int_op(0x1234,OP_EQ
, u1
);
3038 tt_int_op(0x2ABCDEF,OP_EQ
, u2
);
3039 tt_int_op(0xFF,OP_EQ
, u3
);
3040 /* Width works on %x */
3041 tt_int_op(3,OP_EQ
, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1
, &u2
, &u3
));
3042 tt_int_op(0xf00d,OP_EQ
, u1
);
3043 tt_int_op(0xcafe,OP_EQ
, u2
);
3044 tt_int_op(444,OP_EQ
, u3
);
3046 /* Literal '%' (ie. '%%') */
3047 tt_int_op(1,OP_EQ
, tor_sscanf("99% fresh", "%3u%% fresh", &u1
));
3048 tt_int_op(99,OP_EQ
, u1
);
3049 tt_int_op(0,OP_EQ
, tor_sscanf("99 fresh", "%% %3u %s", &u1
, s1
));
3050 tt_int_op(1,OP_EQ
, tor_sscanf("99 fresh", "%3u%% %s", &u1
, s1
));
3051 tt_int_op(2,OP_EQ
, tor_sscanf("99 fresh", "%3u %5s %%", &u1
, s1
));
3052 tt_int_op(99,OP_EQ
, u1
);
3053 tt_str_op(s1
,OP_EQ
, "fresh");
3054 tt_int_op(1,OP_EQ
, tor_sscanf("% boo", "%% %3s", s1
));
3055 tt_str_op("boo",OP_EQ
, s1
);
3057 /* Strings (ie. %s) */
3058 tt_int_op(2,OP_EQ
, tor_sscanf("hello", "%3s%7s", s1
, s2
));
3059 tt_str_op(s1
,OP_EQ
, "hel");
3060 tt_str_op(s2
,OP_EQ
, "lo");
3061 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%2s%u", s3
, &u1
)); /* %s%u */
3062 tt_str_op(s3
,OP_EQ
, "WD");
3063 tt_int_op(40,OP_EQ
, u1
);
3064 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%3s%u", s3
, &u1
)); /* %s%u */
3065 tt_str_op(s3
,OP_EQ
, "WD4");
3066 tt_int_op(0,OP_EQ
, u1
);
3067 tt_int_op(2,OP_EQ
, tor_sscanf("76trombones", "%6u%9s", &u1
, s1
)); /* %u%s */
3068 tt_int_op(76,OP_EQ
, u1
);
3069 tt_str_op(s1
,OP_EQ
, "trombones");
3071 huge
= tor_malloc(1000);
3072 r
= tor_sscanf("prettylongstring", "%999s", huge
);
3073 tt_int_op(1,OP_EQ
, r
);
3074 tt_str_op(huge
,OP_EQ
, "prettylongstring");
3077 /* %s doesn't eat spaces */
3078 tt_int_op(2,OP_EQ
, tor_sscanf("hello world", "%9s %9s", s1
, s2
));
3079 tt_str_op(s1
,OP_EQ
, "hello");
3080 tt_str_op(s2
,OP_EQ
, "world");
3081 tt_int_op(2,OP_EQ
, tor_sscanf("bye world?", "%9s %9s", s1
, s2
));
3082 tt_str_op(s1
,OP_EQ
, "bye");
3083 tt_str_op(s2
,OP_EQ
, "");
3085 tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
)); /* %s can be empty. */
3086 tt_str_op(s1
,OP_EQ
, "hi");
3087 tt_str_op(s2
,OP_EQ
, "");
3088 tt_str_op(s3
,OP_EQ
, "");
3090 tt_int_op(3,OP_EQ
, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3092 tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3093 tt_int_op(' ',OP_EQ
, ch
);
3095 r
= tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1
, &lng1
, &int2
);
3096 tt_int_op(r
,OP_EQ
, 3);
3097 tt_int_op(int1
,OP_EQ
, 12345);
3098 tt_int_op(lng1
,OP_EQ
, -67890);
3099 tt_int_op(int2
,OP_EQ
, -1);
3103 /* UINT32_MAX should work */
3104 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%u", &u1
));
3105 tt_int_op(4294967295U,OP_EQ
, u1
);
3107 /* But UINT32_MAX + 1 shouldn't work */
3108 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%u", &u1
));
3109 /* but parsing only 9... */
3110 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9u", &u1
));
3111 tt_int_op(429496729U,OP_EQ
, u1
);
3114 /* UINT32_MAX should work */
3115 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%x", &u1
));
3116 tt_int_op(0xFFFFFFFF,OP_EQ
, u1
);
3118 /* But UINT32_MAX + 1 shouldn't work */
3119 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%x", &u1
));
3122 /* INT32_MIN and INT32_MAX should work */
3123 r
= tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1
, &int2
);
3124 tt_int_op(r
,OP_EQ
, 2);
3125 tt_int_op(int1
,OP_EQ
, -2147483647 - 1);
3126 tt_int_op(int2
,OP_EQ
, 2147483647);
3128 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3129 r
= tor_sscanf("-2147483649.", "%d.", &int1
);
3130 tt_int_op(r
,OP_EQ
, 0);
3132 r
= tor_sscanf("2147483648.", "%d.", &int1
);
3133 tt_int_op(r
,OP_EQ
, 0);
3135 /* and the first failure stops further processing */
3136 r
= tor_sscanf("-2147483648. 2147483648.",
3137 "%d. %d.", &int1
, &int2
);
3138 tt_int_op(r
,OP_EQ
, 1);
3140 r
= tor_sscanf("-2147483649. 2147483647.",
3141 "%d. %d.", &int1
, &int2
);
3142 tt_int_op(r
,OP_EQ
, 0);
3144 r
= tor_sscanf("2147483648. -2147483649.",
3145 "%d. %d.", &int1
, &int2
);
3146 tt_int_op(r
,OP_EQ
, 0);
3147 #elif SIZEOF_INT == 8
3149 /* UINT64_MAX should work */
3150 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%u", &u1
));
3151 tt_int_op(18446744073709551615U,OP_EQ
, u1
);
3153 /* But UINT64_MAX + 1 shouldn't work */
3154 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%u", &u1
));
3155 /* but parsing only 19... */
3156 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19u", &u1
));
3157 tt_int_op(1844674407370955161U,OP_EQ
, u1
);
3160 /* UINT64_MAX should work */
3161 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1
));
3162 tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ
, u1
);
3164 /* But UINT64_MAX + 1 shouldn't work */
3165 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%x", &u1
));
3168 /* INT64_MIN and INT64_MAX should work */
3169 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3170 "%d. %d.", &int1
, &int2
);
3171 tt_int_op(r
,OP_EQ
, 2);
3172 tt_int_op(int1
,OP_EQ
, -9223372036854775807 - 1);
3173 tt_int_op(int2
,OP_EQ
, 9223372036854775807);
3175 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3176 r
= tor_sscanf("-9223372036854775809.", "%d.", &int1
);
3177 tt_int_op(r
,OP_EQ
, 0);
3179 r
= tor_sscanf("9223372036854775808.", "%d.", &int1
);
3180 tt_int_op(r
,OP_EQ
, 0);
3182 /* and the first failure stops further processing */
3183 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3184 "%d. %d.", &int1
, &int2
);
3185 tt_int_op(r
,OP_EQ
, 1);
3187 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3188 "%d. %d.", &int1
, &int2
);
3189 tt_int_op(r
,OP_EQ
, 0);
3191 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3192 "%d. %d.", &int1
, &int2
);
3193 tt_int_op(r
,OP_EQ
, 0);
3194 #endif /* SIZEOF_INT == 4 || ... */
3196 #if SIZEOF_LONG == 4
3198 /* UINT32_MAX should work */
3199 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%lu", &ulng
));
3200 tt_int_op(4294967295UL,OP_EQ
, ulng
);
3202 /* But UINT32_MAX + 1 shouldn't work */
3203 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%lu", &ulng
));
3204 /* but parsing only 9... */
3205 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9lu", &ulng
));
3206 tt_int_op(429496729UL,OP_EQ
, ulng
);
3209 /* UINT32_MAX should work */
3210 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%lx", &ulng
));
3211 tt_int_op(0xFFFFFFFFUL
,OP_EQ
, ulng
);
3213 /* But UINT32_MAX + 1 shouldn't work */
3214 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%lx", &ulng
));
3217 /* INT32_MIN and INT32_MAX should work */
3218 r
= tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1
, &lng2
);
3219 tt_int_op(r
,OP_EQ
, 2);
3220 tt_int_op(lng1
,OP_EQ
, -2147483647L - 1L);
3221 tt_int_op(lng2
,OP_EQ
, 2147483647L);
3223 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3224 r
= tor_sscanf("-2147483649.", "%ld.", &lng1
);
3225 tt_int_op(r
,OP_EQ
, 0);
3227 r
= tor_sscanf("2147483648.", "%ld.", &lng1
);
3228 tt_int_op(r
,OP_EQ
, 0);
3230 /* and the first failure stops further processing */
3231 r
= tor_sscanf("-2147483648. 2147483648.",
3232 "%ld. %ld.", &lng1
, &lng2
);
3233 tt_int_op(r
,OP_EQ
, 1);
3235 r
= tor_sscanf("-2147483649. 2147483647.",
3236 "%ld. %ld.", &lng1
, &lng2
);
3237 tt_int_op(r
,OP_EQ
, 0);
3239 r
= tor_sscanf("2147483648. -2147483649.",
3240 "%ld. %ld.", &lng1
, &lng2
);
3241 tt_int_op(r
,OP_EQ
, 0);
3242 #elif SIZEOF_LONG == 8
3244 /* UINT64_MAX should work */
3245 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%lu", &ulng
));
3246 tt_int_op(18446744073709551615UL,OP_EQ
, ulng
);
3248 /* But UINT64_MAX + 1 shouldn't work */
3249 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%lu", &ulng
));
3250 /* but parsing only 19... */
3251 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19lu", &ulng
));
3252 tt_int_op(1844674407370955161UL,OP_EQ
, ulng
);
3255 /* UINT64_MAX should work */
3256 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng
));
3257 tt_int_op(0xFFFFFFFFFFFFFFFFUL
,OP_EQ
, ulng
);
3259 /* But UINT64_MAX + 1 shouldn't work */
3260 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%lx", &ulng
));
3263 /* INT64_MIN and INT64_MAX should work */
3264 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3265 "%ld. %ld.", &lng1
, &lng2
);
3266 tt_int_op(r
,OP_EQ
, 2);
3267 tt_int_op(lng1
,OP_EQ
, -9223372036854775807L - 1L);
3268 tt_int_op(lng2
,OP_EQ
, 9223372036854775807L);
3270 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3271 r
= tor_sscanf("-9223372036854775809.", "%ld.", &lng1
);
3272 tt_int_op(r
,OP_EQ
, 0);
3274 r
= tor_sscanf("9223372036854775808.", "%ld.", &lng1
);
3275 tt_int_op(r
,OP_EQ
, 0);
3277 /* and the first failure stops further processing */
3278 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3279 "%ld. %ld.", &lng1
, &lng2
);
3280 tt_int_op(r
,OP_EQ
, 1);
3282 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3283 "%ld. %ld.", &lng1
, &lng2
);
3284 tt_int_op(r
,OP_EQ
, 0);
3286 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3287 "%ld. %ld.", &lng1
, &lng2
);
3288 tt_int_op(r
,OP_EQ
, 0);
3289 #endif /* SIZEOF_LONG == 4 || ... */
3291 r
= tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
3292 "%lf %lf %lf %lf", &d1
,&d2
,&d3
,&d4
);
3293 tt_int_op(r
,OP_EQ
, 4);
3294 test_feq(d1
, 123.456);
3295 test_feq(d2
, .000007);
3296 test_feq(d3
, -900123123.2000787);
3300 r
= tor_sscanf("3 ", "%d %lf", &int1
, &d1
);
3301 tt_int_op(r
, OP_EQ
, 1);
3302 tt_int_op(int1
, OP_EQ
, 3);
3305 r
= tor_sscanf("999 notafloat", "%d %lf", &int1
, &d1
);
3306 tt_int_op(r
, OP_EQ
, 1);
3307 tt_int_op(int1
, OP_EQ
, 999);
3309 /* %s but no buffer. */
3310 char *nullbuf
= NULL
;
3311 r
= tor_sscanf("hello", "%3s", nullbuf
);
3312 tt_int_op(r
, OP_EQ
, 0);
3318 #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
3319 #define tt_ci_char_op(a,op,b) \
3320 tt_char_op(TOR_TOLOWER((int)a),op,TOR_TOLOWER((int)b))
3322 #ifndef HAVE_STRNLEN
3324 strnlen(const char *s
, size_t len
)
3326 const char *p
= memchr(s
, 0, len
);
3331 #endif /* !defined(HAVE_STRNLEN) */
3334 test_util_format_time_interval(void *arg
)
3336 /* use the same sized buffer and integers as tor uses */
3337 #define DBUF_SIZE 64
3338 char dbuf
[DBUF_SIZE
];
3340 long sec
, min
, hour
, day
;
3342 /* we don't care about the exact spelling of the
3343 * second(s), minute(s), hour(s), day(s) labels */
3344 #define LABEL_SIZE 21
3346 char label_s
[LABEL_SIZE
];
3347 char label_m
[LABEL_SIZE
];
3348 char label_h
[LABEL_SIZE
];
3349 char label_d
[LABEL_SIZE
];
3351 #define TL_ T_ " " L_
3357 /* In these tests, we're not picky about
3358 * spelling or abbreviations */
3360 /* seconds: 0, 1, 9, 10, 59 */
3362 /* ignore exact spelling of "second(s)"*/
3363 format_time_interval(dbuf
, sizeof(dbuf
), 0);
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
, 0);
3370 format_time_interval(dbuf
, sizeof(dbuf
), 1);
3371 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3372 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3373 tt_int_op(r
,OP_EQ
, 2);
3374 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3375 tt_int_op(sec
,OP_EQ
, 1);
3377 format_time_interval(dbuf
, sizeof(dbuf
), 10);
3378 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3379 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3380 tt_int_op(r
,OP_EQ
, 2);
3381 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3382 tt_int_op(sec
,OP_EQ
, 10);
3384 format_time_interval(dbuf
, sizeof(dbuf
), 59);
3385 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3386 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3387 tt_int_op(r
,OP_EQ
, 2);
3388 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3389 tt_int_op(sec
,OP_EQ
, 59);
3391 /* negative seconds are reported as their absolute value */
3393 format_time_interval(dbuf
, sizeof(dbuf
), -4);
3394 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3395 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3396 tt_int_op(r
,OP_EQ
, 2);
3397 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3398 tt_int_op(sec
,OP_EQ
, 4);
3399 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3401 format_time_interval(dbuf
, sizeof(dbuf
), -32);
3402 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3403 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3404 tt_int_op(r
,OP_EQ
, 2);
3405 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3406 tt_int_op(sec
,OP_EQ
, 32);
3407 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3409 /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
3411 /* ignore trailing "0 second(s)", if present */
3412 format_time_interval(dbuf
, sizeof(dbuf
), 60);
3413 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3414 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3415 tt_int_op(r
,OP_EQ
, 2);
3416 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3417 tt_int_op(min
,OP_EQ
, 1);
3418 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3420 /* ignore exact spelling of "minute(s)," and "second(s)" */
3421 format_time_interval(dbuf
, sizeof(dbuf
), 60 + 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
, 1);
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');
3430 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3432 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 - 1);
3433 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3434 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3435 &min
, label_m
, &sec
, label_s
);
3436 tt_int_op(r
,OP_EQ
, 4);
3437 tt_int_op(min
,OP_EQ
, 1);
3438 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3439 tt_int_op(sec
,OP_EQ
, 59);
3440 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3442 /* ignore trailing "0 second(s)", if present */
3443 format_time_interval(dbuf
, sizeof(dbuf
), 60*2);
3444 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3445 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3446 tt_int_op(r
,OP_EQ
, 2);
3447 tt_int_op(min
,OP_EQ
, 2);
3448 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3450 /* ignore exact spelling of "minute(s)," and "second(s)" */
3451 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 + 1);
3452 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3453 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3454 &min
, label_m
, &sec
, label_s
);
3455 tt_int_op(r
,OP_EQ
, 4);
3456 tt_int_op(min
,OP_EQ
, 2);
3457 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3458 tt_int_op(sec
,OP_EQ
, 1);
3459 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3461 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 - 1);
3462 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3463 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3464 &min
, label_m
, &sec
, label_s
);
3465 tt_int_op(r
,OP_EQ
, 4);
3466 tt_int_op(min
,OP_EQ
, 59);
3467 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3468 tt_int_op(sec
,OP_EQ
, 59);
3469 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3471 /* negative minutes are reported as their absolute value */
3473 /* ignore trailing "0 second(s)", if present */
3474 format_time_interval(dbuf
, sizeof(dbuf
), -3*60);
3475 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3476 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3477 tt_int_op(r
,OP_EQ
, 2);
3478 tt_int_op(min
,OP_EQ
, 3);
3479 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3481 /* ignore exact spelling of "minute(s)," and "second(s)" */
3482 format_time_interval(dbuf
, sizeof(dbuf
), -96);
3483 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3484 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3485 &min
, label_m
, &sec
, label_s
);
3486 tt_int_op(r
,OP_EQ
, 4);
3487 tt_int_op(min
,OP_EQ
, 1);
3488 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3489 tt_int_op(sec
,OP_EQ
, 36);
3490 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3492 format_time_interval(dbuf
, sizeof(dbuf
), -2815);
3493 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3494 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3495 &min
, label_m
, &sec
, label_s
);
3496 tt_int_op(r
,OP_EQ
, 4);
3497 tt_int_op(min
,OP_EQ
, 46);
3498 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3499 tt_int_op(sec
,OP_EQ
, 55);
3500 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3502 /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
3503 /* always ignore trailing seconds, if present */
3505 /* ignore trailing "0 minute(s)" etc., if present */
3506 format_time_interval(dbuf
, sizeof(dbuf
), 60*60);
3507 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3508 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3509 tt_int_op(r
,OP_EQ
, 2);
3510 tt_int_op(hour
,OP_EQ
, 1);
3511 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3513 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 1);
3514 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3515 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3516 tt_int_op(r
,OP_EQ
, 2);
3517 tt_int_op(hour
,OP_EQ
, 1);
3518 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3520 /* ignore exact spelling of "hour(s)," etc. */
3521 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 60);
3522 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3523 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3524 &hour
, label_h
, &min
, label_m
);
3525 tt_int_op(r
,OP_EQ
, 4);
3526 tt_int_op(hour
,OP_EQ
, 1);
3527 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3528 tt_int_op(min
,OP_EQ
, 1);
3529 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3531 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 60);
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
, 23);
3537 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3538 tt_int_op(min
,OP_EQ
, 59);
3539 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3541 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 1);
3542 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3543 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3544 &hour
, label_h
, &min
, label_m
);
3545 tt_int_op(r
,OP_EQ
, 4);
3546 tt_int_op(hour
,OP_EQ
, 23);
3547 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3548 tt_int_op(min
,OP_EQ
, 59);
3549 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3551 /* negative hours are reported as their absolute value */
3553 /* ignore exact spelling of "hour(s)," etc., if present */
3554 format_time_interval(dbuf
, sizeof(dbuf
), -2*60*60);
3555 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3556 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3557 tt_int_op(r
,OP_EQ
, 2);
3558 tt_int_op(hour
,OP_EQ
, 2);
3559 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3561 format_time_interval(dbuf
, sizeof(dbuf
), -75804);
3562 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3563 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3564 &hour
, label_h
, &min
, label_m
);
3565 tt_int_op(r
,OP_EQ
, 4);
3566 tt_int_op(hour
,OP_EQ
, 21);
3567 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3568 tt_int_op(min
,OP_EQ
, 3);
3569 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3571 /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
3572 /* always ignore trailing seconds, if present */
3574 /* ignore trailing "0 hours(s)" etc., if present */
3575 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60);
3576 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3577 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3578 tt_int_op(r
,OP_EQ
, 2);
3579 tt_int_op(day
,OP_EQ
, 1);
3580 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3582 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 1);
3583 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3584 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3585 tt_int_op(r
,OP_EQ
, 2);
3586 tt_int_op(day
,OP_EQ
, 1);
3587 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3589 /* ignore exact spelling of "days(s)," etc. */
3590 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60);
3591 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3592 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3593 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3595 /* ignore 0 hours(s), if present */
3596 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3597 &day
, label_d
, &min
, label_m
);
3599 tt_assert(r
== 4 || r
== 6);
3600 tt_int_op(day
,OP_EQ
, 1);
3601 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3603 tt_int_op(hour
,OP_EQ
, 0);
3604 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3606 tt_int_op(min
,OP_EQ
, 1);
3607 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3609 /* ignore trailing "0 minutes(s)" etc., if present */
3610 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60*60);
3611 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3612 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3613 &day
, label_d
, &hour
, label_h
);
3614 tt_int_op(r
,OP_EQ
, 4);
3615 tt_int_op(day
,OP_EQ
, 1);
3616 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3617 tt_int_op(hour
,OP_EQ
, 1);
3618 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3620 /* negative days are reported as their absolute value */
3622 format_time_interval(dbuf
, sizeof(dbuf
), -21936184);
3623 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3624 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3625 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3626 tt_int_op(r
,OP_EQ
, 6);
3627 tt_int_op(day
,OP_EQ
, 253);
3628 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3629 tt_int_op(hour
,OP_EQ
, 21);
3630 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3631 tt_int_op(min
,OP_EQ
, 23);
3632 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3634 /* periods > 1 year are reported in days (warn?) */
3636 /* ignore exact spelling of "days(s)," etc., if present */
3637 format_time_interval(dbuf
, sizeof(dbuf
), 758635154);
3638 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3639 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3640 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3641 tt_int_op(r
,OP_EQ
, 6);
3642 tt_int_op(day
,OP_EQ
, 8780);
3643 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3644 tt_int_op(hour
,OP_EQ
, 11);
3645 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3646 tt_int_op(min
,OP_EQ
, 59);
3647 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3649 /* negative periods > 1 year are reported in days (warn?) */
3651 format_time_interval(dbuf
, sizeof(dbuf
), -1427014922);
3652 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3653 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3654 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3655 tt_int_op(r
,OP_EQ
, 6);
3656 tt_int_op(day
,OP_EQ
, 16516);
3657 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3658 tt_int_op(hour
,OP_EQ
, 9);
3659 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3660 tt_int_op(min
,OP_EQ
, 2);
3661 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3663 #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
3665 /* We can try INT32_MIN/MAX */
3666 /* Always ignore second(s) */
3669 format_time_interval(dbuf
, sizeof(dbuf
), 2147483647);
3670 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3671 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3672 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3673 tt_int_op(r
,OP_EQ
, 6);
3674 tt_int_op(day
,OP_EQ
, 24855);
3675 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3676 tt_int_op(hour
,OP_EQ
, 3);
3677 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3678 tt_int_op(min
,OP_EQ
, 14);
3679 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3680 /* and 7 seconds - ignored */
3682 /* INT32_MIN: check that we get the absolute value of interval,
3683 * which doesn't actually fit in int32_t.
3684 * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
3685 format_time_interval(dbuf
, sizeof(dbuf
), -2147483647L - 1L);
3686 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3687 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3688 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3689 tt_int_op(r
,OP_EQ
, 6);
3690 tt_int_op(day
,OP_EQ
, 24855);
3691 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3692 tt_int_op(hour
,OP_EQ
, 3);
3693 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3694 tt_int_op(min
,OP_EQ
, 14);
3695 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3696 /* and 7 or 8 seconds - ignored */
3698 #endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */
3700 #if SIZEOF_LONG == 8
3702 /* We can try INT64_MIN/MAX */
3703 /* Always ignore second(s) */
3706 format_time_interval(dbuf
, sizeof(dbuf
), 9223372036854775807L);
3707 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3708 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3709 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3710 tt_int_op(r
,OP_EQ
, 6);
3711 tt_int_op(day
,OP_EQ
, 106751991167300L);
3712 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3713 tt_int_op(hour
,OP_EQ
, 15);
3714 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3715 tt_int_op(min
,OP_EQ
, 30);
3716 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3717 /* and 7 seconds - ignored */
3719 /* INT64_MIN: check that we get the absolute value of interval,
3720 * which doesn't actually fit in int64_t.
3721 * We expect INT64_MAX */
3722 format_time_interval(dbuf
, sizeof(dbuf
),
3723 -9223372036854775807L - 1L);
3724 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3725 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3726 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3727 tt_int_op(r
,OP_EQ
, 6);
3728 tt_int_op(day
,OP_EQ
, 106751991167300L);
3729 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3730 tt_int_op(hour
,OP_EQ
, 15);
3731 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3732 tt_int_op(min
,OP_EQ
, 30);
3733 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3734 /* and 7 or 8 seconds - ignored */
3736 #endif /* SIZEOF_LONG == 8 */
3743 #undef tt_ci_char_op
3751 test_util_path_is_relative(void *arg
)
3753 /* OS-independent tests */
3755 tt_int_op(1,OP_EQ
, path_is_relative(""));
3756 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3757 tt_int_op(1,OP_EQ
, path_is_relative("dir/"));
3758 tt_int_op(1,OP_EQ
, path_is_relative("./dir"));
3759 tt_int_op(1,OP_EQ
, path_is_relative("../dir"));
3761 tt_int_op(0,OP_EQ
, path_is_relative("/"));
3762 tt_int_op(0,OP_EQ
, path_is_relative("/dir"));
3763 tt_int_op(0,OP_EQ
, path_is_relative("/dir/"));
3767 /* I don't have Windows so I can't test this, hence the "#ifdef
3768 0". These are tests that look useful, so please try to get them
3769 running and uncomment if it all works as it should */
3770 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3771 tt_int_op(1,OP_EQ
, path_is_relative("dir\\"));
3772 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:"));
3773 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:\\"));
3774 tt_int_op(1,OP_EQ
, path_is_relative("http:\\dir"));
3776 tt_int_op(0,OP_EQ
, path_is_relative("\\dir"));
3777 tt_int_op(0,OP_EQ
, path_is_relative("a:\\dir"));
3778 tt_int_op(0,OP_EQ
, path_is_relative("z:\\dir"));
3779 #endif /* defined(_WIN32) */
3785 /** Run unittests for memory area allocator */
3787 test_util_memarea(void *arg
)
3789 memarea_t
*area
= memarea_new();
3790 char *p1
, *p2
, *p3
, *p1_orig
;
3791 void *malloced_ptr
= NULL
;
3794 #ifdef DISABLE_MEMORY_SENTINELS
3795 /* If memory sentinels are disabled, this whole module is just an alias for
3796 malloc(), which is free to lay out memory most any way it wants. */
3799 #endif /* defined(DISABLE_MEMORY_SENTINELS) */
3804 p1_orig
= p1
= memarea_alloc(area
,64);
3805 p2
= memarea_alloc_zero(area
,52);
3806 p3
= memarea_alloc(area
,11);
3808 tt_assert(memarea_owns_ptr(area
, p1
));
3809 tt_assert(memarea_owns_ptr(area
, p2
));
3810 tt_assert(memarea_owns_ptr(area
, p3
));
3811 /* Make sure we left enough space. */
3812 tt_assert(p1
+64 <= p2
);
3813 tt_assert(p2
+52 <= p3
);
3814 /* Make sure we aligned. */
3815 tt_int_op(((uintptr_t)p1
) % sizeof(void*),OP_EQ
, 0);
3816 tt_int_op(((uintptr_t)p2
) % sizeof(void*),OP_EQ
, 0);
3817 tt_int_op(((uintptr_t)p3
) % sizeof(void*),OP_EQ
, 0);
3818 tt_assert(!memarea_owns_ptr(area
, p3
+8192));
3819 tt_assert(!memarea_owns_ptr(area
, p3
+30));
3820 tt_assert(tor_mem_is_zero(p2
, 52));
3821 /* Make sure we don't overalign. */
3822 p1
= memarea_alloc(area
, 1);
3823 p2
= memarea_alloc(area
, 1);
3824 tt_ptr_op(p1
+sizeof(void*),OP_EQ
, p2
);
3826 malloced_ptr
= tor_malloc(64);
3827 tt_assert(!memarea_owns_ptr(area
, malloced_ptr
));
3828 tor_free(malloced_ptr
);
3831 /* memarea_memdup */
3833 malloced_ptr
= tor_malloc(64);
3834 crypto_rand((char*)malloced_ptr
, 64);
3835 p1
= memarea_memdup(area
, malloced_ptr
, 64);
3836 tt_assert(p1
!= malloced_ptr
);
3837 tt_mem_op(p1
,OP_EQ
, malloced_ptr
, 64);
3838 tor_free(malloced_ptr
);
3841 /* memarea_strdup. */
3842 p1
= memarea_strdup(area
,"");
3843 p2
= memarea_strdup(area
, "abcd");
3846 tt_str_op(p1
,OP_EQ
, "");
3847 tt_str_op(p2
,OP_EQ
, "abcd");
3849 /* memarea_strndup. */
3851 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
3852 /* (From Turandot, act 3.) */
3853 size_t len
= strlen(s
);
3854 p1
= memarea_strndup(area
, s
, 1000);
3855 p2
= memarea_strndup(area
, s
, 10);
3856 tt_str_op(p1
,OP_EQ
, s
);
3857 tt_assert(p2
>= p1
+ len
+ 1);
3858 tt_mem_op(s
,OP_EQ
, p2
, 10);
3859 tt_int_op(p2
[10],OP_EQ
, '\0');
3860 p3
= memarea_strndup(area
, s
, len
);
3861 tt_str_op(p3
,OP_EQ
, s
);
3862 p3
= memarea_strndup(area
, s
, len
-1);
3863 tt_mem_op(s
,OP_EQ
, p3
, len
-1);
3864 tt_int_op(p3
[len
-1],OP_EQ
, '\0');
3867 memarea_clear(area
);
3868 p1
= memarea_alloc(area
, 1);
3869 tt_ptr_op(p1
,OP_EQ
, p1_orig
);
3870 memarea_clear(area
);
3871 size_t total
= 0, initial_allocation
, allocation2
, dummy
;
3872 memarea_get_stats(area
, &initial_allocation
, &dummy
);
3874 /* Check for running over an area's size. */
3875 for (i
= 0; i
< 4096; ++i
) {
3876 size_t n
= crypto_rand_int(6);
3877 p1
= memarea_alloc(area
, n
);
3879 tt_assert(memarea_owns_ptr(area
, p1
));
3881 memarea_assert_ok(area
);
3882 memarea_get_stats(area
, &allocation2
, &dummy
);
3883 /* Make sure we can allocate a too-big object. */
3884 p1
= memarea_alloc_zero(area
, 9000);
3885 p2
= memarea_alloc_zero(area
, 16);
3888 tt_assert(memarea_owns_ptr(area
, p1
));
3889 tt_assert(memarea_owns_ptr(area
, p2
));
3891 /* Now test stats... */
3892 size_t allocated
= 0, used
= 0;
3893 memarea_get_stats(area
, &allocated
, &used
);
3894 tt_int_op(used
, OP_LE
, allocated
);
3895 tt_int_op(used
, OP_GE
, total
); /* not EQ, because of alignment and headers*/
3896 tt_int_op(allocated
, OP_GT
, allocation2
);
3898 tt_int_op(allocation2
, OP_GT
, initial_allocation
);
3900 memarea_clear(area
);
3901 memarea_get_stats(area
, &allocated
, &used
);
3902 tt_int_op(used
, OP_LT
, 128); /* Not 0, because of header */
3903 tt_int_op(allocated
, OP_EQ
, initial_allocation
);
3906 memarea_drop_all(area
);
3907 tor_free(malloced_ptr
);
3910 /** Run unit tests for utility functions to get file names relative to
3911 * the data directory. */
3913 test_util_datadir(void *arg
)
3917 char *temp_dir
= NULL
;
3920 temp_dir
= get_datadir_fname(NULL
);
3921 f
= get_datadir_fname("state");
3922 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
3923 tt_str_op(f
,OP_EQ
, buf
);
3925 f
= get_datadir_fname2("cache", "thingy");
3926 tor_snprintf(buf
, sizeof(buf
),
3927 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
3928 tt_str_op(f
,OP_EQ
, buf
);
3930 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
3931 tor_snprintf(buf
, sizeof(buf
),
3932 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
3933 tt_str_op(f
,OP_EQ
, buf
);
3935 f
= get_datadir_fname_suffix("cache", ".foo");
3936 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
3938 tt_str_op(f
,OP_EQ
, buf
);
3946 test_util_strtok(void *arg
)
3954 for (i
= 0; i
< 3; i
++) {
3955 const char *pad1
="", *pad2
="";
3968 tor_snprintf(buf
, sizeof(buf
), "%s", pad1
);
3969 tor_snprintf(buf2
, sizeof(buf2
), "%s", pad2
);
3970 tt_ptr_op(tor_strtok_r_impl(buf
, " ", &cp1
), OP_EQ
, NULL
);
3971 tt_ptr_op(tor_strtok_r_impl(buf2
, ".!..;!", &cp2
), OP_EQ
, NULL
);
3973 tor_snprintf(buf
, sizeof(buf
),
3974 "%sGraved on the dark in gestures of descent%s", pad1
, pad1
);
3975 tor_snprintf(buf2
, sizeof(buf2
),
3976 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2
,pad2
);
3977 /* -- "Year's End", Richard Wilbur */
3979 tt_str_op("Graved",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3980 tt_str_op("they",OP_EQ
, tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
3981 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
3982 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
3983 tt_str_op("on",OP_EQ
, S1());
3984 tt_str_op("the",OP_EQ
, S1());
3985 tt_str_op("dark",OP_EQ
, S1());
3986 tt_str_op("seemed",OP_EQ
, S2());
3987 tt_str_op("their",OP_EQ
, S2());
3988 tt_str_op("own",OP_EQ
, S2());
3989 tt_str_op("in",OP_EQ
, S1());
3990 tt_str_op("gestures",OP_EQ
, S1());
3991 tt_str_op("of",OP_EQ
, S1());
3992 tt_str_op("most",OP_EQ
, S2());
3993 tt_str_op("perfect",OP_EQ
, S2());
3994 tt_str_op("descent",OP_EQ
, S1());
3995 tt_str_op("monument",OP_EQ
, S2());
3996 tt_ptr_op(NULL
,OP_EQ
, S1());
3997 tt_ptr_op(NULL
,OP_EQ
, S2());
4001 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4002 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
4004 strlcpy(buf
, "Howdy!", sizeof(buf
));
4005 tt_str_op("Howdy",OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
4006 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, "!", &cp1
));
4008 strlcpy(buf
, " ", sizeof(buf
));
4009 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4010 strlcpy(buf
, " ", sizeof(buf
));
4011 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4013 strlcpy(buf
, "something ", sizeof(buf
));
4014 tt_str_op("something",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4015 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, ";", &cp1
));
4021 test_util_find_str_at_start_of_line(void *ptr
)
4023 const char *long_string
=
4024 "howdy world. how are you? i hope it's fine.\n"
4027 char *line2
= strchr(long_string
,'\n')+1;
4028 char *line3
= strchr(line2
,'\n')+1;
4029 const char *short_string
= "hello kitty\n"
4031 char *short_line2
= strchr(short_string
,'\n')+1;
4035 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, ""));
4036 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(short_string
, "nonsense"));
4037 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "nonsense"));
4038 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "\n"));
4039 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "how "));
4040 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "kitty"));
4041 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "h"));
4042 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "how"));
4043 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "he"));
4044 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hell"));
4045 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hello k"));
4046 tt_ptr_op(line2
,OP_EQ
,
4047 find_str_at_start_of_line(long_string
, "hello kitty\n"));
4048 tt_ptr_op(line2
,OP_EQ
,
4049 find_str_at_start_of_line(long_string
, "hello kitty\nt"));
4050 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third"));
4051 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third line"));
4052 tt_ptr_op(NULL
, OP_EQ
,
4053 find_str_at_start_of_line(long_string
, "third line\n"));
4054 tt_ptr_op(short_line2
,OP_EQ
, find_str_at_start_of_line(short_string
,
4061 test_util_string_is_C_identifier(void *ptr
)
4065 tt_int_op(1,OP_EQ
, string_is_C_identifier("string_is_C_identifier"));
4066 tt_int_op(1,OP_EQ
, string_is_C_identifier("_string_is_C_identifier"));
4067 tt_int_op(1,OP_EQ
, string_is_C_identifier("_"));
4068 tt_int_op(1,OP_EQ
, string_is_C_identifier("i"));
4069 tt_int_op(1,OP_EQ
, string_is_C_identifier("_____"));
4070 tt_int_op(1,OP_EQ
, string_is_C_identifier("__00__"));
4071 tt_int_op(1,OP_EQ
, string_is_C_identifier("__init__"));
4072 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4073 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0string_is_C_identifier"));
4074 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4076 tt_int_op(0,OP_EQ
, string_is_C_identifier("0_string_is_C_identifier"));
4077 tt_int_op(0,OP_EQ
, string_is_C_identifier("0"));
4078 tt_int_op(0,OP_EQ
, string_is_C_identifier(""));
4079 tt_int_op(0,OP_EQ
, string_is_C_identifier(";"));
4080 tt_int_op(0,OP_EQ
, string_is_C_identifier("i;"));
4081 tt_int_op(0,OP_EQ
, string_is_C_identifier("_;"));
4082 tt_int_op(0,OP_EQ
, string_is_C_identifier("Ã"));
4083 tt_int_op(0,OP_EQ
, string_is_C_identifier("ñ"));
4090 test_util_string_is_utf8(void *ptr
)
4094 tt_int_op(1, OP_EQ
, string_is_utf8(NULL
, 0));
4095 tt_int_op(1, OP_EQ
, string_is_utf8("", 1));
4096 tt_int_op(1, OP_EQ
, string_is_utf8("\uFEFF", 3));
4097 tt_int_op(1, OP_EQ
, string_is_utf8("\uFFFE", 3));
4098 tt_int_op(1, OP_EQ
, string_is_utf8("ascii\x7f\n", 7));
4099 tt_int_op(1, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 9));
4101 // Validate exactly 'len' bytes.
4102 tt_int_op(0, OP_EQ
, string_is_utf8("\0\x80", 2));
4103 tt_int_op(0, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 6));
4105 // Reject sequences with missing bytes.
4106 tt_int_op(0, OP_EQ
, string_is_utf8("\x80", 1));
4107 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2", 1));
4108 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2 ", 2));
4109 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80", 2));
4110 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80 ", 3));
4111 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80", 3));
4112 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80 ", 4));
4114 // Reject encodings that are overly long.
4115 tt_int_op(0, OP_EQ
, string_is_utf8("\xc1\xbf", 2));
4116 tt_int_op(1, OP_EQ
, string_is_utf8("\xc2\x80", 2));
4117 tt_int_op(0, OP_EQ
, string_is_utf8("\xe0\x9f\xbf", 3));
4118 tt_int_op(1, OP_EQ
, string_is_utf8("\xe0\xa0\x80", 3));
4119 tt_int_op(0, OP_EQ
, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
4120 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\x90\x80\x80", 4));
4122 // Reject UTF-16 surrogate halves.
4123 tt_int_op(1, OP_EQ
, string_is_utf8("\xed\x9f\xbf", 3));
4124 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xa0\x80", 3));
4125 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xbf\xbf", 3));
4126 tt_int_op(1, OP_EQ
, string_is_utf8("\xee\x80\x80", 3));
4128 // The maximum legal codepoint, 10FFFF.
4129 tt_int_op(1, OP_EQ
, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
4130 tt_int_op(0, OP_EQ
, string_is_utf8("\xf4\x90\x80\x80", 4));
4137 test_util_asprintf(void *ptr
)
4139 #define LOREMIPSUM \
4140 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
4141 char *cp
=NULL
, *cp2
=NULL
;
4146 r
= tor_asprintf(&cp
, "simple string 100%% safe");
4148 tt_str_op("simple string 100% safe",OP_EQ
, cp
);
4149 tt_int_op(strlen(cp
),OP_EQ
, r
);
4153 r
= tor_asprintf(&cp
, "%s", "");
4155 tt_str_op("",OP_EQ
, cp
);
4156 tt_int_op(strlen(cp
),OP_EQ
, r
);
4160 r
= tor_asprintf(&cp
, "I like numbers-%2i, %i, etc.", -1, 2);
4162 tt_str_op("I like numbers--1, 2, etc.",OP_EQ
, cp
);
4163 tt_int_op(strlen(cp
),OP_EQ
, r
);
4164 /* don't free cp; next test uses it. */
4167 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
4169 tt_int_op(strlen(cp2
),OP_EQ
, r
);
4170 tt_str_op("First=101, Second=202",OP_EQ
, cp2
);
4171 tt_assert(cp
!= cp2
);
4175 /* Glass-box test: a string exactly 128 characters long. */
4176 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
4178 tt_int_op(128,OP_EQ
, r
);
4179 tt_int_op(cp
[128], OP_EQ
, '\0');
4180 tt_str_op("Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
,OP_EQ
, cp
);
4183 /* String longer than 128 characters */
4184 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
4185 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
4187 tt_int_op(strlen(cp
),OP_EQ
, r
);
4188 tt_str_op("1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
,OP_EQ
, cp
);
4196 test_util_listdir(void *ptr
)
4198 smartlist_t
*dir_contents
= NULL
;
4199 char *fname1
=NULL
, *fname2
=NULL
, *fname3
=NULL
, *dir1
=NULL
, *dirname
=NULL
;
4203 fname1
= tor_strdup(get_fname("hopscotch"));
4204 fname2
= tor_strdup(get_fname("mumblety-peg"));
4205 fname3
= tor_strdup(get_fname(".hidden-file"));
4206 dir1
= tor_strdup(get_fname("some-directory"));
4207 dirname
= tor_strdup(get_fname(NULL
));
4209 tt_int_op(0,OP_EQ
, write_str_to_file(fname1
, "X\n", 0));
4210 tt_int_op(0,OP_EQ
, write_str_to_file(fname2
, "Y\n", 0));
4211 tt_int_op(0,OP_EQ
, write_str_to_file(fname3
, "Z\n", 0));
4215 r
= mkdir(dir1
, 0700);
4218 fprintf(stderr
, "Can't create directory %s:", dir1
);
4223 dir_contents
= tor_listdir(dirname
);
4224 tt_assert(dir_contents
);
4225 /* make sure that each filename is listed. */
4226 tt_assert(smartlist_contains_string_case(dir_contents
, "hopscotch"));
4227 tt_assert(smartlist_contains_string_case(dir_contents
, "mumblety-peg"));
4228 tt_assert(smartlist_contains_string_case(dir_contents
, ".hidden-file"));
4229 tt_assert(smartlist_contains_string_case(dir_contents
, "some-directory"));
4231 tt_assert(!smartlist_contains_string(dir_contents
, "."));
4232 tt_assert(!smartlist_contains_string(dir_contents
, ".."));
4241 SMARTLIST_FOREACH(dir_contents
, char *, cp
, tor_free(cp
));
4242 smartlist_free(dir_contents
);
4247 test_util_parent_dir(void *ptr
)
4252 #define T(output,expect_ok,input) \
4255 cp = tor_strdup(input); \
4256 ok = get_parent_directory(cp); \
4257 tt_int_op(expect_ok, OP_EQ, ok); \
4259 tt_str_op(output, OP_EQ, cp); \
4263 T("/home/wombat", 0, "/home/wombat/knish");
4264 T("/home/wombat", 0, "/home/wombat/knish/");
4265 T("/home/wombat", 0, "/home/wombat/knish///");
4266 T("./home/wombat", 0, "./home/wombat/knish/");
4268 T("/", 0, "/home//");
4269 T(".", 0, "./wombat");
4270 T(".", 0, "./wombat/");
4271 T(".", 0, "./wombat//");
4272 T("wombat", 0, "wombat/foo");
4273 T("wombat/..", 0, "wombat/../foo");
4274 T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
4275 T("wombat/.", 0, "wombat/./foo");
4276 T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
4277 T("wombat", 0, "wombat/..//");
4278 T("wombat", 0, "wombat/foo/");
4279 T("wombat", 0, "wombat/.foo");
4280 T("wombat", 0, "wombat/.foo/");
4282 T("wombat", -1, "");
4284 T("wombat", 0, "wombat/knish");
4294 test_util_ftruncate(void *ptr
)
4299 const char *message
= "Hello world";
4300 const char *message2
= "Hola mundo";
4305 fname
= get_fname("ftruncate");
4307 fd
= tor_open_cloexec(fname
, O_WRONLY
|O_CREAT
, 0600);
4308 tt_int_op(fd
, OP_GE
, 0);
4310 /* Make the file be there. */
4311 tt_int_op(strlen(message
), OP_EQ
,
4312 write_all_to_fd(fd
, message
, strlen(message
)));
4313 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message
));
4314 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4315 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message
));
4317 /* Truncate and see if it got truncated */
4318 tt_int_op(0, OP_EQ
, tor_ftruncate(fd
));
4319 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, 0);
4320 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4321 tt_int_op((int)st
.st_size
, OP_EQ
, 0);
4323 /* Replace, and see if it got replaced */
4324 tt_int_op(strlen(message2
), OP_EQ
,
4325 write_all_to_fd(fd
, message2
, strlen(message2
)));
4326 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message2
));
4327 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4328 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message2
));
4333 buf
= read_file_to_str(fname
, 0, NULL
);
4334 tt_str_op(message2
, OP_EQ
, buf
);
4343 test_util_num_cpus(void *arg
)
4346 int num
= compute_num_cpus();
4350 tt_int_op(num
, OP_GE
, 1);
4351 tt_int_op(num
, OP_LE
, 16);
4359 test_util_load_win_lib(void *ptr
)
4361 HANDLE h
= load_windows_system_library(_T("advapi32.dll"));
4369 #endif /* defined(_WIN32) */
4373 clear_hex_errno(char *hex_errno
)
4375 memset(hex_errno
, '\0', HEX_ERRNO_SIZE
+ 1);
4379 test_util_exit_status(void *ptr
)
4381 /* Leave an extra byte for a \0 so we can do string comparison */
4382 char hex_errno
[HEX_ERRNO_SIZE
+ 1];
4387 clear_hex_errno(hex_errno
);
4388 tt_str_op("",OP_EQ
, hex_errno
);
4390 clear_hex_errno(hex_errno
);
4391 n
= format_helper_exit_status(0, 0, hex_errno
);
4392 tt_str_op("0/0\n",OP_EQ
, hex_errno
);
4393 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4397 clear_hex_errno(hex_errno
);
4398 n
= format_helper_exit_status(0, 0x7FFFFFFF, hex_errno
);
4399 tt_str_op("0/7FFFFFFF\n",OP_EQ
, hex_errno
);
4400 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4402 clear_hex_errno(hex_errno
);
4403 n
= format_helper_exit_status(0xFF, -0x80000000, hex_errno
);
4404 tt_str_op("FF/-80000000\n",OP_EQ
, hex_errno
);
4405 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4406 tt_int_op(n
,OP_EQ
, HEX_ERRNO_SIZE
);
4408 #elif SIZEOF_INT == 8
4410 clear_hex_errno(hex_errno
);
4411 n
= format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno
);
4412 tt_str_op("0/7FFFFFFFFFFFFFFF\n",OP_EQ
, hex_errno
);
4413 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4415 clear_hex_errno(hex_errno
);
4416 n
= format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno
);
4417 tt_str_op("FF/-8000000000000000\n",OP_EQ
, hex_errno
);
4418 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4419 tt_int_op(n
,OP_EQ
, HEX_ERRNO_SIZE
);
4421 #endif /* SIZEOF_INT == 4 || ... */
4423 clear_hex_errno(hex_errno
);
4424 n
= format_helper_exit_status(0x7F, 0, hex_errno
);
4425 tt_str_op("7F/0\n",OP_EQ
, hex_errno
);
4426 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4428 clear_hex_errno(hex_errno
);
4429 n
= format_helper_exit_status(0x08, -0x242, hex_errno
);
4430 tt_str_op("8/-242\n",OP_EQ
, hex_errno
);
4431 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4433 clear_hex_errno(hex_errno
);
4434 tt_str_op("",OP_EQ
, hex_errno
);
4439 #endif /* !defined(_WIN32) */
4443 test_util_string_from_pipe(void *ptr
)
4445 int test_pipe
[2] = {-1, -1};
4447 enum stream_status status
= IO_STREAM_TERM
;
4449 char buf
[4] = { 0 };
4455 /* Set up a pipe to test on */
4456 retval
= pipe(test_pipe
);
4457 tt_int_op(retval
, OP_EQ
, 0);
4459 /* Send in a string. */
4460 retlen
= write(test_pipe
[1], "ABC", 3);
4461 tt_int_op(retlen
, OP_EQ
, 3);
4463 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4464 tt_int_op(errno
, OP_EQ
, 0);
4465 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4466 tt_str_op(buf
, OP_EQ
, "ABC");
4469 /* Send in a string that contains a nul. */
4470 retlen
= write(test_pipe
[1], "AB\0", 3);
4471 tt_int_op(retlen
, OP_EQ
, 3);
4473 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4474 tt_int_op(errno
, OP_EQ
, 0);
4475 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4476 tt_str_op(buf
, OP_EQ
, "AB");
4479 /* Send in a string that contains a nul only. */
4480 retlen
= write(test_pipe
[1], "\0", 1);
4481 tt_int_op(retlen
, OP_EQ
, 1);
4483 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4484 tt_int_op(errno
, OP_EQ
, 0);
4485 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4486 tt_str_op(buf
, OP_EQ
, "");
4489 /* Send in a string that contains a trailing newline. */
4490 retlen
= write(test_pipe
[1], "AB\n", 3);
4491 tt_int_op(retlen
, OP_EQ
, 3);
4493 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4494 tt_int_op(errno
, OP_EQ
, 0);
4495 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4496 tt_str_op(buf
, OP_EQ
, "AB");
4499 /* Send in a string that contains a newline only. */
4500 retlen
= write(test_pipe
[1], "\n", 1);
4501 tt_int_op(retlen
, OP_EQ
, 1);
4503 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4504 tt_int_op(errno
, OP_EQ
, 0);
4505 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4506 tt_str_op(buf
, OP_EQ
, "");
4509 /* Send in a string and check that we nul terminate return values. */
4510 retlen
= write(test_pipe
[1], "AAA", 3);
4511 tt_int_op(retlen
, OP_EQ
, 3);
4513 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4514 tt_int_op(errno
, OP_EQ
, 0);
4515 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4516 tt_str_op(buf
, OP_EQ
, "AAA");
4517 tt_mem_op(buf
, OP_EQ
, "AAA\0", sizeof(buf
));
4520 retlen
= write(test_pipe
[1], "B", 1);
4521 tt_int_op(retlen
, OP_EQ
, 1);
4523 memset(buf
, '\xff', sizeof(buf
));
4524 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4525 tt_int_op(errno
, OP_EQ
, 0);
4526 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4527 tt_str_op(buf
, OP_EQ
, "B");
4528 tt_mem_op(buf
, OP_EQ
, "B\0\xff\xff", sizeof(buf
));
4531 /* Send in multiple lines. */
4532 retlen
= write(test_pipe
[1], "A\nB", 3);
4533 tt_int_op(retlen
, OP_EQ
, 3);
4535 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4536 tt_int_op(errno
, OP_EQ
, 0);
4537 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4538 tt_str_op(buf
, OP_EQ
, "A\nB");
4541 /* Send in a line and close */
4542 retlen
= write(test_pipe
[1], "AB", 2);
4543 tt_int_op(retlen
, OP_EQ
, 2);
4544 retval
= close(test_pipe
[1]);
4545 tt_int_op(retval
, OP_EQ
, 0);
4548 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4549 tt_int_op(errno
, OP_EQ
, 0);
4550 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4551 tt_str_op(buf
, OP_EQ
, "AB");
4555 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4556 tt_int_op(errno
, OP_EQ
, 0);
4557 tt_int_op(status
, OP_EQ
, IO_STREAM_CLOSED
);
4561 if (test_pipe
[0] != -1)
4562 close(test_pipe
[0]);
4563 if (test_pipe
[1] != -1)
4564 close(test_pipe
[1]);
4567 #endif /* !defined(_WIN32) */
4570 * Test for format_hex_number_sigsafe()
4574 test_util_format_hex_number(void *ptr
)
4586 {"7FFFFFFF", 0x7fffffff},
4587 {"FFFFFFFF", 0xffffffff},
4588 #if UINT_MAX >= 0xffffffff
4589 {"31BC421D", 0x31bc421d},
4590 {"FFFFFFFF", 0xffffffff},
4597 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
4598 len
= format_hex_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
4599 tt_int_op(len
,OP_NE
, 0);
4600 tt_int_op(len
,OP_EQ
, strlen(buf
));
4601 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4604 tt_int_op(4,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 5));
4605 tt_str_op(buf
,OP_EQ
, "FFFF");
4606 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 4));
4607 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0, buf
, 1));
4614 * Test for format_hex_number_sigsafe()
4618 test_util_format_dec_number(void *ptr
)
4629 {"12345678", 12345678},
4630 {"99999999", 99999999},
4631 {"100000000", 100000000},
4632 {"4294967295", 4294967295u},
4633 #if UINT_MAX > 0xffffffff
4634 {"18446744073709551615", 18446744073709551615u },
4641 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
4642 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
4643 tt_int_op(len
,OP_NE
, 0);
4644 tt_int_op(len
,OP_EQ
, strlen(buf
));
4645 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4647 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
,
4648 (int)(strlen(test_data
[i
].str
) + 1));
4649 tt_int_op(len
,OP_EQ
, strlen(buf
));
4650 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4653 tt_int_op(4,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 5));
4654 tt_str_op(buf
,OP_EQ
, "7331");
4655 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 4));
4656 tt_int_op(1,OP_EQ
, format_dec_number_sigsafe(0, buf
, 2));
4657 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(0, buf
, 1));
4664 * Test that we can properly format a Windows command line
4667 test_util_join_win_cmdline(void *ptr
)
4669 /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
4670 * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
4671 * will try to only generate simple cases for the child process to parse;
4672 * i.e. we never embed quoted strings in arguments. */
4674 const char *argvs
[][4] = {
4675 {"a", "bb", "CCC", NULL
}, // Normal
4676 {NULL
, NULL
, NULL
, NULL
}, // Empty argument list
4677 {"", NULL
, NULL
, NULL
}, // Empty argument
4678 {"\"a", "b\"b", "CCC\"", NULL
}, // Quotes
4679 {"a\tbc", "dd dd", "E", NULL
}, // Whitespace
4680 {"a\\\\\\b", "de fg", "H", NULL
}, // Backslashes
4681 {"a\\\"b", "\\c", "D\\", NULL
}, // Backslashes before quote
4682 {"a\\\\b c", "d", "E", NULL
}, // Backslashes not before quote
4683 { NULL
} // Terminator
4686 const char *cmdlines
[] = {
4690 "\\\"a b\\\"b CCC\\\"",
4691 "\"a\tbc\" \"dd dd\" E",
4692 "a\\\\\\b \"de fg\" H",
4693 "a\\\\\\\"b \\c D\\",
4699 char *joined_argv
= NULL
;
4703 for (i
=0; cmdlines
[i
]!=NULL
; i
++) {
4704 log_info(LD_GENERAL
, "Joining argvs[%d], expecting <%s>", i
, cmdlines
[i
]);
4705 joined_argv
= tor_join_win_cmdline(argvs
[i
]);
4706 tt_str_op(cmdlines
[i
],OP_EQ
, joined_argv
);
4707 tor_free(joined_argv
);
4711 tor_free(joined_argv
);
4714 #define MAX_SPLIT_LINE_COUNT 4
4715 struct split_lines_test_t
{
4716 const char *orig_line
; // Line to be split (may contain \0's)
4717 int orig_length
; // Length of orig_line
4718 const char *split_line
[MAX_SPLIT_LINE_COUNT
]; // Split lines
4722 * Test that we properly split a buffer into lines
4725 test_util_split_lines(void *ptr
)
4727 /* Test cases. orig_line of last test case must be NULL.
4728 * The last element of split_line[i] must be NULL. */
4729 struct split_lines_test_t tests
[] = {
4731 {"foo", 3, {"foo", NULL
}},
4732 {"\n\rfoo\n\rbar\r\n", 12, {"foo", "bar", NULL
}},
4733 {"fo o\r\nb\tar", 10, {"fo o", "b.ar", NULL
}},
4734 {"\x0f""f\0o\0\n\x01""b\0r\0\r", 12, {".f.o.", ".b.r.", NULL
}},
4735 {"line 1\r\nline 2", 14, {"line 1", "line 2", NULL
}},
4736 {"line 1\r\n\r\nline 2", 16, {"line 1", "line 2", NULL
}},
4737 {"line 1\r\n\r\r\r\nline 2", 18, {"line 1", "line 2", NULL
}},
4738 {"line 1\r\n\n\n\n\rline 2", 18, {"line 1", "line 2", NULL
}},
4739 {"line 1\r\n\r\t\r\nline 3", 18, {"line 1", ".", "line 3", NULL
}},
4740 {"\n\t\r\t\nline 3", 11, {".", ".", "line 3", NULL
}},
4745 char *orig_line
=NULL
;
4746 smartlist_t
*sl
=NULL
;
4750 for (i
=0; tests
[i
].orig_line
; i
++) {
4751 sl
= smartlist_new();
4752 /* Allocate space for string and trailing NULL */
4753 orig_line
= tor_memdup(tests
[i
].orig_line
, tests
[i
].orig_length
+ 1);
4754 tor_split_lines(sl
, orig_line
, tests
[i
].orig_length
);
4757 log_info(LD_GENERAL
, "Splitting test %d of length %d",
4758 i
, tests
[i
].orig_length
);
4759 SMARTLIST_FOREACH_BEGIN(sl
, const char *, line
) {
4760 /* Check we have not got too many lines */
4761 tt_int_op(MAX_SPLIT_LINE_COUNT
, OP_GT
, j
);
4762 /* Check that there actually should be a line here */
4763 tt_ptr_op(tests
[i
].split_line
[j
], OP_NE
, NULL
);
4764 log_info(LD_GENERAL
, "Line %d of test %d, should be <%s>",
4765 j
, i
, tests
[i
].split_line
[j
]);
4766 /* Check that the line is as expected */
4767 tt_str_op(line
,OP_EQ
, tests
[i
].split_line
[j
]);
4769 } SMARTLIST_FOREACH_END(line
);
4770 /* Check that we didn't miss some lines */
4771 tt_ptr_op(NULL
,OP_EQ
, tests
[i
].split_line
[j
]);
4772 tor_free(orig_line
);
4778 tor_free(orig_line
);
4783 test_util_di_ops(void *arg
)
4789 const char *a
; int want_sign
; const char *b
;
4791 { "Foo", EQ
, "Foo" },
4792 { "foo", GT
, "bar", },
4793 { "foobar", EQ
,"foobar" },
4794 { "foobar", LT
, "foobaw" },
4795 { "foobar", GT
, "f00bar" },
4796 { "foobar", GT
, "boobar" },
4804 for (i
= 0; examples
[i
].a
; ++i
) {
4805 size_t len
= strlen(examples
[i
].a
);
4806 int eq1
, eq2
, neq1
, neq2
, cmp1
, cmp2
;
4807 tt_int_op(len
,OP_EQ
, strlen(examples
[i
].b
));
4808 /* We do all of the operations, with operands in both orders. */
4809 eq1
= tor_memeq(examples
[i
].a
, examples
[i
].b
, len
);
4810 eq2
= tor_memeq(examples
[i
].b
, examples
[i
].a
, len
);
4811 neq1
= tor_memneq(examples
[i
].a
, examples
[i
].b
, len
);
4812 neq2
= tor_memneq(examples
[i
].b
, examples
[i
].a
, len
);
4813 cmp1
= tor_memcmp(examples
[i
].a
, examples
[i
].b
, len
);
4814 cmp2
= tor_memcmp(examples
[i
].b
, examples
[i
].a
, len
);
4816 /* Check for correctness of cmp1 */
4817 if (cmp1
< 0 && examples
[i
].want_sign
!= LT
)
4818 TT_DIE(("Assertion failed."));
4819 else if (cmp1
> 0 && examples
[i
].want_sign
!= GT
)
4820 TT_DIE(("Assertion failed."));
4821 else if (cmp1
== 0 && examples
[i
].want_sign
!= EQ
)
4822 TT_DIE(("Assertion failed."));
4824 /* Check for consistency of everything else with cmp1 */
4825 tt_int_op(eq1
,OP_EQ
, eq2
);
4826 tt_int_op(neq1
,OP_EQ
, neq2
);
4827 tt_int_op(cmp1
,OP_EQ
, -cmp2
);
4828 tt_int_op(eq1
,OP_EQ
, cmp1
== 0);
4829 tt_int_op(neq1
,OP_EQ
, !eq1
);
4837 /* exhaustively test tor_memeq and tor_memcmp
4838 * against each possible single-byte numeric difference
4839 * some arithmetic bugs only appear with certain bit patterns */
4840 for (z
= 0; z
< 256; z
++) {
4841 for (i
= 0; i
< 256; i
++) {
4844 tt_int_op(tor_memeq(&zz
, &ii
, 1),OP_EQ
, zz
== ii
);
4845 tt_int_op(tor_memcmp(&zz
, &ii
, 1) > 0 ? GT
: EQ
,OP_EQ
,
4847 tt_int_op(tor_memcmp(&ii
, &zz
, 1) < 0 ? LT
: EQ
,OP_EQ
,
4853 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 0));
4854 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 1));
4855 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 1));
4856 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 2));
4857 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0a", 2));
4858 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0a", 2));
4859 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
4860 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
4861 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
4868 test_util_di_map(void *arg
)
4871 di_digest256_map_t
*dimap
= NULL
;
4872 uint8_t key1
[] = "Robert Anton Wilson ";
4873 uint8_t key2
[] = "Martin Gardner, _Fads&fallacies";
4874 uint8_t key3
[] = "Tom Lehrer, _Be Prepared_. ";
4875 uint8_t key4
[] = "Ursula Le Guin,_A Wizard of... ";
4877 char dflt_entry
[] = "'You have made a good beginning', but no more";
4879 tt_int_op(32, OP_EQ
, sizeof(key1
));
4880 tt_int_op(32, OP_EQ
, sizeof(key2
));
4881 tt_int_op(32, OP_EQ
, sizeof(key3
));
4883 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
4885 char *str1
= tor_strdup("You are precisely as big as what you love"
4886 " and precisely as small as what you allow"
4888 char *str2
= tor_strdup("Let us hope that Lysenko's success in Russia will"
4889 " serve for many generations to come as another"
4890 " reminder to the world of how quickly and easily"
4891 " a science can be corrupted when ignorant"
4892 " political leaders deem themselves competent"
4893 " to arbitrate scientific disputes");
4894 char *str3
= tor_strdup("Don't write naughty words on walls "
4895 "if you can't spell.");
4897 dimap_add_entry(&dimap
, key1
, str1
);
4898 dimap_add_entry(&dimap
, key2
, str2
);
4899 dimap_add_entry(&dimap
, key3
, str3
);
4901 tt_ptr_op(str1
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
4902 tt_ptr_op(str3
, OP_EQ
, dimap_search(dimap
, key3
, dflt_entry
));
4903 tt_ptr_op(str2
, OP_EQ
, dimap_search(dimap
, key2
, dflt_entry
));
4904 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key4
, dflt_entry
));
4907 dimap_free(dimap
, tor_free_
);
4911 * Test counting high bits
4914 test_util_n_bits_set(void *ptr
)
4917 tt_int_op(0,OP_EQ
, n_bits_set_u8(0));
4918 tt_int_op(1,OP_EQ
, n_bits_set_u8(1));
4919 tt_int_op(3,OP_EQ
, n_bits_set_u8(7));
4920 tt_int_op(1,OP_EQ
, n_bits_set_u8(8));
4921 tt_int_op(2,OP_EQ
, n_bits_set_u8(129));
4922 tt_int_op(8,OP_EQ
, n_bits_set_u8(255));
4928 * Test LHS whitespace (and comment) eater
4931 test_util_eat_whitespace(void *ptr
)
4933 const char ws
[] = { ' ', '\t', '\r' }; /* Except NL */
4939 /* Try one leading ws */
4940 strlcpy(str
, "fuubaar", sizeof(str
));
4941 for (i
= 0; i
< sizeof(ws
); ++i
) {
4943 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
4944 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4945 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
4946 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4949 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
4950 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4951 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4952 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4955 strlcpy(str
, "", sizeof(str
));
4956 tt_ptr_op(str
,OP_EQ
, eat_whitespace(str
));
4957 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos(str
, str
));
4958 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4959 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
));
4962 strlcpy(str
, " \t\r\n", sizeof(str
));
4963 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4964 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4965 eat_whitespace_eos(str
, str
+ strlen(str
)));
4966 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
4967 eat_whitespace_no_nl(str
));
4968 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
4969 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4971 strlcpy(str
, " \t\r ", sizeof(str
));
4972 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4973 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4974 eat_whitespace_eos(str
, str
+ strlen(str
)));
4975 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace_no_nl(str
));
4976 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4977 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4980 strlcpy(str
, "fuubaar", sizeof(str
));
4981 for (i
= 0; i
< sizeof(ws
); ++i
)
4983 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace(str
));
4984 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
4985 eat_whitespace_eos(str
, str
+ strlen(str
)));
4986 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace_no_nl(str
));
4987 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
4988 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4991 strlcpy(str
, "# Comment \n No Comment", sizeof(str
));
4992 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
4993 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4994 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4995 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4997 /* Eat comment & ws mix */
4998 strlcpy(str
, " # \t Comment \n\t\nNo Comment", sizeof(str
));
4999 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
5000 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5001 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
5002 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5004 /* Eat entire comment */
5005 strlcpy(str
, "#Comment", sizeof(str
));
5006 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5007 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5008 eat_whitespace_eos(str
, str
+ strlen(str
)));
5009 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5010 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5012 /* Blank line, then comment */
5013 strlcpy(str
, " \t\n # Comment", sizeof(str
));
5014 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5015 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5016 eat_whitespace_eos(str
, str
+ strlen(str
)));
5017 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_no_nl(str
));
5018 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5024 /** Return a newly allocated smartlist containing the lines of text in
5025 * <b>lines</b>. The returned strings are heap-allocated, and must be
5026 * freed by the caller.
5028 * XXXX? Move to container.[hc] ? */
5029 static smartlist_t
*
5030 smartlist_new_from_text_lines(const char *lines
)
5032 smartlist_t
*sl
= smartlist_new();
5035 smartlist_split_string(sl
, lines
, "\n", 0, 0);
5037 last_line
= smartlist_pop_last(sl
);
5038 if (last_line
!= NULL
&& *last_line
!= '\0') {
5039 smartlist_add(sl
, last_line
);
5041 tor_free(last_line
);
5047 /** Test smartlist_new_from_text_lines */
5049 test_util_sl_new_from_text_lines(void *ptr
)
5053 { /* Normal usage */
5054 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz\n");
5055 int sl_len
= smartlist_len(sl
);
5057 tt_want_int_op(sl_len
, OP_EQ
, 3);
5059 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5060 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
5061 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
5063 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5067 { /* No final newline */
5068 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz");
5069 int sl_len
= smartlist_len(sl
);
5071 tt_want_int_op(sl_len
, OP_EQ
, 3);
5073 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5074 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
5075 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
5077 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5082 smartlist_t
*sl
= smartlist_new_from_text_lines("foo");
5083 int sl_len
= smartlist_len(sl
);
5085 tt_want_int_op(sl_len
, OP_EQ
, 1);
5087 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5089 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5093 { /* No text at all */
5094 smartlist_t
*sl
= smartlist_new_from_text_lines("");
5095 int sl_len
= smartlist_len(sl
);
5097 tt_want_int_op(sl_len
, OP_EQ
, 0);
5099 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5105 test_util_envnames(void *ptr
)
5109 tt_assert(environment_variable_names_equal("abc", "abc"));
5110 tt_assert(environment_variable_names_equal("abc", "abc="));
5111 tt_assert(environment_variable_names_equal("abc", "abc=def"));
5112 tt_assert(environment_variable_names_equal("abc=def", "abc"));
5113 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
5115 tt_assert(environment_variable_names_equal("abc", "abc"));
5116 tt_assert(environment_variable_names_equal("abc", "abc="));
5117 tt_assert(environment_variable_names_equal("abc", "abc=def"));
5118 tt_assert(environment_variable_names_equal("abc=def", "abc"));
5119 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
5121 tt_assert(!environment_variable_names_equal("abc", "abcd"));
5122 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
5123 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
5124 tt_assert(!environment_variable_names_equal("abc=", "def"));
5125 tt_assert(!environment_variable_names_equal("abc=", "def="));
5126 tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
5128 tt_assert(!environment_variable_names_equal("", "a=def"));
5129 /* A bit surprising. */
5130 tt_assert(environment_variable_names_equal("", "=def"));
5131 tt_assert(environment_variable_names_equal("=y", "=x"));
5137 /** Test process_environment_make */
5139 test_util_make_environment(void *ptr
)
5141 const char *env_vars_string
=
5142 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5143 "HOME=/home/foozer\n";
5144 const char expected_windows_env_block
[] =
5145 "HOME=/home/foozer\000"
5146 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
5148 size_t expected_windows_env_block_len
=
5149 sizeof(expected_windows_env_block
) - 1;
5151 smartlist_t
*env_vars
= smartlist_new_from_text_lines(env_vars_string
);
5152 smartlist_t
*env_vars_sorted
= smartlist_new();
5153 smartlist_t
*env_vars_in_unixoid_env_block_sorted
= smartlist_new();
5155 process_environment_t
*env
;
5159 env
= process_environment_make(env_vars
);
5161 /* Check that the Windows environment block is correct. */
5162 tt_want(tor_memeq(expected_windows_env_block
, env
->windows_environment_block
,
5163 expected_windows_env_block_len
));
5165 /* Now for the Unixoid environment block. We don't care which order
5166 * these environment variables are in, so we sort both lists first. */
5168 smartlist_add_all(env_vars_sorted
, env_vars
);
5172 for (v
= env
->unixoid_environment_block
; *v
; ++v
) {
5173 smartlist_add(env_vars_in_unixoid_env_block_sorted
, *v
);
5177 smartlist_sort_strings(env_vars_sorted
);
5178 smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted
);
5180 tt_want_int_op(smartlist_len(env_vars_sorted
), OP_EQ
,
5181 smartlist_len(env_vars_in_unixoid_env_block_sorted
));
5183 int len
= smartlist_len(env_vars_sorted
);
5186 if (smartlist_len(env_vars_in_unixoid_env_block_sorted
) < len
) {
5187 len
= smartlist_len(env_vars_in_unixoid_env_block_sorted
);
5190 for (i
= 0; i
< len
; ++i
) {
5191 tt_want_str_op(smartlist_get(env_vars_sorted
, i
), OP_EQ
,
5192 smartlist_get(env_vars_in_unixoid_env_block_sorted
, i
));
5197 smartlist_free(env_vars_in_unixoid_env_block_sorted
);
5198 smartlist_free(env_vars_sorted
);
5200 SMARTLIST_FOREACH(env_vars
, char *, x
, tor_free(x
));
5201 smartlist_free(env_vars
);
5203 process_environment_free(env
);
5206 /** Test set_environment_variable_in_smartlist */
5208 test_util_set_env_var_in_sl(void *ptr
)
5210 /* The environment variables in these strings are in arbitrary
5211 * order; we sort the resulting lists before comparing them.
5213 * (They *will not* end up in the order shown in
5214 * expected_resulting_env_vars_string.) */
5216 const char *base_env_vars_string
=
5217 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5218 "HOME=/home/foozer\n"
5227 const char *new_env_vars_string
=
5232 const char *expected_resulting_env_vars_string
=
5233 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5234 "HOME=/home/foozer\n"
5244 smartlist_t
*merged_env_vars
=
5245 smartlist_new_from_text_lines(base_env_vars_string
);
5246 smartlist_t
*new_env_vars
=
5247 smartlist_new_from_text_lines(new_env_vars_string
);
5248 smartlist_t
*expected_resulting_env_vars
=
5249 smartlist_new_from_text_lines(expected_resulting_env_vars_string
);
5251 /* Elements of merged_env_vars are heap-allocated, and must be
5252 * freed. Some of them are (or should) be freed by
5253 * set_environment_variable_in_smartlist.
5255 * Elements of new_env_vars are heap-allocated, but are copied into
5256 * merged_env_vars, so they are not freed separately at the end of
5259 * Elements of expected_resulting_env_vars are heap-allocated, and
5264 SMARTLIST_FOREACH(new_env_vars
, char *, env_var
,
5265 set_environment_variable_in_smartlist(merged_env_vars
,
5270 smartlist_sort_strings(merged_env_vars
);
5271 smartlist_sort_strings(expected_resulting_env_vars
);
5273 tt_want_int_op(smartlist_len(merged_env_vars
), OP_EQ
,
5274 smartlist_len(expected_resulting_env_vars
));
5276 int len
= smartlist_len(merged_env_vars
);
5279 if (smartlist_len(expected_resulting_env_vars
) < len
) {
5280 len
= smartlist_len(expected_resulting_env_vars
);
5283 for (i
= 0; i
< len
; ++i
) {
5284 tt_want_str_op(smartlist_get(merged_env_vars
, i
), OP_EQ
,
5285 smartlist_get(expected_resulting_env_vars
, i
));
5290 SMARTLIST_FOREACH(merged_env_vars
, char *, x
, tor_free(x
));
5291 smartlist_free(merged_env_vars
);
5293 smartlist_free(new_env_vars
);
5295 SMARTLIST_FOREACH(expected_resulting_env_vars
, char *, x
, tor_free(x
));
5296 smartlist_free(expected_resulting_env_vars
);
5300 test_util_weak_random(void *arg
)
5306 tor_init_weak_random(&rng
, (unsigned)time(NULL
));
5308 for (i
= 1; i
<= 256; ++i
) {
5309 for (j
=0;j
<100;++j
) {
5310 int r
= tor_weak_random_range(&rng
, i
);
5311 tt_int_op(0, OP_LE
, r
);
5312 tt_int_op(r
, OP_LT
, i
);
5316 memset(n
,0,sizeof(n
));
5317 for (j
=0;j
<8192;++j
) {
5318 n
[tor_weak_random_range(&rng
, 16)]++;
5322 tt_int_op(n
[i
], OP_GT
, 0);
5328 test_util_mathlog(void *arg
)
5333 d
= tor_mathlog(2.718281828);
5334 tt_double_op(fabs(d
- 1.0), OP_LT
, .000001);
5335 d
= tor_mathlog(10);
5336 tt_double_op(fabs(d
- 2.30258509), OP_LT
, .000001);
5342 test_util_fraction(void *arg
)
5348 simplify_fraction64(&a
,&b
);
5349 tt_u64_op(a
, OP_EQ
, 33);
5350 tt_u64_op(b
, OP_EQ
, 10);
5352 a
= 3000000; b
= 10000000;
5353 simplify_fraction64(&a
,&b
);
5354 tt_u64_op(a
, OP_EQ
, 3);
5355 tt_u64_op(b
, OP_EQ
, 10);
5358 simplify_fraction64(&a
,&b
);
5359 tt_u64_op(a
, OP_EQ
, 0);
5360 tt_u64_op(b
, OP_EQ
, 1);
5367 test_util_round_to_next_multiple_of(void *arg
)
5371 tt_u64_op(round_uint64_to_next_multiple_of(0,1), OP_EQ
, 0);
5372 tt_u64_op(round_uint64_to_next_multiple_of(0,7), OP_EQ
, 0);
5374 tt_u64_op(round_uint64_to_next_multiple_of(99,1), OP_EQ
, 99);
5375 tt_u64_op(round_uint64_to_next_multiple_of(99,7), OP_EQ
, 105);
5376 tt_u64_op(round_uint64_to_next_multiple_of(99,9), OP_EQ
, 99);
5378 tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX
,2), OP_EQ
,
5381 tt_int_op(round_uint32_to_next_multiple_of(0,1), OP_EQ
, 0);
5382 tt_int_op(round_uint32_to_next_multiple_of(0,7), OP_EQ
, 0);
5384 tt_int_op(round_uint32_to_next_multiple_of(99,1), OP_EQ
, 99);
5385 tt_int_op(round_uint32_to_next_multiple_of(99,7), OP_EQ
, 105);
5386 tt_int_op(round_uint32_to_next_multiple_of(99,9), OP_EQ
, 99);
5388 tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX
,2), OP_EQ
,
5391 tt_uint_op(round_to_next_multiple_of(0,1), OP_EQ
, 0);
5392 tt_uint_op(round_to_next_multiple_of(0,7), OP_EQ
, 0);
5394 tt_uint_op(round_to_next_multiple_of(99,1), OP_EQ
, 99);
5395 tt_uint_op(round_to_next_multiple_of(99,7), OP_EQ
, 105);
5396 tt_uint_op(round_to_next_multiple_of(99,9), OP_EQ
, 99);
5398 tt_uint_op(round_to_next_multiple_of(UINT_MAX
,2), OP_EQ
,
5405 test_util_laplace(void *arg
)
5407 /* Sample values produced using Python's SciPy:
5409 * >>> from scipy.stats import laplace
5410 * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
5411 ... loc = 24, scale = 24)
5412 * array([ nan, -inf, -69.88855213, 24. ,
5413 * 24.48486498, 117.88855213, inf, nan])
5415 const double mu
= 24.0, b
= 24.0;
5416 const double delta_f
= 15.0, epsilon
= 0.3; /* b = 15.0 / 0.3 = 50.0 */
5419 tt_i64_op(INT64_MIN
, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.0));
5420 tt_i64_op(-69, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.01));
5421 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.5));
5422 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.51));
5423 tt_i64_op(117, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.99));
5425 /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
5426 * ... loc = 0, scale = 50)
5427 * array([ -inf, -80.47189562, -34.65735903, 0. ,
5428 * 34.65735903, 80.47189562, 195.60115027])
5430 tt_i64_op(INT64_MIN
+ 20, OP_EQ
,
5431 add_laplace_noise(20, 0.0, delta_f
, epsilon
));
5433 tt_i64_op(-60, OP_EQ
, add_laplace_noise(20, 0.1, delta_f
, epsilon
));
5434 tt_i64_op(-14, OP_EQ
, add_laplace_noise(20, 0.25, delta_f
, epsilon
));
5435 tt_i64_op(20, OP_EQ
, add_laplace_noise(20, 0.5, delta_f
, epsilon
));
5436 tt_i64_op(54, OP_EQ
, add_laplace_noise(20, 0.75, delta_f
, epsilon
));
5437 tt_i64_op(100, OP_EQ
, add_laplace_noise(20, 0.9, delta_f
, epsilon
));
5438 tt_i64_op(215, OP_EQ
, add_laplace_noise(20, 0.99, delta_f
, epsilon
));
5440 /* Test extreme values of signal with maximally negative values of noise
5441 * 1.0000000000000002 is the smallest number > 1
5442 * 0.0000000000000002 is the double epsilon (error when calculating near 1)
5443 * this is approximately 1/(2^52)
5444 * per https://en.wikipedia.org/wiki/Double_precision
5445 * (let's not descend into the world of subnormals)
5446 * >>> laplace.ppf([0, 0.0000000000000002], loc = 0, scale = 1)
5447 * array([ -inf, -35.45506713])
5449 const double noscale_df
= 1.0, noscale_eps
= 1.0;
5451 tt_i64_op(INT64_MIN
, OP_EQ
,
5452 add_laplace_noise(0, 0.0, noscale_df
, noscale_eps
));
5454 /* is it clipped to INT64_MIN? */
5455 tt_i64_op(INT64_MIN
, OP_EQ
,
5456 add_laplace_noise(-1, 0.0, noscale_df
, noscale_eps
));
5457 tt_i64_op(INT64_MIN
, OP_EQ
,
5458 add_laplace_noise(INT64_MIN
, 0.0,
5459 noscale_df
, noscale_eps
));
5460 /* ... even when scaled? */
5461 tt_i64_op(INT64_MIN
, OP_EQ
,
5462 add_laplace_noise(0, 0.0, delta_f
, epsilon
));
5463 tt_i64_op(INT64_MIN
, OP_EQ
,
5464 add_laplace_noise(0, 0.0,
5466 tt_i64_op(INT64_MIN
, OP_EQ
,
5467 add_laplace_noise(INT64_MIN
, 0.0,
5470 /* does it play nice with INT64_MAX? */
5471 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5472 add_laplace_noise(INT64_MAX
, 0.0,
5473 noscale_df
, noscale_eps
));
5475 /* do near-zero fractional values work? */
5476 const double min_dbl_error
= 0.0000000000000002;
5478 tt_i64_op(-35, OP_EQ
,
5479 add_laplace_noise(0, min_dbl_error
,
5480 noscale_df
, noscale_eps
));
5481 tt_i64_op(INT64_MIN
, OP_EQ
,
5482 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5483 noscale_df
, noscale_eps
));
5484 tt_i64_op((-35 + INT64_MAX
), OP_EQ
,
5485 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5486 noscale_df
, noscale_eps
));
5487 tt_i64_op(INT64_MIN
, OP_EQ
,
5488 add_laplace_noise(0, min_dbl_error
,
5490 tt_i64_op((INT64_MAX
+ INT64_MIN
), OP_EQ
,
5491 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5493 tt_i64_op(INT64_MIN
, OP_EQ
,
5494 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5497 /* does it play nice with INT64_MAX? */
5498 tt_i64_op((INT64_MAX
- 35), OP_EQ
,
5499 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5500 noscale_df
, noscale_eps
));
5502 /* Test extreme values of signal with maximally positive values of noise
5503 * 1.0000000000000002 is the smallest number > 1
5504 * 0.9999999999999998 is the greatest number < 1 by calculation
5505 * per https://en.wikipedia.org/wiki/Double_precision
5506 * >>> laplace.ppf([1.0, 0.9999999999999998], loc = 0, scale = 1)
5507 * array([inf, 35.35050621])
5508 * but the function rejects p == 1.0, so we just use max_dbl_lt_one
5510 const double max_dbl_lt_one
= 0.9999999999999998;
5512 /* do near-one fractional values work? */
5513 tt_i64_op(35, OP_EQ
,
5514 add_laplace_noise(0, max_dbl_lt_one
, noscale_df
, noscale_eps
));
5516 /* is it clipped to INT64_MAX? */
5517 tt_i64_op(INT64_MAX
, OP_EQ
,
5518 add_laplace_noise(INT64_MAX
- 35, max_dbl_lt_one
,
5519 noscale_df
, noscale_eps
));
5520 tt_i64_op(INT64_MAX
, OP_EQ
,
5521 add_laplace_noise(INT64_MAX
- 34, max_dbl_lt_one
,
5522 noscale_df
, noscale_eps
));
5523 tt_i64_op(INT64_MAX
, OP_EQ
,
5524 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5525 noscale_df
, noscale_eps
));
5526 /* ... even when scaled? */
5527 tt_i64_op(INT64_MAX
, OP_EQ
,
5528 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5530 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5531 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5533 tt_i64_op(INT64_MAX
, OP_EQ
,
5534 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5536 /* does it play nice with INT64_MIN? */
5537 tt_i64_op((INT64_MIN
+ 35), OP_EQ
,
5538 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5539 noscale_df
, noscale_eps
));
5546 test_util_clamp_double_to_int64(void *arg
)
5550 tt_i64_op(INT64_MIN
, OP_EQ
, clamp_double_to_int64(-INFINITY_DBL
));
5551 tt_i64_op(INT64_MIN
, OP_EQ
,
5552 clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0));
5553 tt_i64_op(INT64_MIN
, OP_EQ
,
5554 clamp_double_to_int64(-1.0 * pow(2.0, 63.0) - 1.0));
5555 tt_i64_op(((uint64_t) -1) << 53, OP_EQ
,
5556 clamp_double_to_int64(-1.0 * pow(2.0, 53.0)));
5557 tt_i64_op((((uint64_t) -1) << 53) + 1, OP_EQ
,
5558 clamp_double_to_int64(-1.0 * pow(2.0, 53.0) + 1.0));
5559 tt_i64_op(-1, OP_EQ
, clamp_double_to_int64(-1.0));
5560 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.9));
5561 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.1));
5562 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.0));
5563 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(NAN_DBL
));
5564 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.1));
5565 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.9));
5566 tt_i64_op(1, OP_EQ
, clamp_double_to_int64(1.0));
5567 tt_i64_op((((int64_t) 1) << 53) - 1, OP_EQ
,
5568 clamp_double_to_int64(pow(2.0, 53.0) - 1.0));
5569 tt_i64_op(((int64_t) 1) << 53, OP_EQ
,
5570 clamp_double_to_int64(pow(2.0, 53.0)));
5571 tt_i64_op(INT64_MAX
, OP_EQ
,
5572 clamp_double_to_int64(pow(2.0, 63.0)));
5573 tt_i64_op(INT64_MAX
, OP_EQ
,
5574 clamp_double_to_int64(pow(2.0, 64.0)));
5575 tt_i64_op(INT64_MAX
, OP_EQ
, clamp_double_to_int64(INFINITY_DBL
));
5582 #define CAN_CHECK_CLOEXEC
5584 fd_is_cloexec(tor_socket_t fd
)
5586 int flags
= fcntl(fd
, F_GETFD
, 0);
5587 return (flags
& FD_CLOEXEC
) == FD_CLOEXEC
;
5589 #endif /* defined(FD_CLOEXEC) */
5592 #define CAN_CHECK_NONBLOCK
5594 fd_is_nonblocking(tor_socket_t fd
)
5596 int flags
= fcntl(fd
, F_GETFL
, 0);
5597 return (flags
& O_NONBLOCK
) == O_NONBLOCK
;
5599 #endif /* !defined(_WIN32) */
5601 #define ERRNO_IS_EPROTO(e) (e == SOCK_ERRNO(EPROTONOSUPPORT))
5602 #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s))
5604 /* Test for tor_open_socket*, using IPv4 or IPv6 depending on arg. */
5606 test_util_socket(void *arg
)
5608 const int domain
= !strcmp(arg
, "4") ? AF_INET
: AF_INET6
;
5609 tor_socket_t fd1
= TOR_INVALID_SOCKET
;
5610 tor_socket_t fd2
= TOR_INVALID_SOCKET
;
5611 tor_socket_t fd3
= TOR_INVALID_SOCKET
;
5612 tor_socket_t fd4
= TOR_INVALID_SOCKET
;
5613 int n
= get_n_open_sockets();
5615 TT_BLATHER(("Starting with %d open sockets.", n
));
5619 fd1
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 0);
5620 int err
= tor_socket_errno(fd1
);
5621 if (fd1
< 0 && (err
== SOCK_ERRNO(EPROTONOSUPPORT
) ||
5622 err
== SOCK_ERRNO(EAFNOSUPPORT
))) {
5623 /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */
5626 fd2
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 1);
5627 tt_assert(SOCKET_OK(fd1
));
5628 tt_assert(SOCKET_OK(fd2
));
5629 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5630 //fd3 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 0);
5631 //fd4 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 1);
5632 fd3
= tor_open_socket(domain
, SOCK_STREAM
, 0);
5633 fd4
= tor_open_socket_nonblocking(domain
, SOCK_STREAM
, 0);
5634 tt_assert(SOCKET_OK(fd3
));
5635 tt_assert(SOCKET_OK(fd4
));
5636 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 4);
5638 #ifdef CAN_CHECK_CLOEXEC
5639 tt_int_op(fd_is_cloexec(fd1
), OP_EQ
, 0);
5640 tt_int_op(fd_is_cloexec(fd2
), OP_EQ
, 0);
5641 tt_int_op(fd_is_cloexec(fd3
), OP_EQ
, 1);
5642 tt_int_op(fd_is_cloexec(fd4
), OP_EQ
, 1);
5643 #endif /* defined(CAN_CHECK_CLOEXEC) */
5644 #ifdef CAN_CHECK_NONBLOCK
5645 tt_int_op(fd_is_nonblocking(fd1
), OP_EQ
, 0);
5646 tt_int_op(fd_is_nonblocking(fd2
), OP_EQ
, 1);
5647 tt_int_op(fd_is_nonblocking(fd3
), OP_EQ
, 0);
5648 tt_int_op(fd_is_nonblocking(fd4
), OP_EQ
, 1);
5649 #endif /* defined(CAN_CHECK_NONBLOCK) */
5651 tor_assert(tor_close_socket
== tor_close_socket__real
);
5653 /* we use close_socket__real here so that coverity can tell that we are
5654 * really closing these sockets. */
5655 tor_close_socket__real(fd1
);
5656 tor_close_socket__real(fd2
);
5657 fd1
= fd2
= TOR_INVALID_SOCKET
;
5658 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5659 tor_close_socket__real(fd3
);
5660 tor_close_socket__real(fd4
);
5661 fd3
= fd4
= TOR_INVALID_SOCKET
;
5662 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
5666 tor_close_socket__real(fd1
);
5668 tor_close_socket__real(fd2
);
5670 tor_close_socket__real(fd3
);
5672 tor_close_socket__real(fd4
);
5677 is_there_a_localhost(int family
)
5680 s
= tor_open_socket(family
, SOCK_STREAM
, IPPROTO_TCP
);
5681 tor_assert(SOCKET_OK(s
));
5684 if (family
== AF_INET
) {
5685 struct sockaddr_in s_in
;
5686 memset(&s_in
, 0, sizeof(s_in
));
5687 s_in
.sin_family
= AF_INET
;
5688 s_in
.sin_addr
.s_addr
= htonl(0x7f000001);
5691 if (bind(s
, (void*)&s_in
, sizeof(s_in
)) == 0) {
5694 } else if (family
== AF_INET6
) {
5695 struct sockaddr_in6 sin6
;
5696 memset(&sin6
, 0, sizeof(sin6
));
5697 sin6
.sin6_family
= AF_INET6
;
5698 sin6
.sin6_addr
.s6_addr
[15] = 1;
5701 tor_close_socket(s
);
5707 /* Test for socketpair and ersatz_socketpair(). We test them both, since
5708 * the latter is a tolerably good way to exercise tor_accept_socket(). */
5710 test_util_socketpair(void *arg
)
5712 const int ersatz
= !strcmp(arg
, "1");
5713 int (*const tor_socketpair_fn
)(int, int, int, tor_socket_t
[2]) =
5714 ersatz
? tor_ersatz_socketpair
: tor_socketpair
;
5715 int n
= get_n_open_sockets();
5716 tor_socket_t fds
[2] = {TOR_INVALID_SOCKET
, TOR_INVALID_SOCKET
};
5717 const int family
= AF_UNIX
;
5718 int socketpair_result
= 0;
5720 socketpair_result
= tor_socketpair_fn(family
, SOCK_STREAM
, 0, fds
);
5723 /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
5724 * Otherwise, we risk exposing a socketpair on a routable IP address. (Some
5725 * BSD jails use a routable address for localhost. Fortunately, they have
5726 * the real AF_UNIX socketpair.) */
5727 if (ersatz
&& socketpair_result
< 0) {
5728 /* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
5729 * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
5732 #endif /* defined(__FreeBSD__) */
5733 tt_int_op(0, OP_EQ
, socketpair_result
);
5735 tt_assert(SOCKET_OK(fds
[0]));
5736 tt_assert(SOCKET_OK(fds
[1]));
5738 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
5740 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5741 #ifdef CAN_CHECK_CLOEXEC
5742 tt_int_op(fd_is_cloexec(fds
[0]), OP_EQ
, !ersatz
);
5743 tt_int_op(fd_is_cloexec(fds
[1]), OP_EQ
, !ersatz
);
5745 #ifdef CAN_CHECK_NONBLOCK
5746 tt_int_op(fd_is_nonblocking(fds
[0]), OP_EQ
, 0);
5747 tt_int_op(fd_is_nonblocking(fds
[1]), OP_EQ
, 0);
5752 if (SOCKET_OK(fds
[0]))
5753 tor_close_socket_simple(fds
[0]);
5754 if (SOCKET_OK(fds
[1]))
5755 tor_close_socket_simple(fds
[1]);
5757 if (SOCKET_OK(fds
[0]))
5758 tor_close_socket(fds
[0]);
5759 if (SOCKET_OK(fds
[1]))
5760 tor_close_socket(fds
[1]);
5764 #undef SOCKET_EPROTO
5767 test_util_max_mem(void *arg
)
5769 size_t memory1
, memory2
;
5773 r
= get_total_system_memory(&memory1
);
5774 r2
= get_total_system_memory(&memory2
);
5775 tt_int_op(r
, OP_EQ
, r2
);
5776 tt_uint_op(memory2
, OP_EQ
, memory1
);
5778 TT_BLATHER(("System memory: %"TOR_PRIuSZ
, (memory1
)));
5781 /* You have at least a megabyte. */
5782 tt_uint_op(memory1
, OP_GT
, (1<<20));
5784 /* You do not have a petabyte. */
5785 #if SIZEOF_SIZE_T >= 8
5786 tt_u64_op(memory1
, OP_LT
, (UINT64_C(1)<<50));
5795 test_util_dest_validation_edgecase(void *arg
)
5799 tt_assert(!string_is_valid_dest(NULL
));
5800 tt_assert(!string_is_valid_dest(""));
5807 test_util_hostname_validation(void *arg
)
5811 // Lets try valid hostnames first.
5812 tt_assert(string_is_valid_nonrfc_hostname("torproject.org"));
5813 tt_assert(string_is_valid_nonrfc_hostname("ocw.mit.edu"));
5814 tt_assert(string_is_valid_nonrfc_hostname("i.4cdn.org"));
5815 tt_assert(string_is_valid_nonrfc_hostname("stanford.edu"));
5816 tt_assert(string_is_valid_nonrfc_hostname("multiple-words-with-hypens.jp"));
5818 // Subdomain name cannot start with '-' or '_'.
5819 tt_assert(!string_is_valid_nonrfc_hostname("-torproject.org"));
5820 tt_assert(!string_is_valid_nonrfc_hostname("subdomain.-domain.org"));
5821 tt_assert(!string_is_valid_nonrfc_hostname("-subdomain.domain.org"));
5822 tt_assert(!string_is_valid_nonrfc_hostname("___abc.org"));
5824 // Hostnames cannot contain non-alphanumeric characters.
5825 tt_assert(!string_is_valid_nonrfc_hostname("%%domain.\\org."));
5826 tt_assert(!string_is_valid_nonrfc_hostname("***x.net"));
5827 tt_assert(!string_is_valid_nonrfc_hostname("\xff\xffxyz.org"));
5828 tt_assert(!string_is_valid_nonrfc_hostname("word1 word2.net"));
5830 // Test workaround for nytimes.com stupidity, technically invalid,
5831 // but we allow it since they are big, even though they are failing to
5832 // comply with a ~30 year old standard.
5833 tt_assert(string_is_valid_nonrfc_hostname("core3_euw1.fabrik.nytimes.com"));
5835 // Firefox passes FQDNs with trailing '.'s directly to the SOCKS proxy,
5836 // which is redundant since the spec states DOMAINNAME addresses are fully
5837 // qualified. While unusual, this should be tollerated.
5838 tt_assert(string_is_valid_nonrfc_hostname("core9_euw1.fabrik.nytimes.com."));
5839 tt_assert(!string_is_valid_nonrfc_hostname(
5840 "..washingtonpost.is.better.com"));
5841 tt_assert(!string_is_valid_nonrfc_hostname("so.is..ft.com"));
5842 tt_assert(!string_is_valid_nonrfc_hostname("..."));
5844 // XXX: do we allow single-label DNS names?
5845 // We shouldn't for SOCKS (spec says "contains a fully-qualified domain name"
5846 // but only test pathologically malformed traling '.' cases for now.
5847 tt_assert(!string_is_valid_nonrfc_hostname("."));
5848 tt_assert(!string_is_valid_nonrfc_hostname(".."));
5850 // IP address strings are not hostnames.
5851 tt_assert(!string_is_valid_nonrfc_hostname("8.8.8.8"));
5852 tt_assert(!string_is_valid_nonrfc_hostname("[2a00:1450:401b:800::200e]"));
5853 tt_assert(!string_is_valid_nonrfc_hostname("2a00:1450:401b:800::200e"));
5855 // We allow alphanumeric TLDs. For discussion, see ticket #25055.
5856 tt_assert(string_is_valid_nonrfc_hostname("lucky.13"));
5857 tt_assert(string_is_valid_nonrfc_hostname("luck.y13"));
5858 tt_assert(string_is_valid_nonrfc_hostname("luck.y13."));
5860 // We allow punycode TLDs. For examples, see
5861 // http://data.iana.org/TLD/tlds-alpha-by-domain.txt
5862 tt_assert(string_is_valid_nonrfc_hostname("example.xn--l1acc"));
5869 test_util_ipv4_validation(void *arg
)
5873 tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
5874 tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
5876 tt_assert(!string_is_valid_ipv4_address("abcd"));
5877 tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
5878 tt_assert(!string_is_valid_ipv4_address("8.8."));
5885 test_util_writepid(void *arg
)
5889 char *contents
= NULL
;
5890 const char *fname
= get_fname("tmp_pid");
5894 write_pidfile(fname
);
5896 contents
= read_file_to_str(fname
, 0, NULL
);
5897 tt_assert(contents
);
5899 int n
= tor_sscanf(contents
, "%lu\n%c", &pid
, &c
);
5900 tt_int_op(n
, OP_EQ
, 1);
5903 tt_uint_op(pid
, OP_EQ
, _getpid());
5905 tt_uint_op(pid
, OP_EQ
, getpid());
5913 test_util_get_avail_disk_space(void *arg
)
5918 /* No answer for nonexistent directory */
5919 val
= tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
5920 tt_i64_op(val
, OP_EQ
, -1);
5922 /* Try the current directory */
5923 val
= tor_get_avail_disk_space(".");
5925 #if !defined(HAVE_STATVFS) && !defined(_WIN32)
5926 tt_i64_op(val
, OP_EQ
, -1); /* You don't have an implementation for this */
5928 tt_i64_op(val
, OP_GT
, 0); /* You have some space. */
5929 tt_i64_op(val
, OP_LT
, ((int64_t)1)<<56); /* You don't have a zebibyte */
5930 #endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */
5937 test_util_touch_file(void *arg
)
5940 const char *fname
= get_fname("touch");
5942 const time_t now
= time(NULL
);
5944 write_bytes_to_file(fname
, "abc", 3, 1);
5945 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5946 /* A subtle point: the filesystem time is not necessarily equal to the
5947 * system clock time, since one can be using a monotonic clock, or coarse
5948 * monotonic clock, or whatever. So we might wind up with an mtime a few
5949 * microseconds ago. Let's just give it a lot of wiggle room. */
5950 tt_i64_op(st
.st_mtime
, OP_GE
, now
- 1);
5952 const time_t five_sec_ago
= now
- 5;
5953 struct utimbuf u
= { five_sec_ago
, five_sec_ago
};
5954 tt_int_op(0, OP_EQ
, utime(fname
, &u
));
5955 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5956 /* Let's hope that utime/stat give the same second as a round-trip? */
5957 tt_i64_op(st
.st_mtime
, OP_EQ
, five_sec_ago
);
5959 /* Finally we can touch the file */
5960 tt_int_op(0, OP_EQ
, touch_file(fname
));
5961 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5962 tt_i64_op(st
.st_mtime
, OP_GE
, now
-1);
5970 test_util_pwdb(void *arg
)
5973 const struct passwd
*me
= NULL
, *me2
, *me3
;
5977 /* Uncached case. */
5978 /* Let's assume that we exist. */
5979 me
= tor_getpwuid(getuid());
5980 tt_ptr_op(me
, OP_NE
, NULL
);
5981 name
= tor_strdup(me
->pw_name
);
5984 me2
= tor_getpwnam(name
);
5985 tt_ptr_op(me2
, OP_NE
, NULL
);
5986 tt_int_op(me2
->pw_uid
, OP_EQ
, getuid());
5989 me3
= tor_getpwuid(getuid());
5990 tt_ptr_op(me3
, OP_NE
, NULL
);
5991 tt_str_op(me3
->pw_name
, OP_EQ
, name
);
5993 me3
= tor_getpwnam(name
);
5994 tt_ptr_op(me3
, OP_NE
, NULL
);
5995 tt_int_op(me3
->pw_uid
, OP_EQ
, getuid());
5997 dir
= get_user_homedir(name
);
5998 tt_ptr_op(dir
, OP_NE
, NULL
);
6000 /* Try failing cases. First find a user that doesn't exist by name */
6004 for (i
= 0; i
< 100; ++i
) {
6005 crypto_rand(randbytes
, sizeof(randbytes
));
6006 base16_encode(badname
, sizeof(badname
), randbytes
, sizeof(randbytes
));
6007 if (tor_getpwnam(badname
) == NULL
) {
6015 /* We should do a LOG_ERR */
6016 setup_full_capture_of_logs(LOG_ERR
);
6017 dir
= get_user_homedir(badname
);
6018 tt_ptr_op(dir
, OP_EQ
, NULL
);
6019 expect_log_msg_containing("not found");
6020 tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ
, 1);
6021 teardown_capture_of_logs();
6023 /* Now try to find a user that doesn't exist by ID. */
6025 for (i
= 0; i
< 1000; ++i
) {
6027 crypto_rand((char*)&u
, sizeof(u
));
6028 if (tor_getpwuid(u
) == NULL
) {
6038 teardown_capture_of_logs();
6040 #endif /* !defined(_WIN32) */
6043 test_util_calloc_check(void *arg
)
6046 /* Easy cases that are good. */
6047 tt_assert(size_mul_check(0,0));
6048 tt_assert(size_mul_check(0,100));
6049 tt_assert(size_mul_check(100,0));
6050 tt_assert(size_mul_check(100,100));
6052 /* Harder cases that are still good. */
6053 tt_assert(size_mul_check(SIZE_MAX
, 1));
6054 tt_assert(size_mul_check(1, SIZE_MAX
));
6055 tt_assert(size_mul_check(SIZE_MAX
/ 10, 9));
6056 tt_assert(size_mul_check(11, SIZE_MAX
/ 12));
6057 const size_t sqrt_size_max_p1
= ((size_t)1) << (sizeof(size_t) * 4);
6058 tt_assert(size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
- 1));
6060 /* Cases that overflow */
6061 tt_assert(! size_mul_check(SIZE_MAX
, 2));
6062 tt_assert(! size_mul_check(2, SIZE_MAX
));
6063 tt_assert(! size_mul_check(SIZE_MAX
/ 10, 11));
6064 tt_assert(! size_mul_check(11, SIZE_MAX
/ 10));
6065 tt_assert(! size_mul_check(SIZE_MAX
/ 8, 9));
6066 tt_assert(! size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
));
6073 test_util_monotonic_time(void *arg
)
6077 monotime_t mt1
, mt2
;
6078 monotime_coarse_t mtc1
, mtc2
;
6079 uint64_t nsec1
, nsec2
, usec1
, msec1
;
6080 uint64_t nsecc1
, nsecc2
, usecc1
, msecc1
;
6081 uint32_t stamp1
, stamp2
;
6086 monotime_coarse_get(&mtc1
);
6087 nsec1
= monotime_absolute_nsec();
6088 usec1
= monotime_absolute_usec();
6089 msec1
= monotime_absolute_msec();
6090 nsecc1
= monotime_coarse_absolute_nsec();
6091 usecc1
= monotime_coarse_absolute_usec();
6092 msecc1
= monotime_coarse_absolute_msec();
6093 stamp1
= monotime_coarse_to_stamp(&mtc1
);
6095 tor_sleep_msec(200);
6098 monotime_coarse_get(&mtc2
);
6099 nsec2
= monotime_absolute_nsec();
6100 nsecc2
= monotime_coarse_absolute_nsec();
6101 stamp2
= monotime_coarse_to_stamp(&mtc2
);
6103 /* We need to be a little careful here since we don't know the system load.
6105 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_GE
, 175);
6106 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_LT
, 1000);
6107 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_GE
, 125);
6108 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_LT
, 1000);
6109 tt_u64_op(nsec2
-nsec1
, OP_GE
, 175000000);
6110 tt_u64_op(nsec2
-nsec1
, OP_LT
, 1000000000);
6111 tt_u64_op(nsecc2
-nsecc1
, OP_GE
, 125000000);
6112 tt_u64_op(nsecc2
-nsecc1
, OP_LT
, 1000000000);
6114 tt_u64_op(msec1
, OP_GE
, nsec1
/ 1000000);
6115 tt_u64_op(usec1
, OP_GE
, nsec1
/ 1000);
6116 tt_u64_op(msecc1
, OP_GE
, nsecc1
/ 1000000);
6117 tt_u64_op(usecc1
, OP_GE
, nsecc1
/ 1000);
6118 tt_u64_op(msec1
, OP_LE
, nsec1
/ 1000000 + 10);
6119 tt_u64_op(usec1
, OP_LE
, nsec1
/ 1000 + 10000);
6120 tt_u64_op(msecc1
, OP_LE
, nsecc1
/ 1000000 + 10);
6121 tt_u64_op(usecc1
, OP_LE
, nsecc1
/ 1000 + 10000);
6123 uint64_t coarse_stamp_diff
=
6124 monotime_coarse_stamp_units_to_approx_msec(stamp2
-stamp1
);
6125 tt_u64_op(coarse_stamp_diff
, OP_GE
, 120);
6126 tt_u64_op(coarse_stamp_diff
, OP_LE
, 1200);
6129 uint64_t units
= monotime_msec_to_approx_coarse_stamp_units(5000);
6130 uint64_t ms
= monotime_coarse_stamp_units_to_approx_msec(units
);
6131 tt_u64_op(ms
, OP_GE
, 4950);
6132 tt_u64_op(ms
, OP_LT
, 5050);
6140 test_util_monotonic_time_ratchet(void *arg
)
6144 monotime_reset_ratchets_for_testing();
6146 /* win32, performance counter ratchet. */
6147 tt_i64_op(100, OP_EQ
, ratchet_performance_counter(100));
6148 tt_i64_op(101, OP_EQ
, ratchet_performance_counter(101));
6149 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(2000));
6150 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(100));
6151 tt_i64_op(2005, OP_EQ
, ratchet_performance_counter(105));
6152 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1105));
6153 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1000));
6154 tt_i64_op(3010, OP_EQ
, ratchet_performance_counter(1005));
6156 /* win32, GetTickCounts32 ratchet-and-rollover-detector. */
6157 const int64_t R
= ((int64_t)1) << 32;
6158 tt_i64_op(5, OP_EQ
, ratchet_coarse_performance_counter(5));
6159 tt_i64_op(1000, OP_EQ
, ratchet_coarse_performance_counter(1000));
6160 tt_i64_op(5+R
, OP_EQ
, ratchet_coarse_performance_counter(5));
6161 tt_i64_op(10+R
, OP_EQ
, ratchet_coarse_performance_counter(10));
6162 tt_i64_op(4+R
*2, OP_EQ
, ratchet_coarse_performance_counter(4));
6164 /* gettimeofday regular ratchet. */
6165 struct timeval tv_in
= {0,0}, tv_out
;
6166 tv_in
.tv_usec
= 9000;
6168 ratchet_timeval(&tv_in
, &tv_out
);
6169 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 9000);
6170 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 0);
6172 tv_in
.tv_sec
= 1337;
6174 ratchet_timeval(&tv_in
, &tv_out
);
6175 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
6176 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6178 tv_in
.tv_sec
= 1336;
6179 tv_in
.tv_usec
= 500000;
6180 ratchet_timeval(&tv_in
, &tv_out
);
6181 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
6182 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6184 tv_in
.tv_sec
= 1337;
6186 ratchet_timeval(&tv_in
, &tv_out
);
6187 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 500000);
6188 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6190 tv_in
.tv_sec
= 1337;
6191 tv_in
.tv_usec
= 600000;
6192 ratchet_timeval(&tv_in
, &tv_out
);
6193 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
6194 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
6196 tv_in
.tv_sec
= 1000;
6197 tv_in
.tv_usec
= 1000;
6198 ratchet_timeval(&tv_in
, &tv_out
);
6199 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
6200 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
6202 tv_in
.tv_sec
= 2000;
6203 tv_in
.tv_usec
= 2000;
6204 ratchet_timeval(&tv_in
, &tv_out
);
6205 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 101000);
6206 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 2338);
6213 test_util_monotonic_time_zero(void *arg
)
6217 monotime_coarse_t ct1
;
6219 /* Check 1: The current time is not zero. */
6221 monotime_coarse_get(&ct1
);
6222 tt_assert(!monotime_is_zero(&t1
));
6223 tt_assert(!monotime_coarse_is_zero(&ct1
));
6225 /* Check 2: The _zero() makes the time zero. */
6227 monotime_coarse_zero(&ct1
);
6228 tt_assert(monotime_is_zero(&t1
));
6229 tt_assert(monotime_coarse_is_zero(&ct1
));
6235 test_util_monotonic_time_add_msec(void *arg
)
6239 monotime_coarse_t ct1
, ct2
;
6243 monotime_coarse_get(&ct1
);
6245 /* adding zero does nothing */
6246 monotime_add_msec(&t2
, &t1
, 0);
6247 monotime_coarse_add_msec(&ct2
, &ct1
, 0);
6248 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 0);
6249 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 0);
6251 /* Add 1337 msec; see if the diff function agree */
6252 monotime_add_msec(&t2
, &t1
, 1337);
6253 monotime_coarse_add_msec(&ct2
, &ct1
, 1337);
6254 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337);
6255 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337);
6256 // The 32-bit variant must be within 1% of the regular one.
6257 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 1323);
6258 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 1350);
6260 /* Add 1337 msec twice more; make sure that any second rollover issues
6262 monotime_add_msec(&t2
, &t2
, 1337);
6263 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
6264 monotime_add_msec(&t2
, &t2
, 1337);
6265 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
6266 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337*3);
6267 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337*3);
6268 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 3970);
6269 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 4051);
6276 test_util_nowrap_math(void *arg
)
6280 tt_u64_op(0, OP_EQ
, tor_add_u32_nowrap(0, 0));
6281 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(0, 1));
6282 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(1, 0));
6283 tt_u64_op(4, OP_EQ
, tor_add_u32_nowrap(2, 2));
6284 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
-1, 2));
6285 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(2, UINT32_MAX
-1));
6286 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
, UINT32_MAX
));
6293 test_util_htonll(void *arg
)
6296 #ifdef WORDS_BIGENDIAN
6297 const uint64_t res_be
= 0x8877665544332211;
6299 const uint64_t res_le
= 0x1122334455667788;
6302 tt_u64_op(0, OP_EQ
, tor_htonll(0));
6303 tt_u64_op(0, OP_EQ
, tor_ntohll(0));
6304 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_htonll(UINT64_MAX
));
6305 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_ntohll(UINT64_MAX
));
6307 #ifdef WORDS_BIGENDIAN
6308 tt_u64_op(res_be
, OP_EQ
, tor_htonll(0x8877665544332211));
6309 tt_u64_op(res_be
, OP_EQ
, tor_ntohll(0x8877665544332211));
6311 tt_u64_op(res_le
, OP_EQ
, tor_htonll(0x8877665544332211));
6312 tt_u64_op(res_le
, OP_EQ
, tor_ntohll(0x8877665544332211));
6313 #endif /* defined(WORDS_BIGENDIAN) */
6320 test_util_get_unquoted_path(void *arg
)
6326 r
= get_unquoted_path("\""); // "
6327 tt_ptr_op(r
, OP_EQ
, NULL
);
6330 r
= get_unquoted_path("\"\"\""); // """
6331 tt_ptr_op(r
, OP_EQ
, NULL
);
6334 r
= get_unquoted_path("\\\""); // \"
6335 tt_ptr_op(r
, OP_EQ
, NULL
);
6338 r
= get_unquoted_path("\\\"\\\""); // \"\"
6339 tt_ptr_op(r
, OP_EQ
, NULL
);
6342 r
= get_unquoted_path("A\\B\\C\""); // A\B\C"
6343 tt_ptr_op(r
, OP_EQ
, NULL
);
6346 r
= get_unquoted_path("\"A\\B\\C"); // "A\B\C
6347 tt_ptr_op(r
, OP_EQ
, NULL
);
6350 r
= get_unquoted_path("\"A\\B\"C\""); // "A\B"C"
6351 tt_ptr_op(r
, OP_EQ
, NULL
);
6354 r
= get_unquoted_path("A\\B\"C"); // A\B"C
6355 tt_ptr_op(r
, OP_EQ
, NULL
);
6358 r
= get_unquoted_path("");
6359 tt_str_op(r
, OP_EQ
, "");
6362 r
= get_unquoted_path("\"\""); // ""
6363 tt_str_op(r
, OP_EQ
, "");
6366 r
= get_unquoted_path("A\\B\\C"); // A\B\C
6367 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6370 r
= get_unquoted_path("\"A\\B\\C\""); // "A\B\C"
6371 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6374 r
= get_unquoted_path("\"\\\""); // "\"
6375 tt_str_op(r
, OP_EQ
, "\\"); // \ /* comment to prevent line continuation */
6378 r
= get_unquoted_path("\"\\\"\""); // "\""
6379 tt_str_op(r
, OP_EQ
, "\""); // "
6382 r
= get_unquoted_path("\"A\\B\\C\\\"\""); // "A\B\C\""
6383 tt_str_op(r
, OP_EQ
, "A\\B\\C\""); // A\B\C"
6386 r
= get_unquoted_path("A\\B\\\"C"); // A\B\"C
6387 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6390 r
= get_unquoted_path("\"A\\B\\\"C\""); // "A\B\"C"
6391 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6397 #define UTIL_LEGACY(name) \
6398 { #name, test_util_ ## name , 0, NULL, NULL }
6400 #define UTIL_TEST(name, flags) \
6401 { #name, test_util_ ## name, flags, NULL, NULL }
6403 #define COMPRESS(name, identifier) \
6404 { "compress/" #name, test_util_compress, 0, &compress_setup, \
6405 (char*)(identifier) }
6407 #define COMPRESS_CONCAT(name, identifier) \
6408 { "compress_concat/" #name, test_util_decompress_concatenated, 0, \
6410 (char*)(identifier) }
6412 #define COMPRESS_JUNK(name, identifier) \
6413 { "compress_junk/" #name, test_util_decompress_junk, 0, \
6415 (char*)(identifier) }
6417 #define COMPRESS_DOS(name, identifier) \
6418 { "compress_dos/" #name, test_util_decompress_dos, 0, \
6420 (char*)(identifier) }
6423 #define UTIL_TEST_NO_WIN(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
6424 #define UTIL_TEST_WIN_ONLY(n, f) UTIL_TEST(n, (f))
6425 #define UTIL_LEGACY_NO_WIN(n) UTIL_TEST_NO_WIN(n, 0)
6427 #define UTIL_TEST_NO_WIN(n, f) UTIL_TEST(n, (f))
6428 #define UTIL_TEST_WIN_ONLY(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
6429 #define UTIL_LEGACY_NO_WIN(n) UTIL_LEGACY(n)
6430 #endif /* defined(_WIN32) */
6432 struct testcase_t util_tests
[] = {
6434 UTIL_TEST(parse_http_time
, 0),
6435 UTIL_LEGACY(config_line
),
6436 UTIL_LEGACY(config_line_quotes
),
6437 UTIL_LEGACY(config_line_comment_character
),
6438 UTIL_LEGACY(config_line_escaped_content
),
6439 UTIL_LEGACY(config_line_crlf
),
6440 UTIL_LEGACY_NO_WIN(expand_filename
),
6441 UTIL_LEGACY(escape_string_socks
),
6442 UTIL_LEGACY(string_is_key_value
),
6443 UTIL_LEGACY(strmisc
),
6444 UTIL_TEST(parse_integer
, 0),
6446 COMPRESS(zlib
, "deflate"),
6447 COMPRESS(gzip
, "gzip"),
6448 COMPRESS(lzma
, "x-tor-lzma"),
6449 COMPRESS(zstd
, "x-zstd"),
6450 COMPRESS(zstd_nostatic
, "x-zstd:nostatic"),
6451 COMPRESS(none
, "identity"),
6452 COMPRESS_CONCAT(zlib
, "deflate"),
6453 COMPRESS_CONCAT(gzip
, "gzip"),
6454 COMPRESS_CONCAT(lzma
, "x-tor-lzma"),
6455 COMPRESS_CONCAT(zstd
, "x-zstd"),
6456 COMPRESS_CONCAT(zstd_nostatic
, "x-zstd:nostatic"),
6457 COMPRESS_CONCAT(none
, "identity"),
6458 COMPRESS_JUNK(zlib
, "deflate"),
6459 COMPRESS_JUNK(gzip
, "gzip"),
6460 COMPRESS_JUNK(lzma
, "x-tor-lzma"),
6461 COMPRESS_DOS(zlib
, "deflate"),
6462 COMPRESS_DOS(gzip
, "gzip"),
6463 COMPRESS_DOS(lzma
, "x-tor-lzma"),
6464 COMPRESS_DOS(zstd
, "x-zstd"),
6465 COMPRESS_DOS(zstd_nostatic
, "x-zstd:nostatic"),
6466 UTIL_TEST(gzip_compression_bomb
, TT_FORK
),
6467 UTIL_LEGACY(datadir
),
6468 UTIL_LEGACY(memarea
),
6469 UTIL_LEGACY(control_formats
),
6471 UTIL_TEST(sscanf
, TT_FORK
),
6472 UTIL_LEGACY(format_time_interval
),
6473 UTIL_LEGACY(path_is_relative
),
6474 UTIL_LEGACY(strtok
),
6475 UTIL_LEGACY(di_ops
),
6476 UTIL_TEST(di_map
, 0),
6477 UTIL_TEST(round_to_next_multiple_of
, 0),
6478 UTIL_TEST(laplace
, 0),
6479 UTIL_TEST(clamp_double_to_int64
, 0),
6480 UTIL_TEST(find_str_at_start_of_line
, 0),
6481 UTIL_TEST(string_is_C_identifier
, 0),
6482 UTIL_TEST(string_is_utf8
, 0),
6483 UTIL_TEST(asprintf
, 0),
6484 UTIL_TEST(listdir
, 0),
6485 UTIL_TEST(parent_dir
, 0),
6486 UTIL_TEST(ftruncate
, 0),
6487 UTIL_TEST(nowrap_math
, 0),
6488 UTIL_TEST(num_cpus
, 0),
6489 UTIL_TEST_WIN_ONLY(load_win_lib
, 0),
6490 UTIL_TEST_NO_WIN(exit_status
, 0),
6491 UTIL_TEST_NO_WIN(string_from_pipe
, 0),
6492 UTIL_TEST(format_hex_number
, 0),
6493 UTIL_TEST(format_dec_number
, 0),
6494 UTIL_TEST(join_win_cmdline
, 0),
6495 UTIL_TEST(split_lines
, 0),
6496 UTIL_TEST(n_bits_set
, 0),
6497 UTIL_TEST(eat_whitespace
, 0),
6498 UTIL_TEST(sl_new_from_text_lines
, 0),
6499 UTIL_TEST(envnames
, 0),
6500 UTIL_TEST(make_environment
, 0),
6501 UTIL_TEST(set_env_var_in_sl
, 0),
6502 UTIL_TEST(read_file_eof_tiny_limit
, 0),
6503 UTIL_TEST(read_file_eof_one_loop_a
, 0),
6504 UTIL_TEST(read_file_eof_one_loop_b
, 0),
6505 UTIL_TEST(read_file_eof_two_loops
, 0),
6506 UTIL_TEST(read_file_eof_two_loops_b
, 0),
6507 UTIL_TEST(read_file_eof_zero_bytes
, 0),
6508 UTIL_TEST(read_file_endlines
, 0),
6509 UTIL_TEST(write_chunks_to_file
, 0),
6510 UTIL_TEST(mathlog
, 0),
6511 UTIL_TEST(fraction
, 0),
6512 UTIL_TEST(weak_random
, 0),
6513 { "socket_ipv4", test_util_socket
, TT_FORK
, &passthrough_setup
,
6515 { "socket_ipv6", test_util_socket
, TT_FORK
,
6516 &passthrough_setup
, (void*)"6" },
6517 { "socketpair", test_util_socketpair
, TT_FORK
, &passthrough_setup
,
6519 { "socketpair_ersatz", test_util_socketpair
, TT_FORK
,
6520 &passthrough_setup
, (void*)"1" },
6521 UTIL_TEST(max_mem
, 0),
6522 UTIL_TEST(hostname_validation
, 0),
6523 UTIL_TEST(dest_validation_edgecase
, 0),
6524 UTIL_TEST(ipv4_validation
, 0),
6525 UTIL_TEST(writepid
, 0),
6526 UTIL_TEST(get_avail_disk_space
, 0),
6527 UTIL_TEST(touch_file
, 0),
6528 UTIL_TEST_NO_WIN(pwdb
, TT_FORK
),
6529 UTIL_TEST(calloc_check
, 0),
6530 UTIL_TEST(monotonic_time
, 0),
6531 UTIL_TEST(monotonic_time_ratchet
, TT_FORK
),
6532 UTIL_TEST(monotonic_time_zero
, 0),
6533 UTIL_TEST(monotonic_time_add_msec
, 0),
6534 UTIL_TEST(htonll
, 0),
6535 UTIL_TEST(get_unquoted_path
, 0),