1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
7 #define COMPAT_TIME_PRIVATE
8 #define UTIL_MALLOC_PRIVATE
9 #define PROCESS_WIN32_PRIVATE
10 #define TIME_FMT_PRIVATE
11 #include "lib/testsupport/testsupport.h"
12 #include "core/or/or.h"
13 #include "lib/buf/buffers.h"
14 #include "app/config/config.h"
15 #include "feature/control/control.h"
16 #include "feature/control/control_proto.h"
17 #include "feature/client/transports.h"
18 #include "lib/crypt_ops/crypto_format.h"
19 #include "lib/crypt_ops/crypto_rand.h"
20 #include "lib/defs/time.h"
21 #include "test/test.h"
22 #include "test/test_helpers.h"
23 #include "lib/memarea/memarea.h"
24 #include "lib/process/waitpid.h"
25 #include "lib/process/process_win32.h"
26 #include "test/log_test_helpers.h"
27 #include "lib/compress/compress.h"
28 #include "lib/compress/compress_zstd.h"
29 #include "lib/encoding/keyval.h"
30 #include "lib/fdio/fdio.h"
31 #include "lib/fs/winlib.h"
32 #include "lib/process/env.h"
33 #include "lib/process/pidfile.h"
34 #include "lib/intmath/weakrng.h"
35 #include "lib/intmath/muldiv.h"
36 #include "lib/thread/numcpus.h"
37 #include "lib/math/fp.h"
38 #include "lib/math/laplace.h"
39 #include "lib/meminfo/meminfo.h"
40 #include "lib/time/tvdiff.h"
41 #include "lib/encoding/confline.h"
42 #include "lib/net/socketpair.h"
43 #include "lib/malloc/map_anon.h"
48 #ifdef HAVE_SYS_UTIME_H
49 #include <sys/utime.h>
54 #ifdef HAVE_SYS_STAT_H
63 #ifdef HAVE_SYS_MMAN_H
66 #ifdef HAVE_SYS_WAIT_H
77 /* These platforms don't have meaningful pwdb or homedirs. */
78 #if defined(_WIN32) || defined(__ANDROID__)
79 #define DISABLE_PWDB_TESTS
82 static void set_file_mtime(const char *fname
, time_t when
);
84 #define INFINITY_DBL ((double)INFINITY)
85 #define NAN_DBL ((double)NAN)
87 /** Test the tor_isinf() wrapper */
89 test_tor_isinf(void *arg
)
93 tt_assert(tor_isinf(INFINITY_DBL
));
95 tt_assert(!tor_isinf(NAN_DBL
));
96 tt_assert(!tor_isinf(DBL_EPSILON
));
97 tt_assert(!tor_isinf(DBL_MAX
));
98 tt_assert(!tor_isinf(DBL_MIN
));
100 tt_assert(!tor_isinf(0.0));
101 tt_assert(!tor_isinf(0.1));
102 tt_assert(!tor_isinf(3));
103 tt_assert(!tor_isinf(3.14));
109 /* XXXX this is a minimal wrapper to make the unit tests compile with the
110 * changed tor_timegm interface. */
112 tor_timegm_wrapper(const struct tm
*tm
)
115 if (tor_timegm_impl(tm
, &t
) < 0)
120 #define tor_timegm tor_timegm_wrapper
123 test_util_read_until_eof_impl(const char *fname
, size_t file_len
,
126 char *fifo_name
= NULL
;
127 char *test_str
= NULL
;
133 fifo_name
= tor_strdup(get_fname(fname
));
134 test_str
= tor_malloc(file_len
);
135 crypto_rand(test_str
, file_len
);
137 r
= write_bytes_to_file(fifo_name
, test_str
, file_len
, 1);
138 tt_int_op(r
, OP_EQ
, 0);
140 fd
= open(fifo_name
, O_RDONLY
|O_BINARY
);
141 tt_int_op(fd
, OP_GE
, 0);
142 str
= read_file_to_str_until_eof(fd
, read_limit
, &sz
);
143 tt_ptr_op(str
, OP_NE
, NULL
);
145 if (read_limit
< file_len
)
146 tt_int_op(sz
, OP_EQ
, read_limit
);
148 tt_int_op(sz
, OP_EQ
, file_len
);
150 tt_mem_op(test_str
, OP_EQ
, str
, sz
);
151 tt_int_op(str
[sz
], OP_EQ
, '\0');
163 test_util_read_file_eof_tiny_limit(void *arg
)
166 // purposely set limit shorter than what we wrote to the FIFO to
167 // test the maximum, and that it puts the NUL in the right spot
169 test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
173 test_util_read_file_eof_one_loop_a(void *arg
)
176 test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
180 test_util_read_file_eof_one_loop_b(void *arg
)
183 test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
187 test_util_read_file_eof_two_loops(void *arg
)
190 // write more than 1024 bytes to the FIFO to test two passes through
191 // the loop in the method; if the re-alloc size is changed this
192 // should be updated as well.
194 test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
198 test_util_read_file_eof_two_loops_b(void *arg
)
202 test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
206 test_util_read_file_eof_zero_bytes(void *arg
)
210 test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
214 test_util_read_file_endlines(void *arg
)
219 char *read_content
= NULL
;
222 /* Write a file that contains both \n and \r\n as line ending. */
223 const char *file_content
= "foo bar\n"
227 const char *expected_file_content
= "foo bar\n"
231 fname
= tor_strdup(get_fname("file_with_crlf_ending"));
233 r
= write_bytes_to_file(fname
, file_content
, strlen(file_content
), 1);
234 tt_int_op(r
, OP_EQ
, 0);
236 /* Read the file in text mode: we strip \r's from the files on both Windows
238 read_content
= read_file_to_str(fname
, 0, NULL
);
240 tt_ptr_op(read_content
, OP_NE
, NULL
);
241 tt_int_op(strlen(read_content
), OP_EQ
, strlen(expected_file_content
));
242 tt_str_op(read_content
, OP_EQ
, expected_file_content
);
244 tor_free(read_content
);
246 /* Read the file in binary mode: we should preserve the \r here. */
247 read_content
= read_file_to_str(fname
, RFTS_BIN
, NULL
);
249 tt_ptr_op(read_content
, OP_NE
, NULL
);
250 tt_int_op(strlen(read_content
), OP_EQ
, strlen(file_content
));
251 tt_str_op(read_content
, OP_EQ
, file_content
);
253 tor_free(read_content
);
258 tor_free(read_content
);
261 /* Test the basic expected behaviour for write_chunks_to_file.
262 * NOTE: This will need to be updated if we ever change the tempfile location
265 test_util_write_chunks_to_file(void *arg
)
268 char *tempname
= NULL
;
273 /* These should be two different sizes to ensure the data is different
274 * between the data file and the temp file's 'known string' */
275 int temp_str_len
= 1024;
276 int data_str_len
= 512;
277 char *data_str
= tor_malloc(data_str_len
);
278 char *temp_str
= tor_malloc(temp_str_len
);
280 smartlist_t
*chunks
= smartlist_new();
281 sized_chunk_t c
= {data_str
, data_str_len
/2};
282 sized_chunk_t c2
= {data_str
+ data_str_len
/2, data_str_len
/2};
285 crypto_rand(temp_str
, temp_str_len
);
286 crypto_rand(data_str
, data_str_len
);
288 // Ensure it can write multiple chunks
290 smartlist_add(chunks
, &c
);
291 smartlist_add(chunks
, &c2
);
294 * Check if it writes using a tempfile
296 fname
= tor_strdup(get_fname("write_chunks_with_tempfile"));
297 tor_asprintf(&tempname
, "%s.tmp", fname
);
299 // write a known string to a file where the tempfile will be
300 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
301 tt_int_op(r
, OP_EQ
, 0);
303 // call write_chunks_to_file
304 r
= write_chunks_to_file(fname
, chunks
, 1, 0);
305 tt_int_op(r
, OP_EQ
, 0);
307 // assert the file has been written (expected size)
308 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
309 tt_assert(str
!= NULL
);
310 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
311 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
314 // assert that the tempfile is removed (should not leave artifacts)
315 str
= read_file_to_str(tempname
, RFTS_BIN
|RFTS_IGNORE_MISSING
, &st
);
316 tt_assert(str
== NULL
);
318 // Remove old testfile for second test
320 tt_int_op(r
, OP_EQ
, 0);
325 * Check if it skips using a tempfile with flags
327 fname
= tor_strdup(get_fname("write_chunks_with_no_tempfile"));
328 tor_asprintf(&tempname
, "%s.tmp", fname
);
330 // write a known string to a file where the tempfile will be
331 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
332 tt_int_op(r
, OP_EQ
, 0);
334 // call write_chunks_to_file with no_tempfile = true
335 r
= write_chunks_to_file(fname
, chunks
, 1, 1);
336 tt_int_op(r
, OP_EQ
, 0);
338 // assert the file has been written (expected size)
339 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
340 tt_assert(str
!= NULL
);
341 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
342 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
345 // assert the tempfile still contains the known string
346 str
= read_file_to_str(tempname
, RFTS_BIN
, &st
);
347 tt_assert(str
!= NULL
);
348 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, temp_str_len
);
349 tt_mem_op(temp_str
, OP_EQ
, str
, temp_str_len
);
354 smartlist_free(chunks
);
362 /* Test write_str_to_file_if_not_equal(). */
364 test_util_write_str_if_changed(void *arg
)
367 char *fname
= tor_strdup(get_fname("write_if_changed"));
370 const char str1
[] = "The wombat lives across the seas";
371 const char str2
[] = "Among the far Antipodes"; /* -- Ogden Nash */
373 /* We can create files. */
374 rv
= write_str_to_file_if_not_equal(fname
, str1
);
375 tt_int_op(rv
, OP_EQ
, 0);
376 s
= read_file_to_str(fname
, 0, NULL
);
377 tt_str_op(s
, OP_EQ
, str1
);
380 /* We can replace files. */
381 rv
= write_str_to_file_if_not_equal(fname
, str2
);
382 tt_int_op(rv
, OP_EQ
, 0);
383 s
= read_file_to_str(fname
, 0, NULL
);
384 tt_str_op(s
, OP_EQ
, str2
);
387 /* Make sure we don't replace files when they're equal. (That's the whole
388 * point of the function we're testing. */
389 /* First, change the mtime of the file so that we can tell whether we
391 const time_t now
= time(NULL
);
392 const time_t five_sec_ago
= now
- 5;
393 set_file_mtime(fname
, five_sec_ago
);
394 rv
= write_str_to_file_if_not_equal(fname
, str2
);
395 tt_int_op(rv
, OP_EQ
, 0);
396 /* Make sure that the file's mtime is unchanged... */
398 rv
= stat(fname
, &st
);
399 tt_int_op(rv
, OP_EQ
, 0);
400 tt_i64_op(st
.st_mtime
, OP_EQ
, five_sec_ago
);
401 /* And make sure its contents are unchanged. */
402 s
= read_file_to_str(fname
, 0, NULL
);
403 tt_str_op(s
, OP_EQ
, str2
);
412 #define _TFE(a, b, f) tt_int_op((a).f, OP_EQ, (b).f)
413 /** test the minimum set of struct tm fields needed for a unique epoch value
414 * this is also the set we use to test tor_timegm */
415 #define TM_EQUAL(a, b) \
417 _TFE(a, b, tm_year); \
418 _TFE(a, b, tm_mon ); \
419 _TFE(a, b, tm_mday); \
420 _TFE(a, b, tm_hour); \
421 _TFE(a, b, tm_min ); \
422 _TFE(a, b, tm_sec ); \
424 #endif /* !defined(COCCI) */
427 test_util_time(void *arg
)
429 struct timeval start
, end
;
430 struct tm a_time
, b_time
;
436 /* Test tv_udiff and tv_mdiff */
440 start
.tv_usec
= 5000;
445 tt_int_op(0L,OP_EQ
, tv_udiff(&start
, &end
));
446 tt_int_op(0L,OP_EQ
, tv_mdiff(&start
, &end
));
447 tt_int_op(0L,OP_EQ
, tv_udiff(&end
, &start
));
448 tt_int_op(0L,OP_EQ
, tv_mdiff(&end
, &start
));
452 tt_int_op(2000L,OP_EQ
, tv_udiff(&start
, &end
));
453 tt_int_op(2L,OP_EQ
, tv_mdiff(&start
, &end
));
454 tt_int_op(-2000L,OP_EQ
, tv_udiff(&end
, &start
));
455 tt_int_op(-2L,OP_EQ
, tv_mdiff(&end
, &start
));
459 tt_int_op(1002000L,OP_EQ
, tv_udiff(&start
, &end
));
460 tt_int_op(1002L,OP_EQ
, tv_mdiff(&start
, &end
));
461 tt_int_op(-1002000L,OP_EQ
, tv_udiff(&end
, &start
));
462 tt_int_op(-1002L,OP_EQ
, tv_mdiff(&end
, &start
));
466 tt_int_op(995000L,OP_EQ
, tv_udiff(&start
, &end
));
467 tt_int_op(995L,OP_EQ
, tv_mdiff(&start
, &end
));
468 tt_int_op(-995000L,OP_EQ
, tv_udiff(&end
, &start
));
469 tt_int_op(-995L,OP_EQ
, tv_mdiff(&end
, &start
));
473 tt_int_op(-1005000L,OP_EQ
, tv_udiff(&start
, &end
));
474 tt_int_op(-1005L,OP_EQ
, tv_mdiff(&start
, &end
));
475 tt_int_op(1005000L,OP_EQ
, tv_udiff(&end
, &start
));
476 tt_int_op(1005L,OP_EQ
, tv_mdiff(&end
, &start
));
478 /* Negative tv_sec values, these will break on platforms where tv_sec is
483 tt_int_op(-15005000L,OP_EQ
, tv_udiff(&start
, &end
));
484 tt_int_op(-15005L,OP_EQ
, tv_mdiff(&start
, &end
));
485 tt_int_op(15005000L,OP_EQ
, tv_udiff(&end
, &start
));
486 tt_int_op(15005L,OP_EQ
, tv_mdiff(&end
, &start
));
490 tt_int_op(89995000L,OP_EQ
, tv_udiff(&start
, &end
));
491 tt_int_op(89995L,OP_EQ
, tv_mdiff(&start
, &end
));
492 tt_int_op(-89995000L,OP_EQ
, tv_udiff(&end
, &start
));
493 tt_int_op(-89995L,OP_EQ
, tv_mdiff(&end
, &start
));
495 /* Test that tv_usec values round away from zero when converted to msec */
501 tt_int_op(10000499L, OP_EQ
, tv_udiff(&start
, &end
));
502 tt_int_op(10000L, OP_EQ
, tv_mdiff(&start
, &end
));
503 tt_int_op(-10000499L, OP_EQ
, tv_udiff(&end
, &start
));
504 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
511 tt_int_op(10000500L, OP_EQ
, tv_udiff(&start
, &end
));
512 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
513 tt_int_op(-10000500L, OP_EQ
, tv_udiff(&end
, &start
));
514 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
521 tt_int_op(10000501L, OP_EQ
, tv_udiff(&start
, &end
));
522 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
523 tt_int_op(-10000501L, OP_EQ
, tv_udiff(&end
, &start
));
524 tt_int_op(-10001L, OP_EQ
, tv_mdiff(&end
, &start
));
526 /* Overflow conditions */
529 /* Would you believe that tv_sec is a long on windows? Of course you would.*/
530 #define TV_SEC_MAX LONG_MAX
531 #define TV_SEC_MIN LONG_MIN
533 /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
534 * Which means TIME_MAX is not actually the maximum value of tv_sec.
535 * But that's ok for the moment, because the code correctly performs 64-bit
536 * calculations internally, then catches the overflow. */
537 #define TV_SEC_MAX TIME_MAX
538 #define TV_SEC_MIN TIME_MIN
539 #endif /* defined(_WIN32) */
541 /* Assume tv_usec is an unsigned integer until proven otherwise */
542 #define TV_USEC_MAX UINT_MAX
544 /* Overflows in the result type */
546 /* All comparisons work */
549 end
.tv_sec
= LONG_MAX
/1000 - 2;
552 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
553 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
554 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
555 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
559 end
.tv_sec
= LONG_MAX
/1000000 - 1;
562 tt_int_op(end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&start
, &end
));
563 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
564 tt_int_op(-end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&end
, &start
));
565 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
567 /* No comparisons work */
570 end
.tv_sec
= LONG_MAX
/1000 + 1;
573 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
574 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
575 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
576 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
580 end
.tv_sec
= LONG_MAX
/1000000 + 1;
583 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
584 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
585 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
586 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
590 end
.tv_sec
= LONG_MAX
/1000;
591 end
.tv_usec
= TOR_USEC_PER_SEC
;
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
));
600 end
.tv_sec
= LONG_MAX
/1000000;
601 end
.tv_usec
= TOR_USEC_PER_SEC
;
603 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
604 tt_int_op((end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
605 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
606 tt_int_op(-(end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
608 /* Overflows on comparison to zero */
613 end
.tv_sec
= TV_SEC_MAX
;
616 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
617 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
618 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
619 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
621 end
.tv_sec
= TV_SEC_MAX
;
622 end
.tv_usec
= TOR_USEC_PER_SEC
;
624 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
625 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
626 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
627 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
630 end
.tv_usec
= TV_USEC_MAX
;
632 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
633 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
634 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
635 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
637 end
.tv_sec
= TV_SEC_MAX
;
638 end
.tv_usec
= TV_USEC_MAX
;
640 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
641 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
642 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
643 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
648 start
.tv_sec
= TV_SEC_MIN
;
651 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
652 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
653 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
654 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
656 start
.tv_sec
= TV_SEC_MIN
;
657 start
.tv_usec
= TOR_USEC_PER_SEC
;
659 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
660 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
661 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
662 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
664 start
.tv_sec
= TV_SEC_MIN
;
665 start
.tv_usec
= TV_USEC_MAX
;
667 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
668 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
669 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
670 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
672 /* overflows on comparison to maxima / minima */
674 start
.tv_sec
= TV_SEC_MIN
;
677 end
.tv_sec
= TV_SEC_MAX
;
680 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
681 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
682 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
683 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
685 end
.tv_sec
= TV_SEC_MAX
;
686 end
.tv_usec
= TOR_USEC_PER_SEC
;
688 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
689 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
690 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
691 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
693 end
.tv_sec
= TV_SEC_MAX
;
696 start
.tv_sec
= TV_SEC_MIN
;
699 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
700 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
701 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
702 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
704 start
.tv_sec
= TV_SEC_MIN
;
705 start
.tv_usec
= TOR_USEC_PER_SEC
;
707 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
708 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
709 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
710 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
712 /* overflows on comparison to maxima / minima with extra usec */
714 start
.tv_sec
= TV_SEC_MIN
;
715 start
.tv_usec
= TOR_USEC_PER_SEC
;
717 end
.tv_sec
= TV_SEC_MAX
;
720 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
721 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
722 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
723 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
725 end
.tv_sec
= TV_SEC_MAX
;
726 end
.tv_usec
= TOR_USEC_PER_SEC
;
728 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
729 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
730 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
731 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
733 end
.tv_sec
= TV_SEC_MAX
;
734 end
.tv_usec
= TOR_USEC_PER_SEC
;
736 start
.tv_sec
= TV_SEC_MIN
;
739 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
740 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
741 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
742 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
744 start
.tv_sec
= TV_SEC_MIN
;
745 start
.tv_usec
= TOR_USEC_PER_SEC
;
747 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
748 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
749 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
750 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
752 /* Test tor_timegm & tor_gmtime_r */
754 /* The test values here are confirmed to be correct on a platform
755 * with a working timegm & gmtime_r. */
757 /* Start with known-zero a_time and b_time.
758 * This avoids passing uninitialised values to TM_EQUAL in a_time.
759 * Zeroing may not be needed for b_time, as long as tor_gmtime_r
760 * never reads the existing values in the structure.
761 * But we really don't want intermittently failing tests. */
762 memset(&a_time
, 0, sizeof(struct tm
));
763 memset(&b_time
, 0, sizeof(struct tm
));
765 a_time
.tm_year
= 2003-1900;
771 t_res
= 1062224095UL;
772 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
773 tor_gmtime_r(&t_res
, &b_time
);
774 TM_EQUAL(a_time
, b_time
);
776 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
777 t_res
= 1093846495UL;
778 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
779 tor_gmtime_r(&t_res
, &b_time
);
780 TM_EQUAL(a_time
, b_time
);
782 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
784 t_res
= 1076393695UL;
785 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
786 tor_gmtime_r(&t_res
, &b_time
);
787 TM_EQUAL(a_time
, b_time
);
790 t_res
= 1073715295UL;
791 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
792 tor_gmtime_r(&t_res
, &b_time
);
793 TM_EQUAL(a_time
, b_time
);
795 /* This value is in range with 32 bit and 64 bit time_t */
796 a_time
.tm_year
= 2037-1900;
797 t_res
= 2115180895UL;
798 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
799 tor_gmtime_r(&t_res
, &b_time
);
800 TM_EQUAL(a_time
, b_time
);
802 /* This value is out of range with 32 bit time_t, but in range for 64 bit
804 a_time
.tm_year
= 2039-1900;
805 #if SIZEOF_TIME_T == 4
806 setup_full_capture_of_logs(LOG_WARN
);
807 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
808 //expect_single_log_msg_containing("Result does not fit in tor_timegm");
809 teardown_capture_of_logs();
810 #elif SIZEOF_TIME_T == 8
811 t_res
= 2178252895UL;
812 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
813 tor_gmtime_r(&t_res
, &b_time
);
814 TM_EQUAL(a_time
, b_time
);
815 #endif /* SIZEOF_TIME_T == 4 || ... */
817 /* Test tor_timegm out of range */
819 /* The below tests will all cause a BUG message, so we capture, suppress,
821 #define CAPTURE() do { \
822 teardown_capture_of_logs(); \
823 setup_full_capture_of_logs(LOG_WARN); \
825 #define CHECK_TIMEGM_WARNING(msg) do { \
826 expect_single_log_msg_containing(msg); \
828 #define CHECK_POSSIBLE_EINVAL() do { \
829 if (mock_saved_log_n_entries()) { \
830 expect_single_log_msg_containing("Invalid argument"); \
834 #define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
835 CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
839 /* Wrong year < 1970 */
840 a_time
.tm_year
= 1969-1900;
842 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
843 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
845 a_time
.tm_year
= -1-1900;
847 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
848 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
850 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
851 a_time
.tm_year
= -1*(1 << 16);
853 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
854 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
856 /* one of the smallest tm_year values my 64 bit system supports:
857 * t_res = -9223372036854775LL without clamping */
858 a_time
.tm_year
= -292275055-1900;
860 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
861 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
863 a_time
.tm_year
= INT32_MIN
;
865 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
866 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
867 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
870 a_time
.tm_year
= -1*(1 << 48);
872 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
873 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
875 /* while unlikely, the system's gmtime(_r) could return
876 * a "correct" retrospective gregorian negative year value,
877 * which I'm pretty sure is:
878 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
879 * 730485 is the number of days in two millennia, including leap days */
880 a_time
.tm_year
= -292277022657-1900;
882 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
883 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
885 a_time
.tm_year
= INT64_MIN
;
887 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
888 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
889 #endif /* SIZEOF_INT == 8 */
891 /* Wrong year >= INT32_MAX - 1900 */
892 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
893 a_time
.tm_year
= INT32_MAX
-1900;
895 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
896 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
898 a_time
.tm_year
= INT32_MAX
;
900 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
901 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
902 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
905 /* one of the largest tm_year values my 64 bit system supports */
906 a_time
.tm_year
= 292278994-1900;
908 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
909 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
911 /* while unlikely, the system's gmtime(_r) could return
912 * a "correct" proleptic gregorian year value,
913 * which I'm pretty sure is:
914 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
915 * 730485 is the number of days in two millennia, including leap days */
916 a_time
.tm_year
= 292277026596-1900;
918 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
919 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
921 a_time
.tm_year
= INT64_MAX
-1900;
923 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
924 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
926 a_time
.tm_year
= INT64_MAX
;
928 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
929 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
930 #endif /* SIZEOF_INT == 8 */
933 a_time
.tm_year
= 2007-1900; /* restore valid year */
935 a_time
.tm_mon
= 12; /* Wrong month, it's 0-based */
937 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
938 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
940 a_time
.tm_mon
= -1; /* Wrong month */
942 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
943 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
946 a_time
.tm_mon
= 6; /* Try July */
947 a_time
.tm_mday
= 32; /* Wrong day */
949 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
950 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
952 a_time
.tm_mon
= 5; /* Try June */
953 a_time
.tm_mday
= 31; /* Wrong day */
955 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
956 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
958 a_time
.tm_year
= 2008-1900; /* Try a leap year */
959 a_time
.tm_mon
= 1; /* in feb. */
960 a_time
.tm_mday
= 30; /* Wrong day */
962 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
963 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
965 a_time
.tm_year
= 2011-1900; /* Try a non-leap year */
966 a_time
.tm_mon
= 1; /* in feb. */
967 a_time
.tm_mday
= 29; /* Wrong day */
969 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
970 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
972 a_time
.tm_mday
= 0; /* Wrong day, it's 1-based (to be different) */
974 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
975 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
978 a_time
.tm_mday
= 3; /* restore valid month day */
980 a_time
.tm_hour
= 24; /* Wrong hour, it's 0-based */
982 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
983 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
985 a_time
.tm_hour
= -1; /* Wrong hour */
987 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
988 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
991 a_time
.tm_hour
= 22; /* restore valid hour */
993 a_time
.tm_min
= 60; /* Wrong minute, it's 0-based */
995 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
996 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
998 a_time
.tm_min
= -1; /* Wrong minute */
1000 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
1001 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1004 a_time
.tm_min
= 37; /* restore valid minute */
1006 a_time
.tm_sec
= 61; /* Wrong second: 0-based with leap seconds */
1008 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
1009 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1011 a_time
.tm_sec
= -1; /* Wrong second */
1013 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
1014 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1016 /* Test tor_gmtime_r out of range */
1018 /* time_t < 0 yields a year clamped to 1 or 1970,
1019 * depending on whether the implementation of the system gmtime(_r)
1020 * sets struct tm (1) or not (1970) */
1023 tor_gmtime_r(&t_res
, &b_time
);
1024 CHECK_POSSIBLE_EINVAL();
1025 tt_assert(b_time
.tm_year
== (1970-1900) ||
1026 b_time
.tm_year
== (1969-1900));
1028 if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
1029 t_res
= -1*(1 << 30);
1031 tor_gmtime_r(&t_res
, &b_time
);
1032 CHECK_POSSIBLE_EINVAL();
1033 tt_assert(b_time
.tm_year
== (1970-1900) ||
1034 b_time
.tm_year
== (1935-1900));
1038 tor_gmtime_r(&t_res
, &b_time
);
1039 CHECK_POSSIBLE_EINVAL();
1040 tt_assert(b_time
.tm_year
== (1970-1900) ||
1041 b_time
.tm_year
== (1901-1900));
1044 #if SIZEOF_TIME_T == 8
1046 /* one of the smallest tm_year values my 64 bit system supports:
1047 * b_time.tm_year == (-292275055LL-1900LL) without clamping */
1048 t_res
= -9223372036854775LL;
1050 tor_gmtime_r(&t_res
, &b_time
);
1051 CHECK_POSSIBLE_EINVAL();
1052 tt_assert(b_time
.tm_year
== (1970-1900) ||
1053 b_time
.tm_year
== (1-1900));
1055 /* while unlikely, the system's gmtime(_r) could return
1056 * a "correct" retrospective gregorian negative year value,
1057 * which I'm pretty sure is:
1058 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
1059 * 730485 is the number of days in two millennia, including leap days
1060 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
1063 tor_gmtime_r(&t_res
, &b_time
);
1064 if (! (b_time
.tm_year
== (1970-1900) ||
1065 b_time
.tm_year
== (1-1900))) {
1066 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
1068 if (b_time
.tm_year
!= 1970-1900) {
1069 CHECK_TIMEGM_WARNING("Rounding up to ");
1071 teardown_capture_of_logs();
1075 /* As above, but with localtime. */
1076 t_res
= -9223372036854775LL;
1078 tor_localtime_r(&t_res
, &b_time
);
1079 CHECK_POSSIBLE_EINVAL();
1080 tt_assert(b_time
.tm_year
== (1970-1900) ||
1081 b_time
.tm_year
== (1-1900));
1083 /* while unlikely, the system's gmtime(_r) could return
1084 * a "correct" retrospective gregorian negative year value,
1085 * which I'm pretty sure is:
1086 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
1087 * 730485 is the number of days in two millennia, including leap days
1088 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
1091 tor_localtime_r(&t_res
, &b_time
);
1092 if (! (b_time
.tm_year
== (1970-1900) ||
1093 b_time
.tm_year
== (1-1900))) {
1094 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
1096 if (b_time
.tm_year
!= 1970-1900) {
1097 CHECK_TIMEGM_WARNING("Rounding up to ");
1099 teardown_capture_of_logs();
1102 #endif /* SIZEOF_TIME_T == 8 */
1104 /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
1105 * depending on whether the implementation of the system gmtime(_r)
1106 * sets struct tm (9999) or not (2037) */
1107 #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
1109 t_res
= 3*(1 << 29);
1110 tor_gmtime_r(&t_res
, &b_time
);
1111 tt_assert(b_time
.tm_year
== (2021-1900));
1114 tor_gmtime_r(&t_res
, &b_time
);
1115 tt_assert(b_time
.tm_year
== (2037-1900) ||
1116 b_time
.tm_year
== (2038-1900));
1119 /* as above but with localtime. */
1120 t_res
= 3*(1 << 29);
1121 tor_localtime_r(&t_res
, &b_time
);
1122 tt_assert(b_time
.tm_year
== (2021-1900));
1125 tor_localtime_r(&t_res
, &b_time
);
1126 tt_assert(b_time
.tm_year
== (2037-1900) ||
1127 b_time
.tm_year
== (2038-1900));
1129 #endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
1131 #if SIZEOF_TIME_T == 8
1133 /* one of the largest tm_year values my 64 bit system supports:
1134 * b_time.tm_year == (292278994L-1900L) without clamping */
1135 t_res
= 9223372036854775LL;
1137 tor_gmtime_r(&t_res
, &b_time
);
1138 CHECK_POSSIBLE_EINVAL();
1139 tt_assert(b_time
.tm_year
== (2037-1900) ||
1140 b_time
.tm_year
== (9999-1900));
1142 /* while unlikely, the system's gmtime(_r) could return
1143 * a "correct" proleptic gregorian year value,
1144 * which I'm pretty sure is:
1145 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1146 * 730485 is the number of days in two millennia, including leap days
1147 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1150 tor_gmtime_r(&t_res
, &b_time
);
1151 CHECK_TIMEGM_WARNING("Rounding down to ");
1153 tt_assert(b_time
.tm_year
== (2037-1900) ||
1154 b_time
.tm_year
== (9999-1900));
1157 /* As above but with localtime. */
1158 t_res
= 9223372036854775LL;
1160 tor_localtime_r(&t_res
, &b_time
);
1161 CHECK_POSSIBLE_EINVAL();
1162 tt_assert(b_time
.tm_year
== (2037-1900) ||
1163 b_time
.tm_year
== (9999-1900));
1165 /* while unlikely, the system's gmtime(_r) could return
1166 * a "correct" proleptic gregorian year value,
1167 * which I'm pretty sure is:
1168 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1169 * 730485 is the number of days in two millennia, including leap days
1170 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1173 tor_localtime_r(&t_res
, &b_time
);
1174 CHECK_TIMEGM_WARNING("Rounding down to ");
1176 tt_assert(b_time
.tm_year
== (2037-1900) ||
1177 b_time
.tm_year
== (9999-1900));
1179 #endif /* SIZEOF_TIME_T == 8 */
1181 /* Test {format,parse}_rfc1123_time */
1183 format_rfc1123_time(timestr
, 0);
1184 tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ
, timestr
);
1185 format_rfc1123_time(timestr
, (time_t)1091580502UL);
1186 tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ
, timestr
);
1189 i
= parse_rfc1123_time(timestr
, &t_res
);
1190 tt_int_op(0,OP_EQ
, i
);
1191 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1193 /* This value is in range with 32 bit and 64 bit time_t */
1194 format_rfc1123_time(timestr
, (time_t)2080000000UL);
1195 tt_str_op("Fri, 30 Nov 2035 01:46:40 GMT",OP_EQ
, timestr
);
1198 i
= parse_rfc1123_time(timestr
, &t_res
);
1199 tt_int_op(0,OP_EQ
, i
);
1200 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1202 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1205 format_rfc1123_time(timestr
, (time_t)2150000000UL);
1206 CHECK_POSSIBLE_EINVAL();
1208 #if SIZEOF_TIME_T == 4
1210 /* Wrapping around will have made it this. */
1211 /* On windows, at least, this is clipped to 1 Jan 1970. ??? */
1212 tt_str_op("Sat, 11 Jan 1902 23:45:04 GMT",OP_EQ
, timestr
);
1214 /* Make sure that the right date doesn't parse. */
1215 strlcpy(timestr
, "Wed, 17 Feb 2038 06:13:20 GMT", sizeof(timestr
));
1219 i
= parse_rfc1123_time(timestr
, &t_res
);
1220 // CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1221 tt_int_op(-1,OP_EQ
, i
);
1222 #elif SIZEOF_TIME_T == 8
1223 tt_str_op("Wed, 17 Feb 2038 06:13:20 GMT",OP_EQ
, timestr
);
1226 i
= parse_rfc1123_time(timestr
, &t_res
);
1227 tt_int_op(0,OP_EQ
, i
);
1228 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1229 #endif /* SIZEOF_TIME_T == 4 || ... */
1231 /* The timezone doesn't matter */
1234 parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res
));
1235 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1237 parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
1239 parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res
));
1241 parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res
));
1243 parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res
));
1245 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res
));
1247 parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res
));
1249 parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res
));
1251 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res
));
1253 parse_rfc1123_time("Wed, 30 Mar 1900 23:59:59 GMT", &t_res
));
1257 parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res
));
1259 parse_rfc1123_time("Wed, 29 Feb 2012 16:00:00 GMT", &t_res
));
1261 /* Leap second plus one */
1263 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res
));
1265 /* Test parse_iso_time */
1268 i
= parse_iso_time("", &t_res
);
1269 tt_int_op(-1,OP_EQ
, i
);
1271 i
= parse_iso_time("2004-08-32 00:48:22", &t_res
);
1272 tt_int_op(-1,OP_EQ
, i
);
1274 i
= parse_iso_time("1969-08-03 00:48:22", &t_res
);
1275 tt_int_op(-1,OP_EQ
, i
);
1278 i
= parse_iso_time("2004-08-04 00:48:22", &t_res
);
1279 tt_int_op(0,OP_EQ
, i
);
1280 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1282 i
= parse_iso_time("2004-8-4 0:48:22", &t_res
);
1283 tt_int_op(0,OP_EQ
, i
);
1284 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1286 /* This value is in range with 32 bit and 64 bit time_t */
1288 i
= parse_iso_time("2035-11-30 01:46:40", &t_res
);
1289 tt_int_op(0,OP_EQ
, i
);
1290 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1292 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1295 #if SIZEOF_TIME_T == 4
1297 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1298 tt_int_op(-1,OP_EQ
, i
);
1299 //CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1300 #elif SIZEOF_TIME_T == 8
1301 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1302 tt_int_op(0,OP_EQ
, i
);
1303 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1304 #endif /* SIZEOF_TIME_T == 4 || ... */
1306 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-zz 99-99x99", &t_res
));
1307 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-32 00:00:00", &t_res
));
1308 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 24:00:00", &t_res
));
1309 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:60:00", &t_res
));
1310 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59:62", &t_res
));
1311 tt_int_op(-1,OP_EQ
, parse_iso_time("1969-03-30 23:59:59", &t_res
));
1312 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-00-30 23:59:59", &t_res
));
1313 tt_int_op(-1,OP_EQ
, parse_iso_time("2147483647-08-29 14:00:00", &t_res
));
1314 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59", &t_res
));
1315 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22.100", &t_res
));
1316 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res
));
1318 /* but... that _is_ acceptable if we aren't being strict. */
1320 i
= parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res
, 0, 0);
1321 tt_int_op(0,OP_EQ
, i
);
1322 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1324 /* try nospace variant. */
1326 i
= parse_iso_time_nospace("2004-08-04T00:48:22", &t_res
);
1327 tt_int_op(0,OP_EQ
, i
);
1328 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1330 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04T00:48:22", &t_res
));
1331 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res
));
1332 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04x00:48:22", &t_res
));
1333 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res
));
1335 /* Test tor_gettimeofday */
1338 end
.tv_usec
= 999990;
1340 start
.tv_usec
= 500;
1342 tor_gettimeofday(&start
);
1343 /* now make sure time works. */
1344 tor_gettimeofday(&end
);
1345 /* We might've timewarped a little. */
1346 tt_int_op(tv_udiff(&start
, &end
), OP_GE
, -5000);
1348 /* Test format_iso_time */
1350 tv
.tv_sec
= (time_t)1326296338UL;
1352 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1353 tt_str_op("2012-01-11 15:38:58",OP_EQ
, timestr
);
1354 /* The output of format_local_iso_time will vary by timezone, and setting
1355 our timezone for testing purposes would be a nontrivial flaky pain.
1356 Skip this test for now.
1357 format_local_iso_time(timestr, tv.tv_sec);
1358 test_streq("2012-01-11 10:38:58", timestr);
1360 format_iso_time_nospace(timestr
, (time_t)tv
.tv_sec
);
1361 tt_str_op("2012-01-11T15:38:58",OP_EQ
, timestr
);
1362 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_LEN
);
1363 format_iso_time_nospace_usec(timestr
, &tv
);
1364 tt_str_op("2012-01-11T15:38:58.003060",OP_EQ
, timestr
);
1365 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_USEC_LEN
);
1368 /* This value is in range with 32 bit and 64 bit time_t */
1369 tv
.tv_sec
= (time_t)2080000000UL;
1370 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1371 tt_str_op("2035-11-30 01:46:40",OP_EQ
, timestr
);
1373 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1375 tv
.tv_sec
= (time_t)2150000000UL;
1377 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1378 CHECK_POSSIBLE_EINVAL();
1379 #if SIZEOF_TIME_T == 4
1380 /* format_iso_time should indicate failure on overflow, but it doesn't yet.
1381 * Hopefully #18480 will improve the failure semantics in this case.
1382 tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
1384 #elif SIZEOF_TIME_T == 8
1386 /* This SHOULD work on windows too; see bug #18665 */
1387 tt_str_op("2038-02-17 06:13:20",OP_EQ
, timestr
);
1389 #endif /* SIZEOF_TIME_T == 4 || ... */
1392 #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
1393 #undef CHECK_POSSIBLE_EINVAL
1396 teardown_capture_of_logs();
1400 test_util_parse_http_time(void *arg
)
1403 char b
[ISO_TIME_LEN
+1];
1407 format_iso_time(b, tor_timegm(&a_time)); \
1408 tt_str_op(b, OP_EQ, (s)); \
1412 /* Test parse_http_time */
1415 parse_http_time("", &a_time
));
1417 parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time
));
1419 parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time
));
1421 parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time
));
1423 parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time
));
1425 parse_http_time("Sunday, August the third", &a_time
));
1427 parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time
));
1430 parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time
));
1431 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1432 T("1994-08-04 00:48:22");
1434 parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time
));
1435 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1436 T("1994-08-04 00:48:22");
1438 parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time
));
1439 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1440 T("1994-08-04 00:48:22");
1442 parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time
));
1443 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1444 T("1994-08-04 00:48:22");
1446 parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time
));
1447 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1448 T("1994-08-04 00:48:22");
1450 parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time
));
1451 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1452 T("1994-08-04 00:48:22");
1453 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time
));
1454 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1455 T("1994-08-04 00:48:22");
1456 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time
));
1457 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1458 T("1994-08-04 00:48:22");
1459 tt_int_op(0,OP_EQ
, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time
));
1460 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1461 T("1994-08-04 00:48:22");
1462 tt_int_op(0,OP_EQ
,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time
));
1463 tt_int_op((time_t)1325376000UL,OP_EQ
, tor_timegm(&a_time
));
1464 T("2012-01-01 00:00:00");
1465 tt_int_op(0,OP_EQ
,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time
));
1466 tt_int_op((time_t)1356912000UL,OP_EQ
, tor_timegm(&a_time
));
1467 T("2012-12-31 00:00:00");
1469 /* This value is in range with 32 bit and 64 bit time_t */
1470 tt_int_op(0,OP_EQ
,parse_http_time("Fri, 30 Nov 2035 01:46:40 GMT", &a_time
));
1471 tt_int_op((time_t)2080000000UL,OP_EQ
, tor_timegm(&a_time
));
1472 T("2035-11-30 01:46:40");
1474 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1476 #if SIZEOF_TIME_T == 4
1477 /* parse_http_time should indicate failure on overflow, but it doesn't yet.
1478 * Hopefully #18480 will improve the failure semantics in this case. */
1479 setup_full_capture_of_logs(LOG_WARN
);
1480 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1481 tt_int_op((time_t)-1,OP_EQ
, tor_timegm(&a_time
));
1482 //expect_single_log_msg_containing("does not fit in tor_timegm");
1483 teardown_capture_of_logs();
1484 #elif SIZEOF_TIME_T == 8
1485 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1486 tt_int_op((time_t)2150000000UL,OP_EQ
, tor_timegm(&a_time
));
1487 T("2038-02-17 06:13:20");
1488 #endif /* SIZEOF_TIME_T == 4 || ... */
1490 tt_int_op(-1,OP_EQ
, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time
));
1491 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-32 00:00:00 GMT", &a_time
));
1492 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 24:00:00 GMT", &a_time
));
1493 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:60:00 GMT", &a_time
));
1494 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59:62 GMT", &a_time
));
1495 tt_int_op(-1,OP_EQ
, parse_http_time("1969-03-30 23:59:59 GMT", &a_time
));
1496 tt_int_op(-1,OP_EQ
, parse_http_time("2011-00-30 23:59:59 GMT", &a_time
));
1497 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59", &a_time
));
1501 teardown_capture_of_logs();
1505 test_util_timegm_real(void *arg
)
1508 /* Get the real timegm again! We're not testing our impl; we want the
1509 * one that will actually get called. */
1512 /* Now check: is timegm the real inverse of gmtime? */
1513 time_t now
= time(NULL
), time2
=0;
1515 p
= tor_gmtime_r(&now
, &tm
);
1516 tt_ptr_op(p
, OP_NE
, NULL
);
1518 int r
= tor_timegm(&tm
, &time2
);
1519 tt_int_op(r
, OP_EQ
, 0);
1520 tt_i64_op((int64_t) now
, OP_EQ
, (int64_t) time2
);
1527 test_util_config_line(void *arg
)
1530 char *k
=NULL
, *v
=NULL
;
1533 /* Test parse_config_line_from_str */
1535 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
1537 "k3 \n" "\n" " \n" "#comment\n"
1538 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
1539 "kseven \"a quoted 'string\"\n"
1540 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
1541 "k9 a line that\\\n spans two lines.\n\n"
1542 "k10 more than\\\n one contin\\\nuation\n"
1543 "k11 \\\ncontinuation at the start\n"
1544 "k12 line with a\\\n#comment\n embedded\n"
1545 "k13\\\ncontinuation at the very start\n"
1546 "k14 a line that has a comment and # ends with a slash \\\n"
1547 "k15 this should be the next new line\n"
1548 "k16 a line that has a comment and # ends without a slash \n"
1549 "k17 this should be the next new line\n"
1553 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1554 tt_str_op(k
,OP_EQ
, "k");
1555 tt_str_op(v
,OP_EQ
, "v");
1556 tor_free(k
); tor_free(v
);
1557 tt_assert(!strcmpstart(str
, "key value with"));
1559 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1560 tt_str_op(k
,OP_EQ
, "key");
1561 tt_str_op(v
,OP_EQ
, "value with spaces");
1562 tor_free(k
); tor_free(v
);
1563 tt_assert(!strcmpstart(str
, "keykey"));
1565 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1566 tt_str_op(k
,OP_EQ
, "keykey");
1567 tt_str_op(v
,OP_EQ
, "val");
1568 tor_free(k
); tor_free(v
);
1569 tt_assert(!strcmpstart(str
, "k2\n"));
1571 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1572 tt_str_op(k
,OP_EQ
, "k2");
1573 tt_str_op(v
,OP_EQ
, "");
1574 tor_free(k
); tor_free(v
);
1575 tt_assert(!strcmpstart(str
, "k3 \n"));
1577 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1578 tt_str_op(k
,OP_EQ
, "k3");
1579 tt_str_op(v
,OP_EQ
, "");
1580 tor_free(k
); tor_free(v
);
1581 tt_assert(!strcmpstart(str
, "#comment"));
1583 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1584 tt_str_op(k
,OP_EQ
, "k4");
1585 tt_str_op(v
,OP_EQ
, "");
1586 tor_free(k
); tor_free(v
);
1587 tt_assert(!strcmpstart(str
, "k5#abc"));
1589 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1590 tt_str_op(k
,OP_EQ
, "k5");
1591 tt_str_op(v
,OP_EQ
, "");
1592 tor_free(k
); tor_free(v
);
1593 tt_assert(!strcmpstart(str
, "k6"));
1595 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1596 tt_str_op(k
,OP_EQ
, "k6");
1597 tt_str_op(v
,OP_EQ
, "val");
1598 tor_free(k
); tor_free(v
);
1599 tt_assert(!strcmpstart(str
, "kseven"));
1601 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1602 tt_str_op(k
,OP_EQ
, "kseven");
1603 tt_str_op(v
,OP_EQ
, "a quoted \'string");
1604 tor_free(k
); tor_free(v
);
1605 tt_assert(!strcmpstart(str
, "k8 "));
1607 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1608 tt_str_op(k
,OP_EQ
, "k8");
1609 tt_str_op(v
,OP_EQ
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
1610 tor_free(k
); tor_free(v
);
1612 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1613 tt_str_op(k
,OP_EQ
, "k9");
1614 tt_str_op(v
,OP_EQ
, "a line that spans two lines.");
1615 tor_free(k
); tor_free(v
);
1617 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1618 tt_str_op(k
,OP_EQ
, "k10");
1619 tt_str_op(v
,OP_EQ
, "more than one continuation");
1620 tor_free(k
); tor_free(v
);
1622 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1623 tt_str_op(k
,OP_EQ
, "k11");
1624 tt_str_op(v
,OP_EQ
, "continuation at the start");
1625 tor_free(k
); tor_free(v
);
1627 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1628 tt_str_op(k
,OP_EQ
, "k12");
1629 tt_str_op(v
,OP_EQ
, "line with a embedded");
1630 tor_free(k
); tor_free(v
);
1632 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1633 tt_str_op(k
,OP_EQ
, "k13");
1634 tt_str_op(v
,OP_EQ
, "continuation at the very start");
1635 tor_free(k
); tor_free(v
);
1637 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1638 tt_str_op(k
,OP_EQ
, "k14");
1639 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1640 tor_free(k
); tor_free(v
);
1642 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1643 tt_str_op(k
,OP_EQ
, "k15");
1644 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1645 tor_free(k
); tor_free(v
);
1647 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1648 tt_str_op(k
,OP_EQ
, "k16");
1649 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1650 tor_free(k
); tor_free(v
);
1652 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1653 tt_str_op(k
,OP_EQ
, "k17");
1654 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1655 tor_free(k
); tor_free(v
);
1657 tt_str_op(str
,OP_EQ
, "");
1665 test_util_config_line_quotes(void *arg
)
1671 char *k
=NULL
, *v
=NULL
;
1674 /* Test parse_config_line_from_str */
1676 strlcpy(buf1
, "kTrailingSpace \"quoted value\" \n"
1677 "kTrailingGarbage \"quoted value\"trailing garbage\n"
1679 strlcpy(buf2
, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
1681 strlcpy(buf3
, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
1683 strlcpy(buf4
, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
1687 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1688 tt_str_op(k
,OP_EQ
, "kTrailingSpace");
1689 tt_str_op(v
,OP_EQ
, "quoted value");
1690 tor_free(k
); tor_free(v
);
1692 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1693 tt_ptr_op(str
,OP_EQ
, NULL
);
1694 tor_free(k
); tor_free(v
);
1698 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1699 tt_ptr_op(str
,OP_EQ
, NULL
);
1700 tor_free(k
); tor_free(v
);
1704 const char *err
= NULL
;
1705 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1706 tt_ptr_op(str
,OP_EQ
, NULL
);
1707 tor_free(k
); tor_free(v
);
1708 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1713 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1714 tt_ptr_op(str
,OP_EQ
, NULL
);
1715 tor_free(k
); tor_free(v
);
1716 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1724 test_util_config_line_comment_character(void *arg
)
1727 char *k
=NULL
, *v
=NULL
;
1730 /* Test parse_config_line_from_str */
1732 strlcpy(buf
, "k1 \"# in quotes\"\n"
1733 "k2 some value # some comment\n"
1734 "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
1738 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1739 tt_str_op(k
,OP_EQ
, "k1");
1740 tt_str_op(v
,OP_EQ
, "# in quotes");
1741 tor_free(k
); tor_free(v
);
1743 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1744 tt_str_op(k
,OP_EQ
, "k2");
1745 tt_str_op(v
,OP_EQ
, "some value");
1746 tor_free(k
); tor_free(v
);
1748 tt_str_op(str
,OP_EQ
, "k3 /home/user/myTorNetwork#2\n");
1751 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1752 test_streq(k
, "k3");
1753 test_streq(v
, "/home/user/myTorNetwork#2");
1754 tor_free(k
); tor_free(v
);
1756 test_streq(str
, "");
1765 test_util_config_line_escaped_content(void *arg
)
1773 char *k
=NULL
, *v
=NULL
;
1776 /* Test parse_config_line_from_str */
1778 strlcpy(buf1
, "HexadecimalLower \"\\x2a\"\n"
1779 "HexadecimalUpper \"\\x2A\"\n"
1780 "HexadecimalUpperX \"\\X2A\"\n"
1784 "CarriageReturn \"\\r\"\n"
1785 "DoubleQuote \"\\\"\"\n"
1786 "SimpleQuote \"\\'\"\n"
1787 "Backslash \"\\\\\"\n"
1788 "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
1791 strlcpy(buf2
, "BrokenEscapedContent \"\\a\"\n"
1794 strlcpy(buf3
, "BrokenEscapedContent \"\\x\"\n"
1797 strlcpy(buf4
, "BrokenOctal \"\\8\"\n"
1800 strlcpy(buf5
, "BrokenHex \"\\xg4\"\n"
1803 strlcpy(buf6
, "BrokenEscape \"\\"
1808 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1809 tt_str_op(k
,OP_EQ
, "HexadecimalLower");
1810 tt_str_op(v
,OP_EQ
, "*");
1811 tor_free(k
); tor_free(v
);
1813 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1814 tt_str_op(k
,OP_EQ
, "HexadecimalUpper");
1815 tt_str_op(v
,OP_EQ
, "*");
1816 tor_free(k
); tor_free(v
);
1818 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1819 tt_str_op(k
,OP_EQ
, "HexadecimalUpperX");
1820 tt_str_op(v
,OP_EQ
, "*");
1821 tor_free(k
); tor_free(v
);
1823 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1824 tt_str_op(k
,OP_EQ
, "Octal");
1825 tt_str_op(v
,OP_EQ
, "*");
1826 tor_free(k
); tor_free(v
);
1828 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1829 tt_str_op(k
,OP_EQ
, "Newline");
1830 tt_str_op(v
,OP_EQ
, "\n");
1831 tor_free(k
); tor_free(v
);
1833 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1834 tt_str_op(k
,OP_EQ
, "Tab");
1835 tt_str_op(v
,OP_EQ
, "\t");
1836 tor_free(k
); tor_free(v
);
1838 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1839 tt_str_op(k
,OP_EQ
, "CarriageReturn");
1840 tt_str_op(v
,OP_EQ
, "\r");
1841 tor_free(k
); tor_free(v
);
1843 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1844 tt_str_op(k
,OP_EQ
, "DoubleQuote");
1845 tt_str_op(v
,OP_EQ
, "\"");
1846 tor_free(k
); tor_free(v
);
1848 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1849 tt_str_op(k
,OP_EQ
, "SimpleQuote");
1850 tt_str_op(v
,OP_EQ
, "'");
1851 tor_free(k
); tor_free(v
);
1853 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1854 tt_str_op(k
,OP_EQ
, "Backslash");
1855 tt_str_op(v
,OP_EQ
, "\\");
1856 tor_free(k
); tor_free(v
);
1858 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1859 tt_str_op(k
,OP_EQ
, "Mix");
1860 tt_str_op(v
,OP_EQ
, "This is a \"star\":\t'*'\nAnd second line");
1861 tor_free(k
); tor_free(v
);
1862 tt_str_op(str
,OP_EQ
, "");
1866 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1867 tt_ptr_op(str
,OP_EQ
, NULL
);
1868 tor_free(k
); tor_free(v
);
1872 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1873 tt_ptr_op(str
,OP_EQ
, NULL
);
1874 tor_free(k
); tor_free(v
);
1878 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1879 tt_ptr_op(str
,OP_EQ
, NULL
);
1880 tor_free(k
); tor_free(v
);
1885 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1886 tt_ptr_op(str
, OP_EQ
, NULL
);
1887 tor_free(k
); tor_free(v
);
1892 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1893 tt_ptr_op(str
,OP_EQ
, NULL
);
1894 tor_free(k
); tor_free(v
);
1896 /* more things to try. */
1898 strlcpy(buf1
, "Foo \"\\x9g\"\n", sizeof(buf1
));
1899 strlcpy(buf2
, "Foo \"\\xg0\"\n", sizeof(buf2
));
1900 strlcpy(buf3
, "Foo \"\\xf\"\n", sizeof(buf3
));
1902 strlcpy(buf4
, "Foo \"\\q\"\n", sizeof(buf4
));
1903 /* missing endquote */
1904 strlcpy(buf5
, "Foo \"hello\n", sizeof(buf5
));
1906 strlcpy(buf6
, "Foo \"hello\" world\n", sizeof(buf6
));
1909 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1910 tt_ptr_op(str
,OP_EQ
, NULL
);
1911 tor_free(k
); tor_free(v
);
1914 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1915 tt_ptr_op(str
,OP_EQ
, NULL
);
1916 tor_free(k
); tor_free(v
);
1919 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1920 tt_ptr_op(str
,OP_EQ
, NULL
);
1921 tor_free(k
); tor_free(v
);
1924 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1925 tt_ptr_op(str
,OP_EQ
, NULL
);
1926 tor_free(k
); tor_free(v
);
1930 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1931 tt_ptr_op(str
,OP_EQ
, NULL
);
1932 tor_free(k
); tor_free(v
);
1935 const char *err
= NULL
;
1936 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1937 tt_ptr_op(str
,OP_EQ
, NULL
);
1938 tor_free(k
); tor_free(v
);
1939 tt_str_op(err
,OP_EQ
, "Excess data after quoted string");
1947 test_util_config_line_crlf(void *arg
)
1949 char *k
=NULL
, *v
=NULL
;
1950 const char *err
= NULL
;
1954 "Hello \"nice big world\"\r\n";
1956 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1958 tt_str_op(k
,OP_EQ
,"Hello");
1959 tt_str_op(v
,OP_EQ
,"world");
1960 tt_ptr_op(err
, OP_EQ
, NULL
);
1961 tor_free(k
); tor_free(v
);
1963 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1965 tt_str_op(k
,OP_EQ
,"Hello");
1966 tt_str_op(v
,OP_EQ
,"nice big world");
1967 tt_ptr_op(err
, OP_EQ
, NULL
);
1968 tor_free(k
); tor_free(v
);
1969 tt_str_op(str
,OP_EQ
, "");
1972 tor_free(k
); tor_free(v
);
1976 test_util_config_line_partition(void *arg
)
1979 config_line_t
*lines
= NULL
, *orig
, *rest
= NULL
;
1981 config_line_append(&lines
, "Header", "X");
1982 config_line_append(&lines
, "Item", "Y");
1983 config_line_append(&lines
, "Thing", "Z");
1985 config_line_append(&lines
, "HEADER", "X2");
1987 config_line_append(&lines
, "header", "X3");
1988 config_line_append(&lines
, "Item3", "Foob");
1990 /* set up h2 and h3 to point to the places where we hope the headers will
1992 config_line_t
*h2
= lines
->next
->next
->next
;
1993 config_line_t
*h3
= h2
->next
;
1994 tt_str_op(h2
->key
, OP_EQ
, "HEADER");
1995 tt_str_op(h3
->key
, OP_EQ
, "header");
1998 rest
= config_lines_partition(lines
, "Header");
1999 tt_ptr_op(lines
, OP_EQ
, orig
);
2000 tt_ptr_op(rest
, OP_EQ
, h2
);
2001 tt_str_op(lines
->next
->key
, OP_EQ
, "Item");
2002 tt_str_op(lines
->next
->next
->key
, OP_EQ
, "Thing");
2003 tt_ptr_op(lines
->next
->next
->next
, OP_EQ
, NULL
);
2004 config_free_lines(lines
);
2006 orig
= lines
= rest
;
2007 rest
= config_lines_partition(lines
, "Header");
2008 tt_ptr_op(lines
, OP_EQ
, orig
);
2009 tt_ptr_op(rest
, OP_EQ
, h3
);
2010 tt_ptr_op(lines
->next
, OP_EQ
, NULL
);
2011 config_free_lines(lines
);
2013 orig
= lines
= rest
;
2014 rest
= config_lines_partition(lines
, "Header");
2015 tt_ptr_op(lines
, OP_EQ
, orig
);
2016 tt_ptr_op(rest
, OP_EQ
, NULL
);
2017 tt_str_op(lines
->next
->key
, OP_EQ
, "Item3");
2018 tt_ptr_op(lines
->next
->next
, OP_EQ
, NULL
);
2021 config_free_lines(lines
);
2022 config_free_lines(rest
);
2025 #ifndef DISABLE_PWDB_TESTS
2027 test_util_expand_filename(void *arg
)
2032 setenv("HOME", "/home/itv", 1); /* For "internal test value" */
2034 str
= expand_filename("");
2035 tt_str_op("",OP_EQ
, str
);
2038 str
= expand_filename("/normal/path");
2039 tt_str_op("/normal/path",OP_EQ
, str
);
2042 str
= expand_filename("/normal/trailing/path/");
2043 tt_str_op("/normal/trailing/path/",OP_EQ
, str
);
2046 str
= expand_filename("~");
2047 tt_str_op("/home/itv/",OP_EQ
, str
);
2050 str
= expand_filename("$HOME/nodice");
2051 tt_str_op("$HOME/nodice",OP_EQ
, str
);
2054 str
= expand_filename("~/");
2055 tt_str_op("/home/itv/",OP_EQ
, str
);
2058 str
= expand_filename("~/foobarqux");
2059 tt_str_op("/home/itv/foobarqux",OP_EQ
, str
);
2062 str
= expand_filename("~/../../etc/passwd");
2063 tt_str_op("/home/itv/../../etc/passwd",OP_EQ
, str
);
2066 str
= expand_filename("~/trailing/");
2067 tt_str_op("/home/itv/trailing/",OP_EQ
, str
);
2069 /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
2070 have to somehow inject/fake the get_user_homedir call) */
2072 /* $HOME ending in a trailing slash */
2073 setenv("HOME", "/home/itv/", 1);
2075 str
= expand_filename("~");
2076 tt_str_op("/home/itv/",OP_EQ
, str
);
2079 str
= expand_filename("~/");
2080 tt_str_op("/home/itv/",OP_EQ
, str
);
2083 str
= expand_filename("~/foo");
2084 tt_str_op("/home/itv/foo",OP_EQ
, str
);
2087 /* Try with empty $HOME */
2089 setenv("HOME", "", 1);
2091 str
= expand_filename("~");
2092 tt_str_op("/",OP_EQ
, str
);
2095 str
= expand_filename("~/");
2096 tt_str_op("/",OP_EQ
, str
);
2099 str
= expand_filename("~/foobar");
2100 tt_str_op("/foobar",OP_EQ
, str
);
2103 /* Try with $HOME unset */
2107 str
= expand_filename("~");
2108 tt_str_op("/",OP_EQ
, str
);
2111 str
= expand_filename("~/");
2112 tt_str_op("/",OP_EQ
, str
);
2115 str
= expand_filename("~/foobar");
2116 tt_str_op("/foobar",OP_EQ
, str
);
2122 #endif /* !defined(DISABLE_PWDB_TESTS) */
2124 /** Test tor_escape_str_for_pt_args(). */
2126 test_util_escape_string_socks(void *arg
)
2128 char *escaped_string
= NULL
;
2130 /** Simple backslash escape. */
2132 escaped_string
= tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
2133 tt_assert(escaped_string
);
2134 tt_str_op(escaped_string
,OP_EQ
, "This is a backslash: \\\\");
2135 tor_free(escaped_string
);
2137 /** Simple semicolon escape. */
2138 escaped_string
= tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
2139 tt_assert(escaped_string
);
2140 tt_str_op(escaped_string
,OP_EQ
, "First rule:Do not use \\;");
2141 tor_free(escaped_string
);
2143 /** Empty string. */
2144 escaped_string
= tor_escape_str_for_pt_args("", ";\\");
2145 tt_assert(escaped_string
);
2146 tt_str_op(escaped_string
,OP_EQ
, "");
2147 tor_free(escaped_string
);
2149 /** Escape all characters. */
2150 escaped_string
= tor_escape_str_for_pt_args(";\\;\\", ";\\");
2151 tt_assert(escaped_string
);
2152 tt_str_op(escaped_string
,OP_EQ
, "\\;\\\\\\;\\\\");
2153 tor_free(escaped_string
);
2155 escaped_string
= tor_escape_str_for_pt_args(";", ";\\");
2156 tt_assert(escaped_string
);
2157 tt_str_op(escaped_string
,OP_EQ
, "\\;");
2158 tor_free(escaped_string
);
2161 tor_free(escaped_string
);
2165 test_util_string_is_key_value(void *ptr
)
2168 tt_assert(string_is_key_value(LOG_WARN
, "key=value"));
2169 tt_assert(string_is_key_value(LOG_WARN
, "k=v"));
2170 tt_assert(string_is_key_value(LOG_WARN
, "key="));
2171 tt_assert(string_is_key_value(LOG_WARN
, "x="));
2172 tt_assert(string_is_key_value(LOG_WARN
, "xx="));
2173 tt_assert(!string_is_key_value(LOG_WARN
, "=value"));
2174 tt_assert(!string_is_key_value(LOG_WARN
, "=x"));
2175 tt_assert(!string_is_key_value(LOG_WARN
, "="));
2178 /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
2183 /** Test basic string functionality. */
2185 test_util_strmisc(void *arg
)
2188 char *cp_tmp
= NULL
;
2190 /* Test strl operations */
2192 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 0));
2193 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 10));
2194 tt_str_op(buf
,OP_EQ
, "Hello");
2195 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 6));
2196 tt_str_op(buf
,OP_EQ
, "Hello");
2197 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 5));
2198 tt_str_op(buf
,OP_EQ
, "Hell");
2199 strlcpy(buf
, "Hello", sizeof(buf
));
2200 tt_int_op(10,OP_EQ
, strlcat(buf
, "Hello", 5));
2202 /* Test strstrip() */
2203 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
2204 tor_strstrip(buf
, ",!");
2205 tt_str_op(buf
,OP_EQ
, "Testing 1 2 3");
2206 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
2207 tor_strstrip(buf
, "!? ");
2208 tt_str_op(buf
,OP_EQ
, "Testing123");
2209 strlcpy(buf
, "!!!Testing 1 2 3??", sizeof(buf
));
2210 tor_strstrip(buf
, "!? ");
2211 tt_str_op(buf
,OP_EQ
, "Testing123");
2214 /* Returning -1 when there's not enough room in the output buffer */
2215 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 0, "Foo"));
2216 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 2, "Foo"));
2217 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 3, "Foo"));
2218 tt_int_op(-1,OP_NE
, tor_snprintf(buf
, 4, "Foo"));
2219 /* Always NUL-terminate the output */
2220 tor_snprintf(buf
, 5, "abcdef");
2221 tt_int_op(0,OP_EQ
, buf
[4]);
2222 tor_snprintf(buf
, 10, "abcdef");
2223 tt_int_op(0,OP_EQ
, buf
[6]);
2225 tor_snprintf(buf
, sizeof(buf
), "x!%"PRIu64
"!x",
2226 (UINT64_C(12345678901)));
2227 tt_str_op("x!12345678901!x",OP_EQ
, buf
);
2229 /* Test str{,case}cmpstart */
2230 tt_assert(strcmpstart("abcdef", "abcdef")==0);
2231 tt_assert(strcmpstart("abcdef", "abc")==0);
2232 tt_assert(strcmpstart("abcdef", "abd")<0);
2233 tt_assert(strcmpstart("abcdef", "abb")>0);
2234 tt_assert(strcmpstart("ab", "abb")<0);
2235 tt_assert(strcmpstart("ab", "")==0);
2236 tt_assert(strcmpstart("ab", "ab ")<0);
2237 tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
2238 tt_assert(strcasecmpstart("abcDeF", "abc")==0);
2239 tt_assert(strcasecmpstart("abcdef", "Abd")<0);
2240 tt_assert(strcasecmpstart("Abcdef", "abb")>0);
2241 tt_assert(strcasecmpstart("ab", "Abb")<0);
2242 tt_assert(strcasecmpstart("ab", "")==0);
2243 tt_assert(strcasecmpstart("ab", "ab ")<0);
2245 /* Test str{,case}cmpend */
2246 tt_assert(strcmpend("abcdef", "abcdef")==0);
2247 tt_assert(strcmpend("abcdef", "def")==0);
2248 tt_assert(strcmpend("abcdef", "deg")<0);
2249 tt_assert(strcmpend("abcdef", "dee")>0);
2250 tt_assert(strcmpend("ab", "aab")>0);
2251 tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
2252 tt_assert(strcasecmpend("abcdef", "dEF")==0);
2253 tt_assert(strcasecmpend("abcdef", "Deg")<0);
2254 tt_assert(strcasecmpend("abcDef", "dee")>0);
2255 tt_assert(strcasecmpend("AB", "abb")<0);
2257 /* Test digest_is_zero */
2260 tt_assert(tor_digest_is_zero(buf
));
2262 tt_assert(!tor_digest_is_zero(buf
));
2264 /* Test mem_is_zero */
2267 tt_assert(fast_mem_is_zero(buf
, 10));
2268 tt_assert(fast_mem_is_zero(buf
, 20));
2269 tt_assert(fast_mem_is_zero(buf
, 128));
2270 tt_assert(!fast_mem_is_zero(buf
, 129));
2271 buf
[60] = (char)255;
2272 tt_assert(!fast_mem_is_zero(buf
, 128));
2274 tt_assert(!fast_mem_is_zero(buf
, 10));
2276 /* Test 'escaped' */
2277 tt_ptr_op(escaped(NULL
), OP_EQ
, NULL
);
2278 tt_str_op("\"\"",OP_EQ
, escaped(""));
2279 tt_str_op("\"abcd\"",OP_EQ
, escaped("abcd"));
2280 tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ
, escaped("\\ \n\r\t\"'"));
2281 tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ
,
2282 escaped("unnecessary \'backslashes\'"));
2283 /* Non-printable characters appear as octal */
2284 tt_str_op("\"z\\001abc\\277d\"",OP_EQ
, escaped("z\001abc\277d"));
2285 tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ
, escaped("z\xde\xad\x20;foo"));
2287 /* Other cases of esc_for_log{,_len} */
2288 cp_tmp
= esc_for_log(NULL
);
2289 tt_str_op(cp_tmp
, OP_EQ
, "(null)");
2291 cp_tmp
= esc_for_log_len("abcdefg", 3);
2292 tt_str_op(cp_tmp
, OP_EQ
, "\"abc\"");
2294 cp_tmp
= esc_for_log_len("abcdefg", 100);
2295 tt_str_op(cp_tmp
, OP_EQ
, "\"abcdefg\"");
2298 /* Test strndup and memdup */
2300 const char *s
= "abcdefghijklmnopqrstuvwxyz";
2301 cp_tmp
= tor_strndup(s
, 30);
2302 tt_str_op(cp_tmp
,OP_EQ
, s
); /* same string, */
2303 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2306 cp_tmp
= tor_strndup(s
, 5);
2307 tt_str_op(cp_tmp
,OP_EQ
, "abcde");
2310 s
= "a\0b\0c\0d\0e\0";
2311 cp_tmp
= tor_memdup(s
,10);
2312 tt_mem_op(cp_tmp
,OP_EQ
, s
, 10); /* same ram, */
2313 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2317 /* Test str-foo functions */
2318 cp_tmp
= tor_strdup("abcdef");
2319 tt_assert(tor_strisnonupper(cp_tmp
));
2321 tt_assert(!tor_strisnonupper(cp_tmp
));
2322 tor_strupper(cp_tmp
);
2323 tt_str_op(cp_tmp
,OP_EQ
, "ABCDEF");
2324 tor_strlower(cp_tmp
);
2325 tt_str_op(cp_tmp
,OP_EQ
, "abcdef");
2326 tt_assert(tor_strisnonupper(cp_tmp
));
2327 tt_assert(tor_strisprint(cp_tmp
));
2329 tt_assert(!tor_strisprint(cp_tmp
));
2332 /* Test memmem and memstr */
2334 const char *haystack
= "abcde";
2335 tt_ptr_op(tor_memmem(haystack
, 5, "ef", 2), OP_EQ
, NULL
);
2336 tt_ptr_op(tor_memmem(haystack
, 5, "cd", 2),OP_EQ
, haystack
+ 2);
2337 tt_ptr_op(tor_memmem(haystack
, 5, "cde", 3),OP_EQ
, haystack
+ 2);
2338 tt_ptr_op(tor_memmem(haystack
, 4, "cde", 3), OP_EQ
, NULL
);
2339 haystack
= "ababcad";
2340 tt_ptr_op(tor_memmem(haystack
, 7, "abc", 3),OP_EQ
, haystack
+ 2);
2341 tt_ptr_op(tor_memmem(haystack
, 7, "ad", 2),OP_EQ
, haystack
+ 5);
2342 tt_ptr_op(tor_memmem(haystack
, 7, "cad", 3),OP_EQ
, haystack
+ 4);
2343 tt_ptr_op(tor_memmem(haystack
, 7, "dadad", 5), OP_EQ
, NULL
);
2344 tt_ptr_op(tor_memmem(haystack
, 7, "abcdefghij", 10), OP_EQ
, NULL
);
2346 tt_ptr_op(tor_memstr(haystack
, 7, "abc"),OP_EQ
, haystack
+ 2);
2347 tt_ptr_op(tor_memstr(haystack
, 7, "cad"),OP_EQ
, haystack
+ 4);
2348 tt_ptr_op(tor_memstr(haystack
, 6, "cad"), OP_EQ
, NULL
);
2349 tt_ptr_op(tor_memstr(haystack
, 7, "cadd"), OP_EQ
, NULL
);
2350 tt_ptr_op(tor_memstr(haystack
, 7, "fe"), OP_EQ
, NULL
);
2351 tt_ptr_op(tor_memstr(haystack
, 7, "ababcade"), OP_EQ
, NULL
);
2356 char binary_data
[68];
2358 for (idx
= 0; idx
< sizeof(binary_data
); ++idx
)
2359 binary_data
[idx
] = idx
;
2360 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2361 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2362 tt_str_op(hex_str(binary_data
, 17),OP_EQ
,
2363 "000102030405060708090A0B0C0D0E0F10");
2364 tt_str_op(hex_str(binary_data
, 32),OP_EQ
,
2365 "000102030405060708090A0B0C0D0E0F"
2366 "101112131415161718191A1B1C1D1E1F");
2367 tt_str_op(hex_str(binary_data
, 34),OP_EQ
,
2368 "000102030405060708090A0B0C0D0E0F"
2369 "101112131415161718191A1B1C1D1E1F");
2370 /* Repeat these tests for shorter strings after longer strings
2371 have been tried, to make sure we're correctly terminating strings */
2372 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2373 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2376 /* Test strcmp_opt */
2377 tt_int_op(strcmp_opt("", "foo"), OP_LT
, 0);
2378 tt_int_op(strcmp_opt("", ""), OP_EQ
, 0);
2379 tt_int_op(strcmp_opt("foo", ""), OP_GT
, 0);
2381 tt_int_op(strcmp_opt(NULL
, ""), OP_LT
, 0);
2382 tt_int_op(strcmp_opt(NULL
, NULL
), OP_EQ
, 0);
2383 tt_int_op(strcmp_opt("", NULL
), OP_GT
, 0);
2385 tt_int_op(strcmp_opt(NULL
, "foo"), OP_LT
, 0);
2386 tt_int_op(strcmp_opt("foo", NULL
), OP_GT
, 0);
2393 test_util_parse_integer(void *arg
)
2399 /* Test parse_long */
2400 /* Empty/zero input */
2401 tt_int_op(0L,OP_EQ
, tor_parse_long("",10,0,100,&i
,NULL
));
2402 tt_int_op(0,OP_EQ
, i
);
2403 tt_int_op(0L,OP_EQ
, tor_parse_long("0",10,0,100,&i
,NULL
));
2404 tt_int_op(1,OP_EQ
, i
);
2406 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,100,&i
,NULL
));
2407 tt_int_op(1,OP_EQ
, i
);
2408 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,10,&i
,NULL
));
2409 tt_int_op(1,OP_EQ
, i
);
2410 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,10,100,&i
,NULL
));
2411 tt_int_op(1,OP_EQ
, i
);
2412 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,100,&i
,NULL
));
2413 tt_int_op(1,OP_EQ
, i
);
2414 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,0,&i
,NULL
));
2415 tt_int_op(1,OP_EQ
, i
);
2416 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-50,0,&i
,NULL
));
2417 tt_int_op(1,OP_EQ
, i
);
2419 tt_int_op(0L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,NULL
));
2420 tt_int_op(0,OP_EQ
, i
);
2421 tt_int_op(0L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,NULL
));
2422 tt_int_op(0,OP_EQ
, i
);
2423 tt_int_op(10L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,&cp
));
2424 tt_int_op(1,OP_EQ
, i
);
2425 tt_str_op(cp
,OP_EQ
, "m");
2426 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,&cp
));
2427 tt_int_op(1,OP_EQ
, i
);
2428 tt_str_op(cp
,OP_EQ
, " plus garbage");
2429 /* Illogical min max */
2430 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,4,&i
,NULL
));
2431 tt_int_op(0,OP_EQ
, i
);
2432 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,100,-100,&i
,NULL
));
2433 tt_int_op(0,OP_EQ
, i
);
2435 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,100,&i
,NULL
));
2436 tt_int_op(0,OP_EQ
, i
);
2437 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,0,100,&i
,NULL
));
2438 tt_int_op(0,OP_EQ
, i
);
2439 /* Base different than 10 */
2440 tt_int_op(2L,OP_EQ
, tor_parse_long("10",2,0,100,NULL
,NULL
));
2441 tt_int_op(0L,OP_EQ
, tor_parse_long("2",2,0,100,NULL
,NULL
));
2442 tt_int_op(68284L,OP_EQ
, tor_parse_long("10abc",16,0,70000,NULL
,NULL
));
2443 tt_int_op(68284L,OP_EQ
, tor_parse_long("10ABC",16,0,70000,NULL
,NULL
));
2444 tt_int_op(0L,OP_EQ
, tor_parse_long("10",-2,0,100,NULL
,NULL
));
2445 tt_int_op(0,OP_EQ
, tor_parse_long("10ABC",-1,0,70000,&i
,NULL
));
2446 tt_int_op(i
,OP_EQ
, 0);
2448 /* Test parse_ulong */
2449 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("",10,0,100,NULL
,NULL
));
2450 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("0",10,0,100,NULL
,NULL
));
2451 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
2452 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
2453 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,10,NULL
,NULL
));
2454 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,10,100,NULL
,NULL
));
2455 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("8",8,0,100,NULL
,NULL
));
2456 tt_int_op(50UL,OP_EQ
, tor_parse_ulong("50",10,50,100,NULL
,NULL
));
2457 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,NULL
,NULL
));
2458 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("50",-1,50,100,&i
,NULL
));
2459 tt_int_op(0,OP_EQ
, i
);
2460 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,&i
,NULL
));
2461 tt_int_op(0,OP_EQ
, i
);
2463 /* Test parse_uint64 */
2464 tt_assert(UINT64_C(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
2465 tt_int_op(1,OP_EQ
, i
);
2466 tt_str_op(cp
,OP_EQ
, " x");
2467 tt_assert(UINT64_C(12345678901) ==
2468 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
2469 tt_int_op(1,OP_EQ
, i
);
2470 tt_str_op(cp
,OP_EQ
, "");
2471 tt_assert(UINT64_C(0) ==
2472 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
2473 tt_int_op(0,OP_EQ
, i
);
2474 tt_assert(UINT64_C(0) ==
2475 tor_parse_uint64("123",-1,0,INT32_MAX
, &i
, &cp
));
2476 tt_int_op(0,OP_EQ
, i
);
2479 /* Test parse_double */
2480 double d
= tor_parse_double("10", 0, (double)UINT64_MAX
,&i
,NULL
);
2481 tt_int_op(1,OP_EQ
, i
);
2482 tt_assert(((uint64_t)d
) == 10);
2483 d
= tor_parse_double("0", 0, (double)UINT64_MAX
,&i
,NULL
);
2484 tt_int_op(1,OP_EQ
, i
);
2485 tt_assert(((uint64_t)d
) == 0);
2486 d
= tor_parse_double(" ", 0, (double)UINT64_MAX
,&i
,NULL
);
2487 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2488 tt_int_op(0,OP_EQ
, i
);
2489 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,NULL
);
2490 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2491 tt_int_op(0,OP_EQ
, i
);
2492 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,&cp
);
2493 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2494 tt_int_op(1,OP_EQ
, i
);
2495 d
= tor_parse_double("-.0", 0, (double)UINT64_MAX
,&i
,NULL
);
2496 tt_int_op(1,OP_EQ
, i
);
2497 tt_assert(((uint64_t)d
) == 0);
2498 d
= tor_parse_double("-10", -100.0, 100.0,&i
,NULL
);
2499 tt_int_op(1,OP_EQ
, i
);
2500 tt_double_op(fabs(d
- -10.0),OP_LT
, 1E-12);
2504 /* Test tor_parse_* where we overflow/underflow the underlying type. */
2505 /* This string should overflow 64-bit ints. */
2506 #define TOOBIG "100000000000000000000000000"
2507 tt_int_op(0L, OP_EQ
,
2508 tor_parse_long(TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2509 tt_int_op(i
,OP_EQ
, 0);
2511 tor_parse_long("-"TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2512 tt_int_op(i
,OP_EQ
, 0);
2513 tt_int_op(0UL,OP_EQ
, tor_parse_ulong(TOOBIG
, 10, 0, ULONG_MAX
, &i
, NULL
));
2514 tt_int_op(i
,OP_EQ
, 0);
2515 tt_u64_op(UINT64_C(0), OP_EQ
, tor_parse_uint64(TOOBIG
, 10,
2516 0, UINT64_MAX
, &i
, NULL
));
2517 tt_int_op(i
,OP_EQ
, 0);
2524 test_util_pow2(void *arg
)
2526 /* Test tor_log2(). */
2528 tt_int_op(tor_log2(64),OP_EQ
, 6);
2529 tt_int_op(tor_log2(65),OP_EQ
, 6);
2530 tt_int_op(tor_log2(63),OP_EQ
, 5);
2531 /* incorrect mathematically, but as specified: */
2532 tt_int_op(tor_log2(0),OP_EQ
, 0);
2533 tt_int_op(tor_log2(1),OP_EQ
, 0);
2534 tt_int_op(tor_log2(2),OP_EQ
, 1);
2535 tt_int_op(tor_log2(3),OP_EQ
, 1);
2536 tt_int_op(tor_log2(4),OP_EQ
, 2);
2537 tt_int_op(tor_log2(5),OP_EQ
, 2);
2538 tt_int_op(tor_log2(UINT64_C(40000000000000000)),OP_EQ
, 55);
2539 tt_int_op(tor_log2(UINT64_MAX
),OP_EQ
, 63);
2541 /* Test round_to_power_of_2 */
2542 tt_u64_op(round_to_power_of_2(120), OP_EQ
, 128);
2543 tt_u64_op(round_to_power_of_2(128), OP_EQ
, 128);
2544 tt_u64_op(round_to_power_of_2(130), OP_EQ
, 128);
2545 tt_u64_op(round_to_power_of_2(UINT64_C(40000000000000000)), OP_EQ
,
2547 tt_u64_op(round_to_power_of_2(UINT64_C(0xffffffffffffffff)), OP_EQ
,
2549 tt_u64_op(round_to_power_of_2(0), OP_EQ
, 1);
2550 tt_u64_op(round_to_power_of_2(1), OP_EQ
, 1);
2551 tt_u64_op(round_to_power_of_2(2), OP_EQ
, 2);
2552 tt_u64_op(round_to_power_of_2(3), OP_EQ
, 2);
2553 tt_u64_op(round_to_power_of_2(4), OP_EQ
, 4);
2554 tt_u64_op(round_to_power_of_2(5), OP_EQ
, 4);
2555 tt_u64_op(round_to_power_of_2(6), OP_EQ
, 4);
2556 tt_u64_op(round_to_power_of_2(7), OP_EQ
, 8);
2563 test_util_compress_impl(compress_method_t method
)
2565 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
;
2568 tt_assert(tor_compress_supports_method(method
));
2570 if (method
!= NO_METHOD
) {
2571 tt_ptr_op(tor_compress_version_str(method
), OP_NE
, NULL
);
2572 tt_ptr_op(tor_compress_header_version_str(method
), OP_NE
, NULL
);
2575 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
2576 tt_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
2578 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1, method
));
2579 tt_ptr_op(buf2
, OP_NE
, NULL
);
2580 if (method
== NO_METHOD
) {
2581 // The identity transform doesn't actually compress, and it isn't
2582 // detectable as "the identity transform."
2583 tt_int_op(len1
, OP_EQ
, strlen(buf1
)+1);
2584 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, UNKNOWN_METHOD
);
2586 tt_int_op(len1
, OP_LT
, strlen(buf1
));
2587 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, method
);
2590 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
, method
, 1, LOG_INFO
));
2591 tt_ptr_op(buf3
, OP_NE
, NULL
);
2592 tt_int_op(strlen(buf1
) + 1, OP_EQ
, len2
);
2593 tt_str_op(buf1
, OP_EQ
, buf3
);
2594 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2596 /* Check whether we can uncompress concatenated, compressed strings. */
2598 buf2
= tor_reallocarray(buf2
, len1
, 2);
2599 memcpy(buf2
+len1
, buf2
, len1
);
2600 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
*2, method
, 1, LOG_INFO
));
2601 tt_int_op((strlen(buf1
)+1)*2, OP_EQ
, len2
);
2602 tt_mem_op(buf3
, OP_EQ
,
2603 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
2604 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
2605 (strlen(buf1
)+1)*2);
2606 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2608 /* Check whether we can uncompress partial strings */
2614 size_t b1len
= 1<<10;
2615 if (method
== ZSTD_METHOD
) {
2616 // zstd needs a big input before it starts generating output that it
2617 // can partially decompress.
2620 buf1
= tor_malloc(b1len
);
2621 crypto_rand(buf1
, b1len
);
2622 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, b1len
, method
));
2623 tt_int_op(len1
, OP_GT
, 16);
2624 /* when we allow an incomplete output we should succeed.*/
2625 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2626 method
, 0, LOG_INFO
));
2627 tt_int_op(len2
, OP_GT
, 5);
2628 tt_int_op(len2
, OP_LE
, len1
);
2629 tt_assert(fast_memeq(buf1
, buf3
, len2
));
2630 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2632 /* when we demand a complete output from a real compression method, this
2635 if (method
!= NO_METHOD
) {
2636 tt_assert(tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2637 method
, 1, LOG_INFO
));
2638 tt_ptr_op(buf3
, OP_EQ
, NULL
);
2648 test_util_compress_stream_impl(compress_method_t method
,
2649 compression_level_t level
)
2651 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
2655 tor_compress_state_t
*state
= NULL
;
2656 state
= tor_compress_new(1, method
, level
);
2658 cp1
= buf1
= tor_malloc(1024);
2660 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
2662 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0),
2663 OP_EQ
, TOR_COMPRESS_OK
);
2664 tt_int_op(0, OP_EQ
, len2
); /* Make sure we compressed it all. */
2665 tt_assert(cp1
> buf1
);
2669 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1),
2670 OP_EQ
, TOR_COMPRESS_DONE
);
2671 tt_int_op(0, OP_EQ
, len2
);
2672 if (method
== NO_METHOD
) {
2673 tt_ptr_op(cp1
, OP_EQ
, cp2
);
2675 tt_assert(cp1
> cp2
); /* Make sure we really added something. */
2678 tt_int_op(tor_compress_state_size(state
), OP_GT
, 0);
2680 tt_assert(!tor_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
2681 method
, 1, LOG_WARN
));
2682 /* Make sure it compressed right. */
2683 tt_str_op(buf3
, OP_EQ
, "ABCDEFGHIJABCDEFGHIJ");
2684 tt_int_op(21, OP_EQ
, len2
);
2688 tor_compress_free(state
);
2694 /** Setup function for compression tests: handles x-zstd:nostatic
2697 compression_test_setup(const struct testcase_t
*testcase
)
2699 tor_assert(testcase
->setup_data
);
2700 tor_assert(testcase
->setup_data
!= (void*)TT_SKIP
);
2701 const char *methodname
= testcase
->setup_data
;
2703 if (!strcmp(methodname
, "x-zstd:nostatic")) {
2704 methodname
= "x-zstd";
2705 tor_zstd_set_static_apis_disabled_for_testing(1);
2708 return (void *)methodname
;
2711 /** Cleanup for compression tests: disables nostatic */
2713 compression_test_cleanup(const struct testcase_t
*testcase
, void *ptr
)
2717 tor_zstd_set_static_apis_disabled_for_testing(0);
2721 static const struct testcase_setup_t compress_setup
= {
2722 compression_test_setup
, compression_test_cleanup
2725 /** Run unit tests for compression functions */
2727 test_util_compress(void *arg
)
2729 const char *methodname
= arg
;
2730 tt_assert(methodname
);
2732 compress_method_t method
= compression_method_get_by_name(methodname
);
2733 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2735 if (! tor_compress_supports_method(method
)) {
2739 compression_level_t levels
[] = {
2746 test_util_compress_impl(method
);
2748 for (unsigned l
= 0; l
< ARRAY_LENGTH(levels
); ++l
) {
2749 compression_level_t level
= levels
[l
];
2750 test_util_compress_stream_impl(method
, level
);
2757 test_util_decompress_concatenated_impl(compress_method_t method
)
2760 char *c1
= NULL
, *c2
= NULL
, *c3
= NULL
;
2761 char *result
= NULL
;
2762 size_t sz1
, sz2
, sz3
, szr
;
2765 crypto_rand(input
, sizeof(input
));
2767 /* Compress the input in two chunks. */
2768 r
= tor_compress(&c1
, &sz1
, input
, 2048, method
);
2769 tt_int_op(r
, OP_EQ
, 0);
2770 r
= tor_compress(&c2
, &sz2
, input
+2048, 2048, method
);
2771 tt_int_op(r
, OP_EQ
, 0);
2773 /* concatenate the chunks. */
2775 c3
= tor_malloc(sz3
);
2776 memcpy(c3
, c1
, sz1
);
2777 memcpy(c3
+sz1
, c2
, sz2
);
2779 /* decompress the concatenated result */
2780 r
= tor_uncompress(&result
, &szr
, c3
, sz3
, method
, 0, LOG_WARN
);
2781 tt_int_op(r
, OP_EQ
, 0);
2782 tt_int_op(szr
, OP_EQ
, sizeof(input
));
2783 tt_mem_op(result
, OP_EQ
, input
, sizeof(input
));
2793 test_util_decompress_concatenated(void *arg
)
2795 const char *methodname
= arg
;
2796 tt_assert(methodname
);
2798 compress_method_t method
= compression_method_get_by_name(methodname
);
2799 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2800 if (! tor_compress_supports_method(method
)) {
2804 test_util_decompress_concatenated_impl(method
);
2810 test_util_decompress_junk_impl(compress_method_t method
)
2813 char *result
= NULL
, *result2
= NULL
;
2814 size_t szr
, szr2
, sz
;
2817 /* This shouldn't be a compressed string according to any method. */
2818 strlcpy(input
, "This shouldn't be a compressed string by any means.",
2821 setup_capture_of_logs(LOG_WARN
);
2822 r
= tor_uncompress(&result
, &szr
, input
, sz
, method
, 0, LOG_WARN
);
2823 tt_int_op(r
, OP_EQ
, -1);
2824 tt_ptr_op(result
, OP_EQ
, NULL
);
2825 expect_log_msg_containing("Error while uncompressing data: bad input?");
2826 mock_clean_saved_logs();
2828 /* Now try again, with a compressed object that starts out good and turns to
2830 crypto_rand(input
, sizeof(input
));
2831 r
= tor_compress(&result
, &szr
, input
, sizeof(input
), method
);
2832 tt_int_op(r
, OP_EQ
, 0);
2833 crypto_rand(result
+szr
/2, szr
-(szr
/2)); // trash the 2nd half of the result
2834 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2835 tt_int_op(r
, OP_EQ
, -1);
2836 expect_log_msg_containing("Error while uncompressing data: bad input?");
2839 teardown_capture_of_logs();
2845 test_util_decompress_junk(void *arg
)
2847 const char *methodname
= arg
;
2848 tt_assert(methodname
);
2850 compress_method_t method
= compression_method_get_by_name(methodname
);
2851 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2852 if (! tor_compress_supports_method(method
)) {
2856 test_util_decompress_junk_impl(method
);
2861 /* mock replacement for tor_compress_is_compression_bomb that doesn't
2862 * believe in compression bombs. */
2864 mock_is_never_compression_bomb(size_t in
, size_t out
)
2872 test_util_decompress_dos_impl(compress_method_t method
)
2875 char *result
= NULL
, *result2
= NULL
;
2879 const size_t big
= 1024*1024;
2880 /* one megabyte of 0s. */
2881 input
= tor_malloc_zero(big
);
2883 /* Compress it into "result": it should fail. */
2884 setup_full_capture_of_logs(LOG_WARN
);
2885 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2886 tt_int_op(r
, OP_EQ
, -1);
2887 expect_log_msg_containing(
2888 "other Tors would think this was a compression bomb");
2889 teardown_capture_of_logs();
2891 /* Try again, but this time suppress compression-bomb detection */
2892 MOCK(tor_compress_is_compression_bomb
, mock_is_never_compression_bomb
);
2893 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2894 UNMOCK(tor_compress_is_compression_bomb
);
2895 tt_int_op(r
, OP_EQ
, 0);
2896 tt_ptr_op(result
, OP_NE
, NULL
);
2898 /* We should refuse to uncomrpess it again, since it looks like a
2899 * compression bomb. */
2900 setup_capture_of_logs(LOG_WARN
);
2901 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2902 tt_int_op(r
, OP_EQ
, -1);
2903 expect_log_msg_containing("bomb; abandoning stream");
2906 teardown_capture_of_logs();
2913 test_util_decompress_dos(void *arg
)
2915 const char *methodname
= arg
;
2916 tt_assert(methodname
);
2918 compress_method_t method
= compression_method_get_by_name(methodname
);
2919 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2920 if (! tor_compress_supports_method(method
)) {
2924 test_util_decompress_dos_impl(method
);
2930 test_util_gzip_compression_bomb(void *arg
)
2932 /* A 'compression bomb' is a very small object that uncompresses to a huge
2933 * one. Most compression formats support them, but they can be a DOS vector.
2934 * In Tor we try not to generate them, and we don't accept them.
2937 size_t one_million
= 1<<20;
2938 char *one_mb
= tor_malloc_zero(one_million
);
2939 char *result
= NULL
;
2940 size_t result_len
= 0;
2941 tor_compress_state_t
*state
= NULL
;
2943 /* Make sure we can't produce a compression bomb */
2944 setup_full_capture_of_logs(LOG_WARN
);
2945 tt_int_op(-1, OP_EQ
, tor_compress(&result
, &result_len
,
2946 one_mb
, one_million
,
2948 expect_log_msg_containing(
2949 "We compressed something and got an insanely high "
2950 "compression factor; other Tors would think this "
2951 "was a compression bomb.");
2952 teardown_capture_of_logs();
2954 /* Here's a compression bomb that we made manually. */
2955 const char compression_bomb
[1039] =
2956 { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2,
2957 0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ };
2958 tt_int_op(-1, OP_EQ
, tor_uncompress(&result
, &result_len
,
2959 compression_bomb
, 1039,
2960 ZLIB_METHOD
, 0, LOG_WARN
));
2962 /* Now try streaming that. */
2963 state
= tor_compress_new(0, ZLIB_METHOD
, HIGH_COMPRESSION
);
2964 tor_compress_output_t r
;
2965 const char *inp
= compression_bomb
;
2966 size_t inlen
= 1039;
2968 char *outp
= one_mb
;
2969 size_t outleft
= 4096; /* small on purpose */
2970 r
= tor_compress_process(state
, &outp
, &outleft
, &inp
, &inlen
, 0);
2971 tt_int_op(inlen
, OP_NE
, 0);
2972 } while (r
== TOR_COMPRESS_BUFFER_FULL
);
2974 tt_int_op(r
, OP_EQ
, TOR_COMPRESS_ERROR
);
2978 tor_compress_free(state
);
2981 /** Run unit tests for mmap() wrapper functionality. */
2983 test_util_mmap(void *arg
)
2985 char *fname1
= tor_strdup(get_fname("mapped_1"));
2986 char *fname2
= tor_strdup(get_fname("mapped_2"));
2987 char *fname3
= tor_strdup(get_fname("mapped_3"));
2988 const size_t buflen
= 17000;
2989 char *buf
= tor_malloc(17000);
2990 tor_mmap_t
*mapping
= NULL
;
2993 crypto_rand(buf
, buflen
);
2995 mapping
= tor_mmap_file(fname1
);
2996 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2998 write_str_to_file(fname1
, "Short file.", 1);
3000 mapping
= tor_mmap_file(fname1
);
3002 tt_int_op(mapping
->size
,OP_EQ
, strlen("Short file."));
3003 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
3005 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3007 tt_assert(unlink(fname1
) == 0);
3009 /* make sure we can unlink. */
3010 tt_assert(unlink(fname1
) == 0);
3011 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
3012 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3014 #endif /* defined(_WIN32) */
3016 /* Now a zero-length file. */
3017 write_str_to_file(fname1
, "", 1);
3018 mapping
= tor_mmap_file(fname1
);
3019 tt_ptr_op(mapping
,OP_EQ
, NULL
);
3020 tt_int_op(ERANGE
,OP_EQ
, errno
);
3023 /* Make sure that we fail to map a no-longer-existent file. */
3024 mapping
= tor_mmap_file(fname1
);
3025 tt_ptr_op(mapping
, OP_EQ
, NULL
);
3027 /* Now try a big file that stretches across a few pages and isn't aligned */
3028 write_bytes_to_file(fname2
, buf
, buflen
, 1);
3029 mapping
= tor_mmap_file(fname2
);
3031 tt_int_op(mapping
->size
,OP_EQ
, buflen
);
3032 tt_mem_op(mapping
->data
,OP_EQ
, buf
, buflen
);
3033 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3036 /* Now try a big aligned file. */
3037 write_bytes_to_file(fname3
, buf
, 16384, 1);
3038 mapping
= tor_mmap_file(fname3
);
3040 tt_int_op(mapping
->size
,OP_EQ
, 16384);
3041 tt_mem_op(mapping
->data
,OP_EQ
, buf
, 16384);
3042 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3055 tor_munmap_file(mapping
);
3058 /** Run unit tests for escaping/unescaping data for use by controllers. */
3060 test_util_control_formats(void *arg
)
3064 "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
3068 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
3069 tt_str_op(out
,OP_EQ
,
3070 ".This is a test\nof the emergency \n.system.\n\rZ.\n");
3071 tt_int_op(sz
,OP_EQ
, strlen(out
));
3077 #define test_feq(value1,value2) do { \
3078 double v1 = (value1), v2=(value2); \
3079 double tf_diff = v1-v2; \
3080 double tf_tolerance = ((v1+v2)/2.0)/1e8; \
3081 if (tf_diff<0) tf_diff=-tf_diff; \
3082 if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
3083 if (tf_diff<tf_tolerance) { \
3084 TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
3086 TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
3091 test_util_sscanf(void *arg
)
3093 unsigned u1
, u2
, u3
;
3095 char s1
[20], s2
[10], s3
[10], ch
, *huge
= NULL
;
3101 /* Simple tests (malformed patterns, literal matching, ...) */
3103 tt_int_op(-1,OP_EQ
, tor_sscanf("123", "%i", &r
)); /* %i is not supported */
3105 tor_sscanf("wrong", "%5c", s1
)); /* %c cannot have a number. */
3106 tt_int_op(-1,OP_EQ
, tor_sscanf("hello", "%s", s1
)); /* %s needs a number. */
3107 /* this will fail because we don't allow widths longer than 9999 */
3109 huge
= tor_malloc(1000000);
3110 r
= tor_sscanf("prettylongstring", "%99999s", huge
);
3112 tt_int_op(-1,OP_EQ
, r
);
3115 /* GCC thinks these two are illegal. */
3116 test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1
));
3117 test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL
));
3119 /* No '%'-strings: always "success" */
3120 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "hello world"));
3121 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "good bye"));
3124 tor_sscanf("hello 3", "%u", &u1
)); /* have to match the start */
3125 tt_int_op(0,OP_EQ
, tor_sscanf(" 3 hello", "%u", &u1
));
3127 tor_sscanf(" 3 hello", "%2u", &u1
)); /* not even in this case */
3129 tor_sscanf("3 hello", "%u", &u1
)); /* but trailing is alright */
3131 /* Numbers (ie. %u) */
3133 tor_sscanf("hello world 3", "hello worlb %u", &u1
)); /* d vs b */
3134 tt_int_op(1,OP_EQ
, tor_sscanf("12345", "%u", &u1
));
3135 tt_int_op(12345u,OP_EQ
, u1
);
3136 tt_int_op(1,OP_EQ
, tor_sscanf("12346 ", "%u", &u1
));
3137 tt_int_op(12346u,OP_EQ
, u1
);
3138 tt_int_op(0,OP_EQ
, tor_sscanf(" 12347", "%u", &u1
));
3139 tt_int_op(1,OP_EQ
, tor_sscanf(" 12348", " %u", &u1
));
3140 tt_int_op(12348u,OP_EQ
, u1
);
3141 tt_int_op(1,OP_EQ
, tor_sscanf("0", "%u", &u1
));
3142 tt_int_op(0u,OP_EQ
, u1
);
3143 tt_int_op(1,OP_EQ
, tor_sscanf("0000", "%u", &u2
));
3144 tt_int_op(0u,OP_EQ
, u2
);
3145 tt_int_op(0,OP_EQ
, tor_sscanf("", "%u", &u1
)); /* absent number */
3146 tt_int_op(0,OP_EQ
, tor_sscanf("A", "%u", &u1
)); /* bogus number */
3147 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%u", &u1
)); /* negative number */
3149 /* Numbers with size (eg. %2u) */
3150 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%2u", &u1
));
3151 tt_int_op(2,OP_EQ
, tor_sscanf("123456", "%2u%u", &u1
, &u2
));
3152 tt_int_op(12u,OP_EQ
, u1
);
3153 tt_int_op(3456u,OP_EQ
, u2
);
3154 tt_int_op(1,OP_EQ
, tor_sscanf("123456", "%8u", &u1
));
3155 tt_int_op(123456u,OP_EQ
, u1
);
3156 tt_int_op(1,OP_EQ
, tor_sscanf("123457 ", "%8u", &u1
));
3157 tt_int_op(123457u,OP_EQ
, u1
);
3158 tt_int_op(0,OP_EQ
, tor_sscanf(" 123456", "%8u", &u1
));
3159 tt_int_op(3,OP_EQ
, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
));
3160 tt_int_op(12u,OP_EQ
, u1
);
3161 tt_int_op(3u,OP_EQ
, u2
);
3162 tt_int_op(456u,OP_EQ
, u3
);
3164 tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1
, &u2
, &u3
)); /* 0s */
3165 tt_int_op(67u,OP_EQ
, u1
);
3166 tt_int_op(8u,OP_EQ
, u2
);
3167 tt_int_op(99u,OP_EQ
, u3
);
3168 /* %u does not match space.*/
3169 tt_int_op(2,OP_EQ
, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
3170 tt_int_op(12u,OP_EQ
, u1
);
3171 tt_int_op(3u,OP_EQ
, u2
);
3172 /* %u does not match negative numbers. */
3173 tt_int_op(2,OP_EQ
, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
3174 tt_int_op(67u,OP_EQ
, u1
);
3175 tt_int_op(8u,OP_EQ
, u2
);
3176 /* Arbitrary amounts of 0-padding are okay */
3177 tt_int_op(3,OP_EQ
, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
3179 tt_int_op(12u,OP_EQ
, u1
);
3180 tt_int_op(3u,OP_EQ
, u2
);
3181 tt_int_op(99u,OP_EQ
, u3
);
3185 tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1
, &u2
, &u3
));
3186 tt_int_op(0x1234,OP_EQ
, u1
);
3187 tt_int_op(0x2ABCDEF,OP_EQ
, u2
);
3188 tt_int_op(0xFF,OP_EQ
, u3
);
3189 /* Width works on %x */
3190 tt_int_op(3,OP_EQ
, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1
, &u2
, &u3
));
3191 tt_int_op(0xf00d,OP_EQ
, u1
);
3192 tt_int_op(0xcafe,OP_EQ
, u2
);
3193 tt_int_op(444,OP_EQ
, u3
);
3195 /* Literal '%' (ie. '%%') */
3196 tt_int_op(1,OP_EQ
, tor_sscanf("99% fresh", "%3u%% fresh", &u1
));
3197 tt_int_op(99,OP_EQ
, u1
);
3198 tt_int_op(0,OP_EQ
, tor_sscanf("99 fresh", "%% %3u %s", &u1
, s1
));
3199 tt_int_op(1,OP_EQ
, tor_sscanf("99 fresh", "%3u%% %s", &u1
, s1
));
3200 tt_int_op(2,OP_EQ
, tor_sscanf("99 fresh", "%3u %5s %%", &u1
, s1
));
3201 tt_int_op(99,OP_EQ
, u1
);
3202 tt_str_op(s1
,OP_EQ
, "fresh");
3203 tt_int_op(1,OP_EQ
, tor_sscanf("% boo", "%% %3s", s1
));
3204 tt_str_op("boo",OP_EQ
, s1
);
3206 /* Strings (ie. %s) */
3207 tt_int_op(2,OP_EQ
, tor_sscanf("hello", "%3s%7s", s1
, s2
));
3208 tt_str_op(s1
,OP_EQ
, "hel");
3209 tt_str_op(s2
,OP_EQ
, "lo");
3210 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%2s%u", s3
, &u1
)); /* %s%u */
3211 tt_str_op(s3
,OP_EQ
, "WD");
3212 tt_int_op(40,OP_EQ
, u1
);
3213 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%3s%u", s3
, &u1
)); /* %s%u */
3214 tt_str_op(s3
,OP_EQ
, "WD4");
3215 tt_int_op(0,OP_EQ
, u1
);
3216 tt_int_op(2,OP_EQ
, tor_sscanf("76trombones", "%6u%9s", &u1
, s1
)); /* %u%s */
3217 tt_int_op(76,OP_EQ
, u1
);
3218 tt_str_op(s1
,OP_EQ
, "trombones");
3220 huge
= tor_malloc(1000);
3221 r
= tor_sscanf("prettylongstring", "%999s", huge
);
3222 tt_int_op(1,OP_EQ
, r
);
3223 tt_str_op(huge
,OP_EQ
, "prettylongstring");
3226 /* %s doesn't eat spaces */
3227 tt_int_op(2,OP_EQ
, tor_sscanf("hello world", "%9s %9s", s1
, s2
));
3228 tt_str_op(s1
,OP_EQ
, "hello");
3229 tt_str_op(s2
,OP_EQ
, "world");
3230 tt_int_op(2,OP_EQ
, tor_sscanf("bye world?", "%9s %9s", s1
, s2
));
3231 tt_str_op(s1
,OP_EQ
, "bye");
3232 tt_str_op(s2
,OP_EQ
, "");
3234 tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
)); /* %s can be empty. */
3235 tt_str_op(s1
,OP_EQ
, "hi");
3236 tt_str_op(s2
,OP_EQ
, "");
3237 tt_str_op(s3
,OP_EQ
, "");
3239 tt_int_op(3,OP_EQ
, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3241 tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3242 tt_int_op(' ',OP_EQ
, ch
);
3244 r
= tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1
, &lng1
, &int2
);
3245 tt_int_op(r
,OP_EQ
, 3);
3246 tt_int_op(int1
,OP_EQ
, 12345);
3247 tt_int_op(lng1
,OP_EQ
, -67890);
3248 tt_int_op(int2
,OP_EQ
, -1);
3252 /* UINT32_MAX should work */
3253 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%u", &u1
));
3254 tt_int_op(4294967295U,OP_EQ
, u1
);
3256 /* But UINT32_MAX + 1 shouldn't work */
3257 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%u", &u1
));
3258 /* but parsing only 9... */
3259 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9u", &u1
));
3260 tt_int_op(429496729U,OP_EQ
, u1
);
3263 /* UINT32_MAX should work */
3264 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%x", &u1
));
3265 tt_int_op(0xFFFFFFFF,OP_EQ
, u1
);
3267 /* But UINT32_MAX + 1 shouldn't work */
3268 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%x", &u1
));
3271 /* INT32_MIN and INT32_MAX should work */
3272 r
= tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1
, &int2
);
3273 tt_int_op(r
,OP_EQ
, 2);
3274 tt_int_op(int1
,OP_EQ
, -2147483647 - 1);
3275 tt_int_op(int2
,OP_EQ
, 2147483647);
3277 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3278 r
= tor_sscanf("-2147483649.", "%d.", &int1
);
3279 tt_int_op(r
,OP_EQ
, 0);
3281 r
= tor_sscanf("2147483648.", "%d.", &int1
);
3282 tt_int_op(r
,OP_EQ
, 0);
3284 /* and the first failure stops further processing */
3285 r
= tor_sscanf("-2147483648. 2147483648.",
3286 "%d. %d.", &int1
, &int2
);
3287 tt_int_op(r
,OP_EQ
, 1);
3289 r
= tor_sscanf("-2147483649. 2147483647.",
3290 "%d. %d.", &int1
, &int2
);
3291 tt_int_op(r
,OP_EQ
, 0);
3293 r
= tor_sscanf("2147483648. -2147483649.",
3294 "%d. %d.", &int1
, &int2
);
3295 tt_int_op(r
,OP_EQ
, 0);
3296 #elif SIZEOF_INT == 8
3298 /* UINT64_MAX should work */
3299 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%u", &u1
));
3300 tt_int_op(18446744073709551615U,OP_EQ
, u1
);
3302 /* But UINT64_MAX + 1 shouldn't work */
3303 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%u", &u1
));
3304 /* but parsing only 19... */
3305 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19u", &u1
));
3306 tt_int_op(1844674407370955161U,OP_EQ
, u1
);
3309 /* UINT64_MAX should work */
3310 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1
));
3311 tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ
, u1
);
3313 /* But UINT64_MAX + 1 shouldn't work */
3314 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%x", &u1
));
3317 /* INT64_MIN and INT64_MAX should work */
3318 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3319 "%d. %d.", &int1
, &int2
);
3320 tt_int_op(r
,OP_EQ
, 2);
3321 tt_int_op(int1
,OP_EQ
, -9223372036854775807 - 1);
3322 tt_int_op(int2
,OP_EQ
, 9223372036854775807);
3324 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3325 r
= tor_sscanf("-9223372036854775809.", "%d.", &int1
);
3326 tt_int_op(r
,OP_EQ
, 0);
3328 r
= tor_sscanf("9223372036854775808.", "%d.", &int1
);
3329 tt_int_op(r
,OP_EQ
, 0);
3331 /* and the first failure stops further processing */
3332 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3333 "%d. %d.", &int1
, &int2
);
3334 tt_int_op(r
,OP_EQ
, 1);
3336 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3337 "%d. %d.", &int1
, &int2
);
3338 tt_int_op(r
,OP_EQ
, 0);
3340 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3341 "%d. %d.", &int1
, &int2
);
3342 tt_int_op(r
,OP_EQ
, 0);
3343 #endif /* SIZEOF_INT == 4 || ... */
3345 #if SIZEOF_LONG == 4
3347 /* UINT32_MAX should work */
3348 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%lu", &ulng
));
3349 tt_int_op(4294967295UL,OP_EQ
, ulng
);
3351 /* But UINT32_MAX + 1 shouldn't work */
3352 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%lu", &ulng
));
3353 /* but parsing only 9... */
3354 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9lu", &ulng
));
3355 tt_int_op(429496729UL,OP_EQ
, ulng
);
3358 /* UINT32_MAX should work */
3359 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%lx", &ulng
));
3360 tt_int_op(0xFFFFFFFFUL
,OP_EQ
, ulng
);
3362 /* But UINT32_MAX + 1 shouldn't work */
3363 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%lx", &ulng
));
3366 /* INT32_MIN and INT32_MAX should work */
3367 r
= tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1
, &lng2
);
3368 tt_int_op(r
,OP_EQ
, 2);
3369 tt_int_op(lng1
,OP_EQ
, -2147483647L - 1L);
3370 tt_int_op(lng2
,OP_EQ
, 2147483647L);
3372 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3373 r
= tor_sscanf("-2147483649.", "%ld.", &lng1
);
3374 tt_int_op(r
,OP_EQ
, 0);
3376 r
= tor_sscanf("2147483648.", "%ld.", &lng1
);
3377 tt_int_op(r
,OP_EQ
, 0);
3379 /* and the first failure stops further processing */
3380 r
= tor_sscanf("-2147483648. 2147483648.",
3381 "%ld. %ld.", &lng1
, &lng2
);
3382 tt_int_op(r
,OP_EQ
, 1);
3384 r
= tor_sscanf("-2147483649. 2147483647.",
3385 "%ld. %ld.", &lng1
, &lng2
);
3386 tt_int_op(r
,OP_EQ
, 0);
3388 r
= tor_sscanf("2147483648. -2147483649.",
3389 "%ld. %ld.", &lng1
, &lng2
);
3390 tt_int_op(r
,OP_EQ
, 0);
3391 #elif SIZEOF_LONG == 8
3393 /* UINT64_MAX should work */
3394 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%lu", &ulng
));
3395 tt_int_op(18446744073709551615UL,OP_EQ
, ulng
);
3397 /* But UINT64_MAX + 1 shouldn't work */
3398 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%lu", &ulng
));
3399 /* but parsing only 19... */
3400 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19lu", &ulng
));
3401 tt_int_op(1844674407370955161UL,OP_EQ
, ulng
);
3404 /* UINT64_MAX should work */
3405 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng
));
3406 tt_int_op(0xFFFFFFFFFFFFFFFFUL
,OP_EQ
, ulng
);
3408 /* But UINT64_MAX + 1 shouldn't work */
3409 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%lx", &ulng
));
3412 /* INT64_MIN and INT64_MAX should work */
3413 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3414 "%ld. %ld.", &lng1
, &lng2
);
3415 tt_int_op(r
,OP_EQ
, 2);
3416 tt_int_op(lng1
,OP_EQ
, -9223372036854775807L - 1L);
3417 tt_int_op(lng2
,OP_EQ
, 9223372036854775807L);
3419 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3420 r
= tor_sscanf("-9223372036854775809.", "%ld.", &lng1
);
3421 tt_int_op(r
,OP_EQ
, 0);
3423 r
= tor_sscanf("9223372036854775808.", "%ld.", &lng1
);
3424 tt_int_op(r
,OP_EQ
, 0);
3426 /* and the first failure stops further processing */
3427 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3428 "%ld. %ld.", &lng1
, &lng2
);
3429 tt_int_op(r
,OP_EQ
, 1);
3431 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3432 "%ld. %ld.", &lng1
, &lng2
);
3433 tt_int_op(r
,OP_EQ
, 0);
3435 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3436 "%ld. %ld.", &lng1
, &lng2
);
3437 tt_int_op(r
,OP_EQ
, 0);
3438 #endif /* SIZEOF_LONG == 4 || ... */
3440 r
= tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
3441 "%lf %lf %lf %lf", &d1
,&d2
,&d3
,&d4
);
3442 tt_int_op(r
,OP_EQ
, 4);
3443 test_feq(d1
, 123.456);
3444 test_feq(d2
, .000007);
3445 test_feq(d3
, -900123123.2000787);
3449 r
= tor_sscanf("3 ", "%d %lf", &int1
, &d1
);
3450 tt_int_op(r
, OP_EQ
, 1);
3451 tt_int_op(int1
, OP_EQ
, 3);
3454 r
= tor_sscanf("999 notafloat", "%d %lf", &int1
, &d1
);
3455 tt_int_op(r
, OP_EQ
, 1);
3456 tt_int_op(int1
, OP_EQ
, 999);
3458 /* %s but no buffer. */
3459 char *nullbuf
= NULL
;
3460 r
= tor_sscanf("hello", "%3s", nullbuf
);
3461 tt_int_op(r
, OP_EQ
, 0);
3467 #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
3468 #define tt_ci_char_op(a,op,b) \
3469 tt_char_op(TOR_TOLOWER((int)a),op,TOR_TOLOWER((int)b))
3471 #ifndef HAVE_STRNLEN
3473 strnlen(const char *s
, size_t len
)
3475 const char *p
= memchr(s
, 0, len
);
3480 #endif /* !defined(HAVE_STRNLEN) */
3483 test_util_format_time_interval(void *arg
)
3485 /* use the same sized buffer and integers as tor uses */
3486 #define DBUF_SIZE 64
3487 char dbuf
[DBUF_SIZE
];
3489 long sec
, min
, hour
, day
;
3491 /* we don't care about the exact spelling of the
3492 * second(s), minute(s), hour(s), day(s) labels */
3493 #define LABEL_SIZE 21
3495 char label_s
[LABEL_SIZE
];
3496 char label_m
[LABEL_SIZE
];
3497 char label_h
[LABEL_SIZE
];
3498 char label_d
[LABEL_SIZE
];
3500 #define TL_ T_ " " L_
3506 /* In these tests, we're not picky about
3507 * spelling or abbreviations */
3509 /* seconds: 0, 1, 9, 10, 59 */
3511 /* ignore exact spelling of "second(s)"*/
3512 format_time_interval(dbuf
, sizeof(dbuf
), 0);
3513 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3514 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3515 tt_int_op(r
,OP_EQ
, 2);
3516 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3517 tt_int_op(sec
,OP_EQ
, 0);
3519 format_time_interval(dbuf
, sizeof(dbuf
), 1);
3520 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3521 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3522 tt_int_op(r
,OP_EQ
, 2);
3523 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3524 tt_int_op(sec
,OP_EQ
, 1);
3526 format_time_interval(dbuf
, sizeof(dbuf
), 10);
3527 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3528 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3529 tt_int_op(r
,OP_EQ
, 2);
3530 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3531 tt_int_op(sec
,OP_EQ
, 10);
3533 format_time_interval(dbuf
, sizeof(dbuf
), 59);
3534 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3535 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3536 tt_int_op(r
,OP_EQ
, 2);
3537 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3538 tt_int_op(sec
,OP_EQ
, 59);
3540 /* negative seconds are reported as their absolute value */
3542 format_time_interval(dbuf
, sizeof(dbuf
), -4);
3543 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3544 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3545 tt_int_op(r
,OP_EQ
, 2);
3546 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3547 tt_int_op(sec
,OP_EQ
, 4);
3548 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3550 format_time_interval(dbuf
, sizeof(dbuf
), -32);
3551 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3552 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3553 tt_int_op(r
,OP_EQ
, 2);
3554 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3555 tt_int_op(sec
,OP_EQ
, 32);
3556 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3558 /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
3560 /* ignore trailing "0 second(s)", if present */
3561 format_time_interval(dbuf
, sizeof(dbuf
), 60);
3562 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3563 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3564 tt_int_op(r
,OP_EQ
, 2);
3565 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3566 tt_int_op(min
,OP_EQ
, 1);
3567 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3569 /* ignore exact spelling of "minute(s)," and "second(s)" */
3570 format_time_interval(dbuf
, sizeof(dbuf
), 60 + 1);
3571 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3572 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3573 &min
, label_m
, &sec
, label_s
);
3574 tt_int_op(r
,OP_EQ
, 4);
3575 tt_int_op(min
,OP_EQ
, 1);
3576 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3577 tt_int_op(sec
,OP_EQ
, 1);
3578 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3579 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3581 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 - 1);
3582 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3583 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3584 &min
, label_m
, &sec
, label_s
);
3585 tt_int_op(r
,OP_EQ
, 4);
3586 tt_int_op(min
,OP_EQ
, 1);
3587 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3588 tt_int_op(sec
,OP_EQ
, 59);
3589 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3591 /* ignore trailing "0 second(s)", if present */
3592 format_time_interval(dbuf
, sizeof(dbuf
), 60*2);
3593 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3594 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3595 tt_int_op(r
,OP_EQ
, 2);
3596 tt_int_op(min
,OP_EQ
, 2);
3597 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3599 /* ignore exact spelling of "minute(s)," and "second(s)" */
3600 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 + 1);
3601 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3602 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3603 &min
, label_m
, &sec
, label_s
);
3604 tt_int_op(r
,OP_EQ
, 4);
3605 tt_int_op(min
,OP_EQ
, 2);
3606 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3607 tt_int_op(sec
,OP_EQ
, 1);
3608 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3610 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 - 1);
3611 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3612 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3613 &min
, label_m
, &sec
, label_s
);
3614 tt_int_op(r
,OP_EQ
, 4);
3615 tt_int_op(min
,OP_EQ
, 59);
3616 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3617 tt_int_op(sec
,OP_EQ
, 59);
3618 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3620 /* negative minutes are reported as their absolute value */
3622 /* ignore trailing "0 second(s)", if present */
3623 format_time_interval(dbuf
, sizeof(dbuf
), -3*60);
3624 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3625 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3626 tt_int_op(r
,OP_EQ
, 2);
3627 tt_int_op(min
,OP_EQ
, 3);
3628 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3630 /* ignore exact spelling of "minute(s)," and "second(s)" */
3631 format_time_interval(dbuf
, sizeof(dbuf
), -96);
3632 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3633 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3634 &min
, label_m
, &sec
, label_s
);
3635 tt_int_op(r
,OP_EQ
, 4);
3636 tt_int_op(min
,OP_EQ
, 1);
3637 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3638 tt_int_op(sec
,OP_EQ
, 36);
3639 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3641 format_time_interval(dbuf
, sizeof(dbuf
), -2815);
3642 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3643 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3644 &min
, label_m
, &sec
, label_s
);
3645 tt_int_op(r
,OP_EQ
, 4);
3646 tt_int_op(min
,OP_EQ
, 46);
3647 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3648 tt_int_op(sec
,OP_EQ
, 55);
3649 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3651 /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
3652 /* always ignore trailing seconds, if present */
3654 /* ignore trailing "0 minute(s)" etc., if present */
3655 format_time_interval(dbuf
, sizeof(dbuf
), 60*60);
3656 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3657 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3658 tt_int_op(r
,OP_EQ
, 2);
3659 tt_int_op(hour
,OP_EQ
, 1);
3660 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3662 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 1);
3663 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3664 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3665 tt_int_op(r
,OP_EQ
, 2);
3666 tt_int_op(hour
,OP_EQ
, 1);
3667 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3669 /* ignore exact spelling of "hour(s)," etc. */
3670 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 60);
3671 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3672 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3673 &hour
, label_h
, &min
, label_m
);
3674 tt_int_op(r
,OP_EQ
, 4);
3675 tt_int_op(hour
,OP_EQ
, 1);
3676 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3677 tt_int_op(min
,OP_EQ
, 1);
3678 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3680 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 60);
3681 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3682 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3683 &hour
, label_h
, &min
, label_m
);
3684 tt_int_op(r
,OP_EQ
, 4);
3685 tt_int_op(hour
,OP_EQ
, 23);
3686 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3687 tt_int_op(min
,OP_EQ
, 59);
3688 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3690 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 1);
3691 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3692 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3693 &hour
, label_h
, &min
, label_m
);
3694 tt_int_op(r
,OP_EQ
, 4);
3695 tt_int_op(hour
,OP_EQ
, 23);
3696 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3697 tt_int_op(min
,OP_EQ
, 59);
3698 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3700 /* negative hours are reported as their absolute value */
3702 /* ignore exact spelling of "hour(s)," etc., if present */
3703 format_time_interval(dbuf
, sizeof(dbuf
), -2*60*60);
3704 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3705 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3706 tt_int_op(r
,OP_EQ
, 2);
3707 tt_int_op(hour
,OP_EQ
, 2);
3708 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3710 format_time_interval(dbuf
, sizeof(dbuf
), -75804);
3711 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3712 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3713 &hour
, label_h
, &min
, label_m
);
3714 tt_int_op(r
,OP_EQ
, 4);
3715 tt_int_op(hour
,OP_EQ
, 21);
3716 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3717 tt_int_op(min
,OP_EQ
, 3);
3718 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3720 /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
3721 /* always ignore trailing seconds, if present */
3723 /* ignore trailing "0 hours(s)" etc., if present */
3724 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60);
3725 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3726 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3727 tt_int_op(r
,OP_EQ
, 2);
3728 tt_int_op(day
,OP_EQ
, 1);
3729 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3731 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 1);
3732 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3733 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3734 tt_int_op(r
,OP_EQ
, 2);
3735 tt_int_op(day
,OP_EQ
, 1);
3736 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3738 /* ignore exact spelling of "days(s)," etc. */
3739 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60);
3740 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3741 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3742 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3744 /* ignore 0 hours(s), if present */
3745 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3746 &day
, label_d
, &min
, label_m
);
3748 tt_assert(r
== 4 || r
== 6);
3749 tt_int_op(day
,OP_EQ
, 1);
3750 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3752 tt_int_op(hour
,OP_EQ
, 0);
3753 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3755 tt_int_op(min
,OP_EQ
, 1);
3756 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3758 /* ignore trailing "0 minutes(s)" etc., if present */
3759 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60*60);
3760 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3761 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3762 &day
, label_d
, &hour
, label_h
);
3763 tt_int_op(r
,OP_EQ
, 4);
3764 tt_int_op(day
,OP_EQ
, 1);
3765 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3766 tt_int_op(hour
,OP_EQ
, 1);
3767 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3769 /* negative days are reported as their absolute value */
3771 format_time_interval(dbuf
, sizeof(dbuf
), -21936184);
3772 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3773 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3774 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3775 tt_int_op(r
,OP_EQ
, 6);
3776 tt_int_op(day
,OP_EQ
, 253);
3777 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3778 tt_int_op(hour
,OP_EQ
, 21);
3779 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3780 tt_int_op(min
,OP_EQ
, 23);
3781 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3783 /* periods > 1 year are reported in days (warn?) */
3785 /* ignore exact spelling of "days(s)," etc., if present */
3786 format_time_interval(dbuf
, sizeof(dbuf
), 758635154);
3787 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3788 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3789 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3790 tt_int_op(r
,OP_EQ
, 6);
3791 tt_int_op(day
,OP_EQ
, 8780);
3792 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3793 tt_int_op(hour
,OP_EQ
, 11);
3794 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3795 tt_int_op(min
,OP_EQ
, 59);
3796 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3798 /* negative periods > 1 year are reported in days (warn?) */
3800 format_time_interval(dbuf
, sizeof(dbuf
), -1427014922);
3801 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3802 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3803 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3804 tt_int_op(r
,OP_EQ
, 6);
3805 tt_int_op(day
,OP_EQ
, 16516);
3806 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3807 tt_int_op(hour
,OP_EQ
, 9);
3808 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3809 tt_int_op(min
,OP_EQ
, 2);
3810 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3812 #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
3814 /* We can try INT32_MIN/MAX */
3815 /* Always ignore second(s) */
3818 format_time_interval(dbuf
, sizeof(dbuf
), 2147483647);
3819 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3820 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3821 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3822 tt_int_op(r
,OP_EQ
, 6);
3823 tt_int_op(day
,OP_EQ
, 24855);
3824 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3825 tt_int_op(hour
,OP_EQ
, 3);
3826 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3827 tt_int_op(min
,OP_EQ
, 14);
3828 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3829 /* and 7 seconds - ignored */
3831 /* INT32_MIN: check that we get the absolute value of interval,
3832 * which doesn't actually fit in int32_t.
3833 * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
3834 format_time_interval(dbuf
, sizeof(dbuf
), -2147483647L - 1L);
3835 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3836 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3837 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3838 tt_int_op(r
,OP_EQ
, 6);
3839 tt_int_op(day
,OP_EQ
, 24855);
3840 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3841 tt_int_op(hour
,OP_EQ
, 3);
3842 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3843 tt_int_op(min
,OP_EQ
, 14);
3844 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3845 /* and 7 or 8 seconds - ignored */
3847 #endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */
3849 #if SIZEOF_LONG == 8
3851 /* We can try INT64_MIN/MAX */
3852 /* Always ignore second(s) */
3855 format_time_interval(dbuf
, sizeof(dbuf
), 9223372036854775807L);
3856 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3857 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3858 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3859 tt_int_op(r
,OP_EQ
, 6);
3860 tt_int_op(day
,OP_EQ
, 106751991167300L);
3861 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3862 tt_int_op(hour
,OP_EQ
, 15);
3863 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3864 tt_int_op(min
,OP_EQ
, 30);
3865 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3866 /* and 7 seconds - ignored */
3868 /* INT64_MIN: check that we get the absolute value of interval,
3869 * which doesn't actually fit in int64_t.
3870 * We expect INT64_MAX */
3871 format_time_interval(dbuf
, sizeof(dbuf
),
3872 -9223372036854775807L - 1L);
3873 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3874 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3875 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3876 tt_int_op(r
,OP_EQ
, 6);
3877 tt_int_op(day
,OP_EQ
, 106751991167300L);
3878 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3879 tt_int_op(hour
,OP_EQ
, 15);
3880 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3881 tt_int_op(min
,OP_EQ
, 30);
3882 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3883 /* and 7 or 8 seconds - ignored */
3885 #endif /* SIZEOF_LONG == 8 */
3892 #undef tt_ci_char_op
3900 test_util_path_is_relative(void *arg
)
3902 /* OS-independent tests */
3904 tt_int_op(1,OP_EQ
, path_is_relative(""));
3905 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3906 tt_int_op(1,OP_EQ
, path_is_relative("dir/"));
3907 tt_int_op(1,OP_EQ
, path_is_relative("./dir"));
3908 tt_int_op(1,OP_EQ
, path_is_relative("../dir"));
3910 tt_int_op(0,OP_EQ
, path_is_relative("/"));
3911 tt_int_op(0,OP_EQ
, path_is_relative("/dir"));
3912 tt_int_op(0,OP_EQ
, path_is_relative("/dir/"));
3916 /* I don't have Windows so I can't test this, hence the "#ifdef
3917 0". These are tests that look useful, so please try to get them
3918 running and uncomment if it all works as it should */
3919 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3920 tt_int_op(1,OP_EQ
, path_is_relative("dir\\"));
3921 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:"));
3922 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:\\"));
3923 tt_int_op(1,OP_EQ
, path_is_relative("http:\\dir"));
3925 tt_int_op(0,OP_EQ
, path_is_relative("\\dir"));
3926 tt_int_op(0,OP_EQ
, path_is_relative("a:\\dir"));
3927 tt_int_op(0,OP_EQ
, path_is_relative("z:\\dir"));
3928 #endif /* defined(_WIN32) */
3934 /** Run unittests for memory area allocator */
3936 test_util_memarea(void *arg
)
3938 memarea_t
*area
= memarea_new();
3939 char *p1
, *p2
, *p3
, *p1_orig
;
3940 void *malloced_ptr
= NULL
;
3943 #ifdef DISABLE_MEMORY_SENTINELS
3944 /* If memory sentinels are disabled, this whole module is just an alias for
3945 malloc(), which is free to lay out memory most any way it wants. */
3948 #endif /* defined(DISABLE_MEMORY_SENTINELS) */
3953 p1_orig
= p1
= memarea_alloc(area
,64);
3954 p2
= memarea_alloc_zero(area
,52);
3955 p3
= memarea_alloc(area
,11);
3957 tt_assert(memarea_owns_ptr(area
, p1
));
3958 tt_assert(memarea_owns_ptr(area
, p2
));
3959 tt_assert(memarea_owns_ptr(area
, p3
));
3960 /* Make sure we left enough space. */
3961 tt_assert(p1
+64 <= p2
);
3962 tt_assert(p2
+52 <= p3
);
3963 /* Make sure we aligned. */
3964 tt_int_op(((uintptr_t)p1
) % sizeof(void*),OP_EQ
, 0);
3965 tt_int_op(((uintptr_t)p2
) % sizeof(void*),OP_EQ
, 0);
3966 tt_int_op(((uintptr_t)p3
) % sizeof(void*),OP_EQ
, 0);
3967 tt_assert(!memarea_owns_ptr(area
, p3
+8192));
3968 tt_assert(!memarea_owns_ptr(area
, p3
+30));
3969 tt_assert(fast_mem_is_zero(p2
, 52));
3970 /* Make sure we don't overalign. */
3971 p1
= memarea_alloc(area
, 1);
3972 p2
= memarea_alloc(area
, 1);
3973 tt_ptr_op(p1
+sizeof(void*),OP_EQ
, p2
);
3975 malloced_ptr
= tor_malloc(64);
3976 tt_assert(!memarea_owns_ptr(area
, malloced_ptr
));
3977 tor_free(malloced_ptr
);
3980 /* memarea_memdup */
3982 malloced_ptr
= tor_malloc(64);
3983 crypto_rand((char*)malloced_ptr
, 64);
3984 p1
= memarea_memdup(area
, malloced_ptr
, 64);
3985 tt_assert(p1
!= malloced_ptr
);
3986 tt_mem_op(p1
,OP_EQ
, malloced_ptr
, 64);
3987 tor_free(malloced_ptr
);
3990 /* memarea_strdup. */
3991 p1
= memarea_strdup(area
,"");
3992 p2
= memarea_strdup(area
, "abcd");
3995 tt_str_op(p1
,OP_EQ
, "");
3996 tt_str_op(p2
,OP_EQ
, "abcd");
3998 /* memarea_strndup. */
4000 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
4001 /* (From Turandot, act 3.) */
4002 size_t len
= strlen(s
);
4003 p1
= memarea_strndup(area
, s
, 1000);
4004 p2
= memarea_strndup(area
, s
, 10);
4005 tt_str_op(p1
,OP_EQ
, s
);
4006 tt_assert(p2
>= p1
+ len
+ 1);
4007 tt_mem_op(s
,OP_EQ
, p2
, 10);
4008 tt_int_op(p2
[10],OP_EQ
, '\0');
4009 p3
= memarea_strndup(area
, s
, len
);
4010 tt_str_op(p3
,OP_EQ
, s
);
4011 p3
= memarea_strndup(area
, s
, len
-1);
4012 tt_mem_op(s
,OP_EQ
, p3
, len
-1);
4013 tt_int_op(p3
[len
-1],OP_EQ
, '\0');
4016 memarea_clear(area
);
4017 p1
= memarea_alloc(area
, 1);
4018 tt_ptr_op(p1
,OP_EQ
, p1_orig
);
4019 memarea_clear(area
);
4020 size_t total
= 0, initial_allocation
, allocation2
, dummy
;
4021 memarea_get_stats(area
, &initial_allocation
, &dummy
);
4023 /* Check for running over an area's size. */
4024 for (i
= 0; i
< 4096; ++i
) {
4025 size_t n
= crypto_rand_int(6);
4026 p1
= memarea_alloc(area
, n
);
4028 tt_assert(memarea_owns_ptr(area
, p1
));
4030 memarea_assert_ok(area
);
4031 memarea_get_stats(area
, &allocation2
, &dummy
);
4032 /* Make sure we can allocate a too-big object. */
4033 p1
= memarea_alloc_zero(area
, 9000);
4034 p2
= memarea_alloc_zero(area
, 16);
4037 tt_assert(memarea_owns_ptr(area
, p1
));
4038 tt_assert(memarea_owns_ptr(area
, p2
));
4040 /* Now test stats... */
4041 size_t allocated
= 0, used
= 0;
4042 memarea_get_stats(area
, &allocated
, &used
);
4043 tt_int_op(used
, OP_LE
, allocated
);
4044 tt_int_op(used
, OP_GE
, total
); /* not EQ, because of alignment and headers*/
4045 tt_int_op(allocated
, OP_GT
, allocation2
);
4047 tt_int_op(allocation2
, OP_GT
, initial_allocation
);
4049 memarea_clear(area
);
4050 memarea_get_stats(area
, &allocated
, &used
);
4051 tt_int_op(used
, OP_LT
, 128); /* Not 0, because of header */
4052 tt_int_op(allocated
, OP_EQ
, initial_allocation
);
4055 memarea_drop_all(area
);
4056 tor_free(malloced_ptr
);
4059 /** Run unit tests for utility functions to get file names relative to
4060 * the data directory. */
4062 test_util_datadir(void *arg
)
4066 char *temp_dir
= NULL
;
4069 temp_dir
= get_datadir_fname(NULL
);
4070 f
= get_datadir_fname("state");
4071 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
4072 tt_str_op(f
,OP_EQ
, buf
);
4074 f
= get_datadir_fname2("cache", "thingy");
4075 tor_snprintf(buf
, sizeof(buf
),
4076 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
4077 tt_str_op(f
,OP_EQ
, buf
);
4079 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
4080 tor_snprintf(buf
, sizeof(buf
),
4081 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
4082 tt_str_op(f
,OP_EQ
, buf
);
4084 f
= get_datadir_fname_suffix("cache", ".foo");
4085 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
4087 tt_str_op(f
,OP_EQ
, buf
);
4095 test_util_strtok(void *arg
)
4103 for (i
= 0; i
< 3; i
++) {
4104 const char *pad1
="", *pad2
="";
4117 tor_snprintf(buf
, sizeof(buf
), "%s", pad1
);
4118 tor_snprintf(buf2
, sizeof(buf2
), "%s", pad2
);
4119 tt_ptr_op(tor_strtok_r_impl(buf
, " ", &cp1
), OP_EQ
, NULL
);
4120 tt_ptr_op(tor_strtok_r_impl(buf2
, ".!..;!", &cp2
), OP_EQ
, NULL
);
4122 tor_snprintf(buf
, sizeof(buf
),
4123 "%sGraved on the dark in gestures of descent%s", pad1
, pad1
);
4124 tor_snprintf(buf2
, sizeof(buf2
),
4125 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2
,pad2
);
4126 /* -- "Year's End", Richard Wilbur */
4128 tt_str_op("Graved",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4129 tt_str_op("they",OP_EQ
, tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
4130 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
4131 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
4132 tt_str_op("on",OP_EQ
, S1());
4133 tt_str_op("the",OP_EQ
, S1());
4134 tt_str_op("dark",OP_EQ
, S1());
4135 tt_str_op("seemed",OP_EQ
, S2());
4136 tt_str_op("their",OP_EQ
, S2());
4137 tt_str_op("own",OP_EQ
, S2());
4138 tt_str_op("in",OP_EQ
, S1());
4139 tt_str_op("gestures",OP_EQ
, S1());
4140 tt_str_op("of",OP_EQ
, S1());
4141 tt_str_op("most",OP_EQ
, S2());
4142 tt_str_op("perfect",OP_EQ
, S2());
4143 tt_str_op("descent",OP_EQ
, S1());
4144 tt_str_op("monument",OP_EQ
, S2());
4145 tt_ptr_op(NULL
,OP_EQ
, S1());
4146 tt_ptr_op(NULL
,OP_EQ
, S2());
4150 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4151 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
4153 strlcpy(buf
, "Howdy!", sizeof(buf
));
4154 tt_str_op("Howdy",OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
4155 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, "!", &cp1
));
4157 strlcpy(buf
, " ", sizeof(buf
));
4158 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4159 strlcpy(buf
, " ", sizeof(buf
));
4160 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4162 strlcpy(buf
, "something ", sizeof(buf
));
4163 tt_str_op("something",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4164 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, ";", &cp1
));
4170 test_util_find_str_at_start_of_line(void *ptr
)
4172 const char *long_string
=
4173 "howdy world. how are you? i hope it's fine.\n"
4176 char *line2
= strchr(long_string
,'\n')+1;
4177 char *line3
= strchr(line2
,'\n')+1;
4178 const char *short_string
= "hello kitty\n"
4180 char *short_line2
= strchr(short_string
,'\n')+1;
4184 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, ""));
4185 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(short_string
, "nonsense"));
4186 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "nonsense"));
4187 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "\n"));
4188 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "how "));
4189 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "kitty"));
4190 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "h"));
4191 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "how"));
4192 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "he"));
4193 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hell"));
4194 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hello k"));
4195 tt_ptr_op(line2
,OP_EQ
,
4196 find_str_at_start_of_line(long_string
, "hello kitty\n"));
4197 tt_ptr_op(line2
,OP_EQ
,
4198 find_str_at_start_of_line(long_string
, "hello kitty\nt"));
4199 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third"));
4200 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third line"));
4201 tt_ptr_op(NULL
, OP_EQ
,
4202 find_str_at_start_of_line(long_string
, "third line\n"));
4203 tt_ptr_op(short_line2
,OP_EQ
, find_str_at_start_of_line(short_string
,
4210 test_util_tor_strreplacechar(void *ptr
)
4214 char not_contain
[] = "bbb";
4215 char contains
[] = "bab";
4216 char contains_all
[] = "aaa";
4218 tor_strreplacechar(empty
, 'a', 'b');
4219 tt_str_op(empty
, OP_EQ
, "");
4221 tor_strreplacechar(not_contain
, 'a', 'b');
4222 tt_str_op(not_contain
, OP_EQ
, "bbb");
4224 tor_strreplacechar(contains
, 'a', 'b');
4225 tt_str_op(contains
, OP_EQ
, "bbb");
4227 tor_strreplacechar(contains_all
, 'a', 'b');
4228 tt_str_op(contains_all
, OP_EQ
, "bbb");
4235 test_util_string_is_C_identifier(void *ptr
)
4239 tt_int_op(1,OP_EQ
, string_is_C_identifier("string_is_C_identifier"));
4240 tt_int_op(1,OP_EQ
, string_is_C_identifier("_string_is_C_identifier"));
4241 tt_int_op(1,OP_EQ
, string_is_C_identifier("_"));
4242 tt_int_op(1,OP_EQ
, string_is_C_identifier("i"));
4243 tt_int_op(1,OP_EQ
, string_is_C_identifier("_____"));
4244 tt_int_op(1,OP_EQ
, string_is_C_identifier("__00__"));
4245 tt_int_op(1,OP_EQ
, string_is_C_identifier("__init__"));
4246 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4247 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0string_is_C_identifier"));
4248 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4250 tt_int_op(0,OP_EQ
, string_is_C_identifier("0_string_is_C_identifier"));
4251 tt_int_op(0,OP_EQ
, string_is_C_identifier("0"));
4252 tt_int_op(0,OP_EQ
, string_is_C_identifier(""));
4253 tt_int_op(0,OP_EQ
, string_is_C_identifier(";"));
4254 tt_int_op(0,OP_EQ
, string_is_C_identifier("i;"));
4255 tt_int_op(0,OP_EQ
, string_is_C_identifier("_;"));
4256 tt_int_op(0,OP_EQ
, string_is_C_identifier("Ã"));
4257 tt_int_op(0,OP_EQ
, string_is_C_identifier("ñ"));
4264 test_util_string_is_utf8(void *ptr
)
4268 tt_int_op(1, OP_EQ
, string_is_utf8(NULL
, 0));
4269 tt_int_op(1, OP_EQ
, string_is_utf8("", 1));
4270 tt_int_op(1, OP_EQ
, string_is_utf8("\uFEFF", 3));
4271 tt_int_op(1, OP_EQ
, string_is_utf8("\uFFFE", 3));
4272 tt_int_op(1, OP_EQ
, string_is_utf8("ascii\x7f\n", 7));
4273 tt_int_op(1, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 9));
4275 /* Test the utf8_no_bom function */
4276 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFEFF", 3));
4277 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFFFE", 3));
4278 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFEFFlove", 7));
4279 tt_int_op(1, OP_EQ
, string_is_utf8_no_bom("loveandrespect",
4280 strlen("loveandrespect")));
4282 // Validate exactly 'len' bytes.
4283 tt_int_op(0, OP_EQ
, string_is_utf8("\0\x80", 2));
4284 tt_int_op(0, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 6));
4286 // Reject sequences with missing bytes.
4287 tt_int_op(0, OP_EQ
, string_is_utf8("\x80", 1));
4288 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2", 1));
4289 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2 ", 2));
4290 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80", 2));
4291 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80 ", 3));
4292 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80", 3));
4293 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80 ", 4));
4295 // Reject encodings that are overly long.
4296 tt_int_op(0, OP_EQ
, string_is_utf8("\xc1\xbf", 2));
4297 tt_int_op(1, OP_EQ
, string_is_utf8("\xc2\x80", 2));
4298 tt_int_op(0, OP_EQ
, string_is_utf8("\xe0\x9f\xbf", 3));
4299 tt_int_op(1, OP_EQ
, string_is_utf8("\xe0\xa0\x80", 3));
4300 tt_int_op(0, OP_EQ
, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
4301 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\x90\x80\x80", 4));
4303 // Reject UTF-16 surrogate halves.
4304 tt_int_op(1, OP_EQ
, string_is_utf8("\xed\x9f\xbf", 3));
4305 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xa0\x80", 3));
4306 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xbf\xbf", 3));
4307 tt_int_op(1, OP_EQ
, string_is_utf8("\xee\x80\x80", 3));
4309 // The minimum legal codepoint, 0x00.
4310 tt_int_op(1, OP_EQ
, string_is_utf8("\0", 1));
4312 // The maximum legal codepoint, 0x10FFFF.
4313 tt_int_op(1, OP_EQ
, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
4314 tt_int_op(0, OP_EQ
, string_is_utf8("\xf4\x90\x80\x80", 4));
4316 /* Test cases that vary between programming languages /
4317 * UTF-8 implementations.
4318 * Source: POC||GTFO 19, page 43
4319 * https://www.alchemistowl.org/pocorgtfo/
4322 // Invalid (in most implementations)
4324 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xa0\x81", 3));
4326 tt_int_op(0, OP_EQ
, string_is_utf8("\x30\x00\xed\xa0\x81", 5));
4328 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xbf\xbf", 3));
4330 tt_int_op(0, OP_EQ
, string_is_utf8("\xf4\x90\xbf\xbf", 4));
4332 tt_int_op(0, OP_EQ
, string_is_utf8("\xfb\x80\x80\x80\x80", 5));
4334 tt_int_op(0, OP_EQ
, string_is_utf8("\xfd\x80\x80\x80\x80", 5));
4336 tt_int_op(0, OP_EQ
, string_is_utf8("\xfd\xbf\xbf\xbf\xbf", 5));
4338 // Valid (in most implementations)
4340 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\x90\x8d\x88", 4));
4342 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\xbf\xbf\xbf", 4));
4344 tt_int_op(1, OP_EQ
, string_is_utf8("\x30\x31\x32\x00\x33", 5));
4351 test_util_asprintf(void *ptr
)
4353 #define LOREMIPSUM \
4354 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
4355 char *cp
=NULL
, *cp2
=NULL
;
4360 r
= tor_asprintf(&cp
, "simple string 100%% safe");
4362 tt_str_op("simple string 100% safe",OP_EQ
, cp
);
4363 tt_int_op(strlen(cp
),OP_EQ
, r
);
4367 r
= tor_asprintf(&cp
, "%s", "");
4369 tt_str_op("",OP_EQ
, cp
);
4370 tt_int_op(strlen(cp
),OP_EQ
, r
);
4374 r
= tor_asprintf(&cp
, "I like numbers-%2i, %i, etc.", -1, 2);
4376 tt_str_op("I like numbers--1, 2, etc.",OP_EQ
, cp
);
4377 tt_int_op(strlen(cp
),OP_EQ
, r
);
4378 /* don't free cp; next test uses it. */
4381 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
4383 tt_int_op(strlen(cp2
),OP_EQ
, r
);
4384 tt_str_op("First=101, Second=202",OP_EQ
, cp2
);
4385 tt_assert(cp
!= cp2
);
4389 /* Glass-box test: a string exactly 128 characters long. */
4390 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
4392 tt_int_op(128,OP_EQ
, r
);
4393 tt_int_op(cp
[128], OP_EQ
, '\0');
4394 tt_str_op("Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
,OP_EQ
, cp
);
4397 /* String longer than 128 characters */
4398 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
4399 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
4401 tt_int_op(strlen(cp
),OP_EQ
, r
);
4402 tt_str_op("1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
,OP_EQ
, cp
);
4410 test_util_listdir(void *ptr
)
4412 smartlist_t
*dir_contents
= NULL
;
4413 char *fname1
=NULL
, *fname2
=NULL
, *fname3
=NULL
, *dir1
=NULL
, *dirname
=NULL
;
4417 fname1
= tor_strdup(get_fname("hopscotch"));
4418 fname2
= tor_strdup(get_fname("mumblety-peg"));
4419 fname3
= tor_strdup(get_fname(".hidden-file"));
4420 dir1
= tor_strdup(get_fname("some-directory"));
4421 dirname
= tor_strdup(get_fname(NULL
));
4423 tt_int_op(0,OP_EQ
, write_str_to_file(fname1
, "X\n", 0));
4424 tt_int_op(0,OP_EQ
, write_str_to_file(fname2
, "Y\n", 0));
4425 tt_int_op(0,OP_EQ
, write_str_to_file(fname3
, "Z\n", 0));
4429 r
= mkdir(dir1
, 0700);
4432 fprintf(stderr
, "Can't create directory %s:", dir1
);
4437 dir_contents
= tor_listdir(dirname
);
4438 tt_assert(dir_contents
);
4439 /* make sure that each filename is listed. */
4440 tt_assert(smartlist_contains_string_case(dir_contents
, "hopscotch"));
4441 tt_assert(smartlist_contains_string_case(dir_contents
, "mumblety-peg"));
4442 tt_assert(smartlist_contains_string_case(dir_contents
, ".hidden-file"));
4443 tt_assert(smartlist_contains_string_case(dir_contents
, "some-directory"));
4445 tt_assert(!smartlist_contains_string(dir_contents
, "."));
4446 tt_assert(!smartlist_contains_string(dir_contents
, ".."));
4455 SMARTLIST_FOREACH(dir_contents
, char *, cp
, tor_free(cp
));
4456 smartlist_free(dir_contents
);
4461 test_util_glob(void *ptr
)
4466 smartlist_t
*results
= NULL
;
4468 char *dir1
= NULL
, *dir2
= NULL
, *forbidden
= NULL
, *dirname
= NULL
;
4469 char *expected
= NULL
, *pattern
= NULL
;
4471 char *dir1_forbidden
= NULL
, *dir2_forbidden
= NULL
;
4472 char *forbidden_forbidden
= NULL
;
4474 dirname
= tor_strdup(get_fname("test_glob"));
4475 tt_ptr_op(dirname
, OP_NE
, NULL
);
4480 r
= mkdir(dirname
, 0700);
4483 fprintf(stderr
, "Can't create directory %s:", dirname
);
4488 tt_int_op(0, OP_EQ
, create_test_directory_structure(dirname
));
4489 tor_asprintf(&dir1
, "%s"PATH_SEPARATOR
"dir1", dirname
);
4490 tor_asprintf(&dir1_forbidden
,
4491 "%s"PATH_SEPARATOR
"dir1"PATH_SEPARATOR
"forbidden", dirname
);
4492 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir1
));
4493 tor_asprintf(&dir2
, "%s"PATH_SEPARATOR
"dir2", dirname
);
4494 tor_asprintf(&dir2_forbidden
,
4495 "%s"PATH_SEPARATOR
"dir2"PATH_SEPARATOR
"forbidden", dirname
);
4496 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir2
));
4497 tor_asprintf(&forbidden
, "%s"PATH_SEPARATOR
"forbidden", dirname
);
4498 tor_asprintf(&forbidden_forbidden
,
4499 "%s"PATH_SEPARATOR
"forbidden"PATH_SEPARATOR
"forbidden",dirname
);
4501 tt_int_op(0, OP_EQ
, chmod(forbidden
, 0700));
4503 tt_int_op(0, OP_EQ
, create_test_directory_structure(forbidden
));
4505 tt_int_op(0, OP_EQ
, chmod(forbidden
, 0));
4508 #define TEST(input) \
4510 tor_asprintf(&pattern, "%s"PATH_SEPARATOR"%s", dirname, input); \
4511 results = tor_glob(pattern); \
4512 tor_free(pattern); \
4513 tt_assert(results); \
4514 smartlist_sort_strings(results); \
4517 #define EXPECT(result) \
4519 tt_int_op(smartlist_len(results), OP_EQ, \
4520 sizeof(result)/sizeof(*result)); \
4522 SMARTLIST_FOREACH_BEGIN(results, const char *, f) { \
4523 tor_asprintf(&expected, "%s"PATH_SEPARATOR"%s", dirname, result[i]); \
4524 tt_str_op(f, OP_EQ, expected); \
4526 tor_free(expected); \
4527 } SMARTLIST_FOREACH_END(f); \
4528 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4529 smartlist_free(results); \
4532 #define EXPECT_EMPTY() \
4534 tt_int_op(smartlist_len(results), OP_EQ, 0); \
4535 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4536 smartlist_free(results); \
4539 // wildcards at beginning
4540 const char *results_test1
[] = {"dir2", "file2"};
4542 EXPECT(results_test1
);
4545 const char *results_test2
[] = {"dir1", "dir2"};
4547 EXPECT(results_test2
);
4549 // wildcards at beginning and end
4551 // dot files are not ignored on Windows
4552 const char *results_test3
[] = {".test-hidden", "dir1", "dir2", "file1",
4553 "file2", "forbidden"};
4555 const char *results_test3
[] = {"dir1", "dir2", "file1", "file2",
4557 #endif /* defined(_WIN32) */
4559 EXPECT(results_test3
);
4561 // wildcards in middle
4562 const char *results_test4
[] = {"dir1", "dir2"};
4564 EXPECT(results_test4
);
4566 // test file that does not exist
4570 // test wildcard that matches nothing
4571 TEST("*not-exist*");
4574 // test path separator at end - no wildcards
4575 const char *results_test7
[] = {"dir1"};
4577 EXPECT(results_test7
);
4579 const char *results_test8
[] = {"dir1"};
4580 TEST("dir1"PATH_SEPARATOR
);
4581 EXPECT(results_test8
);
4583 const char *results_test9
[] = {"file1"};
4585 EXPECT(results_test9
);
4587 TEST("file1"PATH_SEPARATOR
);
4590 // test path separator at end - with wildcards and linux path separator
4591 const char *results_test11
[] = {"dir1", "dir2", "forbidden"};
4593 EXPECT(results_test11
);
4596 // dot files are not ignored on Windows
4597 const char *results_test12
[] = {".test-hidden", "dir1", "dir2", "empty",
4598 "file1", "file2", "forbidden"};
4600 const char *results_test12
[] = {"dir1", "dir2", "empty", "file1", "file2",
4602 #endif /* defined(_WIN32) */
4604 EXPECT(results_test12
);
4606 // wildcards on folder and file and linux path separator
4607 const char *results_test13
[] = {"dir1"PATH_SEPARATOR
"dir1",
4608 "dir1"PATH_SEPARATOR
"dir2",
4609 "dir1"PATH_SEPARATOR
"file1",
4610 "dir1"PATH_SEPARATOR
"file2",
4611 "dir2"PATH_SEPARATOR
"dir1",
4612 "dir2"PATH_SEPARATOR
"dir2",
4613 "dir2"PATH_SEPARATOR
"file1",
4614 "dir2"PATH_SEPARATOR
"file2"};
4616 EXPECT(results_test13
);
4618 // wildcards on file only
4619 const char *results_test14
[] = {"dir1"PATH_SEPARATOR
"dir1",
4620 "dir1"PATH_SEPARATOR
"dir2",
4621 "dir1"PATH_SEPARATOR
"file1",
4622 "dir1"PATH_SEPARATOR
"file2"};
4623 TEST("dir1"PATH_SEPARATOR
"?i*");
4624 EXPECT(results_test14
);
4626 // wildcards on folder only
4627 const char *results_test15
[] = {"dir1"PATH_SEPARATOR
"file1",
4628 "dir2"PATH_SEPARATOR
"file1"};
4629 TEST("?i*"PATH_SEPARATOR
"file1");
4630 EXPECT(results_test15
);
4632 // wildcards after file name
4633 TEST("file1"PATH_SEPARATOR
"*");
4637 // test wildcard escaping
4641 if (getuid() != 0) {
4642 // test forbidden directory, if we're not root.
4643 // (Root will be able to see this directory anyway.)
4644 tor_asprintf(&pattern
, "%s"PATH_SEPARATOR
"*"PATH_SEPARATOR
"*", dirname
);
4645 results
= tor_glob(pattern
);
4647 tt_assert(!results
);
4649 #endif /* !defined(_WIN32) */
4657 (void) chmod(forbidden
, 0700);
4658 (void) chmod(dir1_forbidden
, 0700);
4659 (void) chmod(dir2_forbidden
, 0700);
4660 (void) chmod(forbidden_forbidden
, 0700);
4661 #endif /* !defined(_WIN32) */
4664 tor_free(forbidden
);
4666 tor_free(dir1_forbidden
);
4667 tor_free(dir2_forbidden
);
4668 tor_free(forbidden_forbidden
);
4672 SMARTLIST_FOREACH(results
, char *, f
, tor_free(f
));
4673 smartlist_free(results
);
4675 #else /* !defined(HAVE_GLOB) */
4679 #endif /* defined(HAVE_GLOB) */
4683 test_util_get_glob_opened_files(void *ptr
)
4688 smartlist_t
*results
= NULL
;
4690 char *dir1
= NULL
, *dir2
= NULL
, *forbidden
= NULL
, *dirname
= NULL
;
4691 char *expected
= NULL
, *pattern
= NULL
;
4693 char *dir1_forbidden
= NULL
, *dir2_forbidden
= NULL
;
4694 char *forbidden_forbidden
= NULL
;
4696 dirname
= tor_strdup(get_fname("test_get_glob_opened_files"));
4697 tt_ptr_op(dirname
, OP_NE
, NULL
);
4702 r
= mkdir(dirname
, 0700);
4705 fprintf(stderr
, "Can't create directory %s:", dirname
);
4710 tt_int_op(0, OP_EQ
, create_test_directory_structure(dirname
));
4711 tor_asprintf(&dir1
, "%s"PATH_SEPARATOR
"dir1", dirname
);
4712 tor_asprintf(&dir1_forbidden
,
4713 "%s"PATH_SEPARATOR
"dir1"PATH_SEPARATOR
"forbidden", dirname
);
4714 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir1
));
4715 tor_asprintf(&dir2
, "%s"PATH_SEPARATOR
"dir2", dirname
);
4716 tor_asprintf(&dir2_forbidden
,
4717 "%s"PATH_SEPARATOR
"dir2"PATH_SEPARATOR
"forbidden", dirname
);
4718 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir2
));
4719 tor_asprintf(&forbidden
, "%s"PATH_SEPARATOR
"forbidden", dirname
);
4720 tor_asprintf(&forbidden_forbidden
,
4721 "%s"PATH_SEPARATOR
"forbidden"PATH_SEPARATOR
"forbidden",dirname
);
4723 chmod(forbidden
, 0700);
4725 tt_int_op(0, OP_EQ
, create_test_directory_structure(forbidden
));
4727 chmod(forbidden
, 0);
4730 #define TEST(input) \
4733 tor_asprintf(&pattern, "%s"PATH_SEPARATOR"%s", dirname, input); \
4734 } else { /* do not add path separator if empty string */ \
4735 tor_asprintf(&pattern, "%s", dirname); \
4737 results = get_glob_opened_files(pattern); \
4738 tor_free(pattern); \
4739 tt_assert(results); \
4740 smartlist_sort_strings(results); \
4743 #define EXPECT(result) \
4745 tt_int_op(smartlist_len(results), OP_EQ, \
4746 sizeof(result)/sizeof(*result)); \
4748 SMARTLIST_FOREACH_BEGIN(results, const char *, f) { \
4750 tor_asprintf(&expected, "%s"PATH_SEPARATOR"%s", dirname, result[i]); \
4751 } else { /* do not add path separator if empty string */ \
4752 tor_asprintf(&expected, "%s", dirname); \
4754 tt_str_op(f, OP_EQ, expected); \
4756 tor_free(expected); \
4757 } SMARTLIST_FOREACH_END(f); \
4758 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4759 smartlist_free(results); \
4762 #define EXPECT_EMPTY() \
4764 tt_int_op(smartlist_len(results), OP_EQ, 0); \
4765 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4766 smartlist_free(results); \
4769 // all files on folder
4770 const char *results_test1
[] = {""}; // only the folder is read
4772 EXPECT(results_test1
);
4774 // same as before but ending in path separator
4775 const char *results_test2
[] = {""}; // only the folder is read
4776 TEST("*"PATH_SEPARATOR
);
4777 EXPECT(results_test2
);
4779 // wildcards in multiple path components
4781 const char *results_test3
[] = {"", "dir1", "dir2", "empty", "file1", "file2",
4784 // dot files are not special on windows
4785 const char *results_test3
[] = {"", ".test-hidden", "dir1", "dir2", "empty",
4786 "file1", "file2", "forbidden"};
4787 #endif /* !defined(_WIN32) */
4788 TEST("*"PATH_SEPARATOR
"*");
4789 EXPECT(results_test3
);
4791 // same as before but ending in path separator
4793 const char *results_test4
[] = {"", "dir1", "dir2", "empty", "file1", "file2",
4796 // dot files are not special on windows
4797 const char *results_test4
[] = {"", ".test-hidden", "dir1", "dir2", "empty",
4798 "file1", "file2", "forbidden"};
4799 #endif /* !defined(_WIN32) */
4800 TEST("*"PATH_SEPARATOR
"*"PATH_SEPARATOR
);
4801 EXPECT(results_test4
);
4807 // same as before but ending in path separator
4808 TEST(PATH_SEPARATOR
);
4815 // same as before but ending in path separator and linux path separator
4819 // file but with wildcard after
4820 const char *results_test9
[] = {"file1"};
4821 TEST("file1"PATH_SEPARATOR
"*");
4822 EXPECT(results_test9
);
4824 // dir inside dir and linux path separator
4828 // same as before but ending in path separator
4829 TEST("dir1"PATH_SEPARATOR
"dir1"PATH_SEPARATOR
);
4836 // same as before but ending in path separator
4837 TEST("empty"PATH_SEPARATOR
);
4840 // no glob - does not exist
4851 int chmod_failed
= 0;
4853 chmod_failed
|= chmod(forbidden
, 0700);
4855 chmod_failed
|= chmod(dir1_forbidden
, 0700);
4857 chmod_failed
|= chmod(dir2_forbidden
, 0700);
4858 if (forbidden_forbidden
)
4859 chmod_failed
|= chmod(forbidden_forbidden
, 0700);
4861 TT_FAIL(("unable to chmod a file on cleanup: %s", strerror(errno
)));
4864 #endif /* !defined(_WIN32) */
4867 tor_free(forbidden
);
4869 tor_free(dir1_forbidden
);
4870 tor_free(dir2_forbidden
);
4871 tor_free(forbidden_forbidden
);
4875 SMARTLIST_FOREACH(results
, char *, f
, tor_free(f
));
4876 smartlist_free(results
);
4878 #else /* !defined(HAVE_GLOB) */
4882 #endif /* defined(HAVE_GLOB) */
4886 test_util_parent_dir(void *ptr
)
4891 #define T(output,expect_ok,input) \
4894 cp = tor_strdup(input); \
4895 ok = get_parent_directory(cp); \
4896 tt_int_op(expect_ok, OP_EQ, ok); \
4898 tt_str_op(output, OP_EQ, cp); \
4902 T("/home/wombat", 0, "/home/wombat/knish");
4903 T("/home/wombat", 0, "/home/wombat/knish/");
4904 T("/home/wombat", 0, "/home/wombat/knish///");
4905 T("./home/wombat", 0, "./home/wombat/knish/");
4907 T("/", 0, "/home//");
4908 T(".", 0, "./wombat");
4909 T(".", 0, "./wombat/");
4910 T(".", 0, "./wombat//");
4911 T("wombat", 0, "wombat/foo");
4912 T("wombat/..", 0, "wombat/../foo");
4913 T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
4914 T("wombat/.", 0, "wombat/./foo");
4915 T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
4916 T("wombat", 0, "wombat/..//");
4917 T("wombat", 0, "wombat/foo/");
4918 T("wombat", 0, "wombat/.foo");
4919 T("wombat", 0, "wombat/.foo/");
4921 T("wombat", -1, "");
4923 T("wombat", 0, "wombat/knish");
4933 test_util_ftruncate(void *ptr
)
4938 const char *message
= "Hello world";
4939 const char *message2
= "Hola mundo";
4944 fname
= get_fname("ftruncate");
4946 fd
= tor_open_cloexec(fname
, O_WRONLY
|O_CREAT
, 0600);
4947 tt_int_op(fd
, OP_GE
, 0);
4949 /* Make the file be there. */
4950 tt_int_op(strlen(message
), OP_EQ
,
4951 write_all_to_fd(fd
, message
, strlen(message
)));
4952 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message
));
4953 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4954 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message
));
4956 /* Truncate and see if it got truncated */
4957 tt_int_op(0, OP_EQ
, tor_ftruncate(fd
));
4958 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, 0);
4959 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4960 tt_int_op((int)st
.st_size
, OP_EQ
, 0);
4962 /* Replace, and see if it got replaced */
4963 tt_int_op(strlen(message2
), OP_EQ
,
4964 write_all_to_fd(fd
, message2
, strlen(message2
)));
4965 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message2
));
4966 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4967 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message2
));
4972 buf
= read_file_to_str(fname
, 0, NULL
);
4973 tt_str_op(message2
, OP_EQ
, buf
);
4982 test_util_num_cpus(void *arg
)
4985 int num
= compute_num_cpus();
4989 tt_int_op(num
, OP_GE
, 1);
4990 tt_int_op(num
, OP_LE
, 128);
4998 test_util_load_win_lib(void *ptr
)
5000 HANDLE h
= load_windows_system_library(_T("advapi32.dll"));
5008 #endif /* defined(_WIN32) */
5011 * Test for format_hex_number_sigsafe()
5015 test_util_format_hex_number(void *ptr
)
5027 {"7FFFFFFF", 0x7fffffff},
5028 {"FFFFFFFF", 0xffffffff},
5029 #if UINT_MAX >= 0xffffffff
5030 {"31BC421D", 0x31bc421d},
5031 {"FFFFFFFF", 0xffffffff},
5038 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
5039 len
= format_hex_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
5040 tt_int_op(len
,OP_NE
, 0);
5041 tt_int_op(len
,OP_EQ
, strlen(buf
));
5042 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
5045 tt_int_op(4,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 5));
5046 tt_str_op(buf
,OP_EQ
, "FFFF");
5047 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 4));
5048 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0, buf
, 1));
5055 * Test for format_hex_number_sigsafe()
5059 test_util_format_dec_number(void *ptr
)
5070 {"12345678", 12345678},
5071 {"99999999", 99999999},
5072 {"100000000", 100000000},
5073 {"4294967295", 4294967295u},
5074 #if UINT_MAX > 0xffffffff
5075 {"18446744073709551615", 18446744073709551615u },
5082 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
5083 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
5084 tt_int_op(len
,OP_NE
, 0);
5085 tt_int_op(len
,OP_EQ
, strlen(buf
));
5086 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
5088 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
,
5089 (int)(strlen(test_data
[i
].str
) + 1));
5090 tt_int_op(len
,OP_EQ
, strlen(buf
));
5091 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
5094 tt_int_op(4,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 5));
5095 tt_str_op(buf
,OP_EQ
, "7331");
5096 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 4));
5097 tt_int_op(1,OP_EQ
, format_dec_number_sigsafe(0, buf
, 2));
5098 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(0, buf
, 1));
5104 #define MAX_SPLIT_LINE_COUNT 4
5105 struct split_lines_test_t
{
5106 const char *orig_line
; // Line to be split (may contain \0's)
5107 int orig_length
; // Length of orig_line
5108 const char *split_line
[MAX_SPLIT_LINE_COUNT
]; // Split lines
5112 test_util_di_ops(void *arg
)
5118 const char *a
; int want_sign
; const char *b
;
5120 { "Foo", EQ
, "Foo" },
5121 { "foo", GT
, "bar", },
5122 { "foobar", EQ
,"foobar" },
5123 { "foobar", LT
, "foobaw" },
5124 { "foobar", GT
, "f00bar" },
5125 { "foobar", GT
, "boobar" },
5133 for (i
= 0; examples
[i
].a
; ++i
) {
5134 size_t len
= strlen(examples
[i
].a
);
5135 int eq1
, eq2
, neq1
, neq2
, cmp1
, cmp2
;
5136 tt_int_op(len
,OP_EQ
, strlen(examples
[i
].b
));
5137 /* We do all of the operations, with operands in both orders. */
5138 eq1
= tor_memeq(examples
[i
].a
, examples
[i
].b
, len
);
5139 eq2
= tor_memeq(examples
[i
].b
, examples
[i
].a
, len
);
5140 neq1
= tor_memneq(examples
[i
].a
, examples
[i
].b
, len
);
5141 neq2
= tor_memneq(examples
[i
].b
, examples
[i
].a
, len
);
5142 cmp1
= tor_memcmp(examples
[i
].a
, examples
[i
].b
, len
);
5143 cmp2
= tor_memcmp(examples
[i
].b
, examples
[i
].a
, len
);
5145 /* Check for correctness of cmp1 */
5146 if (cmp1
< 0 && examples
[i
].want_sign
!= LT
)
5147 TT_DIE(("Assertion failed."));
5148 else if (cmp1
> 0 && examples
[i
].want_sign
!= GT
)
5149 TT_DIE(("Assertion failed."));
5150 else if (cmp1
== 0 && examples
[i
].want_sign
!= EQ
)
5151 TT_DIE(("Assertion failed."));
5153 /* Check for consistency of everything else with cmp1 */
5154 tt_int_op(eq1
,OP_EQ
, eq2
);
5155 tt_int_op(neq1
,OP_EQ
, neq2
);
5156 tt_int_op(cmp1
,OP_EQ
, -cmp2
);
5157 tt_int_op(eq1
,OP_EQ
, cmp1
== 0);
5158 tt_int_op(neq1
,OP_EQ
, !eq1
);
5166 /* exhaustively test tor_memeq and tor_memcmp
5167 * against each possible single-byte numeric difference
5168 * some arithmetic bugs only appear with certain bit patterns */
5169 for (z
= 0; z
< 256; z
++) {
5170 for (i
= 0; i
< 256; i
++) {
5173 tt_int_op(tor_memeq(&zz
, &ii
, 1),OP_EQ
, zz
== ii
);
5174 tt_int_op(tor_memcmp(&zz
, &ii
, 1) > 0 ? GT
: EQ
,OP_EQ
,
5176 tt_int_op(tor_memcmp(&ii
, &zz
, 1) < 0 ? LT
: EQ
,OP_EQ
,
5182 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 0));
5183 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 1));
5184 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 1));
5185 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 2));
5186 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0a", 2));
5187 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0a", 2));
5188 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
5189 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
5190 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
5197 test_util_memcpy_iftrue_timei(void *arg
)
5204 for (int i
= 0; i
< 100; ++i
) {
5205 crypto_rand(buf1
, sizeof(buf1
));
5206 crypto_rand(buf2
, sizeof(buf2
));
5207 memcpy(buf3
, buf1
, sizeof(buf1
));
5209 /* We just copied buf1 into buf3. Now we're going to copy buf2 into buf2,
5210 iff our coin flip comes up heads. */
5211 bool coinflip
= crypto_rand_int(2) == 0;
5213 memcpy_if_true_timei(coinflip
, buf3
, buf2
, sizeof(buf3
));
5216 tt_mem_op(buf3
, OP_EQ
, buf2
, sizeof(buf2
));
5218 tt_mem_op(buf3
, OP_EQ
, buf1
, sizeof(buf1
));
5226 test_util_di_map(void *arg
)
5229 di_digest256_map_t
*dimap
= NULL
;
5230 uint8_t key1
[] = "Robert Anton Wilson ";
5231 uint8_t key2
[] = "Martin Gardner, _Fads&fallacies";
5232 uint8_t key3
[] = "Tom Lehrer, _Be Prepared_. ";
5233 uint8_t key4
[] = "Ursula Le Guin,_A Wizard of... ";
5235 char dflt_entry
[] = "'You have made a good beginning', but no more";
5237 tt_int_op(32, OP_EQ
, sizeof(key1
));
5238 tt_int_op(32, OP_EQ
, sizeof(key2
));
5239 tt_int_op(32, OP_EQ
, sizeof(key3
));
5241 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
5243 char *str1
= tor_strdup("You are precisely as big as what you love"
5244 " and precisely as small as what you allow"
5246 char *str2
= tor_strdup("Let us hope that Lysenko's success in Russia will"
5247 " serve for many generations to come as another"
5248 " reminder to the world of how quickly and easily"
5249 " a science can be corrupted when ignorant"
5250 " political leaders deem themselves competent"
5251 " to arbitrate scientific disputes");
5252 char *str3
= tor_strdup("Don't write naughty words on walls "
5253 "if you can't spell.");
5255 dimap_add_entry(&dimap
, key1
, str1
);
5256 dimap_add_entry(&dimap
, key2
, str2
);
5257 dimap_add_entry(&dimap
, key3
, str3
);
5259 tt_ptr_op(str1
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
5260 tt_ptr_op(str3
, OP_EQ
, dimap_search(dimap
, key3
, dflt_entry
));
5261 tt_ptr_op(str2
, OP_EQ
, dimap_search(dimap
, key2
, dflt_entry
));
5262 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key4
, dflt_entry
));
5265 dimap_free(dimap
, tor_free_
);
5269 * Test counting high bits
5272 test_util_n_bits_set(void *ptr
)
5275 tt_int_op(0,OP_EQ
, n_bits_set_u8(0));
5276 tt_int_op(1,OP_EQ
, n_bits_set_u8(1));
5277 tt_int_op(3,OP_EQ
, n_bits_set_u8(7));
5278 tt_int_op(1,OP_EQ
, n_bits_set_u8(8));
5279 tt_int_op(2,OP_EQ
, n_bits_set_u8(129));
5280 tt_int_op(8,OP_EQ
, n_bits_set_u8(255));
5286 * Test LHS whitespace (and comment) eater
5289 test_util_eat_whitespace(void *ptr
)
5291 const char ws
[] = { ' ', '\t', '\r' }; /* Except NL */
5297 /* Try one leading ws */
5298 strlcpy(str
, "fuubaar", sizeof(str
));
5299 for (i
= 0; i
< sizeof(ws
); ++i
) {
5301 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
5302 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5303 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
5304 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5307 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
5308 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5309 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5310 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5313 strlcpy(str
, "", sizeof(str
));
5314 tt_ptr_op(str
,OP_EQ
, eat_whitespace(str
));
5315 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos(str
, str
));
5316 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5317 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
));
5320 strlcpy(str
, " \t\r\n", sizeof(str
));
5321 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5322 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5323 eat_whitespace_eos(str
, str
+ strlen(str
)));
5324 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
5325 eat_whitespace_no_nl(str
));
5326 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
5327 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5329 strlcpy(str
, " \t\r ", sizeof(str
));
5330 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5331 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5332 eat_whitespace_eos(str
, str
+ strlen(str
)));
5333 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace_no_nl(str
));
5334 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5335 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5338 strlcpy(str
, "fuubaar", sizeof(str
));
5339 for (i
= 0; i
< sizeof(ws
); ++i
)
5341 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace(str
));
5342 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
5343 eat_whitespace_eos(str
, str
+ strlen(str
)));
5344 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace_no_nl(str
));
5345 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
5346 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5349 strlcpy(str
, "# Comment \n No Comment", sizeof(str
));
5350 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
5351 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5352 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5353 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5355 /* Eat comment & ws mix */
5356 strlcpy(str
, " # \t Comment \n\t\nNo Comment", sizeof(str
));
5357 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
5358 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5359 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
5360 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5362 /* Eat entire comment */
5363 strlcpy(str
, "#Comment", sizeof(str
));
5364 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5365 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5366 eat_whitespace_eos(str
, str
+ strlen(str
)));
5367 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5368 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5370 /* Blank line, then comment */
5371 strlcpy(str
, " \t\n # Comment", sizeof(str
));
5372 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5373 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5374 eat_whitespace_eos(str
, str
+ strlen(str
)));
5375 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_no_nl(str
));
5376 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5382 /** Return a newly allocated smartlist containing the lines of text in
5383 * <b>lines</b>. The returned strings are heap-allocated, and must be
5384 * freed by the caller.
5386 * XXXX? Move to container.[hc] ? */
5387 static smartlist_t
*
5388 smartlist_new_from_text_lines(const char *lines
)
5390 smartlist_t
*sl
= smartlist_new();
5393 smartlist_split_string(sl
, lines
, "\n", 0, 0);
5395 last_line
= smartlist_pop_last(sl
);
5396 if (last_line
!= NULL
&& *last_line
!= '\0') {
5397 smartlist_add(sl
, last_line
);
5399 tor_free(last_line
);
5405 /** Test smartlist_new_from_text_lines */
5407 test_util_sl_new_from_text_lines(void *ptr
)
5411 { /* Normal usage */
5412 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz\n");
5413 int sl_len
= smartlist_len(sl
);
5415 tt_want_int_op(sl_len
, OP_EQ
, 3);
5417 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5418 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
5419 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
5421 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5425 { /* No final newline */
5426 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz");
5427 int sl_len
= smartlist_len(sl
);
5429 tt_want_int_op(sl_len
, OP_EQ
, 3);
5431 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5432 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
5433 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
5435 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5440 smartlist_t
*sl
= smartlist_new_from_text_lines("foo");
5441 int sl_len
= smartlist_len(sl
);
5443 tt_want_int_op(sl_len
, OP_EQ
, 1);
5445 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5447 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5451 { /* No text at all */
5452 smartlist_t
*sl
= smartlist_new_from_text_lines("");
5453 int sl_len
= smartlist_len(sl
);
5455 tt_want_int_op(sl_len
, OP_EQ
, 0);
5457 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5463 test_util_envnames(void *ptr
)
5467 tt_assert(environment_variable_names_equal("abc", "abc"));
5468 tt_assert(environment_variable_names_equal("abc", "abc="));
5469 tt_assert(environment_variable_names_equal("abc", "abc=def"));
5470 tt_assert(environment_variable_names_equal("abc=def", "abc"));
5471 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
5473 tt_assert(environment_variable_names_equal("abc", "abc"));
5474 tt_assert(environment_variable_names_equal("abc", "abc="));
5475 tt_assert(environment_variable_names_equal("abc", "abc=def"));
5476 tt_assert(environment_variable_names_equal("abc=def", "abc"));
5477 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
5479 tt_assert(!environment_variable_names_equal("abc", "abcd"));
5480 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
5481 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
5482 tt_assert(!environment_variable_names_equal("abc=", "def"));
5483 tt_assert(!environment_variable_names_equal("abc=", "def="));
5484 tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
5486 tt_assert(!environment_variable_names_equal("", "a=def"));
5487 /* A bit surprising. */
5488 tt_assert(environment_variable_names_equal("", "=def"));
5489 tt_assert(environment_variable_names_equal("=y", "=x"));
5495 /** Test process_environment_make */
5497 test_util_make_environment(void *ptr
)
5499 const char *env_vars_string
=
5500 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5501 "HOME=/home/foozer\n";
5502 const char expected_windows_env_block
[] =
5503 "HOME=/home/foozer\000"
5504 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
5506 size_t expected_windows_env_block_len
=
5507 sizeof(expected_windows_env_block
) - 1;
5509 smartlist_t
*env_vars
= smartlist_new_from_text_lines(env_vars_string
);
5510 smartlist_t
*env_vars_sorted
= smartlist_new();
5511 smartlist_t
*env_vars_in_unixoid_env_block_sorted
= smartlist_new();
5513 process_environment_t
*env
;
5517 env
= process_environment_make(env_vars
);
5519 /* Check that the Windows environment block is correct. */
5520 tt_want(tor_memeq(expected_windows_env_block
, env
->windows_environment_block
,
5521 expected_windows_env_block_len
));
5523 /* Now for the Unixoid environment block. We don't care which order
5524 * these environment variables are in, so we sort both lists first. */
5526 smartlist_add_all(env_vars_sorted
, env_vars
);
5530 for (v
= env
->unixoid_environment_block
; *v
; ++v
) {
5531 smartlist_add(env_vars_in_unixoid_env_block_sorted
, *v
);
5535 smartlist_sort_strings(env_vars_sorted
);
5536 smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted
);
5538 tt_want_int_op(smartlist_len(env_vars_sorted
), OP_EQ
,
5539 smartlist_len(env_vars_in_unixoid_env_block_sorted
));
5541 int len
= smartlist_len(env_vars_sorted
);
5544 if (smartlist_len(env_vars_in_unixoid_env_block_sorted
) < len
) {
5545 len
= smartlist_len(env_vars_in_unixoid_env_block_sorted
);
5548 for (i
= 0; i
< len
; ++i
) {
5549 tt_want_str_op(smartlist_get(env_vars_sorted
, i
), OP_EQ
,
5550 smartlist_get(env_vars_in_unixoid_env_block_sorted
, i
));
5555 smartlist_free(env_vars_in_unixoid_env_block_sorted
);
5556 smartlist_free(env_vars_sorted
);
5558 SMARTLIST_FOREACH(env_vars
, char *, x
, tor_free(x
));
5559 smartlist_free(env_vars
);
5561 process_environment_free(env
);
5564 /** Test set_environment_variable_in_smartlist */
5566 test_util_set_env_var_in_sl(void *ptr
)
5568 /* The environment variables in these strings are in arbitrary
5569 * order; we sort the resulting lists before comparing them.
5571 * (They *will not* end up in the order shown in
5572 * expected_resulting_env_vars_string.) */
5574 const char *base_env_vars_string
=
5575 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5576 "HOME=/home/foozer\n"
5585 const char *new_env_vars_string
=
5590 const char *expected_resulting_env_vars_string
=
5591 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5592 "HOME=/home/foozer\n"
5602 smartlist_t
*merged_env_vars
=
5603 smartlist_new_from_text_lines(base_env_vars_string
);
5604 smartlist_t
*new_env_vars
=
5605 smartlist_new_from_text_lines(new_env_vars_string
);
5606 smartlist_t
*expected_resulting_env_vars
=
5607 smartlist_new_from_text_lines(expected_resulting_env_vars_string
);
5609 /* Elements of merged_env_vars are heap-allocated, and must be
5610 * freed. Some of them are (or should) be freed by
5611 * set_environment_variable_in_smartlist.
5613 * Elements of new_env_vars are heap-allocated, but are copied into
5614 * merged_env_vars, so they are not freed separately at the end of
5617 * Elements of expected_resulting_env_vars are heap-allocated, and
5622 SMARTLIST_FOREACH(new_env_vars
, char *, env_var
,
5623 set_environment_variable_in_smartlist(merged_env_vars
,
5628 smartlist_sort_strings(merged_env_vars
);
5629 smartlist_sort_strings(expected_resulting_env_vars
);
5631 tt_want_int_op(smartlist_len(merged_env_vars
), OP_EQ
,
5632 smartlist_len(expected_resulting_env_vars
));
5634 int len
= smartlist_len(merged_env_vars
);
5637 if (smartlist_len(expected_resulting_env_vars
) < len
) {
5638 len
= smartlist_len(expected_resulting_env_vars
);
5641 for (i
= 0; i
< len
; ++i
) {
5642 tt_want_str_op(smartlist_get(merged_env_vars
, i
), OP_EQ
,
5643 smartlist_get(expected_resulting_env_vars
, i
));
5648 SMARTLIST_FOREACH(merged_env_vars
, char *, x
, tor_free(x
));
5649 smartlist_free(merged_env_vars
);
5651 smartlist_free(new_env_vars
);
5653 SMARTLIST_FOREACH(expected_resulting_env_vars
, char *, x
, tor_free(x
));
5654 smartlist_free(expected_resulting_env_vars
);
5658 test_util_weak_random(void *arg
)
5664 tor_init_weak_random(&rng
, (unsigned)time(NULL
));
5666 for (i
= 1; i
<= 256; ++i
) {
5667 for (j
=0;j
<100;++j
) {
5668 int r
= tor_weak_random_range(&rng
, i
);
5669 tt_int_op(0, OP_LE
, r
);
5670 tt_int_op(r
, OP_LT
, i
);
5674 memset(n
,0,sizeof(n
));
5675 for (j
=0;j
<8192;++j
) {
5676 n
[tor_weak_random_range(&rng
, 16)]++;
5680 tt_int_op(n
[i
], OP_GT
, 0);
5686 test_util_mathlog(void *arg
)
5691 d
= tor_mathlog(2.718281828);
5692 tt_double_op(fabs(d
- 1.0), OP_LT
, .000001);
5693 d
= tor_mathlog(10);
5694 tt_double_op(fabs(d
- 2.30258509), OP_LT
, .000001);
5700 test_util_fraction(void *arg
)
5706 simplify_fraction64(&a
,&b
);
5707 tt_u64_op(a
, OP_EQ
, 33);
5708 tt_u64_op(b
, OP_EQ
, 10);
5710 a
= 3000000; b
= 10000000;
5711 simplify_fraction64(&a
,&b
);
5712 tt_u64_op(a
, OP_EQ
, 3);
5713 tt_u64_op(b
, OP_EQ
, 10);
5716 simplify_fraction64(&a
,&b
);
5717 tt_u64_op(a
, OP_EQ
, 0);
5718 tt_u64_op(b
, OP_EQ
, 1);
5725 test_util_round_to_next_multiple_of(void *arg
)
5729 tt_u64_op(round_uint64_to_next_multiple_of(0,1), OP_EQ
, 0);
5730 tt_u64_op(round_uint64_to_next_multiple_of(0,7), OP_EQ
, 0);
5732 tt_u64_op(round_uint64_to_next_multiple_of(99,1), OP_EQ
, 99);
5733 tt_u64_op(round_uint64_to_next_multiple_of(99,7), OP_EQ
, 105);
5734 tt_u64_op(round_uint64_to_next_multiple_of(99,9), OP_EQ
, 99);
5736 tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX
,2), OP_EQ
,
5739 tt_int_op(round_uint32_to_next_multiple_of(0,1), OP_EQ
, 0);
5740 tt_int_op(round_uint32_to_next_multiple_of(0,7), OP_EQ
, 0);
5742 tt_int_op(round_uint32_to_next_multiple_of(99,1), OP_EQ
, 99);
5743 tt_int_op(round_uint32_to_next_multiple_of(99,7), OP_EQ
, 105);
5744 tt_int_op(round_uint32_to_next_multiple_of(99,9), OP_EQ
, 99);
5746 tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX
,2), OP_EQ
,
5749 tt_uint_op(round_to_next_multiple_of(0,1), OP_EQ
, 0);
5750 tt_uint_op(round_to_next_multiple_of(0,7), OP_EQ
, 0);
5752 tt_uint_op(round_to_next_multiple_of(99,1), OP_EQ
, 99);
5753 tt_uint_op(round_to_next_multiple_of(99,7), OP_EQ
, 105);
5754 tt_uint_op(round_to_next_multiple_of(99,9), OP_EQ
, 99);
5756 tt_uint_op(round_to_next_multiple_of(UINT_MAX
,2), OP_EQ
,
5763 test_util_laplace(void *arg
)
5765 /* Sample values produced using Python's SciPy:
5767 * >>> from scipy.stats import laplace
5768 * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
5769 ... loc = 24, scale = 24)
5770 * array([ nan, -inf, -69.88855213, 24. ,
5771 * 24.48486498, 117.88855213, inf, nan])
5773 const double mu
= 24.0, b
= 24.0;
5774 const double delta_f
= 15.0, epsilon
= 0.3; /* b = 15.0 / 0.3 = 50.0 */
5777 tt_i64_op(INT64_MIN
, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.0));
5778 tt_i64_op(-69, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.01));
5779 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.5));
5780 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.51));
5781 tt_i64_op(117, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.99));
5783 /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
5784 * ... loc = 0, scale = 50)
5785 * array([ -inf, -80.47189562, -34.65735903, 0. ,
5786 * 34.65735903, 80.47189562, 195.60115027])
5788 tt_i64_op(INT64_MIN
+ 20, OP_EQ
,
5789 add_laplace_noise(20, 0.0, delta_f
, epsilon
));
5791 tt_i64_op(-60, OP_EQ
, add_laplace_noise(20, 0.1, delta_f
, epsilon
));
5792 tt_i64_op(-14, OP_EQ
, add_laplace_noise(20, 0.25, delta_f
, epsilon
));
5793 tt_i64_op(20, OP_EQ
, add_laplace_noise(20, 0.5, delta_f
, epsilon
));
5794 tt_i64_op(54, OP_EQ
, add_laplace_noise(20, 0.75, delta_f
, epsilon
));
5795 tt_i64_op(100, OP_EQ
, add_laplace_noise(20, 0.9, delta_f
, epsilon
));
5796 tt_i64_op(215, OP_EQ
, add_laplace_noise(20, 0.99, delta_f
, epsilon
));
5798 /* Test extreme values of signal with maximally negative values of noise
5799 * 1.0000000000000002 is the smallest number > 1
5800 * 0.0000000000000002 is the double epsilon (error when calculating near 1)
5801 * this is approximately 1/(2^52)
5802 * per https://en.wikipedia.org/wiki/Double_precision
5803 * (let's not descend into the world of subnormals)
5804 * >>> laplace.ppf([0, 0.0000000000000002], loc = 0, scale = 1)
5805 * array([ -inf, -35.45506713])
5807 const double noscale_df
= 1.0, noscale_eps
= 1.0;
5809 tt_i64_op(INT64_MIN
, OP_EQ
,
5810 add_laplace_noise(0, 0.0, noscale_df
, noscale_eps
));
5812 /* is it clipped to INT64_MIN? */
5813 tt_i64_op(INT64_MIN
, OP_EQ
,
5814 add_laplace_noise(-1, 0.0, noscale_df
, noscale_eps
));
5815 tt_i64_op(INT64_MIN
, OP_EQ
,
5816 add_laplace_noise(INT64_MIN
, 0.0,
5817 noscale_df
, noscale_eps
));
5818 /* ... even when scaled? */
5819 tt_i64_op(INT64_MIN
, OP_EQ
,
5820 add_laplace_noise(0, 0.0, delta_f
, epsilon
));
5821 tt_i64_op(INT64_MIN
, OP_EQ
,
5822 add_laplace_noise(0, 0.0,
5824 tt_i64_op(INT64_MIN
, OP_EQ
,
5825 add_laplace_noise(INT64_MIN
, 0.0,
5828 /* does it play nice with INT64_MAX? */
5829 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5830 add_laplace_noise(INT64_MAX
, 0.0,
5831 noscale_df
, noscale_eps
));
5833 /* do near-zero fractional values work? */
5834 const double min_dbl_error
= 0.0000000000000002;
5836 tt_i64_op(-35, OP_EQ
,
5837 add_laplace_noise(0, min_dbl_error
,
5838 noscale_df
, noscale_eps
));
5839 tt_i64_op(INT64_MIN
, OP_EQ
,
5840 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5841 noscale_df
, noscale_eps
));
5842 tt_i64_op((-35 + INT64_MAX
), OP_EQ
,
5843 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5844 noscale_df
, noscale_eps
));
5845 tt_i64_op(INT64_MIN
, OP_EQ
,
5846 add_laplace_noise(0, min_dbl_error
,
5848 tt_i64_op((INT64_MAX
+ INT64_MIN
), OP_EQ
,
5849 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5851 tt_i64_op(INT64_MIN
, OP_EQ
,
5852 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5855 /* does it play nice with INT64_MAX? */
5856 tt_i64_op((INT64_MAX
- 35), OP_EQ
,
5857 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5858 noscale_df
, noscale_eps
));
5860 /* Test extreme values of signal with maximally positive values of noise
5861 * 1.0000000000000002 is the smallest number > 1
5862 * 0.9999999999999998 is the greatest number < 1 by calculation
5863 * per https://en.wikipedia.org/wiki/Double_precision
5864 * >>> laplace.ppf([1.0, 0.9999999999999998], loc = 0, scale = 1)
5865 * array([inf, 35.35050621])
5866 * but the function rejects p == 1.0, so we just use max_dbl_lt_one
5868 const double max_dbl_lt_one
= 0.9999999999999998;
5870 /* do near-one fractional values work? */
5871 tt_i64_op(35, OP_EQ
,
5872 add_laplace_noise(0, max_dbl_lt_one
, noscale_df
, noscale_eps
));
5874 /* is it clipped to INT64_MAX? */
5875 tt_i64_op(INT64_MAX
, OP_EQ
,
5876 add_laplace_noise(INT64_MAX
- 35, max_dbl_lt_one
,
5877 noscale_df
, noscale_eps
));
5878 tt_i64_op(INT64_MAX
, OP_EQ
,
5879 add_laplace_noise(INT64_MAX
- 34, max_dbl_lt_one
,
5880 noscale_df
, noscale_eps
));
5881 tt_i64_op(INT64_MAX
, OP_EQ
,
5882 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5883 noscale_df
, noscale_eps
));
5884 /* ... even when scaled? */
5885 tt_i64_op(INT64_MAX
, OP_EQ
,
5886 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5888 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5889 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5891 tt_i64_op(INT64_MAX
, OP_EQ
,
5892 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5894 /* does it play nice with INT64_MIN? */
5895 tt_i64_op((INT64_MIN
+ 35), OP_EQ
,
5896 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5897 noscale_df
, noscale_eps
));
5904 test_util_clamp_double_to_int64(void *arg
)
5908 tt_i64_op(INT64_MIN
, OP_EQ
, clamp_double_to_int64(-INFINITY_DBL
));
5909 tt_i64_op(INT64_MIN
, OP_EQ
,
5910 clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0));
5911 tt_i64_op(INT64_MIN
, OP_EQ
,
5912 clamp_double_to_int64(-1.0 * pow(2.0, 63.0) - 1.0));
5913 tt_i64_op(((uint64_t) -1) << 53, OP_EQ
,
5914 clamp_double_to_int64(-1.0 * pow(2.0, 53.0)));
5915 tt_i64_op((((uint64_t) -1) << 53) + 1, OP_EQ
,
5916 clamp_double_to_int64(-1.0 * pow(2.0, 53.0) + 1.0));
5917 tt_i64_op(-1, OP_EQ
, clamp_double_to_int64(-1.0));
5918 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.9));
5919 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.1));
5920 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.0));
5921 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(NAN_DBL
));
5922 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.1));
5923 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.9));
5924 tt_i64_op(1, OP_EQ
, clamp_double_to_int64(1.0));
5925 tt_i64_op((((int64_t) 1) << 53) - 1, OP_EQ
,
5926 clamp_double_to_int64(pow(2.0, 53.0) - 1.0));
5927 tt_i64_op(((int64_t) 1) << 53, OP_EQ
,
5928 clamp_double_to_int64(pow(2.0, 53.0)));
5929 tt_i64_op(INT64_MAX
, OP_EQ
,
5930 clamp_double_to_int64(pow(2.0, 63.0)));
5931 tt_i64_op(INT64_MAX
, OP_EQ
,
5932 clamp_double_to_int64(pow(2.0, 64.0)));
5933 tt_i64_op(INT64_MAX
, OP_EQ
, clamp_double_to_int64(INFINITY_DBL
));
5940 #define CAN_CHECK_CLOEXEC
5942 fd_is_cloexec(tor_socket_t fd
)
5944 int flags
= fcntl(fd
, F_GETFD
, 0);
5945 return (flags
& FD_CLOEXEC
) != 0;
5947 #endif /* defined(FD_CLOEXEC) */
5950 #define CAN_CHECK_NONBLOCK
5952 fd_is_nonblocking(tor_socket_t fd
)
5954 int flags
= fcntl(fd
, F_GETFL
, 0);
5955 return (flags
& O_NONBLOCK
) != 0;
5957 #endif /* !defined(_WIN32) */
5959 #define ERRNO_IS_EPROTO(e) (e == SOCK_ERRNO(EPROTONOSUPPORT))
5960 #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s))
5962 /* Test for tor_open_socket*, using IPv4 or IPv6 depending on arg. */
5964 test_util_socket(void *arg
)
5966 const int domain
= !strcmp(arg
, "4") ? AF_INET
: AF_INET6
;
5967 tor_socket_t fd1
= TOR_INVALID_SOCKET
;
5968 tor_socket_t fd2
= TOR_INVALID_SOCKET
;
5969 tor_socket_t fd3
= TOR_INVALID_SOCKET
;
5970 tor_socket_t fd4
= TOR_INVALID_SOCKET
;
5971 int n
= get_n_open_sockets();
5973 TT_BLATHER(("Starting with %d open sockets.", n
));
5977 fd1
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 0);
5978 int err
= tor_socket_errno(fd1
);
5979 if (fd1
< 0 && (err
== SOCK_ERRNO(EPROTONOSUPPORT
) ||
5980 err
== SOCK_ERRNO(EAFNOSUPPORT
))) {
5981 /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */
5984 fd2
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 1);
5985 tt_assert(SOCKET_OK(fd1
));
5986 tt_assert(SOCKET_OK(fd2
));
5987 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5988 //fd3 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 0);
5989 //fd4 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 1);
5990 fd3
= tor_open_socket(domain
, SOCK_STREAM
, 0);
5991 fd4
= tor_open_socket_nonblocking(domain
, SOCK_STREAM
, 0);
5992 tt_assert(SOCKET_OK(fd3
));
5993 tt_assert(SOCKET_OK(fd4
));
5994 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 4);
5996 #ifdef CAN_CHECK_CLOEXEC
5997 tt_int_op(fd_is_cloexec(fd1
), OP_EQ
, 0);
5998 tt_int_op(fd_is_cloexec(fd2
), OP_EQ
, 0);
5999 tt_int_op(fd_is_cloexec(fd3
), OP_EQ
, 1);
6000 tt_int_op(fd_is_cloexec(fd4
), OP_EQ
, 1);
6001 #endif /* defined(CAN_CHECK_CLOEXEC) */
6002 #ifdef CAN_CHECK_NONBLOCK
6003 tt_int_op(fd_is_nonblocking(fd1
), OP_EQ
, 0);
6004 tt_int_op(fd_is_nonblocking(fd2
), OP_EQ
, 1);
6005 tt_int_op(fd_is_nonblocking(fd3
), OP_EQ
, 0);
6006 tt_int_op(fd_is_nonblocking(fd4
), OP_EQ
, 1);
6007 #endif /* defined(CAN_CHECK_NONBLOCK) */
6009 tor_assert(tor_close_socket
== tor_close_socket__real
);
6011 /* we use close_socket__real here so that coverity can tell that we are
6012 * really closing these sockets. */
6013 tor_close_socket__real(fd1
);
6014 tor_close_socket__real(fd2
);
6015 fd1
= fd2
= TOR_INVALID_SOCKET
;
6016 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
6017 tor_close_socket__real(fd3
);
6018 tor_close_socket__real(fd4
);
6019 fd3
= fd4
= TOR_INVALID_SOCKET
;
6020 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
6024 tor_close_socket__real(fd1
);
6026 tor_close_socket__real(fd2
);
6028 tor_close_socket__real(fd3
);
6030 tor_close_socket__real(fd4
);
6035 is_there_a_localhost(int family
)
6038 s
= tor_open_socket(family
, SOCK_STREAM
, IPPROTO_TCP
);
6039 tor_assert(SOCKET_OK(s
));
6042 if (family
== AF_INET
) {
6043 struct sockaddr_in s_in
;
6044 memset(&s_in
, 0, sizeof(s_in
));
6045 s_in
.sin_family
= AF_INET
;
6046 s_in
.sin_addr
.s_addr
= htonl(0x7f000001);
6049 if (bind(s
, (void*)&s_in
, sizeof(s_in
)) == 0) {
6052 } else if (family
== AF_INET6
) {
6053 struct sockaddr_in6 sin6
;
6054 memset(&sin6
, 0, sizeof(sin6
));
6055 sin6
.sin6_family
= AF_INET6
;
6056 sin6
.sin6_addr
.s6_addr
[15] = 1;
6059 tor_close_socket(s
);
6065 /* Test for socketpair and ersatz_socketpair(). We test them both, since
6066 * the latter is a tolerably good way to exercise tor_accept_socket(). */
6068 test_util_socketpair(void *arg
)
6070 const int ersatz
= !strcmp(arg
, "1");
6071 int (*const tor_socketpair_fn
)(int, int, int, tor_socket_t
[2]) =
6072 ersatz
? tor_ersatz_socketpair
: tor_socketpair
;
6073 int n
= get_n_open_sockets();
6074 tor_socket_t fds
[2] = {TOR_INVALID_SOCKET
, TOR_INVALID_SOCKET
};
6075 const int family
= AF_UNIX
;
6076 int socketpair_result
= 0;
6078 socketpair_result
= tor_socketpair_fn(family
, SOCK_STREAM
, 0, fds
);
6081 /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
6082 * Otherwise, we risk exposing a socketpair on a routable IP address. (Some
6083 * BSD jails use a routable address for localhost. Fortunately, they have
6084 * the real AF_UNIX socketpair.) */
6085 if (ersatz
&& socketpair_result
< 0) {
6086 /* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
6087 * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
6090 #endif /* defined(__FreeBSD__) */
6092 if (ersatz
&& socketpair_result
== -ENETUNREACH
) {
6093 /* We can also fail with -ENETUNREACH if we have no network stack at
6097 #endif /* defined(ENETUNREACH) */
6098 tt_int_op(0, OP_EQ
, socketpair_result
);
6100 tt_assert(SOCKET_OK(fds
[0]));
6101 tt_assert(SOCKET_OK(fds
[1]));
6103 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
6105 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
6106 #ifdef CAN_CHECK_CLOEXEC
6107 tt_int_op(fd_is_cloexec(fds
[0]), OP_EQ
, !ersatz
);
6108 tt_int_op(fd_is_cloexec(fds
[1]), OP_EQ
, !ersatz
);
6110 #ifdef CAN_CHECK_NONBLOCK
6111 tt_int_op(fd_is_nonblocking(fds
[0]), OP_EQ
, 0);
6112 tt_int_op(fd_is_nonblocking(fds
[1]), OP_EQ
, 0);
6117 if (SOCKET_OK(fds
[0]))
6118 tor_close_socket_simple(fds
[0]);
6119 if (SOCKET_OK(fds
[1]))
6120 tor_close_socket_simple(fds
[1]);
6122 if (SOCKET_OK(fds
[0]))
6123 tor_close_socket(fds
[0]);
6124 if (SOCKET_OK(fds
[1]))
6125 tor_close_socket(fds
[1]);
6129 #undef SOCKET_EPROTO
6132 test_util_max_mem(void *arg
)
6134 size_t memory1
, memory2
;
6138 r
= get_total_system_memory(&memory1
);
6139 r2
= get_total_system_memory(&memory2
);
6140 tt_int_op(r
, OP_EQ
, r2
);
6141 tt_uint_op(memory2
, OP_EQ
, memory1
);
6143 TT_BLATHER(("System memory: %"TOR_PRIuSZ
, (memory1
)));
6146 /* You have at least a megabyte. */
6147 tt_uint_op(memory1
, OP_GT
, (1<<20));
6149 /* You do not have a petabyte. */
6150 #if SIZEOF_SIZE_T >= 8
6151 tt_u64_op(memory1
, OP_LT
, (UINT64_C(1)<<50));
6160 test_util_dest_validation_edgecase(void *arg
)
6164 tt_assert(!string_is_valid_dest(NULL
));
6165 tt_assert(!string_is_valid_dest(""));
6172 test_util_hostname_validation(void *arg
)
6176 // Lets try valid hostnames first.
6177 tt_assert(string_is_valid_nonrfc_hostname("torproject.org"));
6178 tt_assert(string_is_valid_nonrfc_hostname("ocw.mit.edu"));
6179 tt_assert(string_is_valid_nonrfc_hostname("i.4cdn.org"));
6180 tt_assert(string_is_valid_nonrfc_hostname("stanford.edu"));
6181 tt_assert(string_is_valid_nonrfc_hostname("multiple-words-with-hypens.jp"));
6183 // Subdomain name cannot start with '-' or '_'.
6184 tt_assert(!string_is_valid_nonrfc_hostname("-torproject.org"));
6185 tt_assert(!string_is_valid_nonrfc_hostname("subdomain.-domain.org"));
6186 tt_assert(!string_is_valid_nonrfc_hostname("-subdomain.domain.org"));
6187 tt_assert(!string_is_valid_nonrfc_hostname("___abc.org"));
6189 // Hostnames cannot contain non-alphanumeric characters.
6190 tt_assert(!string_is_valid_nonrfc_hostname("%%domain.\\org."));
6191 tt_assert(!string_is_valid_nonrfc_hostname("***x.net"));
6192 tt_assert(!string_is_valid_nonrfc_hostname("\xff\xffxyz.org"));
6193 tt_assert(!string_is_valid_nonrfc_hostname("word1 word2.net"));
6195 // Test workaround for nytimes.com stupidity, technically invalid,
6196 // but we allow it since they are big, even though they are failing to
6197 // comply with a ~30 year old standard.
6198 tt_assert(string_is_valid_nonrfc_hostname("core3_euw1.fabrik.nytimes.com"));
6200 // Firefox passes FQDNs with trailing '.'s directly to the SOCKS proxy,
6201 // which is redundant since the spec states DOMAINNAME addresses are fully
6202 // qualified. While unusual, this should be tollerated.
6203 tt_assert(string_is_valid_nonrfc_hostname("core9_euw1.fabrik.nytimes.com."));
6204 tt_assert(!string_is_valid_nonrfc_hostname(
6205 "..washingtonpost.is.better.com"));
6206 tt_assert(!string_is_valid_nonrfc_hostname("so.is..ft.com"));
6207 tt_assert(!string_is_valid_nonrfc_hostname("..."));
6209 // XXX: do we allow single-label DNS names?
6210 // We shouldn't for SOCKS (spec says "contains a fully-qualified domain name"
6211 // but only test pathologically malformed trailing '.' cases for now.
6212 tt_assert(!string_is_valid_nonrfc_hostname("."));
6213 tt_assert(!string_is_valid_nonrfc_hostname(".."));
6215 // IP address strings are not hostnames.
6216 tt_assert(!string_is_valid_nonrfc_hostname("8.8.8.8"));
6217 tt_assert(!string_is_valid_nonrfc_hostname("[2a00:1450:401b:800::200e]"));
6218 tt_assert(!string_is_valid_nonrfc_hostname("2a00:1450:401b:800::200e"));
6220 // We allow alphanumeric TLDs. For discussion, see ticket #25055.
6221 tt_assert(string_is_valid_nonrfc_hostname("lucky.13"));
6222 tt_assert(string_is_valid_nonrfc_hostname("luck.y13"));
6223 tt_assert(string_is_valid_nonrfc_hostname("luck.y13."));
6225 // We allow punycode TLDs. For examples, see
6226 // https://data.iana.org/TLD/tlds-alpha-by-domain.txt
6227 tt_assert(string_is_valid_nonrfc_hostname("example.xn--l1acc"));
6234 test_util_ipv4_validation(void *arg
)
6238 tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
6239 tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
6241 tt_assert(!string_is_valid_ipv4_address("abcd"));
6242 tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
6243 tt_assert(!string_is_valid_ipv4_address("8.8."));
6250 test_util_ipv6_validation(void *arg
)
6254 tt_assert(string_is_valid_ipv6_address("2a00:1450:401b:800::200e"));
6255 tt_assert(!string_is_valid_ipv6_address("11:22::33:44:"));
6262 test_util_writepid(void *arg
)
6266 char *contents
= NULL
;
6267 const char *fname
= get_fname("tmp_pid");
6271 write_pidfile(fname
);
6273 contents
= read_file_to_str(fname
, 0, NULL
);
6274 tt_assert(contents
);
6276 int n
= tor_sscanf(contents
, "%lu\n%c", &pid
, &c
);
6277 tt_int_op(n
, OP_EQ
, 1);
6280 tt_uint_op(pid
, OP_EQ
, _getpid());
6282 tt_uint_op(pid
, OP_EQ
, getpid());
6290 test_util_get_avail_disk_space(void *arg
)
6295 /* No answer for nonexistent directory */
6296 val
= tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
6297 tt_i64_op(val
, OP_EQ
, -1);
6299 /* Try the current directory */
6300 val
= tor_get_avail_disk_space(".");
6302 #if !defined(HAVE_STATVFS) && !defined(_WIN32)
6303 tt_i64_op(val
, OP_EQ
, -1); /* You don't have an implementation for this */
6305 tt_i64_op(val
, OP_GT
, 0); /* You have some space. */
6306 tt_i64_op(val
, OP_LT
, ((int64_t)1)<<56); /* You don't have a zebibyte */
6307 #endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */
6313 /** Helper: Change the atime and mtime of a file. */
6315 set_file_mtime(const char *fname
, time_t when
)
6317 struct utimbuf u
= { when
, when
};
6319 tt_int_op(0, OP_EQ
, utime(fname
, &u
));
6320 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
6321 /* Let's hope that utime/stat give the same second as a round-trip? */
6322 tt_i64_op(st
.st_mtime
, OP_EQ
, when
);
6328 test_util_touch_file(void *arg
)
6331 const char *fname
= get_fname("touch");
6333 const time_t now
= time(NULL
);
6335 write_bytes_to_file(fname
, "abc", 3, 1);
6336 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
6337 /* A subtle point: the filesystem time is not necessarily equal to the
6338 * system clock time, since one can be using a monotonic clock, or coarse
6339 * monotonic clock, or whatever. So we might wind up with an mtime a few
6340 * microseconds ago. Let's just give it a lot of wiggle room. */
6341 tt_i64_op(st
.st_mtime
, OP_GE
, now
- 1);
6343 const time_t five_sec_ago
= now
- 5;
6344 set_file_mtime(fname
, five_sec_ago
);
6346 /* Finally we can touch the file */
6347 tt_int_op(0, OP_EQ
, touch_file(fname
));
6348 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
6349 tt_i64_op(st
.st_mtime
, OP_GE
, now
-1);
6355 #ifndef DISABLE_PWDB_TESTS
6357 test_util_pwdb(void *arg
)
6360 const struct passwd
*me
= NULL
, *me2
, *me3
;
6364 /* Uncached case. */
6365 /* Let's assume that we exist. */
6366 me
= tor_getpwuid(getuid());
6367 tt_ptr_op(me
, OP_NE
, NULL
);
6368 name
= tor_strdup(me
->pw_name
);
6371 me2
= tor_getpwnam(name
);
6372 tt_ptr_op(me2
, OP_NE
, NULL
);
6373 tt_int_op(me2
->pw_uid
, OP_EQ
, getuid());
6376 me3
= tor_getpwuid(getuid());
6377 tt_ptr_op(me3
, OP_NE
, NULL
);
6378 tt_str_op(me3
->pw_name
, OP_EQ
, name
);
6380 me3
= tor_getpwnam(name
);
6381 tt_ptr_op(me3
, OP_NE
, NULL
);
6382 tt_int_op(me3
->pw_uid
, OP_EQ
, getuid());
6384 dir
= get_user_homedir(name
);
6385 tt_ptr_op(dir
, OP_NE
, NULL
);
6387 /* Try failing cases. First find a user that doesn't exist by name */
6391 for (i
= 0; i
< 100; ++i
) {
6392 crypto_rand(randbytes
, sizeof(randbytes
));
6393 base16_encode(badname
, sizeof(badname
), randbytes
, sizeof(randbytes
));
6394 if (tor_getpwnam(badname
) == NULL
) {
6402 /* We should do a LOG_ERR */
6403 setup_full_capture_of_logs(LOG_ERR
);
6404 dir
= get_user_homedir(badname
);
6405 tt_ptr_op(dir
, OP_EQ
, NULL
);
6406 expect_log_msg_containing("not found");
6407 tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ
, 1);
6408 teardown_capture_of_logs();
6410 /* Now try to find a user that doesn't exist by ID. */
6412 for (i
= 0; i
< 1000; ++i
) {
6414 crypto_rand((char*)&u
, sizeof(u
));
6415 if (tor_getpwuid(u
) == NULL
) {
6425 teardown_capture_of_logs();
6427 #endif /* !defined(DISABLE_PWDB_TESTS) */
6430 test_util_calloc_check(void *arg
)
6433 /* Easy cases that are good. */
6434 tt_assert(size_mul_check(0,0));
6435 tt_assert(size_mul_check(0,100));
6436 tt_assert(size_mul_check(100,0));
6437 tt_assert(size_mul_check(100,100));
6439 /* Harder cases that are still good. */
6440 tt_assert(size_mul_check(SIZE_MAX
, 1));
6441 tt_assert(size_mul_check(1, SIZE_MAX
));
6442 tt_assert(size_mul_check(SIZE_MAX
/ 10, 9));
6443 tt_assert(size_mul_check(11, SIZE_MAX
/ 12));
6444 const size_t sqrt_size_max_p1
= ((size_t)1) << (sizeof(size_t) * 4);
6445 tt_assert(size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
- 1));
6447 /* Cases that overflow */
6448 tt_assert(! size_mul_check(SIZE_MAX
, 2));
6449 tt_assert(! size_mul_check(2, SIZE_MAX
));
6450 tt_assert(! size_mul_check(SIZE_MAX
/ 10, 11));
6451 tt_assert(! size_mul_check(11, SIZE_MAX
/ 10));
6452 tt_assert(! size_mul_check(SIZE_MAX
/ 8, 9));
6453 tt_assert(! size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
));
6460 test_util_monotonic_time(void *arg
)
6464 monotime_t mt1
, mt2
;
6465 monotime_coarse_t mtc1
, mtc2
;
6466 uint64_t nsec1
, nsec2
, usec1
, msec1
;
6467 uint64_t nsecc1
, nsecc2
, usecc1
, msecc1
;
6468 uint32_t stamp1
, stamp2
;
6473 monotime_coarse_get(&mtc1
);
6474 nsec1
= monotime_absolute_nsec();
6475 usec1
= monotime_absolute_usec();
6476 msec1
= monotime_absolute_msec();
6477 nsecc1
= monotime_coarse_absolute_nsec();
6478 usecc1
= monotime_coarse_absolute_usec();
6479 msecc1
= monotime_coarse_absolute_msec();
6480 stamp1
= monotime_coarse_to_stamp(&mtc1
);
6482 tor_sleep_msec(200);
6485 monotime_coarse_get(&mtc2
);
6486 nsec2
= monotime_absolute_nsec();
6487 nsecc2
= monotime_coarse_absolute_nsec();
6488 stamp2
= monotime_coarse_to_stamp(&mtc2
);
6490 /* We need to be a little careful here since we don't know the system load.
6492 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_GE
, 175);
6493 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_LT
, 1000);
6494 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_GE
, 125);
6495 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_LT
, 1000);
6496 tt_u64_op(nsec2
-nsec1
, OP_GE
, 175000000);
6497 tt_u64_op(nsec2
-nsec1
, OP_LT
, 1000000000);
6498 tt_u64_op(nsecc2
-nsecc1
, OP_GE
, 125000000);
6499 tt_u64_op(nsecc2
-nsecc1
, OP_LT
, 1000000000);
6501 tt_u64_op(msec1
, OP_GE
, nsec1
/ 1000000);
6502 tt_u64_op(usec1
, OP_GE
, nsec1
/ 1000);
6503 tt_u64_op(msecc1
, OP_GE
, nsecc1
/ 1000000);
6504 tt_u64_op(usecc1
, OP_GE
, nsecc1
/ 1000);
6505 tt_u64_op(msec1
, OP_LE
, nsec1
/ 1000000 + 10);
6506 tt_u64_op(usec1
, OP_LE
, nsec1
/ 1000 + 10000);
6507 tt_u64_op(msecc1
, OP_LE
, nsecc1
/ 1000000 + 10);
6508 tt_u64_op(usecc1
, OP_LE
, nsecc1
/ 1000 + 10000);
6510 uint64_t coarse_stamp_diff
=
6511 monotime_coarse_stamp_units_to_approx_msec(stamp2
-stamp1
);
6512 tt_u64_op(coarse_stamp_diff
, OP_GE
, 120);
6513 tt_u64_op(coarse_stamp_diff
, OP_LE
, 1200);
6516 uint64_t units
= monotime_msec_to_approx_coarse_stamp_units(5000);
6517 uint64_t ms
= monotime_coarse_stamp_units_to_approx_msec(units
);
6518 tt_u64_op(ms
, OP_GE
, 4950);
6519 tt_u64_op(ms
, OP_LT
, 5050);
6527 test_util_monotonic_time_ratchet(void *arg
)
6531 monotime_reset_ratchets_for_testing();
6533 /* win32, performance counter ratchet. */
6534 tt_i64_op(100, OP_EQ
, ratchet_performance_counter(100));
6535 tt_i64_op(101, OP_EQ
, ratchet_performance_counter(101));
6536 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(2000));
6537 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(100));
6538 tt_i64_op(2005, OP_EQ
, ratchet_performance_counter(105));
6539 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1105));
6540 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1000));
6541 tt_i64_op(3010, OP_EQ
, ratchet_performance_counter(1005));
6543 /* win32, GetTickCounts32 ratchet-and-rollover-detector. */
6544 const int64_t R
= ((int64_t)1) << 32;
6545 tt_i64_op(5, OP_EQ
, ratchet_coarse_performance_counter(5));
6546 tt_i64_op(1000, OP_EQ
, ratchet_coarse_performance_counter(1000));
6547 tt_i64_op(5+R
, OP_EQ
, ratchet_coarse_performance_counter(5));
6548 tt_i64_op(10+R
, OP_EQ
, ratchet_coarse_performance_counter(10));
6549 tt_i64_op(4+R
*2, OP_EQ
, ratchet_coarse_performance_counter(4));
6551 /* gettimeofday regular ratchet. */
6552 struct timeval tv_in
= {0,0}, tv_out
;
6553 tv_in
.tv_usec
= 9000;
6555 ratchet_timeval(&tv_in
, &tv_out
);
6556 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 9000);
6557 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 0);
6559 tv_in
.tv_sec
= 1337;
6561 ratchet_timeval(&tv_in
, &tv_out
);
6562 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
6563 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6565 tv_in
.tv_sec
= 1336;
6566 tv_in
.tv_usec
= 500000;
6567 ratchet_timeval(&tv_in
, &tv_out
);
6568 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
6569 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6571 tv_in
.tv_sec
= 1337;
6573 ratchet_timeval(&tv_in
, &tv_out
);
6574 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 500000);
6575 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6577 tv_in
.tv_sec
= 1337;
6578 tv_in
.tv_usec
= 600000;
6579 ratchet_timeval(&tv_in
, &tv_out
);
6580 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
6581 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
6583 tv_in
.tv_sec
= 1000;
6584 tv_in
.tv_usec
= 1000;
6585 ratchet_timeval(&tv_in
, &tv_out
);
6586 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
6587 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
6589 tv_in
.tv_sec
= 2000;
6590 tv_in
.tv_usec
= 2000;
6591 ratchet_timeval(&tv_in
, &tv_out
);
6592 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 101000);
6593 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 2338);
6600 test_util_monotonic_time_zero(void *arg
)
6604 monotime_coarse_t ct1
;
6606 /* Check 1: The current time is not zero. */
6608 monotime_coarse_get(&ct1
);
6609 tt_assert(!monotime_is_zero(&t1
));
6610 tt_assert(!monotime_coarse_is_zero(&ct1
));
6612 /* Check 2: The _zero() makes the time zero. */
6614 monotime_coarse_zero(&ct1
);
6615 tt_assert(monotime_is_zero(&t1
));
6616 tt_assert(monotime_coarse_is_zero(&ct1
));
6622 test_util_monotonic_time_add_msec(void *arg
)
6626 monotime_coarse_t ct1
, ct2
;
6630 monotime_coarse_get(&ct1
);
6632 /* adding zero does nothing */
6633 monotime_add_msec(&t2
, &t1
, 0);
6634 monotime_coarse_add_msec(&ct2
, &ct1
, 0);
6635 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 0);
6636 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 0);
6638 /* Add 1337 msec; see if the diff function agree */
6639 monotime_add_msec(&t2
, &t1
, 1337);
6640 monotime_coarse_add_msec(&ct2
, &ct1
, 1337);
6641 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337);
6642 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337);
6643 // The 32-bit variant must be within 1% of the regular one.
6644 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 1323);
6645 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 1350);
6647 /* Add 1337 msec twice more; make sure that any second rollover issues
6649 monotime_add_msec(&t2
, &t2
, 1337);
6650 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
6651 monotime_add_msec(&t2
, &t2
, 1337);
6652 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
6653 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337*3);
6654 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337*3);
6655 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 3970);
6656 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 4051);
6663 test_util_nowrap_math(void *arg
)
6667 tt_u64_op(0, OP_EQ
, tor_add_u32_nowrap(0, 0));
6668 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(0, 1));
6669 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(1, 0));
6670 tt_u64_op(4, OP_EQ
, tor_add_u32_nowrap(2, 2));
6671 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
-1, 2));
6672 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(2, UINT32_MAX
-1));
6673 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
, UINT32_MAX
));
6675 tt_u64_op(0, OP_EQ
, tor_mul_u64_nowrap(0, 0));
6676 tt_u64_op(1, OP_EQ
, tor_mul_u64_nowrap(1, 1));
6677 tt_u64_op(2, OP_EQ
, tor_mul_u64_nowrap(2, 1));
6678 tt_u64_op(4, OP_EQ
, tor_mul_u64_nowrap(2, 2));
6679 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_mul_u64_nowrap(UINT64_MAX
, 1));
6680 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_mul_u64_nowrap(2, UINT64_MAX
));
6681 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_mul_u64_nowrap(UINT64_MAX
, UINT64_MAX
));
6688 test_util_htonll(void *arg
)
6691 #ifdef WORDS_BIGENDIAN
6692 const uint64_t res_be
= 0x8877665544332211;
6694 const uint64_t res_le
= 0x1122334455667788;
6697 tt_u64_op(0, OP_EQ
, tor_htonll(0));
6698 tt_u64_op(0, OP_EQ
, tor_ntohll(0));
6699 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_htonll(UINT64_MAX
));
6700 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_ntohll(UINT64_MAX
));
6702 #ifdef WORDS_BIGENDIAN
6703 tt_u64_op(res_be
, OP_EQ
, tor_htonll(0x8877665544332211));
6704 tt_u64_op(res_be
, OP_EQ
, tor_ntohll(0x8877665544332211));
6706 tt_u64_op(res_le
, OP_EQ
, tor_htonll(0x8877665544332211));
6707 tt_u64_op(res_le
, OP_EQ
, tor_ntohll(0x8877665544332211));
6708 #endif /* defined(WORDS_BIGENDIAN) */
6715 test_util_get_unquoted_path(void *arg
)
6721 r
= get_unquoted_path("\""); // "
6722 tt_ptr_op(r
, OP_EQ
, NULL
);
6725 r
= get_unquoted_path("\"\"\""); // """
6726 tt_ptr_op(r
, OP_EQ
, NULL
);
6729 r
= get_unquoted_path("\\\""); // \"
6730 tt_ptr_op(r
, OP_EQ
, NULL
);
6733 r
= get_unquoted_path("\\\"\\\""); // \"\"
6734 tt_ptr_op(r
, OP_EQ
, NULL
);
6737 r
= get_unquoted_path("A\\B\\C\""); // A\B\C"
6738 tt_ptr_op(r
, OP_EQ
, NULL
);
6741 r
= get_unquoted_path("\"A\\B\\C"); // "A\B\C
6742 tt_ptr_op(r
, OP_EQ
, NULL
);
6745 r
= get_unquoted_path("\"A\\B\"C\""); // "A\B"C"
6746 tt_ptr_op(r
, OP_EQ
, NULL
);
6749 r
= get_unquoted_path("A\\B\"C"); // A\B"C
6750 tt_ptr_op(r
, OP_EQ
, NULL
);
6753 r
= get_unquoted_path("");
6754 tt_str_op(r
, OP_EQ
, "");
6757 r
= get_unquoted_path("\"\""); // ""
6758 tt_str_op(r
, OP_EQ
, "");
6761 r
= get_unquoted_path("A\\B\\C"); // A\B\C
6762 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6765 r
= get_unquoted_path("\"A\\B\\C\""); // "A\B\C"
6766 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6769 r
= get_unquoted_path("\"\\\""); // "\"
6770 tt_str_op(r
, OP_EQ
, "\\"); // \ /* comment to prevent line continuation */
6773 r
= get_unquoted_path("\"\\\"\""); // "\""
6774 tt_str_op(r
, OP_EQ
, "\""); // "
6777 r
= get_unquoted_path("\"A\\B\\C\\\"\""); // "A\B\C\""
6778 tt_str_op(r
, OP_EQ
, "A\\B\\C\""); // A\B\C"
6781 r
= get_unquoted_path("A\\B\\\"C"); // A\B\"C
6782 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6785 r
= get_unquoted_path("\"A\\B\\\"C\""); // "A\B\"C"
6786 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6793 test_util_map_anon(void *arg
)
6801 ptr
= tor_mmap_anonymous(sz
, 0, &inherit
);
6802 tt_ptr_op(ptr
, OP_NE
, 0);
6803 tt_int_op(inherit
, OP_EQ
, INHERIT_RES_KEEP
);
6805 tt_int_op(ptr
[0], OP_EQ
, 0);
6806 tt_int_op(ptr
[sz
-2], OP_EQ
, 0);
6807 tt_int_op(ptr
[sz
-1], OP_EQ
, 3);
6809 /* Try again, with a private (non-swappable) mapping. */
6810 tor_munmap_anonymous(ptr
, sz
);
6811 ptr
= tor_mmap_anonymous(sz
, ANONMAP_PRIVATE
, &inherit
);
6812 tt_ptr_op(ptr
, OP_NE
, 0);
6813 tt_int_op(inherit
, OP_EQ
, INHERIT_RES_KEEP
);
6815 tt_int_op(ptr
[0], OP_EQ
, 0);
6816 tt_int_op(ptr
[sz
/2], OP_EQ
, 0);
6817 tt_int_op(ptr
[sz
-1], OP_EQ
, 10);
6819 /* Now let's test a drop-on-fork mapping. */
6820 tor_munmap_anonymous(ptr
, sz
);
6821 ptr
= tor_mmap_anonymous(sz
, ANONMAP_NOINHERIT
, &inherit
);
6822 tt_ptr_op(ptr
, OP_NE
, 0);
6824 tt_int_op(ptr
[0], OP_EQ
, 0);
6825 tt_int_op(ptr
[sz
/2], OP_EQ
, 0);
6826 tt_int_op(ptr
[sz
-1], OP_EQ
, 10);
6829 tor_munmap_anonymous(ptr
, sz
);
6833 test_util_map_anon_nofork(void *arg
)
6837 /* The operating system doesn't support forking. */
6841 #else /* !defined(_WIN32) */
6842 /* We have the right OS support. We're going to try marking the buffer as
6843 * either zero-on-fork or as drop-on-fork, whichever is supported. Then we
6844 * will fork and send a byte back to the parent process. This will either
6845 * crash, or send zero. */
6848 const char TEST_VALUE
= 0xd0;
6850 int pipefd
[2] = {-1, -1};
6853 tor_munmap_anonymous(ptr
, sz
);
6854 ptr
= tor_mmap_anonymous(sz
, ANONMAP_NOINHERIT
, &inherit
);
6855 tt_ptr_op(ptr
, OP_NE
, 0);
6856 memset(ptr
, (uint8_t)TEST_VALUE
, sz
);
6858 tt_int_op(0, OP_EQ
, pipe(pipefd
));
6859 pid_t child
= fork();
6861 /* We're in the child. */
6863 ssize_t r
= write(pipefd
[1], &ptr
[sz
-1], 1); /* This may crash. */
6869 tt_int_op(child
, OP_GT
, 0);
6870 /* In the parent. */
6874 ssize_t r
= read(pipefd
[0], buf
, 1);
6876 if (inherit
== INHERIT_RES_ZERO
) {
6877 // We should be seeing clear-on-fork behavior.
6878 tt_int_op((int)r
, OP_EQ
, 1); // child should send us a byte.
6879 tt_int_op(buf
[0], OP_EQ
, 0); // that byte should be zero.
6880 } else if (inherit
== INHERIT_RES_DROP
) {
6881 // We should be seeing noinherit behavior.
6882 tt_int_op(r
, OP_LE
, 0); // child said nothing; it should have crashed.
6884 // noinherit isn't implemented.
6885 tt_int_op(inherit
, OP_EQ
, INHERIT_RES_KEEP
);
6886 tt_int_op((int)r
, OP_EQ
, 1); // child should send us a byte.
6887 tt_int_op(buf
[0], OP_EQ
, TEST_VALUE
); // that byte should be TEST_VALUE.
6891 waitpid(child
, &ws
, 0);
6893 #ifndef NOINHERIT_CAN_FAIL
6894 /* Only if NOINHERIT_CAN_FAIL should it be possible for us to get
6895 * INHERIT_KEEP behavior in this case. */
6896 tt_int_op(inherit
, OP_NE
, INHERIT_RES_KEEP
);
6898 if (inherit
== INHERIT_RES_KEEP
) {
6899 /* Call this test "skipped", not "passed", since noinherit wasn't
6903 #endif /* !defined(NOINHERIT_CAN_FAIL) */
6906 tor_munmap_anonymous(ptr
, sz
);
6907 if (pipefd
[0] >= 0) {
6910 if (pipefd
[1] >= 0) {
6913 #endif /* defined(_WIN32) */
6917 #define UTIL_LEGACY(name) \
6918 { (#name), test_util_ ## name , 0, NULL, NULL }
6920 #define UTIL_TEST(name, flags) \
6921 { (#name), test_util_ ## name, flags, NULL, NULL }
6923 #define COMPRESS(name, identifier) \
6924 { ("compress/" #name), test_util_compress, 0, &compress_setup, \
6925 (char*)(identifier) }
6927 #define COMPRESS_CONCAT(name, identifier) \
6928 { ("compress_concat/" #name), test_util_decompress_concatenated, 0, \
6930 (char*)(identifier) }
6932 #define COMPRESS_JUNK(name, identifier) \
6933 { ("compress_junk/" #name), test_util_decompress_junk, 0, \
6935 (char*)(identifier) }
6937 #define COMPRESS_DOS(name, identifier) \
6938 { ("compress_dos/" #name), test_util_decompress_dos, 0, \
6940 (char*)(identifier) }
6943 #define UTIL_TEST_WIN_ONLY(n, f) UTIL_TEST(n, (f))
6945 #define UTIL_TEST_WIN_ONLY(n, f) { (#n), NULL, TT_SKIP, NULL, NULL }
6948 #ifdef DISABLE_PWDB_TESTS
6949 #define UTIL_TEST_PWDB(n, f) { (#n), NULL, TT_SKIP, NULL, NULL }
6951 #define UTIL_TEST_PWDB(n, f) UTIL_TEST(n, (f))
6953 #endif /* !defined(COCCI) */
6955 struct testcase_t util_tests
[] = {
6957 UTIL_TEST(parse_http_time
, 0),
6958 UTIL_LEGACY(config_line
),
6959 UTIL_LEGACY(config_line_quotes
),
6960 UTIL_LEGACY(config_line_comment_character
),
6961 UTIL_LEGACY(config_line_escaped_content
),
6962 UTIL_LEGACY(config_line_crlf
),
6963 UTIL_TEST(config_line_partition
, 0),
6964 UTIL_TEST_PWDB(expand_filename
, 0),
6965 UTIL_LEGACY(escape_string_socks
),
6966 UTIL_LEGACY(string_is_key_value
),
6967 UTIL_LEGACY(strmisc
),
6968 UTIL_TEST(parse_integer
, 0),
6970 COMPRESS(zlib
, "deflate"),
6971 COMPRESS(gzip
, "gzip"),
6972 COMPRESS(lzma
, "x-tor-lzma"),
6973 COMPRESS(zstd
, "x-zstd"),
6974 COMPRESS(zstd_nostatic
, "x-zstd:nostatic"),
6975 COMPRESS(none
, "identity"),
6976 COMPRESS_CONCAT(zlib
, "deflate"),
6977 COMPRESS_CONCAT(gzip
, "gzip"),
6978 COMPRESS_CONCAT(lzma
, "x-tor-lzma"),
6979 COMPRESS_CONCAT(zstd
, "x-zstd"),
6980 COMPRESS_CONCAT(zstd_nostatic
, "x-zstd:nostatic"),
6981 COMPRESS_CONCAT(none
, "identity"),
6982 COMPRESS_JUNK(zlib
, "deflate"),
6983 COMPRESS_JUNK(gzip
, "gzip"),
6984 COMPRESS_JUNK(lzma
, "x-tor-lzma"),
6985 COMPRESS_DOS(zlib
, "deflate"),
6986 COMPRESS_DOS(gzip
, "gzip"),
6987 COMPRESS_DOS(lzma
, "x-tor-lzma"),
6988 COMPRESS_DOS(zstd
, "x-zstd"),
6989 COMPRESS_DOS(zstd_nostatic
, "x-zstd:nostatic"),
6990 UTIL_TEST(gzip_compression_bomb
, TT_FORK
),
6991 UTIL_LEGACY(datadir
),
6992 UTIL_LEGACY(memarea
),
6993 UTIL_LEGACY(control_formats
),
6995 UTIL_TEST(sscanf
, TT_FORK
),
6996 UTIL_LEGACY(format_time_interval
),
6997 UTIL_LEGACY(path_is_relative
),
6998 UTIL_LEGACY(strtok
),
6999 UTIL_LEGACY(di_ops
),
7000 UTIL_TEST(memcpy_iftrue_timei
, 0),
7001 UTIL_TEST(di_map
, 0),
7002 UTIL_TEST(round_to_next_multiple_of
, 0),
7003 UTIL_TEST(laplace
, 0),
7004 UTIL_TEST(clamp_double_to_int64
, 0),
7005 UTIL_TEST(find_str_at_start_of_line
, 0),
7006 UTIL_TEST(tor_strreplacechar
, 0),
7007 UTIL_TEST(string_is_C_identifier
, 0),
7008 UTIL_TEST(string_is_utf8
, 0),
7009 UTIL_TEST(asprintf
, 0),
7010 UTIL_TEST(listdir
, 0),
7012 UTIL_TEST(get_glob_opened_files
, 0),
7013 UTIL_TEST(parent_dir
, 0),
7014 UTIL_TEST(ftruncate
, 0),
7015 UTIL_TEST(nowrap_math
, 0),
7016 UTIL_TEST(num_cpus
, 0),
7017 UTIL_TEST_WIN_ONLY(load_win_lib
, 0),
7018 UTIL_TEST(format_hex_number
, 0),
7019 UTIL_TEST(format_dec_number
, 0),
7020 UTIL_TEST(n_bits_set
, 0),
7021 UTIL_TEST(eat_whitespace
, 0),
7022 UTIL_TEST(sl_new_from_text_lines
, 0),
7023 UTIL_TEST(envnames
, 0),
7024 UTIL_TEST(make_environment
, 0),
7025 UTIL_TEST(set_env_var_in_sl
, 0),
7026 UTIL_TEST(read_file_eof_tiny_limit
, 0),
7027 UTIL_TEST(read_file_eof_one_loop_a
, 0),
7028 UTIL_TEST(read_file_eof_one_loop_b
, 0),
7029 UTIL_TEST(read_file_eof_two_loops
, 0),
7030 UTIL_TEST(read_file_eof_two_loops_b
, 0),
7031 UTIL_TEST(read_file_eof_zero_bytes
, 0),
7032 UTIL_TEST(read_file_endlines
, 0),
7033 UTIL_TEST(write_chunks_to_file
, 0),
7034 UTIL_TEST(write_str_if_changed
, 0),
7035 UTIL_TEST(mathlog
, 0),
7036 UTIL_TEST(fraction
, 0),
7037 UTIL_TEST(weak_random
, 0),
7038 { "tor_isinf", test_tor_isinf
, TT_FORK
, NULL
, NULL
},
7039 { "socket_ipv4", test_util_socket
, TT_FORK
, &passthrough_setup
,
7041 { "socket_ipv6", test_util_socket
, TT_FORK
,
7042 &passthrough_setup
, (void*)"6" },
7043 { "socketpair", test_util_socketpair
, TT_FORK
, &passthrough_setup
,
7045 { "socketpair_ersatz", test_util_socketpair
, TT_FORK
,
7046 &passthrough_setup
, (void*)"1" },
7047 UTIL_TEST(max_mem
, 0),
7048 UTIL_TEST(hostname_validation
, 0),
7049 UTIL_TEST(dest_validation_edgecase
, 0),
7050 UTIL_TEST(ipv4_validation
, 0),
7051 UTIL_TEST(ipv6_validation
, 0),
7052 UTIL_TEST(writepid
, 0),
7053 UTIL_TEST(get_avail_disk_space
, 0),
7054 UTIL_TEST(touch_file
, 0),
7055 UTIL_TEST_PWDB(pwdb
, TT_FORK
),
7056 UTIL_TEST(calloc_check
, 0),
7057 UTIL_TEST(monotonic_time
, 0),
7058 UTIL_TEST(monotonic_time_ratchet
, TT_FORK
),
7059 UTIL_TEST(monotonic_time_zero
, 0),
7060 UTIL_TEST(monotonic_time_add_msec
, 0),
7061 UTIL_TEST(timegm_real
, 0),
7062 UTIL_TEST(htonll
, 0),
7063 UTIL_TEST(get_unquoted_path
, 0),
7064 UTIL_TEST(map_anon
, 0),
7065 UTIL_TEST(map_anon_nofork
, 0),