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 setup_full_capture_of_logs(LOG_WARN); \
824 #define CHECK_TIMEGM_WARNING(msg) do { \
825 expect_single_log_msg_containing(msg); \
826 teardown_capture_of_logs(); \
828 #define CHECK_POSSIBLE_EINVAL() do { \
829 if (mock_saved_log_n_entries()) { \
830 expect_single_log_msg_containing("Invalid argument"); \
832 teardown_capture_of_logs(); \
835 #define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
836 CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
840 /* Wrong year < 1970 */
841 a_time
.tm_year
= 1969-1900;
843 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
844 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
846 a_time
.tm_year
= -1-1900;
848 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
849 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
851 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
852 a_time
.tm_year
= -1*(1 << 16);
854 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
855 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
857 /* one of the smallest tm_year values my 64 bit system supports:
858 * t_res = -9223372036854775LL without clamping */
859 a_time
.tm_year
= -292275055-1900;
861 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
862 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
864 a_time
.tm_year
= INT32_MIN
;
866 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
867 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
868 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
871 a_time
.tm_year
= -1*(1 << 48);
873 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
874 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
876 /* while unlikely, the system's gmtime(_r) could return
877 * a "correct" retrospective gregorian negative year value,
878 * which I'm pretty sure is:
879 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
880 * 730485 is the number of days in two millennia, including leap days */
881 a_time
.tm_year
= -292277022657-1900;
883 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
884 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
886 a_time
.tm_year
= INT64_MIN
;
888 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
889 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
890 #endif /* SIZEOF_INT == 8 */
892 /* Wrong year >= INT32_MAX - 1900 */
893 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
894 a_time
.tm_year
= INT32_MAX
-1900;
896 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
897 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
899 a_time
.tm_year
= INT32_MAX
;
901 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
902 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
903 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
906 /* one of the largest tm_year values my 64 bit system supports */
907 a_time
.tm_year
= 292278994-1900;
909 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
910 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
912 /* while unlikely, the system's gmtime(_r) could return
913 * a "correct" proleptic gregorian year value,
914 * which I'm pretty sure is:
915 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
916 * 730485 is the number of days in two millennia, including leap days */
917 a_time
.tm_year
= 292277026596-1900;
919 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
920 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
922 a_time
.tm_year
= INT64_MAX
-1900;
924 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
925 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
927 a_time
.tm_year
= INT64_MAX
;
929 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
930 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
931 #endif /* SIZEOF_INT == 8 */
934 a_time
.tm_year
= 2007-1900; /* restore valid year */
936 a_time
.tm_mon
= 12; /* Wrong month, it's 0-based */
938 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
939 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
941 a_time
.tm_mon
= -1; /* Wrong month */
943 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
944 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
947 a_time
.tm_mon
= 6; /* Try July */
948 a_time
.tm_mday
= 32; /* Wrong day */
950 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
951 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
953 a_time
.tm_mon
= 5; /* Try June */
954 a_time
.tm_mday
= 31; /* Wrong day */
956 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
957 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
959 a_time
.tm_year
= 2008-1900; /* Try a leap year */
960 a_time
.tm_mon
= 1; /* in feb. */
961 a_time
.tm_mday
= 30; /* Wrong day */
963 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
964 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
966 a_time
.tm_year
= 2011-1900; /* Try a non-leap year */
967 a_time
.tm_mon
= 1; /* in feb. */
968 a_time
.tm_mday
= 29; /* Wrong day */
970 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
971 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
973 a_time
.tm_mday
= 0; /* Wrong day, it's 1-based (to be different) */
975 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
976 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
979 a_time
.tm_mday
= 3; /* restore valid month day */
981 a_time
.tm_hour
= 24; /* Wrong hour, it's 0-based */
983 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
984 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
986 a_time
.tm_hour
= -1; /* Wrong hour */
988 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
989 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
992 a_time
.tm_hour
= 22; /* restore valid hour */
994 a_time
.tm_min
= 60; /* Wrong minute, it's 0-based */
996 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
997 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
999 a_time
.tm_min
= -1; /* Wrong minute */
1001 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
1002 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1005 a_time
.tm_min
= 37; /* restore valid minute */
1007 a_time
.tm_sec
= 61; /* Wrong second: 0-based with leap seconds */
1009 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
1010 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1012 a_time
.tm_sec
= -1; /* Wrong second */
1014 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
1015 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
1017 /* Test tor_gmtime_r out of range */
1019 /* time_t < 0 yields a year clamped to 1 or 1970,
1020 * depending on whether the implementation of the system gmtime(_r)
1021 * sets struct tm (1) or not (1970) */
1024 tor_gmtime_r(&t_res
, &b_time
);
1025 CHECK_POSSIBLE_EINVAL();
1026 tt_assert(b_time
.tm_year
== (1970-1900) ||
1027 b_time
.tm_year
== (1969-1900));
1029 if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
1030 t_res
= -1*(1 << 30);
1032 tor_gmtime_r(&t_res
, &b_time
);
1033 CHECK_POSSIBLE_EINVAL();
1034 tt_assert(b_time
.tm_year
== (1970-1900) ||
1035 b_time
.tm_year
== (1935-1900));
1039 tor_gmtime_r(&t_res
, &b_time
);
1040 CHECK_POSSIBLE_EINVAL();
1041 tt_assert(b_time
.tm_year
== (1970-1900) ||
1042 b_time
.tm_year
== (1901-1900));
1045 #if SIZEOF_TIME_T == 8
1047 /* one of the smallest tm_year values my 64 bit system supports:
1048 * b_time.tm_year == (-292275055LL-1900LL) without clamping */
1049 t_res
= -9223372036854775LL;
1051 tor_gmtime_r(&t_res
, &b_time
);
1052 CHECK_POSSIBLE_EINVAL();
1053 tt_assert(b_time
.tm_year
== (1970-1900) ||
1054 b_time
.tm_year
== (1-1900));
1056 /* while unlikely, the system's gmtime(_r) could return
1057 * a "correct" retrospective gregorian negative year value,
1058 * which I'm pretty sure is:
1059 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
1060 * 730485 is the number of days in two millennia, including leap days
1061 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
1064 tor_gmtime_r(&t_res
, &b_time
);
1065 if (! (b_time
.tm_year
== (1970-1900) ||
1066 b_time
.tm_year
== (1-1900))) {
1067 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
1069 if (b_time
.tm_year
!= 1970-1900) {
1070 CHECK_TIMEGM_WARNING("Rounding up to ");
1072 teardown_capture_of_logs();
1076 /* As above, but with localtime. */
1077 t_res
= -9223372036854775LL;
1079 tor_localtime_r(&t_res
, &b_time
);
1080 CHECK_POSSIBLE_EINVAL();
1081 tt_assert(b_time
.tm_year
== (1970-1900) ||
1082 b_time
.tm_year
== (1-1900));
1084 /* while unlikely, the system's gmtime(_r) could return
1085 * a "correct" retrospective gregorian negative year value,
1086 * which I'm pretty sure is:
1087 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
1088 * 730485 is the number of days in two millennia, including leap days
1089 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
1092 tor_localtime_r(&t_res
, &b_time
);
1093 if (! (b_time
.tm_year
== (1970-1900) ||
1094 b_time
.tm_year
== (1-1900))) {
1095 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
1097 if (b_time
.tm_year
!= 1970-1900) {
1098 CHECK_TIMEGM_WARNING("Rounding up to ");
1100 teardown_capture_of_logs();
1103 #endif /* SIZEOF_TIME_T == 8 */
1105 /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
1106 * depending on whether the implementation of the system gmtime(_r)
1107 * sets struct tm (9999) or not (2037) */
1108 #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
1110 t_res
= 3*(1 << 29);
1111 tor_gmtime_r(&t_res
, &b_time
);
1112 tt_assert(b_time
.tm_year
== (2021-1900));
1115 tor_gmtime_r(&t_res
, &b_time
);
1116 tt_assert(b_time
.tm_year
== (2037-1900) ||
1117 b_time
.tm_year
== (2038-1900));
1120 /* as above but with localtime. */
1121 t_res
= 3*(1 << 29);
1122 tor_localtime_r(&t_res
, &b_time
);
1123 tt_assert(b_time
.tm_year
== (2021-1900));
1126 tor_localtime_r(&t_res
, &b_time
);
1127 tt_assert(b_time
.tm_year
== (2037-1900) ||
1128 b_time
.tm_year
== (2038-1900));
1130 #endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
1132 #if SIZEOF_TIME_T == 8
1134 /* one of the largest tm_year values my 64 bit system supports:
1135 * b_time.tm_year == (292278994L-1900L) without clamping */
1136 t_res
= 9223372036854775LL;
1138 tor_gmtime_r(&t_res
, &b_time
);
1139 CHECK_POSSIBLE_EINVAL();
1140 tt_assert(b_time
.tm_year
== (2037-1900) ||
1141 b_time
.tm_year
== (9999-1900));
1143 /* while unlikely, the system's gmtime(_r) could return
1144 * a "correct" proleptic gregorian year value,
1145 * which I'm pretty sure is:
1146 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1147 * 730485 is the number of days in two millennia, including leap days
1148 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1151 tor_gmtime_r(&t_res
, &b_time
);
1152 CHECK_TIMEGM_WARNING("Rounding down to ");
1154 tt_assert(b_time
.tm_year
== (2037-1900) ||
1155 b_time
.tm_year
== (9999-1900));
1158 /* As above but with localtime. */
1159 t_res
= 9223372036854775LL;
1161 tor_localtime_r(&t_res
, &b_time
);
1162 CHECK_POSSIBLE_EINVAL();
1163 tt_assert(b_time
.tm_year
== (2037-1900) ||
1164 b_time
.tm_year
== (9999-1900));
1166 /* while unlikely, the system's gmtime(_r) could return
1167 * a "correct" proleptic gregorian year value,
1168 * which I'm pretty sure is:
1169 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
1170 * 730485 is the number of days in two millennia, including leap days
1171 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
1174 tor_localtime_r(&t_res
, &b_time
);
1175 CHECK_TIMEGM_WARNING("Rounding down to ");
1177 tt_assert(b_time
.tm_year
== (2037-1900) ||
1178 b_time
.tm_year
== (9999-1900));
1180 #endif /* SIZEOF_TIME_T == 8 */
1182 /* Test {format,parse}_rfc1123_time */
1184 format_rfc1123_time(timestr
, 0);
1185 tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ
, timestr
);
1186 format_rfc1123_time(timestr
, (time_t)1091580502UL);
1187 tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ
, timestr
);
1190 i
= parse_rfc1123_time(timestr
, &t_res
);
1191 tt_int_op(0,OP_EQ
, i
);
1192 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1194 /* This value is in range with 32 bit and 64 bit time_t */
1195 format_rfc1123_time(timestr
, (time_t)2080000000UL);
1196 tt_str_op("Fri, 30 Nov 2035 01:46:40 GMT",OP_EQ
, timestr
);
1199 i
= parse_rfc1123_time(timestr
, &t_res
);
1200 tt_int_op(0,OP_EQ
, i
);
1201 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1203 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1206 format_rfc1123_time(timestr
, (time_t)2150000000UL);
1207 CHECK_POSSIBLE_EINVAL();
1209 #if SIZEOF_TIME_T == 4
1211 /* Wrapping around will have made it this. */
1212 /* On windows, at least, this is clipped to 1 Jan 1970. ??? */
1213 tt_str_op("Sat, 11 Jan 1902 23:45:04 GMT",OP_EQ
, timestr
);
1215 /* Make sure that the right date doesn't parse. */
1216 strlcpy(timestr
, "Wed, 17 Feb 2038 06:13:20 GMT", sizeof(timestr
));
1220 i
= parse_rfc1123_time(timestr
, &t_res
);
1221 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1222 tt_int_op(-1,OP_EQ
, i
);
1223 #elif SIZEOF_TIME_T == 8
1224 tt_str_op("Wed, 17 Feb 2038 06:13:20 GMT",OP_EQ
, timestr
);
1227 i
= parse_rfc1123_time(timestr
, &t_res
);
1228 tt_int_op(0,OP_EQ
, i
);
1229 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1230 #endif /* SIZEOF_TIME_T == 4 || ... */
1232 /* The timezone doesn't matter */
1235 parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res
));
1236 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1238 parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
1240 parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res
));
1242 parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res
));
1244 parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res
));
1246 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res
));
1248 parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res
));
1250 parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res
));
1252 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res
));
1254 parse_rfc1123_time("Wed, 30 Mar 1900 23:59:59 GMT", &t_res
));
1258 parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res
));
1260 parse_rfc1123_time("Wed, 29 Feb 2012 16:00:00 GMT", &t_res
));
1262 /* Leap second plus one */
1264 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res
));
1266 /* Test parse_iso_time */
1269 i
= parse_iso_time("", &t_res
);
1270 tt_int_op(-1,OP_EQ
, i
);
1272 i
= parse_iso_time("2004-08-32 00:48:22", &t_res
);
1273 tt_int_op(-1,OP_EQ
, i
);
1275 i
= parse_iso_time("1969-08-03 00:48:22", &t_res
);
1276 tt_int_op(-1,OP_EQ
, i
);
1279 i
= parse_iso_time("2004-08-04 00:48:22", &t_res
);
1280 tt_int_op(0,OP_EQ
, i
);
1281 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1283 i
= parse_iso_time("2004-8-4 0:48:22", &t_res
);
1284 tt_int_op(0,OP_EQ
, i
);
1285 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1287 /* This value is in range with 32 bit and 64 bit time_t */
1289 i
= parse_iso_time("2035-11-30 01:46:40", &t_res
);
1290 tt_int_op(0,OP_EQ
, i
);
1291 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1293 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1296 #if SIZEOF_TIME_T == 4
1298 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1299 tt_int_op(-1,OP_EQ
, i
);
1300 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1301 #elif SIZEOF_TIME_T == 8
1302 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1303 tt_int_op(0,OP_EQ
, i
);
1304 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1305 #endif /* SIZEOF_TIME_T == 4 || ... */
1307 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-zz 99-99x99", &t_res
));
1308 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-32 00:00:00", &t_res
));
1309 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 24:00:00", &t_res
));
1310 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:60:00", &t_res
));
1311 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59:62", &t_res
));
1312 tt_int_op(-1,OP_EQ
, parse_iso_time("1969-03-30 23:59:59", &t_res
));
1313 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-00-30 23:59:59", &t_res
));
1314 tt_int_op(-1,OP_EQ
, parse_iso_time("2147483647-08-29 14:00:00", &t_res
));
1315 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59", &t_res
));
1316 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22.100", &t_res
));
1317 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res
));
1319 /* but... that _is_ acceptable if we aren't being strict. */
1321 i
= parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res
, 0, 0);
1322 tt_int_op(0,OP_EQ
, i
);
1323 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1325 /* try nospace variant. */
1327 i
= parse_iso_time_nospace("2004-08-04T00:48:22", &t_res
);
1328 tt_int_op(0,OP_EQ
, i
);
1329 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1331 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04T00:48:22", &t_res
));
1332 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res
));
1333 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04x00:48:22", &t_res
));
1334 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res
));
1336 /* Test tor_gettimeofday */
1339 end
.tv_usec
= 999990;
1341 start
.tv_usec
= 500;
1343 tor_gettimeofday(&start
);
1344 /* now make sure time works. */
1345 tor_gettimeofday(&end
);
1346 /* We might've timewarped a little. */
1347 tt_int_op(tv_udiff(&start
, &end
), OP_GE
, -5000);
1349 /* Test format_iso_time */
1351 tv
.tv_sec
= (time_t)1326296338UL;
1353 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1354 tt_str_op("2012-01-11 15:38:58",OP_EQ
, timestr
);
1355 /* The output of format_local_iso_time will vary by timezone, and setting
1356 our timezone for testing purposes would be a nontrivial flaky pain.
1357 Skip this test for now.
1358 format_local_iso_time(timestr, tv.tv_sec);
1359 test_streq("2012-01-11 10:38:58", timestr);
1361 format_iso_time_nospace(timestr
, (time_t)tv
.tv_sec
);
1362 tt_str_op("2012-01-11T15:38:58",OP_EQ
, timestr
);
1363 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_LEN
);
1364 format_iso_time_nospace_usec(timestr
, &tv
);
1365 tt_str_op("2012-01-11T15:38:58.003060",OP_EQ
, timestr
);
1366 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_USEC_LEN
);
1369 /* This value is in range with 32 bit and 64 bit time_t */
1370 tv
.tv_sec
= (time_t)2080000000UL;
1371 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1372 tt_str_op("2035-11-30 01:46:40",OP_EQ
, timestr
);
1374 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1376 tv
.tv_sec
= (time_t)2150000000UL;
1378 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1379 CHECK_POSSIBLE_EINVAL();
1380 #if SIZEOF_TIME_T == 4
1381 /* format_iso_time should indicate failure on overflow, but it doesn't yet.
1382 * Hopefully #18480 will improve the failure semantics in this case.
1383 tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
1385 #elif SIZEOF_TIME_T == 8
1387 /* This SHOULD work on windows too; see bug #18665 */
1388 tt_str_op("2038-02-17 06:13:20",OP_EQ
, timestr
);
1390 #endif /* SIZEOF_TIME_T == 4 || ... */
1393 #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
1394 #undef CHECK_POSSIBLE_EINVAL
1397 teardown_capture_of_logs();
1401 test_util_parse_http_time(void *arg
)
1404 char b
[ISO_TIME_LEN
+1];
1408 format_iso_time(b, tor_timegm(&a_time)); \
1409 tt_str_op(b, OP_EQ, (s)); \
1413 /* Test parse_http_time */
1416 parse_http_time("", &a_time
));
1418 parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time
));
1420 parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time
));
1422 parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time
));
1424 parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time
));
1426 parse_http_time("Sunday, August the third", &a_time
));
1428 parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time
));
1431 parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time
));
1432 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1433 T("1994-08-04 00:48:22");
1435 parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time
));
1436 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1437 T("1994-08-04 00:48:22");
1439 parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time
));
1440 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1441 T("1994-08-04 00:48:22");
1443 parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time
));
1444 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1445 T("1994-08-04 00:48:22");
1447 parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time
));
1448 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1449 T("1994-08-04 00:48:22");
1451 parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time
));
1452 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1453 T("1994-08-04 00:48:22");
1454 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time
));
1455 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1456 T("1994-08-04 00:48:22");
1457 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time
));
1458 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1459 T("1994-08-04 00:48:22");
1460 tt_int_op(0,OP_EQ
, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time
));
1461 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1462 T("1994-08-04 00:48:22");
1463 tt_int_op(0,OP_EQ
,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time
));
1464 tt_int_op((time_t)1325376000UL,OP_EQ
, tor_timegm(&a_time
));
1465 T("2012-01-01 00:00:00");
1466 tt_int_op(0,OP_EQ
,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time
));
1467 tt_int_op((time_t)1356912000UL,OP_EQ
, tor_timegm(&a_time
));
1468 T("2012-12-31 00:00:00");
1470 /* This value is in range with 32 bit and 64 bit time_t */
1471 tt_int_op(0,OP_EQ
,parse_http_time("Fri, 30 Nov 2035 01:46:40 GMT", &a_time
));
1472 tt_int_op((time_t)2080000000UL,OP_EQ
, tor_timegm(&a_time
));
1473 T("2035-11-30 01:46:40");
1475 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1477 #if SIZEOF_TIME_T == 4
1478 /* parse_http_time should indicate failure on overflow, but it doesn't yet.
1479 * Hopefully #18480 will improve the failure semantics in this case. */
1480 setup_full_capture_of_logs(LOG_WARN
);
1481 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1482 tt_int_op((time_t)-1,OP_EQ
, tor_timegm(&a_time
));
1483 expect_single_log_msg_containing("does not fit in tor_timegm");
1484 teardown_capture_of_logs();
1485 #elif SIZEOF_TIME_T == 8
1486 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1487 tt_int_op((time_t)2150000000UL,OP_EQ
, tor_timegm(&a_time
));
1488 T("2038-02-17 06:13:20");
1489 #endif /* SIZEOF_TIME_T == 4 || ... */
1491 tt_int_op(-1,OP_EQ
, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time
));
1492 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-32 00:00:00 GMT", &a_time
));
1493 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 24:00:00 GMT", &a_time
));
1494 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:60:00 GMT", &a_time
));
1495 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59:62 GMT", &a_time
));
1496 tt_int_op(-1,OP_EQ
, parse_http_time("1969-03-30 23:59:59 GMT", &a_time
));
1497 tt_int_op(-1,OP_EQ
, parse_http_time("2011-00-30 23:59:59 GMT", &a_time
));
1498 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59", &a_time
));
1502 teardown_capture_of_logs();
1506 test_util_timegm_real(void *arg
)
1509 /* Get the real timegm again! We're not testing our impl; we want the
1510 * one that will actually get called. */
1513 /* Now check: is timegm the real inverse of gmtime? */
1514 time_t now
= time(NULL
), time2
=0;
1516 p
= tor_gmtime_r(&now
, &tm
);
1517 tt_ptr_op(p
, OP_NE
, NULL
);
1519 int r
= tor_timegm(&tm
, &time2
);
1520 tt_int_op(r
, OP_EQ
, 0);
1521 tt_i64_op((int64_t) now
, OP_EQ
, (int64_t) time2
);
1528 test_util_config_line(void *arg
)
1531 char *k
=NULL
, *v
=NULL
;
1534 /* Test parse_config_line_from_str */
1536 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
1538 "k3 \n" "\n" " \n" "#comment\n"
1539 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
1540 "kseven \"a quoted 'string\"\n"
1541 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
1542 "k9 a line that\\\n spans two lines.\n\n"
1543 "k10 more than\\\n one contin\\\nuation\n"
1544 "k11 \\\ncontinuation at the start\n"
1545 "k12 line with a\\\n#comment\n embedded\n"
1546 "k13\\\ncontinuation at the very start\n"
1547 "k14 a line that has a comment and # ends with a slash \\\n"
1548 "k15 this should be the next new line\n"
1549 "k16 a line that has a comment and # ends without a slash \n"
1550 "k17 this should be the next new line\n"
1554 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1555 tt_str_op(k
,OP_EQ
, "k");
1556 tt_str_op(v
,OP_EQ
, "v");
1557 tor_free(k
); tor_free(v
);
1558 tt_assert(!strcmpstart(str
, "key value with"));
1560 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1561 tt_str_op(k
,OP_EQ
, "key");
1562 tt_str_op(v
,OP_EQ
, "value with spaces");
1563 tor_free(k
); tor_free(v
);
1564 tt_assert(!strcmpstart(str
, "keykey"));
1566 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1567 tt_str_op(k
,OP_EQ
, "keykey");
1568 tt_str_op(v
,OP_EQ
, "val");
1569 tor_free(k
); tor_free(v
);
1570 tt_assert(!strcmpstart(str
, "k2\n"));
1572 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1573 tt_str_op(k
,OP_EQ
, "k2");
1574 tt_str_op(v
,OP_EQ
, "");
1575 tor_free(k
); tor_free(v
);
1576 tt_assert(!strcmpstart(str
, "k3 \n"));
1578 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1579 tt_str_op(k
,OP_EQ
, "k3");
1580 tt_str_op(v
,OP_EQ
, "");
1581 tor_free(k
); tor_free(v
);
1582 tt_assert(!strcmpstart(str
, "#comment"));
1584 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1585 tt_str_op(k
,OP_EQ
, "k4");
1586 tt_str_op(v
,OP_EQ
, "");
1587 tor_free(k
); tor_free(v
);
1588 tt_assert(!strcmpstart(str
, "k5#abc"));
1590 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1591 tt_str_op(k
,OP_EQ
, "k5");
1592 tt_str_op(v
,OP_EQ
, "");
1593 tor_free(k
); tor_free(v
);
1594 tt_assert(!strcmpstart(str
, "k6"));
1596 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1597 tt_str_op(k
,OP_EQ
, "k6");
1598 tt_str_op(v
,OP_EQ
, "val");
1599 tor_free(k
); tor_free(v
);
1600 tt_assert(!strcmpstart(str
, "kseven"));
1602 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1603 tt_str_op(k
,OP_EQ
, "kseven");
1604 tt_str_op(v
,OP_EQ
, "a quoted \'string");
1605 tor_free(k
); tor_free(v
);
1606 tt_assert(!strcmpstart(str
, "k8 "));
1608 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1609 tt_str_op(k
,OP_EQ
, "k8");
1610 tt_str_op(v
,OP_EQ
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
1611 tor_free(k
); tor_free(v
);
1613 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1614 tt_str_op(k
,OP_EQ
, "k9");
1615 tt_str_op(v
,OP_EQ
, "a line that spans two lines.");
1616 tor_free(k
); tor_free(v
);
1618 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1619 tt_str_op(k
,OP_EQ
, "k10");
1620 tt_str_op(v
,OP_EQ
, "more than one continuation");
1621 tor_free(k
); tor_free(v
);
1623 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1624 tt_str_op(k
,OP_EQ
, "k11");
1625 tt_str_op(v
,OP_EQ
, "continuation at the start");
1626 tor_free(k
); tor_free(v
);
1628 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1629 tt_str_op(k
,OP_EQ
, "k12");
1630 tt_str_op(v
,OP_EQ
, "line with a embedded");
1631 tor_free(k
); tor_free(v
);
1633 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1634 tt_str_op(k
,OP_EQ
, "k13");
1635 tt_str_op(v
,OP_EQ
, "continuation at the very start");
1636 tor_free(k
); tor_free(v
);
1638 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1639 tt_str_op(k
,OP_EQ
, "k14");
1640 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1641 tor_free(k
); tor_free(v
);
1643 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1644 tt_str_op(k
,OP_EQ
, "k15");
1645 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1646 tor_free(k
); tor_free(v
);
1648 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1649 tt_str_op(k
,OP_EQ
, "k16");
1650 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1651 tor_free(k
); tor_free(v
);
1653 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1654 tt_str_op(k
,OP_EQ
, "k17");
1655 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1656 tor_free(k
); tor_free(v
);
1658 tt_str_op(str
,OP_EQ
, "");
1666 test_util_config_line_quotes(void *arg
)
1672 char *k
=NULL
, *v
=NULL
;
1675 /* Test parse_config_line_from_str */
1677 strlcpy(buf1
, "kTrailingSpace \"quoted value\" \n"
1678 "kTrailingGarbage \"quoted value\"trailing garbage\n"
1680 strlcpy(buf2
, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
1682 strlcpy(buf3
, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
1684 strlcpy(buf4
, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
1688 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1689 tt_str_op(k
,OP_EQ
, "kTrailingSpace");
1690 tt_str_op(v
,OP_EQ
, "quoted value");
1691 tor_free(k
); tor_free(v
);
1693 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1694 tt_ptr_op(str
,OP_EQ
, NULL
);
1695 tor_free(k
); tor_free(v
);
1699 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1700 tt_ptr_op(str
,OP_EQ
, NULL
);
1701 tor_free(k
); tor_free(v
);
1705 const char *err
= NULL
;
1706 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1707 tt_ptr_op(str
,OP_EQ
, NULL
);
1708 tor_free(k
); tor_free(v
);
1709 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1714 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1715 tt_ptr_op(str
,OP_EQ
, NULL
);
1716 tor_free(k
); tor_free(v
);
1717 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1725 test_util_config_line_comment_character(void *arg
)
1728 char *k
=NULL
, *v
=NULL
;
1731 /* Test parse_config_line_from_str */
1733 strlcpy(buf
, "k1 \"# in quotes\"\n"
1734 "k2 some value # some comment\n"
1735 "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
1739 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1740 tt_str_op(k
,OP_EQ
, "k1");
1741 tt_str_op(v
,OP_EQ
, "# in quotes");
1742 tor_free(k
); tor_free(v
);
1744 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1745 tt_str_op(k
,OP_EQ
, "k2");
1746 tt_str_op(v
,OP_EQ
, "some value");
1747 tor_free(k
); tor_free(v
);
1749 tt_str_op(str
,OP_EQ
, "k3 /home/user/myTorNetwork#2\n");
1752 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1753 test_streq(k
, "k3");
1754 test_streq(v
, "/home/user/myTorNetwork#2");
1755 tor_free(k
); tor_free(v
);
1757 test_streq(str
, "");
1766 test_util_config_line_escaped_content(void *arg
)
1774 char *k
=NULL
, *v
=NULL
;
1777 /* Test parse_config_line_from_str */
1779 strlcpy(buf1
, "HexadecimalLower \"\\x2a\"\n"
1780 "HexadecimalUpper \"\\x2A\"\n"
1781 "HexadecimalUpperX \"\\X2A\"\n"
1785 "CarriageReturn \"\\r\"\n"
1786 "DoubleQuote \"\\\"\"\n"
1787 "SimpleQuote \"\\'\"\n"
1788 "Backslash \"\\\\\"\n"
1789 "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
1792 strlcpy(buf2
, "BrokenEscapedContent \"\\a\"\n"
1795 strlcpy(buf3
, "BrokenEscapedContent \"\\x\"\n"
1798 strlcpy(buf4
, "BrokenOctal \"\\8\"\n"
1801 strlcpy(buf5
, "BrokenHex \"\\xg4\"\n"
1804 strlcpy(buf6
, "BrokenEscape \"\\"
1809 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1810 tt_str_op(k
,OP_EQ
, "HexadecimalLower");
1811 tt_str_op(v
,OP_EQ
, "*");
1812 tor_free(k
); tor_free(v
);
1814 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1815 tt_str_op(k
,OP_EQ
, "HexadecimalUpper");
1816 tt_str_op(v
,OP_EQ
, "*");
1817 tor_free(k
); tor_free(v
);
1819 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1820 tt_str_op(k
,OP_EQ
, "HexadecimalUpperX");
1821 tt_str_op(v
,OP_EQ
, "*");
1822 tor_free(k
); tor_free(v
);
1824 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1825 tt_str_op(k
,OP_EQ
, "Octal");
1826 tt_str_op(v
,OP_EQ
, "*");
1827 tor_free(k
); tor_free(v
);
1829 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1830 tt_str_op(k
,OP_EQ
, "Newline");
1831 tt_str_op(v
,OP_EQ
, "\n");
1832 tor_free(k
); tor_free(v
);
1834 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1835 tt_str_op(k
,OP_EQ
, "Tab");
1836 tt_str_op(v
,OP_EQ
, "\t");
1837 tor_free(k
); tor_free(v
);
1839 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1840 tt_str_op(k
,OP_EQ
, "CarriageReturn");
1841 tt_str_op(v
,OP_EQ
, "\r");
1842 tor_free(k
); tor_free(v
);
1844 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1845 tt_str_op(k
,OP_EQ
, "DoubleQuote");
1846 tt_str_op(v
,OP_EQ
, "\"");
1847 tor_free(k
); tor_free(v
);
1849 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1850 tt_str_op(k
,OP_EQ
, "SimpleQuote");
1851 tt_str_op(v
,OP_EQ
, "'");
1852 tor_free(k
); tor_free(v
);
1854 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1855 tt_str_op(k
,OP_EQ
, "Backslash");
1856 tt_str_op(v
,OP_EQ
, "\\");
1857 tor_free(k
); tor_free(v
);
1859 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1860 tt_str_op(k
,OP_EQ
, "Mix");
1861 tt_str_op(v
,OP_EQ
, "This is a \"star\":\t'*'\nAnd second line");
1862 tor_free(k
); tor_free(v
);
1863 tt_str_op(str
,OP_EQ
, "");
1867 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1868 tt_ptr_op(str
,OP_EQ
, NULL
);
1869 tor_free(k
); tor_free(v
);
1873 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1874 tt_ptr_op(str
,OP_EQ
, NULL
);
1875 tor_free(k
); tor_free(v
);
1879 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1880 tt_ptr_op(str
,OP_EQ
, NULL
);
1881 tor_free(k
); tor_free(v
);
1886 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1887 tt_ptr_op(str
, OP_EQ
, NULL
);
1888 tor_free(k
); tor_free(v
);
1893 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1894 tt_ptr_op(str
,OP_EQ
, NULL
);
1895 tor_free(k
); tor_free(v
);
1897 /* more things to try. */
1899 strlcpy(buf1
, "Foo \"\\x9g\"\n", sizeof(buf1
));
1900 strlcpy(buf2
, "Foo \"\\xg0\"\n", sizeof(buf2
));
1901 strlcpy(buf3
, "Foo \"\\xf\"\n", sizeof(buf3
));
1903 strlcpy(buf4
, "Foo \"\\q\"\n", sizeof(buf4
));
1904 /* missing endquote */
1905 strlcpy(buf5
, "Foo \"hello\n", sizeof(buf5
));
1907 strlcpy(buf6
, "Foo \"hello\" world\n", sizeof(buf6
));
1910 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1911 tt_ptr_op(str
,OP_EQ
, NULL
);
1912 tor_free(k
); tor_free(v
);
1915 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1916 tt_ptr_op(str
,OP_EQ
, NULL
);
1917 tor_free(k
); tor_free(v
);
1920 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1921 tt_ptr_op(str
,OP_EQ
, NULL
);
1922 tor_free(k
); tor_free(v
);
1925 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1926 tt_ptr_op(str
,OP_EQ
, NULL
);
1927 tor_free(k
); tor_free(v
);
1931 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1932 tt_ptr_op(str
,OP_EQ
, NULL
);
1933 tor_free(k
); tor_free(v
);
1936 const char *err
= NULL
;
1937 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1938 tt_ptr_op(str
,OP_EQ
, NULL
);
1939 tor_free(k
); tor_free(v
);
1940 tt_str_op(err
,OP_EQ
, "Excess data after quoted string");
1948 test_util_config_line_crlf(void *arg
)
1950 char *k
=NULL
, *v
=NULL
;
1951 const char *err
= NULL
;
1955 "Hello \"nice big world\"\r\n";
1957 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1959 tt_str_op(k
,OP_EQ
,"Hello");
1960 tt_str_op(v
,OP_EQ
,"world");
1961 tt_ptr_op(err
, OP_EQ
, NULL
);
1962 tor_free(k
); tor_free(v
);
1964 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1966 tt_str_op(k
,OP_EQ
,"Hello");
1967 tt_str_op(v
,OP_EQ
,"nice big world");
1968 tt_ptr_op(err
, OP_EQ
, NULL
);
1969 tor_free(k
); tor_free(v
);
1970 tt_str_op(str
,OP_EQ
, "");
1973 tor_free(k
); tor_free(v
);
1977 test_util_config_line_partition(void *arg
)
1980 config_line_t
*lines
= NULL
, *orig
, *rest
= NULL
;
1982 config_line_append(&lines
, "Header", "X");
1983 config_line_append(&lines
, "Item", "Y");
1984 config_line_append(&lines
, "Thing", "Z");
1986 config_line_append(&lines
, "HEADER", "X2");
1988 config_line_append(&lines
, "header", "X3");
1989 config_line_append(&lines
, "Item3", "Foob");
1991 /* set up h2 and h3 to point to the places where we hope the headers will
1993 config_line_t
*h2
= lines
->next
->next
->next
;
1994 config_line_t
*h3
= h2
->next
;
1995 tt_str_op(h2
->key
, OP_EQ
, "HEADER");
1996 tt_str_op(h3
->key
, OP_EQ
, "header");
1999 rest
= config_lines_partition(lines
, "Header");
2000 tt_ptr_op(lines
, OP_EQ
, orig
);
2001 tt_ptr_op(rest
, OP_EQ
, h2
);
2002 tt_str_op(lines
->next
->key
, OP_EQ
, "Item");
2003 tt_str_op(lines
->next
->next
->key
, OP_EQ
, "Thing");
2004 tt_ptr_op(lines
->next
->next
->next
, OP_EQ
, NULL
);
2005 config_free_lines(lines
);
2007 orig
= lines
= rest
;
2008 rest
= config_lines_partition(lines
, "Header");
2009 tt_ptr_op(lines
, OP_EQ
, orig
);
2010 tt_ptr_op(rest
, OP_EQ
, h3
);
2011 tt_ptr_op(lines
->next
, OP_EQ
, NULL
);
2012 config_free_lines(lines
);
2014 orig
= lines
= rest
;
2015 rest
= config_lines_partition(lines
, "Header");
2016 tt_ptr_op(lines
, OP_EQ
, orig
);
2017 tt_ptr_op(rest
, OP_EQ
, NULL
);
2018 tt_str_op(lines
->next
->key
, OP_EQ
, "Item3");
2019 tt_ptr_op(lines
->next
->next
, OP_EQ
, NULL
);
2022 config_free_lines(lines
);
2023 config_free_lines(rest
);
2026 #ifndef DISABLE_PWDB_TESTS
2028 test_util_expand_filename(void *arg
)
2033 setenv("HOME", "/home/itv", 1); /* For "internal test value" */
2035 str
= expand_filename("");
2036 tt_str_op("",OP_EQ
, str
);
2039 str
= expand_filename("/normal/path");
2040 tt_str_op("/normal/path",OP_EQ
, str
);
2043 str
= expand_filename("/normal/trailing/path/");
2044 tt_str_op("/normal/trailing/path/",OP_EQ
, str
);
2047 str
= expand_filename("~");
2048 tt_str_op("/home/itv/",OP_EQ
, str
);
2051 str
= expand_filename("$HOME/nodice");
2052 tt_str_op("$HOME/nodice",OP_EQ
, str
);
2055 str
= expand_filename("~/");
2056 tt_str_op("/home/itv/",OP_EQ
, str
);
2059 str
= expand_filename("~/foobarqux");
2060 tt_str_op("/home/itv/foobarqux",OP_EQ
, str
);
2063 str
= expand_filename("~/../../etc/passwd");
2064 tt_str_op("/home/itv/../../etc/passwd",OP_EQ
, str
);
2067 str
= expand_filename("~/trailing/");
2068 tt_str_op("/home/itv/trailing/",OP_EQ
, str
);
2070 /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
2071 have to somehow inject/fake the get_user_homedir call) */
2073 /* $HOME ending in a trailing slash */
2074 setenv("HOME", "/home/itv/", 1);
2076 str
= expand_filename("~");
2077 tt_str_op("/home/itv/",OP_EQ
, str
);
2080 str
= expand_filename("~/");
2081 tt_str_op("/home/itv/",OP_EQ
, str
);
2084 str
= expand_filename("~/foo");
2085 tt_str_op("/home/itv/foo",OP_EQ
, str
);
2088 /* Try with empty $HOME */
2090 setenv("HOME", "", 1);
2092 str
= expand_filename("~");
2093 tt_str_op("/",OP_EQ
, str
);
2096 str
= expand_filename("~/");
2097 tt_str_op("/",OP_EQ
, str
);
2100 str
= expand_filename("~/foobar");
2101 tt_str_op("/foobar",OP_EQ
, str
);
2104 /* Try with $HOME unset */
2108 str
= expand_filename("~");
2109 tt_str_op("/",OP_EQ
, str
);
2112 str
= expand_filename("~/");
2113 tt_str_op("/",OP_EQ
, str
);
2116 str
= expand_filename("~/foobar");
2117 tt_str_op("/foobar",OP_EQ
, str
);
2123 #endif /* !defined(DISABLE_PWDB_TESTS) */
2125 /** Test tor_escape_str_for_pt_args(). */
2127 test_util_escape_string_socks(void *arg
)
2129 char *escaped_string
= NULL
;
2131 /** Simple backslash escape. */
2133 escaped_string
= tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
2134 tt_assert(escaped_string
);
2135 tt_str_op(escaped_string
,OP_EQ
, "This is a backslash: \\\\");
2136 tor_free(escaped_string
);
2138 /** Simple semicolon escape. */
2139 escaped_string
= tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
2140 tt_assert(escaped_string
);
2141 tt_str_op(escaped_string
,OP_EQ
, "First rule:Do not use \\;");
2142 tor_free(escaped_string
);
2144 /** Empty string. */
2145 escaped_string
= tor_escape_str_for_pt_args("", ";\\");
2146 tt_assert(escaped_string
);
2147 tt_str_op(escaped_string
,OP_EQ
, "");
2148 tor_free(escaped_string
);
2150 /** Escape all characters. */
2151 escaped_string
= tor_escape_str_for_pt_args(";\\;\\", ";\\");
2152 tt_assert(escaped_string
);
2153 tt_str_op(escaped_string
,OP_EQ
, "\\;\\\\\\;\\\\");
2154 tor_free(escaped_string
);
2156 escaped_string
= tor_escape_str_for_pt_args(";", ";\\");
2157 tt_assert(escaped_string
);
2158 tt_str_op(escaped_string
,OP_EQ
, "\\;");
2159 tor_free(escaped_string
);
2162 tor_free(escaped_string
);
2166 test_util_string_is_key_value(void *ptr
)
2169 tt_assert(string_is_key_value(LOG_WARN
, "key=value"));
2170 tt_assert(string_is_key_value(LOG_WARN
, "k=v"));
2171 tt_assert(string_is_key_value(LOG_WARN
, "key="));
2172 tt_assert(string_is_key_value(LOG_WARN
, "x="));
2173 tt_assert(string_is_key_value(LOG_WARN
, "xx="));
2174 tt_assert(!string_is_key_value(LOG_WARN
, "=value"));
2175 tt_assert(!string_is_key_value(LOG_WARN
, "=x"));
2176 tt_assert(!string_is_key_value(LOG_WARN
, "="));
2179 /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
2184 /** Test basic string functionality. */
2186 test_util_strmisc(void *arg
)
2189 char *cp_tmp
= NULL
;
2191 /* Test strl operations */
2193 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 0));
2194 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 10));
2195 tt_str_op(buf
,OP_EQ
, "Hello");
2196 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 6));
2197 tt_str_op(buf
,OP_EQ
, "Hello");
2198 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 5));
2199 tt_str_op(buf
,OP_EQ
, "Hell");
2200 strlcpy(buf
, "Hello", sizeof(buf
));
2201 tt_int_op(10,OP_EQ
, strlcat(buf
, "Hello", 5));
2203 /* Test strstrip() */
2204 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
2205 tor_strstrip(buf
, ",!");
2206 tt_str_op(buf
,OP_EQ
, "Testing 1 2 3");
2207 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
2208 tor_strstrip(buf
, "!? ");
2209 tt_str_op(buf
,OP_EQ
, "Testing123");
2210 strlcpy(buf
, "!!!Testing 1 2 3??", sizeof(buf
));
2211 tor_strstrip(buf
, "!? ");
2212 tt_str_op(buf
,OP_EQ
, "Testing123");
2215 /* Returning -1 when there's not enough room in the output buffer */
2216 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 0, "Foo"));
2217 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 2, "Foo"));
2218 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 3, "Foo"));
2219 tt_int_op(-1,OP_NE
, tor_snprintf(buf
, 4, "Foo"));
2220 /* Always NUL-terminate the output */
2221 tor_snprintf(buf
, 5, "abcdef");
2222 tt_int_op(0,OP_EQ
, buf
[4]);
2223 tor_snprintf(buf
, 10, "abcdef");
2224 tt_int_op(0,OP_EQ
, buf
[6]);
2226 tor_snprintf(buf
, sizeof(buf
), "x!%"PRIu64
"!x",
2227 (UINT64_C(12345678901)));
2228 tt_str_op("x!12345678901!x",OP_EQ
, buf
);
2230 /* Test str{,case}cmpstart */
2231 tt_assert(strcmpstart("abcdef", "abcdef")==0);
2232 tt_assert(strcmpstart("abcdef", "abc")==0);
2233 tt_assert(strcmpstart("abcdef", "abd")<0);
2234 tt_assert(strcmpstart("abcdef", "abb")>0);
2235 tt_assert(strcmpstart("ab", "abb")<0);
2236 tt_assert(strcmpstart("ab", "")==0);
2237 tt_assert(strcmpstart("ab", "ab ")<0);
2238 tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
2239 tt_assert(strcasecmpstart("abcDeF", "abc")==0);
2240 tt_assert(strcasecmpstart("abcdef", "Abd")<0);
2241 tt_assert(strcasecmpstart("Abcdef", "abb")>0);
2242 tt_assert(strcasecmpstart("ab", "Abb")<0);
2243 tt_assert(strcasecmpstart("ab", "")==0);
2244 tt_assert(strcasecmpstart("ab", "ab ")<0);
2246 /* Test str{,case}cmpend */
2247 tt_assert(strcmpend("abcdef", "abcdef")==0);
2248 tt_assert(strcmpend("abcdef", "def")==0);
2249 tt_assert(strcmpend("abcdef", "deg")<0);
2250 tt_assert(strcmpend("abcdef", "dee")>0);
2251 tt_assert(strcmpend("ab", "aab")>0);
2252 tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
2253 tt_assert(strcasecmpend("abcdef", "dEF")==0);
2254 tt_assert(strcasecmpend("abcdef", "Deg")<0);
2255 tt_assert(strcasecmpend("abcDef", "dee")>0);
2256 tt_assert(strcasecmpend("AB", "abb")<0);
2258 /* Test digest_is_zero */
2261 tt_assert(tor_digest_is_zero(buf
));
2263 tt_assert(!tor_digest_is_zero(buf
));
2265 /* Test mem_is_zero */
2268 tt_assert(fast_mem_is_zero(buf
, 10));
2269 tt_assert(fast_mem_is_zero(buf
, 20));
2270 tt_assert(fast_mem_is_zero(buf
, 128));
2271 tt_assert(!fast_mem_is_zero(buf
, 129));
2272 buf
[60] = (char)255;
2273 tt_assert(!fast_mem_is_zero(buf
, 128));
2275 tt_assert(!fast_mem_is_zero(buf
, 10));
2277 /* Test 'escaped' */
2278 tt_ptr_op(escaped(NULL
), OP_EQ
, NULL
);
2279 tt_str_op("\"\"",OP_EQ
, escaped(""));
2280 tt_str_op("\"abcd\"",OP_EQ
, escaped("abcd"));
2281 tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ
, escaped("\\ \n\r\t\"'"));
2282 tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ
,
2283 escaped("unnecessary \'backslashes\'"));
2284 /* Non-printable characters appear as octal */
2285 tt_str_op("\"z\\001abc\\277d\"",OP_EQ
, escaped("z\001abc\277d"));
2286 tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ
, escaped("z\xde\xad\x20;foo"));
2288 /* Other cases of esc_for_log{,_len} */
2289 cp_tmp
= esc_for_log(NULL
);
2290 tt_str_op(cp_tmp
, OP_EQ
, "(null)");
2292 cp_tmp
= esc_for_log_len("abcdefg", 3);
2293 tt_str_op(cp_tmp
, OP_EQ
, "\"abc\"");
2295 cp_tmp
= esc_for_log_len("abcdefg", 100);
2296 tt_str_op(cp_tmp
, OP_EQ
, "\"abcdefg\"");
2299 /* Test strndup and memdup */
2301 const char *s
= "abcdefghijklmnopqrstuvwxyz";
2302 cp_tmp
= tor_strndup(s
, 30);
2303 tt_str_op(cp_tmp
,OP_EQ
, s
); /* same string, */
2304 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2307 cp_tmp
= tor_strndup(s
, 5);
2308 tt_str_op(cp_tmp
,OP_EQ
, "abcde");
2311 s
= "a\0b\0c\0d\0e\0";
2312 cp_tmp
= tor_memdup(s
,10);
2313 tt_mem_op(cp_tmp
,OP_EQ
, s
, 10); /* same ram, */
2314 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
2318 /* Test str-foo functions */
2319 cp_tmp
= tor_strdup("abcdef");
2320 tt_assert(tor_strisnonupper(cp_tmp
));
2322 tt_assert(!tor_strisnonupper(cp_tmp
));
2323 tor_strupper(cp_tmp
);
2324 tt_str_op(cp_tmp
,OP_EQ
, "ABCDEF");
2325 tor_strlower(cp_tmp
);
2326 tt_str_op(cp_tmp
,OP_EQ
, "abcdef");
2327 tt_assert(tor_strisnonupper(cp_tmp
));
2328 tt_assert(tor_strisprint(cp_tmp
));
2330 tt_assert(!tor_strisprint(cp_tmp
));
2333 /* Test memmem and memstr */
2335 const char *haystack
= "abcde";
2336 tt_ptr_op(tor_memmem(haystack
, 5, "ef", 2), OP_EQ
, NULL
);
2337 tt_ptr_op(tor_memmem(haystack
, 5, "cd", 2),OP_EQ
, haystack
+ 2);
2338 tt_ptr_op(tor_memmem(haystack
, 5, "cde", 3),OP_EQ
, haystack
+ 2);
2339 tt_ptr_op(tor_memmem(haystack
, 4, "cde", 3), OP_EQ
, NULL
);
2340 haystack
= "ababcad";
2341 tt_ptr_op(tor_memmem(haystack
, 7, "abc", 3),OP_EQ
, haystack
+ 2);
2342 tt_ptr_op(tor_memmem(haystack
, 7, "ad", 2),OP_EQ
, haystack
+ 5);
2343 tt_ptr_op(tor_memmem(haystack
, 7, "cad", 3),OP_EQ
, haystack
+ 4);
2344 tt_ptr_op(tor_memmem(haystack
, 7, "dadad", 5), OP_EQ
, NULL
);
2345 tt_ptr_op(tor_memmem(haystack
, 7, "abcdefghij", 10), OP_EQ
, NULL
);
2347 tt_ptr_op(tor_memstr(haystack
, 7, "abc"),OP_EQ
, haystack
+ 2);
2348 tt_ptr_op(tor_memstr(haystack
, 7, "cad"),OP_EQ
, haystack
+ 4);
2349 tt_ptr_op(tor_memstr(haystack
, 6, "cad"), OP_EQ
, NULL
);
2350 tt_ptr_op(tor_memstr(haystack
, 7, "cadd"), OP_EQ
, NULL
);
2351 tt_ptr_op(tor_memstr(haystack
, 7, "fe"), OP_EQ
, NULL
);
2352 tt_ptr_op(tor_memstr(haystack
, 7, "ababcade"), OP_EQ
, NULL
);
2357 char binary_data
[68];
2359 for (idx
= 0; idx
< sizeof(binary_data
); ++idx
)
2360 binary_data
[idx
] = idx
;
2361 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2362 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2363 tt_str_op(hex_str(binary_data
, 17),OP_EQ
,
2364 "000102030405060708090A0B0C0D0E0F10");
2365 tt_str_op(hex_str(binary_data
, 32),OP_EQ
,
2366 "000102030405060708090A0B0C0D0E0F"
2367 "101112131415161718191A1B1C1D1E1F");
2368 tt_str_op(hex_str(binary_data
, 34),OP_EQ
,
2369 "000102030405060708090A0B0C0D0E0F"
2370 "101112131415161718191A1B1C1D1E1F");
2371 /* Repeat these tests for shorter strings after longer strings
2372 have been tried, to make sure we're correctly terminating strings */
2373 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2374 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2377 /* Test strcmp_opt */
2378 tt_int_op(strcmp_opt("", "foo"), OP_LT
, 0);
2379 tt_int_op(strcmp_opt("", ""), OP_EQ
, 0);
2380 tt_int_op(strcmp_opt("foo", ""), OP_GT
, 0);
2382 tt_int_op(strcmp_opt(NULL
, ""), OP_LT
, 0);
2383 tt_int_op(strcmp_opt(NULL
, NULL
), OP_EQ
, 0);
2384 tt_int_op(strcmp_opt("", NULL
), OP_GT
, 0);
2386 tt_int_op(strcmp_opt(NULL
, "foo"), OP_LT
, 0);
2387 tt_int_op(strcmp_opt("foo", NULL
), OP_GT
, 0);
2394 test_util_parse_integer(void *arg
)
2400 /* Test parse_long */
2401 /* Empty/zero input */
2402 tt_int_op(0L,OP_EQ
, tor_parse_long("",10,0,100,&i
,NULL
));
2403 tt_int_op(0,OP_EQ
, i
);
2404 tt_int_op(0L,OP_EQ
, tor_parse_long("0",10,0,100,&i
,NULL
));
2405 tt_int_op(1,OP_EQ
, i
);
2407 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,100,&i
,NULL
));
2408 tt_int_op(1,OP_EQ
, i
);
2409 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,10,&i
,NULL
));
2410 tt_int_op(1,OP_EQ
, i
);
2411 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,10,100,&i
,NULL
));
2412 tt_int_op(1,OP_EQ
, i
);
2413 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,100,&i
,NULL
));
2414 tt_int_op(1,OP_EQ
, i
);
2415 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,0,&i
,NULL
));
2416 tt_int_op(1,OP_EQ
, i
);
2417 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-50,0,&i
,NULL
));
2418 tt_int_op(1,OP_EQ
, i
);
2420 tt_int_op(0L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,NULL
));
2421 tt_int_op(0,OP_EQ
, i
);
2422 tt_int_op(0L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,NULL
));
2423 tt_int_op(0,OP_EQ
, i
);
2424 tt_int_op(10L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,&cp
));
2425 tt_int_op(1,OP_EQ
, i
);
2426 tt_str_op(cp
,OP_EQ
, "m");
2427 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,&cp
));
2428 tt_int_op(1,OP_EQ
, i
);
2429 tt_str_op(cp
,OP_EQ
, " plus garbage");
2430 /* Illogical min max */
2431 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,4,&i
,NULL
));
2432 tt_int_op(0,OP_EQ
, i
);
2433 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,100,-100,&i
,NULL
));
2434 tt_int_op(0,OP_EQ
, i
);
2436 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,100,&i
,NULL
));
2437 tt_int_op(0,OP_EQ
, i
);
2438 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,0,100,&i
,NULL
));
2439 tt_int_op(0,OP_EQ
, i
);
2440 /* Base different than 10 */
2441 tt_int_op(2L,OP_EQ
, tor_parse_long("10",2,0,100,NULL
,NULL
));
2442 tt_int_op(0L,OP_EQ
, tor_parse_long("2",2,0,100,NULL
,NULL
));
2443 tt_int_op(68284L,OP_EQ
, tor_parse_long("10abc",16,0,70000,NULL
,NULL
));
2444 tt_int_op(68284L,OP_EQ
, tor_parse_long("10ABC",16,0,70000,NULL
,NULL
));
2445 tt_int_op(0L,OP_EQ
, tor_parse_long("10",-2,0,100,NULL
,NULL
));
2446 tt_int_op(0,OP_EQ
, tor_parse_long("10ABC",-1,0,70000,&i
,NULL
));
2447 tt_int_op(i
,OP_EQ
, 0);
2449 /* Test parse_ulong */
2450 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("",10,0,100,NULL
,NULL
));
2451 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("0",10,0,100,NULL
,NULL
));
2452 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
2453 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
2454 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,10,NULL
,NULL
));
2455 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,10,100,NULL
,NULL
));
2456 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("8",8,0,100,NULL
,NULL
));
2457 tt_int_op(50UL,OP_EQ
, tor_parse_ulong("50",10,50,100,NULL
,NULL
));
2458 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,NULL
,NULL
));
2459 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("50",-1,50,100,&i
,NULL
));
2460 tt_int_op(0,OP_EQ
, i
);
2461 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,&i
,NULL
));
2462 tt_int_op(0,OP_EQ
, i
);
2464 /* Test parse_uint64 */
2465 tt_assert(UINT64_C(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
2466 tt_int_op(1,OP_EQ
, i
);
2467 tt_str_op(cp
,OP_EQ
, " x");
2468 tt_assert(UINT64_C(12345678901) ==
2469 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
2470 tt_int_op(1,OP_EQ
, i
);
2471 tt_str_op(cp
,OP_EQ
, "");
2472 tt_assert(UINT64_C(0) ==
2473 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
2474 tt_int_op(0,OP_EQ
, i
);
2475 tt_assert(UINT64_C(0) ==
2476 tor_parse_uint64("123",-1,0,INT32_MAX
, &i
, &cp
));
2477 tt_int_op(0,OP_EQ
, i
);
2480 /* Test parse_double */
2481 double d
= tor_parse_double("10", 0, (double)UINT64_MAX
,&i
,NULL
);
2482 tt_int_op(1,OP_EQ
, i
);
2483 tt_assert(((uint64_t)d
) == 10);
2484 d
= tor_parse_double("0", 0, (double)UINT64_MAX
,&i
,NULL
);
2485 tt_int_op(1,OP_EQ
, i
);
2486 tt_assert(((uint64_t)d
) == 0);
2487 d
= tor_parse_double(" ", 0, (double)UINT64_MAX
,&i
,NULL
);
2488 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2489 tt_int_op(0,OP_EQ
, i
);
2490 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,NULL
);
2491 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2492 tt_int_op(0,OP_EQ
, i
);
2493 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,&cp
);
2494 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2495 tt_int_op(1,OP_EQ
, i
);
2496 d
= tor_parse_double("-.0", 0, (double)UINT64_MAX
,&i
,NULL
);
2497 tt_int_op(1,OP_EQ
, i
);
2498 tt_assert(((uint64_t)d
) == 0);
2499 d
= tor_parse_double("-10", -100.0, 100.0,&i
,NULL
);
2500 tt_int_op(1,OP_EQ
, i
);
2501 tt_double_op(fabs(d
- -10.0),OP_LT
, 1E-12);
2505 /* Test tor_parse_* where we overflow/underflow the underlying type. */
2506 /* This string should overflow 64-bit ints. */
2507 #define TOOBIG "100000000000000000000000000"
2508 tt_int_op(0L, OP_EQ
,
2509 tor_parse_long(TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2510 tt_int_op(i
,OP_EQ
, 0);
2512 tor_parse_long("-"TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2513 tt_int_op(i
,OP_EQ
, 0);
2514 tt_int_op(0UL,OP_EQ
, tor_parse_ulong(TOOBIG
, 10, 0, ULONG_MAX
, &i
, NULL
));
2515 tt_int_op(i
,OP_EQ
, 0);
2516 tt_u64_op(UINT64_C(0), OP_EQ
, tor_parse_uint64(TOOBIG
, 10,
2517 0, UINT64_MAX
, &i
, NULL
));
2518 tt_int_op(i
,OP_EQ
, 0);
2525 test_util_pow2(void *arg
)
2527 /* Test tor_log2(). */
2529 tt_int_op(tor_log2(64),OP_EQ
, 6);
2530 tt_int_op(tor_log2(65),OP_EQ
, 6);
2531 tt_int_op(tor_log2(63),OP_EQ
, 5);
2532 /* incorrect mathematically, but as specified: */
2533 tt_int_op(tor_log2(0),OP_EQ
, 0);
2534 tt_int_op(tor_log2(1),OP_EQ
, 0);
2535 tt_int_op(tor_log2(2),OP_EQ
, 1);
2536 tt_int_op(tor_log2(3),OP_EQ
, 1);
2537 tt_int_op(tor_log2(4),OP_EQ
, 2);
2538 tt_int_op(tor_log2(5),OP_EQ
, 2);
2539 tt_int_op(tor_log2(UINT64_C(40000000000000000)),OP_EQ
, 55);
2540 tt_int_op(tor_log2(UINT64_MAX
),OP_EQ
, 63);
2542 /* Test round_to_power_of_2 */
2543 tt_u64_op(round_to_power_of_2(120), OP_EQ
, 128);
2544 tt_u64_op(round_to_power_of_2(128), OP_EQ
, 128);
2545 tt_u64_op(round_to_power_of_2(130), OP_EQ
, 128);
2546 tt_u64_op(round_to_power_of_2(UINT64_C(40000000000000000)), OP_EQ
,
2548 tt_u64_op(round_to_power_of_2(UINT64_C(0xffffffffffffffff)), OP_EQ
,
2550 tt_u64_op(round_to_power_of_2(0), OP_EQ
, 1);
2551 tt_u64_op(round_to_power_of_2(1), OP_EQ
, 1);
2552 tt_u64_op(round_to_power_of_2(2), OP_EQ
, 2);
2553 tt_u64_op(round_to_power_of_2(3), OP_EQ
, 2);
2554 tt_u64_op(round_to_power_of_2(4), OP_EQ
, 4);
2555 tt_u64_op(round_to_power_of_2(5), OP_EQ
, 4);
2556 tt_u64_op(round_to_power_of_2(6), OP_EQ
, 4);
2557 tt_u64_op(round_to_power_of_2(7), OP_EQ
, 8);
2564 test_util_compress_impl(compress_method_t method
)
2566 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
;
2569 tt_assert(tor_compress_supports_method(method
));
2571 if (method
!= NO_METHOD
) {
2572 tt_ptr_op(tor_compress_version_str(method
), OP_NE
, NULL
);
2573 tt_ptr_op(tor_compress_header_version_str(method
), OP_NE
, NULL
);
2576 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
2577 tt_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
2579 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1, method
));
2580 tt_ptr_op(buf2
, OP_NE
, NULL
);
2581 if (method
== NO_METHOD
) {
2582 // The identity transform doesn't actually compress, and it isn't
2583 // detectable as "the identity transform."
2584 tt_int_op(len1
, OP_EQ
, strlen(buf1
)+1);
2585 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, UNKNOWN_METHOD
);
2587 tt_int_op(len1
, OP_LT
, strlen(buf1
));
2588 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, method
);
2591 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
, method
, 1, LOG_INFO
));
2592 tt_ptr_op(buf3
, OP_NE
, NULL
);
2593 tt_int_op(strlen(buf1
) + 1, OP_EQ
, len2
);
2594 tt_str_op(buf1
, OP_EQ
, buf3
);
2595 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2597 /* Check whether we can uncompress concatenated, compressed strings. */
2599 buf2
= tor_reallocarray(buf2
, len1
, 2);
2600 memcpy(buf2
+len1
, buf2
, len1
);
2601 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
*2, method
, 1, LOG_INFO
));
2602 tt_int_op((strlen(buf1
)+1)*2, OP_EQ
, len2
);
2603 tt_mem_op(buf3
, OP_EQ
,
2604 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
2605 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
2606 (strlen(buf1
)+1)*2);
2607 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2609 /* Check whether we can uncompress partial strings */
2615 size_t b1len
= 1<<10;
2616 if (method
== ZSTD_METHOD
) {
2617 // zstd needs a big input before it starts generating output that it
2618 // can partially decompress.
2621 buf1
= tor_malloc(b1len
);
2622 crypto_rand(buf1
, b1len
);
2623 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, b1len
, method
));
2624 tt_int_op(len1
, OP_GT
, 16);
2625 /* when we allow an incomplete output we should succeed.*/
2626 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2627 method
, 0, LOG_INFO
));
2628 tt_int_op(len2
, OP_GT
, 5);
2629 tt_int_op(len2
, OP_LE
, len1
);
2630 tt_assert(fast_memeq(buf1
, buf3
, len2
));
2631 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2633 /* when we demand a complete output from a real compression method, this
2636 if (method
!= NO_METHOD
) {
2637 tt_assert(tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2638 method
, 1, LOG_INFO
));
2639 tt_ptr_op(buf3
, OP_EQ
, NULL
);
2649 test_util_compress_stream_impl(compress_method_t method
,
2650 compression_level_t level
)
2652 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
2656 tor_compress_state_t
*state
= NULL
;
2657 state
= tor_compress_new(1, method
, level
);
2659 cp1
= buf1
= tor_malloc(1024);
2661 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
2663 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0),
2664 OP_EQ
, TOR_COMPRESS_OK
);
2665 tt_int_op(0, OP_EQ
, len2
); /* Make sure we compressed it all. */
2666 tt_assert(cp1
> buf1
);
2670 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1),
2671 OP_EQ
, TOR_COMPRESS_DONE
);
2672 tt_int_op(0, OP_EQ
, len2
);
2673 if (method
== NO_METHOD
) {
2674 tt_ptr_op(cp1
, OP_EQ
, cp2
);
2676 tt_assert(cp1
> cp2
); /* Make sure we really added something. */
2679 tt_int_op(tor_compress_state_size(state
), OP_GT
, 0);
2681 tt_assert(!tor_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
2682 method
, 1, LOG_WARN
));
2683 /* Make sure it compressed right. */
2684 tt_str_op(buf3
, OP_EQ
, "ABCDEFGHIJABCDEFGHIJ");
2685 tt_int_op(21, OP_EQ
, len2
);
2689 tor_compress_free(state
);
2695 /** Setup function for compression tests: handles x-zstd:nostatic
2698 compression_test_setup(const struct testcase_t
*testcase
)
2700 tor_assert(testcase
->setup_data
);
2701 tor_assert(testcase
->setup_data
!= (void*)TT_SKIP
);
2702 const char *methodname
= testcase
->setup_data
;
2704 if (!strcmp(methodname
, "x-zstd:nostatic")) {
2705 methodname
= "x-zstd";
2706 tor_zstd_set_static_apis_disabled_for_testing(1);
2709 return (void *)methodname
;
2712 /** Cleanup for compression tests: disables nostatic */
2714 compression_test_cleanup(const struct testcase_t
*testcase
, void *ptr
)
2718 tor_zstd_set_static_apis_disabled_for_testing(0);
2722 static const struct testcase_setup_t compress_setup
= {
2723 compression_test_setup
, compression_test_cleanup
2726 /** Run unit tests for compression functions */
2728 test_util_compress(void *arg
)
2730 const char *methodname
= arg
;
2731 tt_assert(methodname
);
2733 compress_method_t method
= compression_method_get_by_name(methodname
);
2734 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2736 if (! tor_compress_supports_method(method
)) {
2740 compression_level_t levels
[] = {
2747 test_util_compress_impl(method
);
2749 for (unsigned l
= 0; l
< ARRAY_LENGTH(levels
); ++l
) {
2750 compression_level_t level
= levels
[l
];
2751 test_util_compress_stream_impl(method
, level
);
2758 test_util_decompress_concatenated_impl(compress_method_t method
)
2761 char *c1
= NULL
, *c2
= NULL
, *c3
= NULL
;
2762 char *result
= NULL
;
2763 size_t sz1
, sz2
, sz3
, szr
;
2766 crypto_rand(input
, sizeof(input
));
2768 /* Compress the input in two chunks. */
2769 r
= tor_compress(&c1
, &sz1
, input
, 2048, method
);
2770 tt_int_op(r
, OP_EQ
, 0);
2771 r
= tor_compress(&c2
, &sz2
, input
+2048, 2048, method
);
2772 tt_int_op(r
, OP_EQ
, 0);
2774 /* concatenate the chunks. */
2776 c3
= tor_malloc(sz3
);
2777 memcpy(c3
, c1
, sz1
);
2778 memcpy(c3
+sz1
, c2
, sz2
);
2780 /* decompress the concatenated result */
2781 r
= tor_uncompress(&result
, &szr
, c3
, sz3
, method
, 0, LOG_WARN
);
2782 tt_int_op(r
, OP_EQ
, 0);
2783 tt_int_op(szr
, OP_EQ
, sizeof(input
));
2784 tt_mem_op(result
, OP_EQ
, input
, sizeof(input
));
2794 test_util_decompress_concatenated(void *arg
)
2796 const char *methodname
= arg
;
2797 tt_assert(methodname
);
2799 compress_method_t method
= compression_method_get_by_name(methodname
);
2800 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2801 if (! tor_compress_supports_method(method
)) {
2805 test_util_decompress_concatenated_impl(method
);
2811 test_util_decompress_junk_impl(compress_method_t method
)
2814 char *result
= NULL
, *result2
= NULL
;
2815 size_t szr
, szr2
, sz
;
2818 /* This shouldn't be a compressed string according to any method. */
2819 strlcpy(input
, "This shouldn't be a compressed string by any means.",
2822 setup_capture_of_logs(LOG_WARN
);
2823 r
= tor_uncompress(&result
, &szr
, input
, sz
, method
, 0, LOG_WARN
);
2824 tt_int_op(r
, OP_EQ
, -1);
2825 tt_ptr_op(result
, OP_EQ
, NULL
);
2826 expect_log_msg_containing("Error while uncompressing data: bad input?");
2827 mock_clean_saved_logs();
2829 /* Now try again, with a compressed object that starts out good and turns to
2831 crypto_rand(input
, sizeof(input
));
2832 r
= tor_compress(&result
, &szr
, input
, sizeof(input
), method
);
2833 tt_int_op(r
, OP_EQ
, 0);
2834 crypto_rand(result
+szr
/2, szr
-(szr
/2)); // trash the 2nd half of the result
2835 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2836 tt_int_op(r
, OP_EQ
, -1);
2837 expect_log_msg_containing("Error while uncompressing data: bad input?");
2840 teardown_capture_of_logs();
2846 test_util_decompress_junk(void *arg
)
2848 const char *methodname
= arg
;
2849 tt_assert(methodname
);
2851 compress_method_t method
= compression_method_get_by_name(methodname
);
2852 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2853 if (! tor_compress_supports_method(method
)) {
2857 test_util_decompress_junk_impl(method
);
2862 /* mock replacement for tor_compress_is_compression_bomb that doesn't
2863 * believe in compression bombs. */
2865 mock_is_never_compression_bomb(size_t in
, size_t out
)
2873 test_util_decompress_dos_impl(compress_method_t method
)
2876 char *result
= NULL
, *result2
= NULL
;
2880 const size_t big
= 1024*1024;
2881 /* one megabyte of 0s. */
2882 input
= tor_malloc_zero(big
);
2884 /* Compress it into "result": it should fail. */
2885 setup_full_capture_of_logs(LOG_WARN
);
2886 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2887 tt_int_op(r
, OP_EQ
, -1);
2888 expect_log_msg_containing(
2889 "other Tors would think this was a compression bomb");
2890 teardown_capture_of_logs();
2892 /* Try again, but this time suppress compression-bomb detection */
2893 MOCK(tor_compress_is_compression_bomb
, mock_is_never_compression_bomb
);
2894 r
= tor_compress(&result
, &szr
, input
, big
, method
);
2895 UNMOCK(tor_compress_is_compression_bomb
);
2896 tt_int_op(r
, OP_EQ
, 0);
2897 tt_ptr_op(result
, OP_NE
, NULL
);
2899 /* We should refuse to uncomrpess it again, since it looks like a
2900 * compression bomb. */
2901 setup_capture_of_logs(LOG_WARN
);
2902 r
= tor_uncompress(&result2
, &szr2
, result
, szr
, method
, 0, LOG_WARN
);
2903 tt_int_op(r
, OP_EQ
, -1);
2904 expect_log_msg_containing("bomb; abandoning stream");
2907 teardown_capture_of_logs();
2914 test_util_decompress_dos(void *arg
)
2916 const char *methodname
= arg
;
2917 tt_assert(methodname
);
2919 compress_method_t method
= compression_method_get_by_name(methodname
);
2920 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2921 if (! tor_compress_supports_method(method
)) {
2925 test_util_decompress_dos_impl(method
);
2931 test_util_gzip_compression_bomb(void *arg
)
2933 /* A 'compression bomb' is a very small object that uncompresses to a huge
2934 * one. Most compression formats support them, but they can be a DOS vector.
2935 * In Tor we try not to generate them, and we don't accept them.
2938 size_t one_million
= 1<<20;
2939 char *one_mb
= tor_malloc_zero(one_million
);
2940 char *result
= NULL
;
2941 size_t result_len
= 0;
2942 tor_compress_state_t
*state
= NULL
;
2944 /* Make sure we can't produce a compression bomb */
2945 setup_full_capture_of_logs(LOG_WARN
);
2946 tt_int_op(-1, OP_EQ
, tor_compress(&result
, &result_len
,
2947 one_mb
, one_million
,
2949 expect_single_log_msg_containing(
2950 "We compressed something and got an insanely high "
2951 "compression factor; other Tors would think this "
2952 "was a compression bomb.");
2953 teardown_capture_of_logs();
2955 /* Here's a compression bomb that we made manually. */
2956 const char compression_bomb
[1039] =
2957 { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2,
2958 0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ };
2959 tt_int_op(-1, OP_EQ
, tor_uncompress(&result
, &result_len
,
2960 compression_bomb
, 1039,
2961 ZLIB_METHOD
, 0, LOG_WARN
));
2963 /* Now try streaming that. */
2964 state
= tor_compress_new(0, ZLIB_METHOD
, HIGH_COMPRESSION
);
2965 tor_compress_output_t r
;
2966 const char *inp
= compression_bomb
;
2967 size_t inlen
= 1039;
2969 char *outp
= one_mb
;
2970 size_t outleft
= 4096; /* small on purpose */
2971 r
= tor_compress_process(state
, &outp
, &outleft
, &inp
, &inlen
, 0);
2972 tt_int_op(inlen
, OP_NE
, 0);
2973 } while (r
== TOR_COMPRESS_BUFFER_FULL
);
2975 tt_int_op(r
, OP_EQ
, TOR_COMPRESS_ERROR
);
2979 tor_compress_free(state
);
2982 /** Run unit tests for mmap() wrapper functionality. */
2984 test_util_mmap(void *arg
)
2986 char *fname1
= tor_strdup(get_fname("mapped_1"));
2987 char *fname2
= tor_strdup(get_fname("mapped_2"));
2988 char *fname3
= tor_strdup(get_fname("mapped_3"));
2989 const size_t buflen
= 17000;
2990 char *buf
= tor_malloc(17000);
2991 tor_mmap_t
*mapping
= NULL
;
2994 crypto_rand(buf
, buflen
);
2996 mapping
= tor_mmap_file(fname1
);
2997 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2999 write_str_to_file(fname1
, "Short file.", 1);
3001 mapping
= tor_mmap_file(fname1
);
3003 tt_int_op(mapping
->size
,OP_EQ
, strlen("Short file."));
3004 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
3006 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3008 tt_assert(unlink(fname1
) == 0);
3010 /* make sure we can unlink. */
3011 tt_assert(unlink(fname1
) == 0);
3012 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
3013 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3015 #endif /* defined(_WIN32) */
3017 /* Now a zero-length file. */
3018 write_str_to_file(fname1
, "", 1);
3019 mapping
= tor_mmap_file(fname1
);
3020 tt_ptr_op(mapping
,OP_EQ
, NULL
);
3021 tt_int_op(ERANGE
,OP_EQ
, errno
);
3024 /* Make sure that we fail to map a no-longer-existent file. */
3025 mapping
= tor_mmap_file(fname1
);
3026 tt_ptr_op(mapping
, OP_EQ
, NULL
);
3028 /* Now try a big file that stretches across a few pages and isn't aligned */
3029 write_bytes_to_file(fname2
, buf
, buflen
, 1);
3030 mapping
= tor_mmap_file(fname2
);
3032 tt_int_op(mapping
->size
,OP_EQ
, buflen
);
3033 tt_mem_op(mapping
->data
,OP_EQ
, buf
, buflen
);
3034 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3037 /* Now try a big aligned file. */
3038 write_bytes_to_file(fname3
, buf
, 16384, 1);
3039 mapping
= tor_mmap_file(fname3
);
3041 tt_int_op(mapping
->size
,OP_EQ
, 16384);
3042 tt_mem_op(mapping
->data
,OP_EQ
, buf
, 16384);
3043 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
3056 tor_munmap_file(mapping
);
3059 /** Run unit tests for escaping/unescaping data for use by controllers. */
3061 test_util_control_formats(void *arg
)
3065 "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
3069 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
3070 tt_str_op(out
,OP_EQ
,
3071 ".This is a test\nof the emergency \n.system.\n\rZ.\n");
3072 tt_int_op(sz
,OP_EQ
, strlen(out
));
3078 #define test_feq(value1,value2) do { \
3079 double v1 = (value1), v2=(value2); \
3080 double tf_diff = v1-v2; \
3081 double tf_tolerance = ((v1+v2)/2.0)/1e8; \
3082 if (tf_diff<0) tf_diff=-tf_diff; \
3083 if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
3084 if (tf_diff<tf_tolerance) { \
3085 TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
3087 TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
3092 test_util_sscanf(void *arg
)
3094 unsigned u1
, u2
, u3
;
3096 char s1
[20], s2
[10], s3
[10], ch
, *huge
= NULL
;
3102 /* Simple tests (malformed patterns, literal matching, ...) */
3104 tt_int_op(-1,OP_EQ
, tor_sscanf("123", "%i", &r
)); /* %i is not supported */
3106 tor_sscanf("wrong", "%5c", s1
)); /* %c cannot have a number. */
3107 tt_int_op(-1,OP_EQ
, tor_sscanf("hello", "%s", s1
)); /* %s needs a number. */
3108 /* this will fail because we don't allow widths longer than 9999 */
3110 huge
= tor_malloc(1000000);
3111 r
= tor_sscanf("prettylongstring", "%99999s", huge
);
3113 tt_int_op(-1,OP_EQ
, r
);
3116 /* GCC thinks these two are illegal. */
3117 test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1
));
3118 test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL
));
3120 /* No '%'-strings: always "success" */
3121 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "hello world"));
3122 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "good bye"));
3125 tor_sscanf("hello 3", "%u", &u1
)); /* have to match the start */
3126 tt_int_op(0,OP_EQ
, tor_sscanf(" 3 hello", "%u", &u1
));
3128 tor_sscanf(" 3 hello", "%2u", &u1
)); /* not even in this case */
3130 tor_sscanf("3 hello", "%u", &u1
)); /* but trailing is alright */
3132 /* Numbers (ie. %u) */
3134 tor_sscanf("hello world 3", "hello worlb %u", &u1
)); /* d vs b */
3135 tt_int_op(1,OP_EQ
, tor_sscanf("12345", "%u", &u1
));
3136 tt_int_op(12345u,OP_EQ
, u1
);
3137 tt_int_op(1,OP_EQ
, tor_sscanf("12346 ", "%u", &u1
));
3138 tt_int_op(12346u,OP_EQ
, u1
);
3139 tt_int_op(0,OP_EQ
, tor_sscanf(" 12347", "%u", &u1
));
3140 tt_int_op(1,OP_EQ
, tor_sscanf(" 12348", " %u", &u1
));
3141 tt_int_op(12348u,OP_EQ
, u1
);
3142 tt_int_op(1,OP_EQ
, tor_sscanf("0", "%u", &u1
));
3143 tt_int_op(0u,OP_EQ
, u1
);
3144 tt_int_op(1,OP_EQ
, tor_sscanf("0000", "%u", &u2
));
3145 tt_int_op(0u,OP_EQ
, u2
);
3146 tt_int_op(0,OP_EQ
, tor_sscanf("", "%u", &u1
)); /* absent number */
3147 tt_int_op(0,OP_EQ
, tor_sscanf("A", "%u", &u1
)); /* bogus number */
3148 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%u", &u1
)); /* negative number */
3150 /* Numbers with size (eg. %2u) */
3151 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%2u", &u1
));
3152 tt_int_op(2,OP_EQ
, tor_sscanf("123456", "%2u%u", &u1
, &u2
));
3153 tt_int_op(12u,OP_EQ
, u1
);
3154 tt_int_op(3456u,OP_EQ
, u2
);
3155 tt_int_op(1,OP_EQ
, tor_sscanf("123456", "%8u", &u1
));
3156 tt_int_op(123456u,OP_EQ
, u1
);
3157 tt_int_op(1,OP_EQ
, tor_sscanf("123457 ", "%8u", &u1
));
3158 tt_int_op(123457u,OP_EQ
, u1
);
3159 tt_int_op(0,OP_EQ
, tor_sscanf(" 123456", "%8u", &u1
));
3160 tt_int_op(3,OP_EQ
, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
));
3161 tt_int_op(12u,OP_EQ
, u1
);
3162 tt_int_op(3u,OP_EQ
, u2
);
3163 tt_int_op(456u,OP_EQ
, u3
);
3165 tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1
, &u2
, &u3
)); /* 0s */
3166 tt_int_op(67u,OP_EQ
, u1
);
3167 tt_int_op(8u,OP_EQ
, u2
);
3168 tt_int_op(99u,OP_EQ
, u3
);
3169 /* %u does not match space.*/
3170 tt_int_op(2,OP_EQ
, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
3171 tt_int_op(12u,OP_EQ
, u1
);
3172 tt_int_op(3u,OP_EQ
, u2
);
3173 /* %u does not match negative numbers. */
3174 tt_int_op(2,OP_EQ
, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
3175 tt_int_op(67u,OP_EQ
, u1
);
3176 tt_int_op(8u,OP_EQ
, u2
);
3177 /* Arbitrary amounts of 0-padding are okay */
3178 tt_int_op(3,OP_EQ
, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
3180 tt_int_op(12u,OP_EQ
, u1
);
3181 tt_int_op(3u,OP_EQ
, u2
);
3182 tt_int_op(99u,OP_EQ
, u3
);
3186 tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1
, &u2
, &u3
));
3187 tt_int_op(0x1234,OP_EQ
, u1
);
3188 tt_int_op(0x2ABCDEF,OP_EQ
, u2
);
3189 tt_int_op(0xFF,OP_EQ
, u3
);
3190 /* Width works on %x */
3191 tt_int_op(3,OP_EQ
, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1
, &u2
, &u3
));
3192 tt_int_op(0xf00d,OP_EQ
, u1
);
3193 tt_int_op(0xcafe,OP_EQ
, u2
);
3194 tt_int_op(444,OP_EQ
, u3
);
3196 /* Literal '%' (ie. '%%') */
3197 tt_int_op(1,OP_EQ
, tor_sscanf("99% fresh", "%3u%% fresh", &u1
));
3198 tt_int_op(99,OP_EQ
, u1
);
3199 tt_int_op(0,OP_EQ
, tor_sscanf("99 fresh", "%% %3u %s", &u1
, s1
));
3200 tt_int_op(1,OP_EQ
, tor_sscanf("99 fresh", "%3u%% %s", &u1
, s1
));
3201 tt_int_op(2,OP_EQ
, tor_sscanf("99 fresh", "%3u %5s %%", &u1
, s1
));
3202 tt_int_op(99,OP_EQ
, u1
);
3203 tt_str_op(s1
,OP_EQ
, "fresh");
3204 tt_int_op(1,OP_EQ
, tor_sscanf("% boo", "%% %3s", s1
));
3205 tt_str_op("boo",OP_EQ
, s1
);
3207 /* Strings (ie. %s) */
3208 tt_int_op(2,OP_EQ
, tor_sscanf("hello", "%3s%7s", s1
, s2
));
3209 tt_str_op(s1
,OP_EQ
, "hel");
3210 tt_str_op(s2
,OP_EQ
, "lo");
3211 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%2s%u", s3
, &u1
)); /* %s%u */
3212 tt_str_op(s3
,OP_EQ
, "WD");
3213 tt_int_op(40,OP_EQ
, u1
);
3214 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%3s%u", s3
, &u1
)); /* %s%u */
3215 tt_str_op(s3
,OP_EQ
, "WD4");
3216 tt_int_op(0,OP_EQ
, u1
);
3217 tt_int_op(2,OP_EQ
, tor_sscanf("76trombones", "%6u%9s", &u1
, s1
)); /* %u%s */
3218 tt_int_op(76,OP_EQ
, u1
);
3219 tt_str_op(s1
,OP_EQ
, "trombones");
3221 huge
= tor_malloc(1000);
3222 r
= tor_sscanf("prettylongstring", "%999s", huge
);
3223 tt_int_op(1,OP_EQ
, r
);
3224 tt_str_op(huge
,OP_EQ
, "prettylongstring");
3227 /* %s doesn't eat spaces */
3228 tt_int_op(2,OP_EQ
, tor_sscanf("hello world", "%9s %9s", s1
, s2
));
3229 tt_str_op(s1
,OP_EQ
, "hello");
3230 tt_str_op(s2
,OP_EQ
, "world");
3231 tt_int_op(2,OP_EQ
, tor_sscanf("bye world?", "%9s %9s", s1
, s2
));
3232 tt_str_op(s1
,OP_EQ
, "bye");
3233 tt_str_op(s2
,OP_EQ
, "");
3235 tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
)); /* %s can be empty. */
3236 tt_str_op(s1
,OP_EQ
, "hi");
3237 tt_str_op(s2
,OP_EQ
, "");
3238 tt_str_op(s3
,OP_EQ
, "");
3240 tt_int_op(3,OP_EQ
, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3242 tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
3243 tt_int_op(' ',OP_EQ
, ch
);
3245 r
= tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1
, &lng1
, &int2
);
3246 tt_int_op(r
,OP_EQ
, 3);
3247 tt_int_op(int1
,OP_EQ
, 12345);
3248 tt_int_op(lng1
,OP_EQ
, -67890);
3249 tt_int_op(int2
,OP_EQ
, -1);
3253 /* UINT32_MAX should work */
3254 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%u", &u1
));
3255 tt_int_op(4294967295U,OP_EQ
, u1
);
3257 /* But UINT32_MAX + 1 shouldn't work */
3258 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%u", &u1
));
3259 /* but parsing only 9... */
3260 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9u", &u1
));
3261 tt_int_op(429496729U,OP_EQ
, u1
);
3264 /* UINT32_MAX should work */
3265 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%x", &u1
));
3266 tt_int_op(0xFFFFFFFF,OP_EQ
, u1
);
3268 /* But UINT32_MAX + 1 shouldn't work */
3269 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%x", &u1
));
3272 /* INT32_MIN and INT32_MAX should work */
3273 r
= tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1
, &int2
);
3274 tt_int_op(r
,OP_EQ
, 2);
3275 tt_int_op(int1
,OP_EQ
, -2147483647 - 1);
3276 tt_int_op(int2
,OP_EQ
, 2147483647);
3278 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3279 r
= tor_sscanf("-2147483649.", "%d.", &int1
);
3280 tt_int_op(r
,OP_EQ
, 0);
3282 r
= tor_sscanf("2147483648.", "%d.", &int1
);
3283 tt_int_op(r
,OP_EQ
, 0);
3285 /* and the first failure stops further processing */
3286 r
= tor_sscanf("-2147483648. 2147483648.",
3287 "%d. %d.", &int1
, &int2
);
3288 tt_int_op(r
,OP_EQ
, 1);
3290 r
= tor_sscanf("-2147483649. 2147483647.",
3291 "%d. %d.", &int1
, &int2
);
3292 tt_int_op(r
,OP_EQ
, 0);
3294 r
= tor_sscanf("2147483648. -2147483649.",
3295 "%d. %d.", &int1
, &int2
);
3296 tt_int_op(r
,OP_EQ
, 0);
3297 #elif SIZEOF_INT == 8
3299 /* UINT64_MAX should work */
3300 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%u", &u1
));
3301 tt_int_op(18446744073709551615U,OP_EQ
, u1
);
3303 /* But UINT64_MAX + 1 shouldn't work */
3304 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%u", &u1
));
3305 /* but parsing only 19... */
3306 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19u", &u1
));
3307 tt_int_op(1844674407370955161U,OP_EQ
, u1
);
3310 /* UINT64_MAX should work */
3311 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1
));
3312 tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ
, u1
);
3314 /* But UINT64_MAX + 1 shouldn't work */
3315 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%x", &u1
));
3318 /* INT64_MIN and INT64_MAX should work */
3319 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3320 "%d. %d.", &int1
, &int2
);
3321 tt_int_op(r
,OP_EQ
, 2);
3322 tt_int_op(int1
,OP_EQ
, -9223372036854775807 - 1);
3323 tt_int_op(int2
,OP_EQ
, 9223372036854775807);
3325 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3326 r
= tor_sscanf("-9223372036854775809.", "%d.", &int1
);
3327 tt_int_op(r
,OP_EQ
, 0);
3329 r
= tor_sscanf("9223372036854775808.", "%d.", &int1
);
3330 tt_int_op(r
,OP_EQ
, 0);
3332 /* and the first failure stops further processing */
3333 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3334 "%d. %d.", &int1
, &int2
);
3335 tt_int_op(r
,OP_EQ
, 1);
3337 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3338 "%d. %d.", &int1
, &int2
);
3339 tt_int_op(r
,OP_EQ
, 0);
3341 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3342 "%d. %d.", &int1
, &int2
);
3343 tt_int_op(r
,OP_EQ
, 0);
3344 #endif /* SIZEOF_INT == 4 || ... */
3346 #if SIZEOF_LONG == 4
3348 /* UINT32_MAX should work */
3349 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%lu", &ulng
));
3350 tt_int_op(4294967295UL,OP_EQ
, ulng
);
3352 /* But UINT32_MAX + 1 shouldn't work */
3353 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%lu", &ulng
));
3354 /* but parsing only 9... */
3355 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9lu", &ulng
));
3356 tt_int_op(429496729UL,OP_EQ
, ulng
);
3359 /* UINT32_MAX should work */
3360 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%lx", &ulng
));
3361 tt_int_op(0xFFFFFFFFUL
,OP_EQ
, ulng
);
3363 /* But UINT32_MAX + 1 shouldn't work */
3364 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%lx", &ulng
));
3367 /* INT32_MIN and INT32_MAX should work */
3368 r
= tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1
, &lng2
);
3369 tt_int_op(r
,OP_EQ
, 2);
3370 tt_int_op(lng1
,OP_EQ
, -2147483647L - 1L);
3371 tt_int_op(lng2
,OP_EQ
, 2147483647L);
3373 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
3374 r
= tor_sscanf("-2147483649.", "%ld.", &lng1
);
3375 tt_int_op(r
,OP_EQ
, 0);
3377 r
= tor_sscanf("2147483648.", "%ld.", &lng1
);
3378 tt_int_op(r
,OP_EQ
, 0);
3380 /* and the first failure stops further processing */
3381 r
= tor_sscanf("-2147483648. 2147483648.",
3382 "%ld. %ld.", &lng1
, &lng2
);
3383 tt_int_op(r
,OP_EQ
, 1);
3385 r
= tor_sscanf("-2147483649. 2147483647.",
3386 "%ld. %ld.", &lng1
, &lng2
);
3387 tt_int_op(r
,OP_EQ
, 0);
3389 r
= tor_sscanf("2147483648. -2147483649.",
3390 "%ld. %ld.", &lng1
, &lng2
);
3391 tt_int_op(r
,OP_EQ
, 0);
3392 #elif SIZEOF_LONG == 8
3394 /* UINT64_MAX should work */
3395 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%lu", &ulng
));
3396 tt_int_op(18446744073709551615UL,OP_EQ
, ulng
);
3398 /* But UINT64_MAX + 1 shouldn't work */
3399 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%lu", &ulng
));
3400 /* but parsing only 19... */
3401 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19lu", &ulng
));
3402 tt_int_op(1844674407370955161UL,OP_EQ
, ulng
);
3405 /* UINT64_MAX should work */
3406 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng
));
3407 tt_int_op(0xFFFFFFFFFFFFFFFFUL
,OP_EQ
, ulng
);
3409 /* But UINT64_MAX + 1 shouldn't work */
3410 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%lx", &ulng
));
3413 /* INT64_MIN and INT64_MAX should work */
3414 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
3415 "%ld. %ld.", &lng1
, &lng2
);
3416 tt_int_op(r
,OP_EQ
, 2);
3417 tt_int_op(lng1
,OP_EQ
, -9223372036854775807L - 1L);
3418 tt_int_op(lng2
,OP_EQ
, 9223372036854775807L);
3420 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
3421 r
= tor_sscanf("-9223372036854775809.", "%ld.", &lng1
);
3422 tt_int_op(r
,OP_EQ
, 0);
3424 r
= tor_sscanf("9223372036854775808.", "%ld.", &lng1
);
3425 tt_int_op(r
,OP_EQ
, 0);
3427 /* and the first failure stops further processing */
3428 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
3429 "%ld. %ld.", &lng1
, &lng2
);
3430 tt_int_op(r
,OP_EQ
, 1);
3432 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
3433 "%ld. %ld.", &lng1
, &lng2
);
3434 tt_int_op(r
,OP_EQ
, 0);
3436 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
3437 "%ld. %ld.", &lng1
, &lng2
);
3438 tt_int_op(r
,OP_EQ
, 0);
3439 #endif /* SIZEOF_LONG == 4 || ... */
3441 r
= tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
3442 "%lf %lf %lf %lf", &d1
,&d2
,&d3
,&d4
);
3443 tt_int_op(r
,OP_EQ
, 4);
3444 test_feq(d1
, 123.456);
3445 test_feq(d2
, .000007);
3446 test_feq(d3
, -900123123.2000787);
3450 r
= tor_sscanf("3 ", "%d %lf", &int1
, &d1
);
3451 tt_int_op(r
, OP_EQ
, 1);
3452 tt_int_op(int1
, OP_EQ
, 3);
3455 r
= tor_sscanf("999 notafloat", "%d %lf", &int1
, &d1
);
3456 tt_int_op(r
, OP_EQ
, 1);
3457 tt_int_op(int1
, OP_EQ
, 999);
3459 /* %s but no buffer. */
3460 char *nullbuf
= NULL
;
3461 r
= tor_sscanf("hello", "%3s", nullbuf
);
3462 tt_int_op(r
, OP_EQ
, 0);
3468 #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
3469 #define tt_ci_char_op(a,op,b) \
3470 tt_char_op(TOR_TOLOWER((int)a),op,TOR_TOLOWER((int)b))
3472 #ifndef HAVE_STRNLEN
3474 strnlen(const char *s
, size_t len
)
3476 const char *p
= memchr(s
, 0, len
);
3481 #endif /* !defined(HAVE_STRNLEN) */
3484 test_util_format_time_interval(void *arg
)
3486 /* use the same sized buffer and integers as tor uses */
3487 #define DBUF_SIZE 64
3488 char dbuf
[DBUF_SIZE
];
3490 long sec
, min
, hour
, day
;
3492 /* we don't care about the exact spelling of the
3493 * second(s), minute(s), hour(s), day(s) labels */
3494 #define LABEL_SIZE 21
3496 char label_s
[LABEL_SIZE
];
3497 char label_m
[LABEL_SIZE
];
3498 char label_h
[LABEL_SIZE
];
3499 char label_d
[LABEL_SIZE
];
3501 #define TL_ T_ " " L_
3507 /* In these tests, we're not picky about
3508 * spelling or abbreviations */
3510 /* seconds: 0, 1, 9, 10, 59 */
3512 /* ignore exact spelling of "second(s)"*/
3513 format_time_interval(dbuf
, sizeof(dbuf
), 0);
3514 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3515 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3516 tt_int_op(r
,OP_EQ
, 2);
3517 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3518 tt_int_op(sec
,OP_EQ
, 0);
3520 format_time_interval(dbuf
, sizeof(dbuf
), 1);
3521 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3522 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3523 tt_int_op(r
,OP_EQ
, 2);
3524 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3525 tt_int_op(sec
,OP_EQ
, 1);
3527 format_time_interval(dbuf
, sizeof(dbuf
), 10);
3528 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3529 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3530 tt_int_op(r
,OP_EQ
, 2);
3531 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3532 tt_int_op(sec
,OP_EQ
, 10);
3534 format_time_interval(dbuf
, sizeof(dbuf
), 59);
3535 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3536 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3537 tt_int_op(r
,OP_EQ
, 2);
3538 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3539 tt_int_op(sec
,OP_EQ
, 59);
3541 /* negative seconds are reported as their absolute value */
3543 format_time_interval(dbuf
, sizeof(dbuf
), -4);
3544 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3545 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3546 tt_int_op(r
,OP_EQ
, 2);
3547 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3548 tt_int_op(sec
,OP_EQ
, 4);
3549 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3551 format_time_interval(dbuf
, sizeof(dbuf
), -32);
3552 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3553 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3554 tt_int_op(r
,OP_EQ
, 2);
3555 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3556 tt_int_op(sec
,OP_EQ
, 32);
3557 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3559 /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
3561 /* ignore trailing "0 second(s)", if present */
3562 format_time_interval(dbuf
, sizeof(dbuf
), 60);
3563 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3564 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3565 tt_int_op(r
,OP_EQ
, 2);
3566 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3567 tt_int_op(min
,OP_EQ
, 1);
3568 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3570 /* ignore exact spelling of "minute(s)," and "second(s)" */
3571 format_time_interval(dbuf
, sizeof(dbuf
), 60 + 1);
3572 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3573 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3574 &min
, label_m
, &sec
, label_s
);
3575 tt_int_op(r
,OP_EQ
, 4);
3576 tt_int_op(min
,OP_EQ
, 1);
3577 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3578 tt_int_op(sec
,OP_EQ
, 1);
3579 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3580 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3582 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 - 1);
3583 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3584 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3585 &min
, label_m
, &sec
, label_s
);
3586 tt_int_op(r
,OP_EQ
, 4);
3587 tt_int_op(min
,OP_EQ
, 1);
3588 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3589 tt_int_op(sec
,OP_EQ
, 59);
3590 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3592 /* ignore trailing "0 second(s)", if present */
3593 format_time_interval(dbuf
, sizeof(dbuf
), 60*2);
3594 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3595 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3596 tt_int_op(r
,OP_EQ
, 2);
3597 tt_int_op(min
,OP_EQ
, 2);
3598 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3600 /* ignore exact spelling of "minute(s)," and "second(s)" */
3601 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 + 1);
3602 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3603 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3604 &min
, label_m
, &sec
, label_s
);
3605 tt_int_op(r
,OP_EQ
, 4);
3606 tt_int_op(min
,OP_EQ
, 2);
3607 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3608 tt_int_op(sec
,OP_EQ
, 1);
3609 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3611 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 - 1);
3612 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3613 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3614 &min
, label_m
, &sec
, label_s
);
3615 tt_int_op(r
,OP_EQ
, 4);
3616 tt_int_op(min
,OP_EQ
, 59);
3617 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3618 tt_int_op(sec
,OP_EQ
, 59);
3619 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3621 /* negative minutes are reported as their absolute value */
3623 /* ignore trailing "0 second(s)", if present */
3624 format_time_interval(dbuf
, sizeof(dbuf
), -3*60);
3625 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3626 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3627 tt_int_op(r
,OP_EQ
, 2);
3628 tt_int_op(min
,OP_EQ
, 3);
3629 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3631 /* ignore exact spelling of "minute(s)," and "second(s)" */
3632 format_time_interval(dbuf
, sizeof(dbuf
), -96);
3633 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3634 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3635 &min
, label_m
, &sec
, label_s
);
3636 tt_int_op(r
,OP_EQ
, 4);
3637 tt_int_op(min
,OP_EQ
, 1);
3638 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3639 tt_int_op(sec
,OP_EQ
, 36);
3640 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3642 format_time_interval(dbuf
, sizeof(dbuf
), -2815);
3643 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3644 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3645 &min
, label_m
, &sec
, label_s
);
3646 tt_int_op(r
,OP_EQ
, 4);
3647 tt_int_op(min
,OP_EQ
, 46);
3648 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3649 tt_int_op(sec
,OP_EQ
, 55);
3650 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3652 /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
3653 /* always ignore trailing seconds, if present */
3655 /* ignore trailing "0 minute(s)" etc., if present */
3656 format_time_interval(dbuf
, sizeof(dbuf
), 60*60);
3657 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3658 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3659 tt_int_op(r
,OP_EQ
, 2);
3660 tt_int_op(hour
,OP_EQ
, 1);
3661 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3663 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 1);
3664 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3665 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3666 tt_int_op(r
,OP_EQ
, 2);
3667 tt_int_op(hour
,OP_EQ
, 1);
3668 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3670 /* ignore exact spelling of "hour(s)," etc. */
3671 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 60);
3672 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3673 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3674 &hour
, label_h
, &min
, label_m
);
3675 tt_int_op(r
,OP_EQ
, 4);
3676 tt_int_op(hour
,OP_EQ
, 1);
3677 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3678 tt_int_op(min
,OP_EQ
, 1);
3679 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3681 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 60);
3682 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3683 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3684 &hour
, label_h
, &min
, label_m
);
3685 tt_int_op(r
,OP_EQ
, 4);
3686 tt_int_op(hour
,OP_EQ
, 23);
3687 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3688 tt_int_op(min
,OP_EQ
, 59);
3689 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3691 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 1);
3692 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3693 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3694 &hour
, label_h
, &min
, label_m
);
3695 tt_int_op(r
,OP_EQ
, 4);
3696 tt_int_op(hour
,OP_EQ
, 23);
3697 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3698 tt_int_op(min
,OP_EQ
, 59);
3699 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3701 /* negative hours are reported as their absolute value */
3703 /* ignore exact spelling of "hour(s)," etc., if present */
3704 format_time_interval(dbuf
, sizeof(dbuf
), -2*60*60);
3705 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3706 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3707 tt_int_op(r
,OP_EQ
, 2);
3708 tt_int_op(hour
,OP_EQ
, 2);
3709 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3711 format_time_interval(dbuf
, sizeof(dbuf
), -75804);
3712 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3713 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3714 &hour
, label_h
, &min
, label_m
);
3715 tt_int_op(r
,OP_EQ
, 4);
3716 tt_int_op(hour
,OP_EQ
, 21);
3717 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3718 tt_int_op(min
,OP_EQ
, 3);
3719 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3721 /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
3722 /* always ignore trailing seconds, if present */
3724 /* ignore trailing "0 hours(s)" etc., if present */
3725 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60);
3726 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3727 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3728 tt_int_op(r
,OP_EQ
, 2);
3729 tt_int_op(day
,OP_EQ
, 1);
3730 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3732 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 1);
3733 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3734 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3735 tt_int_op(r
,OP_EQ
, 2);
3736 tt_int_op(day
,OP_EQ
, 1);
3737 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3739 /* ignore exact spelling of "days(s)," etc. */
3740 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60);
3741 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3742 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3743 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3745 /* ignore 0 hours(s), if present */
3746 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3747 &day
, label_d
, &min
, label_m
);
3749 tt_assert(r
== 4 || r
== 6);
3750 tt_int_op(day
,OP_EQ
, 1);
3751 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3753 tt_int_op(hour
,OP_EQ
, 0);
3754 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3756 tt_int_op(min
,OP_EQ
, 1);
3757 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3759 /* ignore trailing "0 minutes(s)" etc., if present */
3760 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60*60);
3761 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3762 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3763 &day
, label_d
, &hour
, label_h
);
3764 tt_int_op(r
,OP_EQ
, 4);
3765 tt_int_op(day
,OP_EQ
, 1);
3766 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3767 tt_int_op(hour
,OP_EQ
, 1);
3768 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3770 /* negative days are reported as their absolute value */
3772 format_time_interval(dbuf
, sizeof(dbuf
), -21936184);
3773 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3774 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3775 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3776 tt_int_op(r
,OP_EQ
, 6);
3777 tt_int_op(day
,OP_EQ
, 253);
3778 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3779 tt_int_op(hour
,OP_EQ
, 21);
3780 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3781 tt_int_op(min
,OP_EQ
, 23);
3782 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3784 /* periods > 1 year are reported in days (warn?) */
3786 /* ignore exact spelling of "days(s)," etc., if present */
3787 format_time_interval(dbuf
, sizeof(dbuf
), 758635154);
3788 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3789 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3790 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3791 tt_int_op(r
,OP_EQ
, 6);
3792 tt_int_op(day
,OP_EQ
, 8780);
3793 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3794 tt_int_op(hour
,OP_EQ
, 11);
3795 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3796 tt_int_op(min
,OP_EQ
, 59);
3797 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3799 /* negative periods > 1 year are reported in days (warn?) */
3801 format_time_interval(dbuf
, sizeof(dbuf
), -1427014922);
3802 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3803 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3804 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3805 tt_int_op(r
,OP_EQ
, 6);
3806 tt_int_op(day
,OP_EQ
, 16516);
3807 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3808 tt_int_op(hour
,OP_EQ
, 9);
3809 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3810 tt_int_op(min
,OP_EQ
, 2);
3811 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3813 #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
3815 /* We can try INT32_MIN/MAX */
3816 /* Always ignore second(s) */
3819 format_time_interval(dbuf
, sizeof(dbuf
), 2147483647);
3820 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3821 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3822 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3823 tt_int_op(r
,OP_EQ
, 6);
3824 tt_int_op(day
,OP_EQ
, 24855);
3825 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3826 tt_int_op(hour
,OP_EQ
, 3);
3827 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3828 tt_int_op(min
,OP_EQ
, 14);
3829 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3830 /* and 7 seconds - ignored */
3832 /* INT32_MIN: check that we get the absolute value of interval,
3833 * which doesn't actually fit in int32_t.
3834 * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
3835 format_time_interval(dbuf
, sizeof(dbuf
), -2147483647L - 1L);
3836 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3837 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3838 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3839 tt_int_op(r
,OP_EQ
, 6);
3840 tt_int_op(day
,OP_EQ
, 24855);
3841 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3842 tt_int_op(hour
,OP_EQ
, 3);
3843 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3844 tt_int_op(min
,OP_EQ
, 14);
3845 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3846 /* and 7 or 8 seconds - ignored */
3848 #endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */
3850 #if SIZEOF_LONG == 8
3852 /* We can try INT64_MIN/MAX */
3853 /* Always ignore second(s) */
3856 format_time_interval(dbuf
, sizeof(dbuf
), 9223372036854775807L);
3857 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3858 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3859 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3860 tt_int_op(r
,OP_EQ
, 6);
3861 tt_int_op(day
,OP_EQ
, 106751991167300L);
3862 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3863 tt_int_op(hour
,OP_EQ
, 15);
3864 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3865 tt_int_op(min
,OP_EQ
, 30);
3866 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3867 /* and 7 seconds - ignored */
3869 /* INT64_MIN: check that we get the absolute value of interval,
3870 * which doesn't actually fit in int64_t.
3871 * We expect INT64_MAX */
3872 format_time_interval(dbuf
, sizeof(dbuf
),
3873 -9223372036854775807L - 1L);
3874 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3875 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3876 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3877 tt_int_op(r
,OP_EQ
, 6);
3878 tt_int_op(day
,OP_EQ
, 106751991167300L);
3879 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3880 tt_int_op(hour
,OP_EQ
, 15);
3881 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3882 tt_int_op(min
,OP_EQ
, 30);
3883 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3884 /* and 7 or 8 seconds - ignored */
3886 #endif /* SIZEOF_LONG == 8 */
3893 #undef tt_ci_char_op
3901 test_util_path_is_relative(void *arg
)
3903 /* OS-independent tests */
3905 tt_int_op(1,OP_EQ
, path_is_relative(""));
3906 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3907 tt_int_op(1,OP_EQ
, path_is_relative("dir/"));
3908 tt_int_op(1,OP_EQ
, path_is_relative("./dir"));
3909 tt_int_op(1,OP_EQ
, path_is_relative("../dir"));
3911 tt_int_op(0,OP_EQ
, path_is_relative("/"));
3912 tt_int_op(0,OP_EQ
, path_is_relative("/dir"));
3913 tt_int_op(0,OP_EQ
, path_is_relative("/dir/"));
3917 /* I don't have Windows so I can't test this, hence the "#ifdef
3918 0". These are tests that look useful, so please try to get them
3919 running and uncomment if it all works as it should */
3920 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3921 tt_int_op(1,OP_EQ
, path_is_relative("dir\\"));
3922 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:"));
3923 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:\\"));
3924 tt_int_op(1,OP_EQ
, path_is_relative("http:\\dir"));
3926 tt_int_op(0,OP_EQ
, path_is_relative("\\dir"));
3927 tt_int_op(0,OP_EQ
, path_is_relative("a:\\dir"));
3928 tt_int_op(0,OP_EQ
, path_is_relative("z:\\dir"));
3929 #endif /* defined(_WIN32) */
3935 /** Run unittests for memory area allocator */
3937 test_util_memarea(void *arg
)
3939 memarea_t
*area
= memarea_new();
3940 char *p1
, *p2
, *p3
, *p1_orig
;
3941 void *malloced_ptr
= NULL
;
3944 #ifdef DISABLE_MEMORY_SENTINELS
3945 /* If memory sentinels are disabled, this whole module is just an alias for
3946 malloc(), which is free to lay out memory most any way it wants. */
3949 #endif /* defined(DISABLE_MEMORY_SENTINELS) */
3954 p1_orig
= p1
= memarea_alloc(area
,64);
3955 p2
= memarea_alloc_zero(area
,52);
3956 p3
= memarea_alloc(area
,11);
3958 tt_assert(memarea_owns_ptr(area
, p1
));
3959 tt_assert(memarea_owns_ptr(area
, p2
));
3960 tt_assert(memarea_owns_ptr(area
, p3
));
3961 /* Make sure we left enough space. */
3962 tt_assert(p1
+64 <= p2
);
3963 tt_assert(p2
+52 <= p3
);
3964 /* Make sure we aligned. */
3965 tt_int_op(((uintptr_t)p1
) % sizeof(void*),OP_EQ
, 0);
3966 tt_int_op(((uintptr_t)p2
) % sizeof(void*),OP_EQ
, 0);
3967 tt_int_op(((uintptr_t)p3
) % sizeof(void*),OP_EQ
, 0);
3968 tt_assert(!memarea_owns_ptr(area
, p3
+8192));
3969 tt_assert(!memarea_owns_ptr(area
, p3
+30));
3970 tt_assert(fast_mem_is_zero(p2
, 52));
3971 /* Make sure we don't overalign. */
3972 p1
= memarea_alloc(area
, 1);
3973 p2
= memarea_alloc(area
, 1);
3974 tt_ptr_op(p1
+sizeof(void*),OP_EQ
, p2
);
3976 malloced_ptr
= tor_malloc(64);
3977 tt_assert(!memarea_owns_ptr(area
, malloced_ptr
));
3978 tor_free(malloced_ptr
);
3981 /* memarea_memdup */
3983 malloced_ptr
= tor_malloc(64);
3984 crypto_rand((char*)malloced_ptr
, 64);
3985 p1
= memarea_memdup(area
, malloced_ptr
, 64);
3986 tt_assert(p1
!= malloced_ptr
);
3987 tt_mem_op(p1
,OP_EQ
, malloced_ptr
, 64);
3988 tor_free(malloced_ptr
);
3991 /* memarea_strdup. */
3992 p1
= memarea_strdup(area
,"");
3993 p2
= memarea_strdup(area
, "abcd");
3996 tt_str_op(p1
,OP_EQ
, "");
3997 tt_str_op(p2
,OP_EQ
, "abcd");
3999 /* memarea_strndup. */
4001 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
4002 /* (From Turandot, act 3.) */
4003 size_t len
= strlen(s
);
4004 p1
= memarea_strndup(area
, s
, 1000);
4005 p2
= memarea_strndup(area
, s
, 10);
4006 tt_str_op(p1
,OP_EQ
, s
);
4007 tt_assert(p2
>= p1
+ len
+ 1);
4008 tt_mem_op(s
,OP_EQ
, p2
, 10);
4009 tt_int_op(p2
[10],OP_EQ
, '\0');
4010 p3
= memarea_strndup(area
, s
, len
);
4011 tt_str_op(p3
,OP_EQ
, s
);
4012 p3
= memarea_strndup(area
, s
, len
-1);
4013 tt_mem_op(s
,OP_EQ
, p3
, len
-1);
4014 tt_int_op(p3
[len
-1],OP_EQ
, '\0');
4017 memarea_clear(area
);
4018 p1
= memarea_alloc(area
, 1);
4019 tt_ptr_op(p1
,OP_EQ
, p1_orig
);
4020 memarea_clear(area
);
4021 size_t total
= 0, initial_allocation
, allocation2
, dummy
;
4022 memarea_get_stats(area
, &initial_allocation
, &dummy
);
4024 /* Check for running over an area's size. */
4025 for (i
= 0; i
< 4096; ++i
) {
4026 size_t n
= crypto_rand_int(6);
4027 p1
= memarea_alloc(area
, n
);
4029 tt_assert(memarea_owns_ptr(area
, p1
));
4031 memarea_assert_ok(area
);
4032 memarea_get_stats(area
, &allocation2
, &dummy
);
4033 /* Make sure we can allocate a too-big object. */
4034 p1
= memarea_alloc_zero(area
, 9000);
4035 p2
= memarea_alloc_zero(area
, 16);
4038 tt_assert(memarea_owns_ptr(area
, p1
));
4039 tt_assert(memarea_owns_ptr(area
, p2
));
4041 /* Now test stats... */
4042 size_t allocated
= 0, used
= 0;
4043 memarea_get_stats(area
, &allocated
, &used
);
4044 tt_int_op(used
, OP_LE
, allocated
);
4045 tt_int_op(used
, OP_GE
, total
); /* not EQ, because of alignment and headers*/
4046 tt_int_op(allocated
, OP_GT
, allocation2
);
4048 tt_int_op(allocation2
, OP_GT
, initial_allocation
);
4050 memarea_clear(area
);
4051 memarea_get_stats(area
, &allocated
, &used
);
4052 tt_int_op(used
, OP_LT
, 128); /* Not 0, because of header */
4053 tt_int_op(allocated
, OP_EQ
, initial_allocation
);
4056 memarea_drop_all(area
);
4057 tor_free(malloced_ptr
);
4060 /** Run unit tests for utility functions to get file names relative to
4061 * the data directory. */
4063 test_util_datadir(void *arg
)
4067 char *temp_dir
= NULL
;
4070 temp_dir
= get_datadir_fname(NULL
);
4071 f
= get_datadir_fname("state");
4072 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
4073 tt_str_op(f
,OP_EQ
, buf
);
4075 f
= get_datadir_fname2("cache", "thingy");
4076 tor_snprintf(buf
, sizeof(buf
),
4077 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
4078 tt_str_op(f
,OP_EQ
, buf
);
4080 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
4081 tor_snprintf(buf
, sizeof(buf
),
4082 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
4083 tt_str_op(f
,OP_EQ
, buf
);
4085 f
= get_datadir_fname_suffix("cache", ".foo");
4086 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
4088 tt_str_op(f
,OP_EQ
, buf
);
4096 test_util_strtok(void *arg
)
4104 for (i
= 0; i
< 3; i
++) {
4105 const char *pad1
="", *pad2
="";
4118 tor_snprintf(buf
, sizeof(buf
), "%s", pad1
);
4119 tor_snprintf(buf2
, sizeof(buf2
), "%s", pad2
);
4120 tt_ptr_op(tor_strtok_r_impl(buf
, " ", &cp1
), OP_EQ
, NULL
);
4121 tt_ptr_op(tor_strtok_r_impl(buf2
, ".!..;!", &cp2
), OP_EQ
, NULL
);
4123 tor_snprintf(buf
, sizeof(buf
),
4124 "%sGraved on the dark in gestures of descent%s", pad1
, pad1
);
4125 tor_snprintf(buf2
, sizeof(buf2
),
4126 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2
,pad2
);
4127 /* -- "Year's End", Richard Wilbur */
4129 tt_str_op("Graved",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4130 tt_str_op("they",OP_EQ
, tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
4131 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
4132 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
4133 tt_str_op("on",OP_EQ
, S1());
4134 tt_str_op("the",OP_EQ
, S1());
4135 tt_str_op("dark",OP_EQ
, S1());
4136 tt_str_op("seemed",OP_EQ
, S2());
4137 tt_str_op("their",OP_EQ
, S2());
4138 tt_str_op("own",OP_EQ
, S2());
4139 tt_str_op("in",OP_EQ
, S1());
4140 tt_str_op("gestures",OP_EQ
, S1());
4141 tt_str_op("of",OP_EQ
, S1());
4142 tt_str_op("most",OP_EQ
, S2());
4143 tt_str_op("perfect",OP_EQ
, S2());
4144 tt_str_op("descent",OP_EQ
, S1());
4145 tt_str_op("monument",OP_EQ
, S2());
4146 tt_ptr_op(NULL
,OP_EQ
, S1());
4147 tt_ptr_op(NULL
,OP_EQ
, S2());
4151 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4152 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
4154 strlcpy(buf
, "Howdy!", sizeof(buf
));
4155 tt_str_op("Howdy",OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
4156 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, "!", &cp1
));
4158 strlcpy(buf
, " ", sizeof(buf
));
4159 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4160 strlcpy(buf
, " ", sizeof(buf
));
4161 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4163 strlcpy(buf
, "something ", sizeof(buf
));
4164 tt_str_op("something",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
4165 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, ";", &cp1
));
4171 test_util_find_str_at_start_of_line(void *ptr
)
4173 const char *long_string
=
4174 "howdy world. how are you? i hope it's fine.\n"
4177 char *line2
= strchr(long_string
,'\n')+1;
4178 char *line3
= strchr(line2
,'\n')+1;
4179 const char *short_string
= "hello kitty\n"
4181 char *short_line2
= strchr(short_string
,'\n')+1;
4185 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, ""));
4186 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(short_string
, "nonsense"));
4187 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "nonsense"));
4188 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "\n"));
4189 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "how "));
4190 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "kitty"));
4191 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "h"));
4192 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "how"));
4193 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "he"));
4194 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hell"));
4195 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hello k"));
4196 tt_ptr_op(line2
,OP_EQ
,
4197 find_str_at_start_of_line(long_string
, "hello kitty\n"));
4198 tt_ptr_op(line2
,OP_EQ
,
4199 find_str_at_start_of_line(long_string
, "hello kitty\nt"));
4200 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third"));
4201 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third line"));
4202 tt_ptr_op(NULL
, OP_EQ
,
4203 find_str_at_start_of_line(long_string
, "third line\n"));
4204 tt_ptr_op(short_line2
,OP_EQ
, find_str_at_start_of_line(short_string
,
4211 test_util_tor_strreplacechar(void *ptr
)
4215 char not_contain
[] = "bbb";
4216 char contains
[] = "bab";
4217 char contains_all
[] = "aaa";
4219 tor_strreplacechar(empty
, 'a', 'b');
4220 tt_str_op(empty
, OP_EQ
, "");
4222 tor_strreplacechar(not_contain
, 'a', 'b');
4223 tt_str_op(not_contain
, OP_EQ
, "bbb");
4225 tor_strreplacechar(contains
, 'a', 'b');
4226 tt_str_op(contains
, OP_EQ
, "bbb");
4228 tor_strreplacechar(contains_all
, 'a', 'b');
4229 tt_str_op(contains_all
, OP_EQ
, "bbb");
4236 test_util_string_is_C_identifier(void *ptr
)
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("_string_is_C_identifier"));
4242 tt_int_op(1,OP_EQ
, string_is_C_identifier("_"));
4243 tt_int_op(1,OP_EQ
, string_is_C_identifier("i"));
4244 tt_int_op(1,OP_EQ
, string_is_C_identifier("_____"));
4245 tt_int_op(1,OP_EQ
, string_is_C_identifier("__00__"));
4246 tt_int_op(1,OP_EQ
, string_is_C_identifier("__init__"));
4247 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4248 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0string_is_C_identifier"));
4249 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
4251 tt_int_op(0,OP_EQ
, string_is_C_identifier("0_string_is_C_identifier"));
4252 tt_int_op(0,OP_EQ
, string_is_C_identifier("0"));
4253 tt_int_op(0,OP_EQ
, string_is_C_identifier(""));
4254 tt_int_op(0,OP_EQ
, string_is_C_identifier(";"));
4255 tt_int_op(0,OP_EQ
, string_is_C_identifier("i;"));
4256 tt_int_op(0,OP_EQ
, string_is_C_identifier("_;"));
4257 tt_int_op(0,OP_EQ
, string_is_C_identifier("Ã"));
4258 tt_int_op(0,OP_EQ
, string_is_C_identifier("ñ"));
4265 test_util_string_is_utf8(void *ptr
)
4269 tt_int_op(1, OP_EQ
, string_is_utf8(NULL
, 0));
4270 tt_int_op(1, OP_EQ
, string_is_utf8("", 1));
4271 tt_int_op(1, OP_EQ
, string_is_utf8("\uFEFF", 3));
4272 tt_int_op(1, OP_EQ
, string_is_utf8("\uFFFE", 3));
4273 tt_int_op(1, OP_EQ
, string_is_utf8("ascii\x7f\n", 7));
4274 tt_int_op(1, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 9));
4276 /* Test the utf8_no_bom function */
4277 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFEFF", 3));
4278 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFFFE", 3));
4279 tt_int_op(0, OP_EQ
, string_is_utf8_no_bom("\uFEFFlove", 7));
4280 tt_int_op(1, OP_EQ
, string_is_utf8_no_bom("loveandrespect",
4281 strlen("loveandrespect")));
4283 // Validate exactly 'len' bytes.
4284 tt_int_op(0, OP_EQ
, string_is_utf8("\0\x80", 2));
4285 tt_int_op(0, OP_EQ
, string_is_utf8("Risqu\u00e9=1", 6));
4287 // Reject sequences with missing bytes.
4288 tt_int_op(0, OP_EQ
, string_is_utf8("\x80", 1));
4289 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2", 1));
4290 tt_int_op(0, OP_EQ
, string_is_utf8("\xc2 ", 2));
4291 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80", 2));
4292 tt_int_op(0, OP_EQ
, string_is_utf8("\xe1\x80 ", 3));
4293 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80", 3));
4294 tt_int_op(0, OP_EQ
, string_is_utf8("\xf1\x80\x80 ", 4));
4296 // Reject encodings that are overly long.
4297 tt_int_op(0, OP_EQ
, string_is_utf8("\xc1\xbf", 2));
4298 tt_int_op(1, OP_EQ
, string_is_utf8("\xc2\x80", 2));
4299 tt_int_op(0, OP_EQ
, string_is_utf8("\xe0\x9f\xbf", 3));
4300 tt_int_op(1, OP_EQ
, string_is_utf8("\xe0\xa0\x80", 3));
4301 tt_int_op(0, OP_EQ
, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
4302 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\x90\x80\x80", 4));
4304 // Reject UTF-16 surrogate halves.
4305 tt_int_op(1, OP_EQ
, string_is_utf8("\xed\x9f\xbf", 3));
4306 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xa0\x80", 3));
4307 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xbf\xbf", 3));
4308 tt_int_op(1, OP_EQ
, string_is_utf8("\xee\x80\x80", 3));
4310 // The minimum legal codepoint, 0x00.
4311 tt_int_op(1, OP_EQ
, string_is_utf8("\0", 1));
4313 // The maximum legal codepoint, 0x10FFFF.
4314 tt_int_op(1, OP_EQ
, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
4315 tt_int_op(0, OP_EQ
, string_is_utf8("\xf4\x90\x80\x80", 4));
4317 /* Test cases that vary between programming languages /
4318 * UTF-8 implementations.
4319 * Source: POC||GTFO 19, page 43
4320 * https://www.alchemistowl.org/pocorgtfo/
4323 // Invalid (in most implementations)
4325 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xa0\x81", 3));
4327 tt_int_op(0, OP_EQ
, string_is_utf8("\x30\x00\xed\xa0\x81", 5));
4329 tt_int_op(0, OP_EQ
, string_is_utf8("\xed\xbf\xbf", 3));
4331 tt_int_op(0, OP_EQ
, string_is_utf8("\xf4\x90\xbf\xbf", 4));
4333 tt_int_op(0, OP_EQ
, string_is_utf8("\xfb\x80\x80\x80\x80", 5));
4335 tt_int_op(0, OP_EQ
, string_is_utf8("\xfd\x80\x80\x80\x80", 5));
4337 tt_int_op(0, OP_EQ
, string_is_utf8("\xfd\xbf\xbf\xbf\xbf", 5));
4339 // Valid (in most implementations)
4341 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\x90\x8d\x88", 4));
4343 tt_int_op(1, OP_EQ
, string_is_utf8("\xf0\xbf\xbf\xbf", 4));
4345 tt_int_op(1, OP_EQ
, string_is_utf8("\x30\x31\x32\x00\x33", 5));
4352 test_util_asprintf(void *ptr
)
4354 #define LOREMIPSUM \
4355 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
4356 char *cp
=NULL
, *cp2
=NULL
;
4361 r
= tor_asprintf(&cp
, "simple string 100%% safe");
4363 tt_str_op("simple string 100% safe",OP_EQ
, cp
);
4364 tt_int_op(strlen(cp
),OP_EQ
, r
);
4368 r
= tor_asprintf(&cp
, "%s", "");
4370 tt_str_op("",OP_EQ
, cp
);
4371 tt_int_op(strlen(cp
),OP_EQ
, r
);
4375 r
= tor_asprintf(&cp
, "I like numbers-%2i, %i, etc.", -1, 2);
4377 tt_str_op("I like numbers--1, 2, etc.",OP_EQ
, cp
);
4378 tt_int_op(strlen(cp
),OP_EQ
, r
);
4379 /* don't free cp; next test uses it. */
4382 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
4384 tt_int_op(strlen(cp2
),OP_EQ
, r
);
4385 tt_str_op("First=101, Second=202",OP_EQ
, cp2
);
4386 tt_assert(cp
!= cp2
);
4390 /* Glass-box test: a string exactly 128 characters long. */
4391 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
4393 tt_int_op(128,OP_EQ
, r
);
4394 tt_int_op(cp
[128], OP_EQ
, '\0');
4395 tt_str_op("Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
,OP_EQ
, cp
);
4398 /* String longer than 128 characters */
4399 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
4400 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
4402 tt_int_op(strlen(cp
),OP_EQ
, r
);
4403 tt_str_op("1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
,OP_EQ
, cp
);
4411 test_util_listdir(void *ptr
)
4413 smartlist_t
*dir_contents
= NULL
;
4414 char *fname1
=NULL
, *fname2
=NULL
, *fname3
=NULL
, *dir1
=NULL
, *dirname
=NULL
;
4418 fname1
= tor_strdup(get_fname("hopscotch"));
4419 fname2
= tor_strdup(get_fname("mumblety-peg"));
4420 fname3
= tor_strdup(get_fname(".hidden-file"));
4421 dir1
= tor_strdup(get_fname("some-directory"));
4422 dirname
= tor_strdup(get_fname(NULL
));
4424 tt_int_op(0,OP_EQ
, write_str_to_file(fname1
, "X\n", 0));
4425 tt_int_op(0,OP_EQ
, write_str_to_file(fname2
, "Y\n", 0));
4426 tt_int_op(0,OP_EQ
, write_str_to_file(fname3
, "Z\n", 0));
4430 r
= mkdir(dir1
, 0700);
4433 fprintf(stderr
, "Can't create directory %s:", dir1
);
4438 dir_contents
= tor_listdir(dirname
);
4439 tt_assert(dir_contents
);
4440 /* make sure that each filename is listed. */
4441 tt_assert(smartlist_contains_string_case(dir_contents
, "hopscotch"));
4442 tt_assert(smartlist_contains_string_case(dir_contents
, "mumblety-peg"));
4443 tt_assert(smartlist_contains_string_case(dir_contents
, ".hidden-file"));
4444 tt_assert(smartlist_contains_string_case(dir_contents
, "some-directory"));
4446 tt_assert(!smartlist_contains_string(dir_contents
, "."));
4447 tt_assert(!smartlist_contains_string(dir_contents
, ".."));
4456 SMARTLIST_FOREACH(dir_contents
, char *, cp
, tor_free(cp
));
4457 smartlist_free(dir_contents
);
4462 test_util_glob(void *ptr
)
4467 smartlist_t
*results
= NULL
;
4469 char *dir1
= NULL
, *dir2
= NULL
, *forbidden
= NULL
, *dirname
= NULL
;
4470 char *expected
= NULL
, *pattern
= NULL
;
4472 char *dir1_forbidden
= NULL
, *dir2_forbidden
= NULL
;
4473 char *forbidden_forbidden
= NULL
;
4475 dirname
= tor_strdup(get_fname("test_glob"));
4476 tt_ptr_op(dirname
, OP_NE
, NULL
);
4481 r
= mkdir(dirname
, 0700);
4484 fprintf(stderr
, "Can't create directory %s:", dirname
);
4489 tt_int_op(0, OP_EQ
, create_test_directory_structure(dirname
));
4490 tor_asprintf(&dir1
, "%s"PATH_SEPARATOR
"dir1", dirname
);
4491 tor_asprintf(&dir1_forbidden
,
4492 "%s"PATH_SEPARATOR
"dir1"PATH_SEPARATOR
"forbidden", dirname
);
4493 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir1
));
4494 tor_asprintf(&dir2
, "%s"PATH_SEPARATOR
"dir2", dirname
);
4495 tor_asprintf(&dir2_forbidden
,
4496 "%s"PATH_SEPARATOR
"dir2"PATH_SEPARATOR
"forbidden", dirname
);
4497 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir2
));
4498 tor_asprintf(&forbidden
, "%s"PATH_SEPARATOR
"forbidden", dirname
);
4499 tor_asprintf(&forbidden_forbidden
,
4500 "%s"PATH_SEPARATOR
"forbidden"PATH_SEPARATOR
"forbidden",dirname
);
4502 tt_int_op(0, OP_EQ
, chmod(forbidden
, 0700));
4504 tt_int_op(0, OP_EQ
, create_test_directory_structure(forbidden
));
4506 tt_int_op(0, OP_EQ
, chmod(forbidden
, 0));
4509 #define TEST(input) \
4511 tor_asprintf(&pattern, "%s"PATH_SEPARATOR"%s", dirname, input); \
4512 results = tor_glob(pattern); \
4513 tor_free(pattern); \
4514 tt_assert(results); \
4515 smartlist_sort_strings(results); \
4518 #define EXPECT(result) \
4520 tt_int_op(smartlist_len(results), OP_EQ, \
4521 sizeof(result)/sizeof(*result)); \
4523 SMARTLIST_FOREACH_BEGIN(results, const char *, f) { \
4524 tor_asprintf(&expected, "%s"PATH_SEPARATOR"%s", dirname, result[i]); \
4525 tt_str_op(f, OP_EQ, expected); \
4527 tor_free(expected); \
4528 } SMARTLIST_FOREACH_END(f); \
4529 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4530 smartlist_free(results); \
4533 #define EXPECT_EMPTY() \
4535 tt_int_op(smartlist_len(results), OP_EQ, 0); \
4536 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4537 smartlist_free(results); \
4540 // wildcards at beginning
4541 const char *results_test1
[] = {"dir2", "file2"};
4543 EXPECT(results_test1
);
4546 const char *results_test2
[] = {"dir1", "dir2"};
4548 EXPECT(results_test2
);
4550 // wildcards at beginning and end
4552 // dot files are not ignored on Windows
4553 const char *results_test3
[] = {".test-hidden", "dir1", "dir2", "file1",
4554 "file2", "forbidden"};
4556 const char *results_test3
[] = {"dir1", "dir2", "file1", "file2",
4558 #endif /* defined(_WIN32) */
4560 EXPECT(results_test3
);
4562 // wildcards in middle
4563 const char *results_test4
[] = {"dir1", "dir2"};
4565 EXPECT(results_test4
);
4567 // test file that does not exist
4571 // test wildcard that matches nothing
4572 TEST("*not-exist*");
4575 // test path separator at end - no wildcards
4576 const char *results_test7
[] = {"dir1"};
4578 EXPECT(results_test7
);
4580 const char *results_test8
[] = {"dir1"};
4581 TEST("dir1"PATH_SEPARATOR
);
4582 EXPECT(results_test8
);
4584 const char *results_test9
[] = {"file1"};
4586 EXPECT(results_test9
);
4588 TEST("file1"PATH_SEPARATOR
);
4591 // test path separator at end - with wildcards and linux path separator
4592 const char *results_test11
[] = {"dir1", "dir2", "forbidden"};
4594 EXPECT(results_test11
);
4597 // dot files are not ignored on Windows
4598 const char *results_test12
[] = {".test-hidden", "dir1", "dir2", "empty",
4599 "file1", "file2", "forbidden"};
4601 const char *results_test12
[] = {"dir1", "dir2", "empty", "file1", "file2",
4603 #endif /* defined(_WIN32) */
4605 EXPECT(results_test12
);
4607 // wildcards on folder and file and linux path separator
4608 const char *results_test13
[] = {"dir1"PATH_SEPARATOR
"dir1",
4609 "dir1"PATH_SEPARATOR
"dir2",
4610 "dir1"PATH_SEPARATOR
"file1",
4611 "dir1"PATH_SEPARATOR
"file2",
4612 "dir2"PATH_SEPARATOR
"dir1",
4613 "dir2"PATH_SEPARATOR
"dir2",
4614 "dir2"PATH_SEPARATOR
"file1",
4615 "dir2"PATH_SEPARATOR
"file2"};
4617 EXPECT(results_test13
);
4619 // wildcards on file only
4620 const char *results_test14
[] = {"dir1"PATH_SEPARATOR
"dir1",
4621 "dir1"PATH_SEPARATOR
"dir2",
4622 "dir1"PATH_SEPARATOR
"file1",
4623 "dir1"PATH_SEPARATOR
"file2"};
4624 TEST("dir1"PATH_SEPARATOR
"?i*");
4625 EXPECT(results_test14
);
4627 // wildcards on folder only
4628 const char *results_test15
[] = {"dir1"PATH_SEPARATOR
"file1",
4629 "dir2"PATH_SEPARATOR
"file1"};
4630 TEST("?i*"PATH_SEPARATOR
"file1");
4631 EXPECT(results_test15
);
4633 // wildcards after file name
4634 TEST("file1"PATH_SEPARATOR
"*");
4638 // test wildcard escaping
4642 if (getuid() != 0) {
4643 // test forbidden directory, if we're not root.
4644 // (Root will be able to see this directory anyway.)
4645 tor_asprintf(&pattern
, "%s"PATH_SEPARATOR
"*"PATH_SEPARATOR
"*", dirname
);
4646 results
= tor_glob(pattern
);
4648 tt_assert(!results
);
4650 #endif /* !defined(_WIN32) */
4658 (void) chmod(forbidden
, 0700);
4659 (void) chmod(dir1_forbidden
, 0700);
4660 (void) chmod(dir2_forbidden
, 0700);
4661 (void) chmod(forbidden_forbidden
, 0700);
4662 #endif /* !defined(_WIN32) */
4665 tor_free(forbidden
);
4667 tor_free(dir1_forbidden
);
4668 tor_free(dir2_forbidden
);
4669 tor_free(forbidden_forbidden
);
4673 SMARTLIST_FOREACH(results
, char *, f
, tor_free(f
));
4674 smartlist_free(results
);
4676 #else /* !defined(HAVE_GLOB) */
4680 #endif /* defined(HAVE_GLOB) */
4684 test_util_get_glob_opened_files(void *ptr
)
4689 smartlist_t
*results
= NULL
;
4691 char *dir1
= NULL
, *dir2
= NULL
, *forbidden
= NULL
, *dirname
= NULL
;
4692 char *expected
= NULL
, *pattern
= NULL
;
4694 char *dir1_forbidden
= NULL
, *dir2_forbidden
= NULL
;
4695 char *forbidden_forbidden
= NULL
;
4697 dirname
= tor_strdup(get_fname("test_get_glob_opened_files"));
4698 tt_ptr_op(dirname
, OP_NE
, NULL
);
4703 r
= mkdir(dirname
, 0700);
4706 fprintf(stderr
, "Can't create directory %s:", dirname
);
4711 tt_int_op(0, OP_EQ
, create_test_directory_structure(dirname
));
4712 tor_asprintf(&dir1
, "%s"PATH_SEPARATOR
"dir1", dirname
);
4713 tor_asprintf(&dir1_forbidden
,
4714 "%s"PATH_SEPARATOR
"dir1"PATH_SEPARATOR
"forbidden", dirname
);
4715 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir1
));
4716 tor_asprintf(&dir2
, "%s"PATH_SEPARATOR
"dir2", dirname
);
4717 tor_asprintf(&dir2_forbidden
,
4718 "%s"PATH_SEPARATOR
"dir2"PATH_SEPARATOR
"forbidden", dirname
);
4719 tt_int_op(0, OP_EQ
, create_test_directory_structure(dir2
));
4720 tor_asprintf(&forbidden
, "%s"PATH_SEPARATOR
"forbidden", dirname
);
4721 tor_asprintf(&forbidden_forbidden
,
4722 "%s"PATH_SEPARATOR
"forbidden"PATH_SEPARATOR
"forbidden",dirname
);
4724 chmod(forbidden
, 0700);
4726 tt_int_op(0, OP_EQ
, create_test_directory_structure(forbidden
));
4728 chmod(forbidden
, 0);
4731 #define TEST(input) \
4734 tor_asprintf(&pattern, "%s"PATH_SEPARATOR"%s", dirname, input); \
4735 } else { /* do not add path separator if empty string */ \
4736 tor_asprintf(&pattern, "%s", dirname); \
4738 results = get_glob_opened_files(pattern); \
4739 tor_free(pattern); \
4740 tt_assert(results); \
4741 smartlist_sort_strings(results); \
4744 #define EXPECT(result) \
4746 tt_int_op(smartlist_len(results), OP_EQ, \
4747 sizeof(result)/sizeof(*result)); \
4749 SMARTLIST_FOREACH_BEGIN(results, const char *, f) { \
4751 tor_asprintf(&expected, "%s"PATH_SEPARATOR"%s", dirname, result[i]); \
4752 } else { /* do not add path separator if empty string */ \
4753 tor_asprintf(&expected, "%s", dirname); \
4755 tt_str_op(f, OP_EQ, expected); \
4757 tor_free(expected); \
4758 } SMARTLIST_FOREACH_END(f); \
4759 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4760 smartlist_free(results); \
4763 #define EXPECT_EMPTY() \
4765 tt_int_op(smartlist_len(results), OP_EQ, 0); \
4766 SMARTLIST_FOREACH(results, char *, f, tor_free(f)); \
4767 smartlist_free(results); \
4770 // all files on folder
4771 const char *results_test1
[] = {""}; // only the folder is read
4773 EXPECT(results_test1
);
4775 // same as before but ending in path separator
4776 const char *results_test2
[] = {""}; // only the folder is read
4777 TEST("*"PATH_SEPARATOR
);
4778 EXPECT(results_test2
);
4780 // wildcards in multiple path components
4782 const char *results_test3
[] = {"", "dir1", "dir2", "empty", "file1", "file2",
4785 // dot files are not special on windows
4786 const char *results_test3
[] = {"", ".test-hidden", "dir1", "dir2", "empty",
4787 "file1", "file2", "forbidden"};
4788 #endif /* !defined(_WIN32) */
4789 TEST("*"PATH_SEPARATOR
"*");
4790 EXPECT(results_test3
);
4792 // same as before but ending in path separator
4794 const char *results_test4
[] = {"", "dir1", "dir2", "empty", "file1", "file2",
4797 // dot files are not special on windows
4798 const char *results_test4
[] = {"", ".test-hidden", "dir1", "dir2", "empty",
4799 "file1", "file2", "forbidden"};
4800 #endif /* !defined(_WIN32) */
4801 TEST("*"PATH_SEPARATOR
"*"PATH_SEPARATOR
);
4802 EXPECT(results_test4
);
4808 // same as before but ending in path separator
4809 TEST(PATH_SEPARATOR
);
4816 // same as before but ending in path separator and linux path separator
4820 // file but with wildcard after
4821 const char *results_test9
[] = {"file1"};
4822 TEST("file1"PATH_SEPARATOR
"*");
4823 EXPECT(results_test9
);
4825 // dir inside dir and linux path separator
4829 // same as before but ending in path separator
4830 TEST("dir1"PATH_SEPARATOR
"dir1"PATH_SEPARATOR
);
4837 // same as before but ending in path separator
4838 TEST("empty"PATH_SEPARATOR
);
4841 // no glob - does not exist
4852 int chmod_failed
= 0;
4854 chmod_failed
|= chmod(forbidden
, 0700);
4856 chmod_failed
|= chmod(dir1_forbidden
, 0700);
4858 chmod_failed
|= chmod(dir2_forbidden
, 0700);
4859 if (forbidden_forbidden
)
4860 chmod_failed
|= chmod(forbidden_forbidden
, 0700);
4862 TT_FAIL(("unable to chmod a file on cleanup: %s", strerror(errno
)));
4865 #endif /* !defined(_WIN32) */
4868 tor_free(forbidden
);
4870 tor_free(dir1_forbidden
);
4871 tor_free(dir2_forbidden
);
4872 tor_free(forbidden_forbidden
);
4876 SMARTLIST_FOREACH(results
, char *, f
, tor_free(f
));
4877 smartlist_free(results
);
4879 #else /* !defined(HAVE_GLOB) */
4883 #endif /* defined(HAVE_GLOB) */
4887 test_util_parent_dir(void *ptr
)
4892 #define T(output,expect_ok,input) \
4895 cp = tor_strdup(input); \
4896 ok = get_parent_directory(cp); \
4897 tt_int_op(expect_ok, OP_EQ, ok); \
4899 tt_str_op(output, OP_EQ, cp); \
4903 T("/home/wombat", 0, "/home/wombat/knish");
4904 T("/home/wombat", 0, "/home/wombat/knish/");
4905 T("/home/wombat", 0, "/home/wombat/knish///");
4906 T("./home/wombat", 0, "./home/wombat/knish/");
4908 T("/", 0, "/home//");
4909 T(".", 0, "./wombat");
4910 T(".", 0, "./wombat/");
4911 T(".", 0, "./wombat//");
4912 T("wombat", 0, "wombat/foo");
4913 T("wombat/..", 0, "wombat/../foo");
4914 T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
4915 T("wombat/.", 0, "wombat/./foo");
4916 T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
4917 T("wombat", 0, "wombat/..//");
4918 T("wombat", 0, "wombat/foo/");
4919 T("wombat", 0, "wombat/.foo");
4920 T("wombat", 0, "wombat/.foo/");
4922 T("wombat", -1, "");
4924 T("wombat", 0, "wombat/knish");
4934 test_util_ftruncate(void *ptr
)
4939 const char *message
= "Hello world";
4940 const char *message2
= "Hola mundo";
4945 fname
= get_fname("ftruncate");
4947 fd
= tor_open_cloexec(fname
, O_WRONLY
|O_CREAT
, 0600);
4948 tt_int_op(fd
, OP_GE
, 0);
4950 /* Make the file be there. */
4951 tt_int_op(strlen(message
), OP_EQ
,
4952 write_all_to_fd(fd
, message
, strlen(message
)));
4953 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message
));
4954 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4955 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message
));
4957 /* Truncate and see if it got truncated */
4958 tt_int_op(0, OP_EQ
, tor_ftruncate(fd
));
4959 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, 0);
4960 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4961 tt_int_op((int)st
.st_size
, OP_EQ
, 0);
4963 /* Replace, and see if it got replaced */
4964 tt_int_op(strlen(message2
), OP_EQ
,
4965 write_all_to_fd(fd
, message2
, strlen(message2
)));
4966 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message2
));
4967 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
4968 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message2
));
4973 buf
= read_file_to_str(fname
, 0, NULL
);
4974 tt_str_op(message2
, OP_EQ
, buf
);
4983 test_util_num_cpus(void *arg
)
4986 int num
= compute_num_cpus();
4990 tt_int_op(num
, OP_GE
, 1);
4991 tt_int_op(num
, OP_LE
, 16);
4999 test_util_load_win_lib(void *ptr
)
5001 HANDLE h
= load_windows_system_library(_T("advapi32.dll"));
5009 #endif /* defined(_WIN32) */
5012 * Test for format_hex_number_sigsafe()
5016 test_util_format_hex_number(void *ptr
)
5028 {"7FFFFFFF", 0x7fffffff},
5029 {"FFFFFFFF", 0xffffffff},
5030 #if UINT_MAX >= 0xffffffff
5031 {"31BC421D", 0x31bc421d},
5032 {"FFFFFFFF", 0xffffffff},
5039 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
5040 len
= format_hex_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
5041 tt_int_op(len
,OP_NE
, 0);
5042 tt_int_op(len
,OP_EQ
, strlen(buf
));
5043 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
5046 tt_int_op(4,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 5));
5047 tt_str_op(buf
,OP_EQ
, "FFFF");
5048 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 4));
5049 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0, buf
, 1));
5056 * Test for format_hex_number_sigsafe()
5060 test_util_format_dec_number(void *ptr
)
5071 {"12345678", 12345678},
5072 {"99999999", 99999999},
5073 {"100000000", 100000000},
5074 {"4294967295", 4294967295u},
5075 #if UINT_MAX > 0xffffffff
5076 {"18446744073709551615", 18446744073709551615u },
5083 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
5084 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
5085 tt_int_op(len
,OP_NE
, 0);
5086 tt_int_op(len
,OP_EQ
, strlen(buf
));
5087 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
5089 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
,
5090 (int)(strlen(test_data
[i
].str
) + 1));
5091 tt_int_op(len
,OP_EQ
, strlen(buf
));
5092 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
5095 tt_int_op(4,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 5));
5096 tt_str_op(buf
,OP_EQ
, "7331");
5097 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 4));
5098 tt_int_op(1,OP_EQ
, format_dec_number_sigsafe(0, buf
, 2));
5099 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(0, buf
, 1));
5105 #define MAX_SPLIT_LINE_COUNT 4
5106 struct split_lines_test_t
{
5107 const char *orig_line
; // Line to be split (may contain \0's)
5108 int orig_length
; // Length of orig_line
5109 const char *split_line
[MAX_SPLIT_LINE_COUNT
]; // Split lines
5113 test_util_di_ops(void *arg
)
5119 const char *a
; int want_sign
; const char *b
;
5121 { "Foo", EQ
, "Foo" },
5122 { "foo", GT
, "bar", },
5123 { "foobar", EQ
,"foobar" },
5124 { "foobar", LT
, "foobaw" },
5125 { "foobar", GT
, "f00bar" },
5126 { "foobar", GT
, "boobar" },
5134 for (i
= 0; examples
[i
].a
; ++i
) {
5135 size_t len
= strlen(examples
[i
].a
);
5136 int eq1
, eq2
, neq1
, neq2
, cmp1
, cmp2
;
5137 tt_int_op(len
,OP_EQ
, strlen(examples
[i
].b
));
5138 /* We do all of the operations, with operands in both orders. */
5139 eq1
= tor_memeq(examples
[i
].a
, examples
[i
].b
, len
);
5140 eq2
= tor_memeq(examples
[i
].b
, examples
[i
].a
, len
);
5141 neq1
= tor_memneq(examples
[i
].a
, examples
[i
].b
, len
);
5142 neq2
= tor_memneq(examples
[i
].b
, examples
[i
].a
, len
);
5143 cmp1
= tor_memcmp(examples
[i
].a
, examples
[i
].b
, len
);
5144 cmp2
= tor_memcmp(examples
[i
].b
, examples
[i
].a
, len
);
5146 /* Check for correctness of cmp1 */
5147 if (cmp1
< 0 && examples
[i
].want_sign
!= LT
)
5148 TT_DIE(("Assertion failed."));
5149 else if (cmp1
> 0 && examples
[i
].want_sign
!= GT
)
5150 TT_DIE(("Assertion failed."));
5151 else if (cmp1
== 0 && examples
[i
].want_sign
!= EQ
)
5152 TT_DIE(("Assertion failed."));
5154 /* Check for consistency of everything else with cmp1 */
5155 tt_int_op(eq1
,OP_EQ
, eq2
);
5156 tt_int_op(neq1
,OP_EQ
, neq2
);
5157 tt_int_op(cmp1
,OP_EQ
, -cmp2
);
5158 tt_int_op(eq1
,OP_EQ
, cmp1
== 0);
5159 tt_int_op(neq1
,OP_EQ
, !eq1
);
5167 /* exhaustively test tor_memeq and tor_memcmp
5168 * against each possible single-byte numeric difference
5169 * some arithmetic bugs only appear with certain bit patterns */
5170 for (z
= 0; z
< 256; z
++) {
5171 for (i
= 0; i
< 256; i
++) {
5174 tt_int_op(tor_memeq(&zz
, &ii
, 1),OP_EQ
, zz
== ii
);
5175 tt_int_op(tor_memcmp(&zz
, &ii
, 1) > 0 ? GT
: EQ
,OP_EQ
,
5177 tt_int_op(tor_memcmp(&ii
, &zz
, 1) < 0 ? LT
: EQ
,OP_EQ
,
5183 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 0));
5184 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 1));
5185 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 1));
5186 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 2));
5187 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0a", 2));
5188 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0a", 2));
5189 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
5190 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
5191 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
5198 test_util_memcpy_iftrue_timei(void *arg
)
5205 for (int i
= 0; i
< 100; ++i
) {
5206 crypto_rand(buf1
, sizeof(buf1
));
5207 crypto_rand(buf2
, sizeof(buf2
));
5208 memcpy(buf3
, buf1
, sizeof(buf1
));
5210 /* We just copied buf1 into buf3. Now we're going to copy buf2 into buf2,
5211 iff our coin flip comes up heads. */
5212 bool coinflip
= crypto_rand_int(2) == 0;
5214 memcpy_if_true_timei(coinflip
, buf3
, buf2
, sizeof(buf3
));
5217 tt_mem_op(buf3
, OP_EQ
, buf2
, sizeof(buf2
));
5219 tt_mem_op(buf3
, OP_EQ
, buf1
, sizeof(buf1
));
5227 test_util_di_map(void *arg
)
5230 di_digest256_map_t
*dimap
= NULL
;
5231 uint8_t key1
[] = "Robert Anton Wilson ";
5232 uint8_t key2
[] = "Martin Gardner, _Fads&fallacies";
5233 uint8_t key3
[] = "Tom Lehrer, _Be Prepared_. ";
5234 uint8_t key4
[] = "Ursula Le Guin,_A Wizard of... ";
5236 char dflt_entry
[] = "'You have made a good beginning', but no more";
5238 tt_int_op(32, OP_EQ
, sizeof(key1
));
5239 tt_int_op(32, OP_EQ
, sizeof(key2
));
5240 tt_int_op(32, OP_EQ
, sizeof(key3
));
5242 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
5244 char *str1
= tor_strdup("You are precisely as big as what you love"
5245 " and precisely as small as what you allow"
5247 char *str2
= tor_strdup("Let us hope that Lysenko's success in Russia will"
5248 " serve for many generations to come as another"
5249 " reminder to the world of how quickly and easily"
5250 " a science can be corrupted when ignorant"
5251 " political leaders deem themselves competent"
5252 " to arbitrate scientific disputes");
5253 char *str3
= tor_strdup("Don't write naughty words on walls "
5254 "if you can't spell.");
5256 dimap_add_entry(&dimap
, key1
, str1
);
5257 dimap_add_entry(&dimap
, key2
, str2
);
5258 dimap_add_entry(&dimap
, key3
, str3
);
5260 tt_ptr_op(str1
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
5261 tt_ptr_op(str3
, OP_EQ
, dimap_search(dimap
, key3
, dflt_entry
));
5262 tt_ptr_op(str2
, OP_EQ
, dimap_search(dimap
, key2
, dflt_entry
));
5263 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key4
, dflt_entry
));
5266 dimap_free(dimap
, tor_free_
);
5270 * Test counting high bits
5273 test_util_n_bits_set(void *ptr
)
5276 tt_int_op(0,OP_EQ
, n_bits_set_u8(0));
5277 tt_int_op(1,OP_EQ
, n_bits_set_u8(1));
5278 tt_int_op(3,OP_EQ
, n_bits_set_u8(7));
5279 tt_int_op(1,OP_EQ
, n_bits_set_u8(8));
5280 tt_int_op(2,OP_EQ
, n_bits_set_u8(129));
5281 tt_int_op(8,OP_EQ
, n_bits_set_u8(255));
5287 * Test LHS whitespace (and comment) eater
5290 test_util_eat_whitespace(void *ptr
)
5292 const char ws
[] = { ' ', '\t', '\r' }; /* Except NL */
5298 /* Try one leading ws */
5299 strlcpy(str
, "fuubaar", sizeof(str
));
5300 for (i
= 0; i
< sizeof(ws
); ++i
) {
5302 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
5303 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5304 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
5305 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5308 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
5309 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5310 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5311 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5314 strlcpy(str
, "", sizeof(str
));
5315 tt_ptr_op(str
,OP_EQ
, eat_whitespace(str
));
5316 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos(str
, str
));
5317 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5318 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
));
5321 strlcpy(str
, " \t\r\n", sizeof(str
));
5322 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5323 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5324 eat_whitespace_eos(str
, str
+ strlen(str
)));
5325 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
5326 eat_whitespace_no_nl(str
));
5327 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
5328 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5330 strlcpy(str
, " \t\r ", sizeof(str
));
5331 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5332 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5333 eat_whitespace_eos(str
, str
+ strlen(str
)));
5334 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace_no_nl(str
));
5335 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5336 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5339 strlcpy(str
, "fuubaar", sizeof(str
));
5340 for (i
= 0; i
< sizeof(ws
); ++i
)
5342 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace(str
));
5343 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
5344 eat_whitespace_eos(str
, str
+ strlen(str
)));
5345 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace_no_nl(str
));
5346 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
5347 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5350 strlcpy(str
, "# Comment \n No Comment", sizeof(str
));
5351 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
5352 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5353 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5354 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5356 /* Eat comment & ws mix */
5357 strlcpy(str
, " # \t Comment \n\t\nNo Comment", sizeof(str
));
5358 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
5359 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
5360 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
5361 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5363 /* Eat entire comment */
5364 strlcpy(str
, "#Comment", sizeof(str
));
5365 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5366 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5367 eat_whitespace_eos(str
, str
+ strlen(str
)));
5368 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
5369 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5371 /* Blank line, then comment */
5372 strlcpy(str
, " \t\n # Comment", sizeof(str
));
5373 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
5374 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
5375 eat_whitespace_eos(str
, str
+ strlen(str
)));
5376 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_no_nl(str
));
5377 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
5383 /** Return a newly allocated smartlist containing the lines of text in
5384 * <b>lines</b>. The returned strings are heap-allocated, and must be
5385 * freed by the caller.
5387 * XXXX? Move to container.[hc] ? */
5388 static smartlist_t
*
5389 smartlist_new_from_text_lines(const char *lines
)
5391 smartlist_t
*sl
= smartlist_new();
5394 smartlist_split_string(sl
, lines
, "\n", 0, 0);
5396 last_line
= smartlist_pop_last(sl
);
5397 if (last_line
!= NULL
&& *last_line
!= '\0') {
5398 smartlist_add(sl
, last_line
);
5400 tor_free(last_line
);
5406 /** Test smartlist_new_from_text_lines */
5408 test_util_sl_new_from_text_lines(void *ptr
)
5412 { /* Normal usage */
5413 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz\n");
5414 int sl_len
= smartlist_len(sl
);
5416 tt_want_int_op(sl_len
, OP_EQ
, 3);
5418 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5419 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
5420 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
5422 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5426 { /* No final newline */
5427 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz");
5428 int sl_len
= smartlist_len(sl
);
5430 tt_want_int_op(sl_len
, OP_EQ
, 3);
5432 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5433 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
5434 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
5436 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5441 smartlist_t
*sl
= smartlist_new_from_text_lines("foo");
5442 int sl_len
= smartlist_len(sl
);
5444 tt_want_int_op(sl_len
, OP_EQ
, 1);
5446 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
5448 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5452 { /* No text at all */
5453 smartlist_t
*sl
= smartlist_new_from_text_lines("");
5454 int sl_len
= smartlist_len(sl
);
5456 tt_want_int_op(sl_len
, OP_EQ
, 0);
5458 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
5464 test_util_envnames(void *ptr
)
5468 tt_assert(environment_variable_names_equal("abc", "abc"));
5469 tt_assert(environment_variable_names_equal("abc", "abc="));
5470 tt_assert(environment_variable_names_equal("abc", "abc=def"));
5471 tt_assert(environment_variable_names_equal("abc=def", "abc"));
5472 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
5474 tt_assert(environment_variable_names_equal("abc", "abc"));
5475 tt_assert(environment_variable_names_equal("abc", "abc="));
5476 tt_assert(environment_variable_names_equal("abc", "abc=def"));
5477 tt_assert(environment_variable_names_equal("abc=def", "abc"));
5478 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
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=", "abcd"));
5483 tt_assert(!environment_variable_names_equal("abc=", "def"));
5484 tt_assert(!environment_variable_names_equal("abc=", "def="));
5485 tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
5487 tt_assert(!environment_variable_names_equal("", "a=def"));
5488 /* A bit surprising. */
5489 tt_assert(environment_variable_names_equal("", "=def"));
5490 tt_assert(environment_variable_names_equal("=y", "=x"));
5496 /** Test process_environment_make */
5498 test_util_make_environment(void *ptr
)
5500 const char *env_vars_string
=
5501 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5502 "HOME=/home/foozer\n";
5503 const char expected_windows_env_block
[] =
5504 "HOME=/home/foozer\000"
5505 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
5507 size_t expected_windows_env_block_len
=
5508 sizeof(expected_windows_env_block
) - 1;
5510 smartlist_t
*env_vars
= smartlist_new_from_text_lines(env_vars_string
);
5511 smartlist_t
*env_vars_sorted
= smartlist_new();
5512 smartlist_t
*env_vars_in_unixoid_env_block_sorted
= smartlist_new();
5514 process_environment_t
*env
;
5518 env
= process_environment_make(env_vars
);
5520 /* Check that the Windows environment block is correct. */
5521 tt_want(tor_memeq(expected_windows_env_block
, env
->windows_environment_block
,
5522 expected_windows_env_block_len
));
5524 /* Now for the Unixoid environment block. We don't care which order
5525 * these environment variables are in, so we sort both lists first. */
5527 smartlist_add_all(env_vars_sorted
, env_vars
);
5531 for (v
= env
->unixoid_environment_block
; *v
; ++v
) {
5532 smartlist_add(env_vars_in_unixoid_env_block_sorted
, *v
);
5536 smartlist_sort_strings(env_vars_sorted
);
5537 smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted
);
5539 tt_want_int_op(smartlist_len(env_vars_sorted
), OP_EQ
,
5540 smartlist_len(env_vars_in_unixoid_env_block_sorted
));
5542 int len
= smartlist_len(env_vars_sorted
);
5545 if (smartlist_len(env_vars_in_unixoid_env_block_sorted
) < len
) {
5546 len
= smartlist_len(env_vars_in_unixoid_env_block_sorted
);
5549 for (i
= 0; i
< len
; ++i
) {
5550 tt_want_str_op(smartlist_get(env_vars_sorted
, i
), OP_EQ
,
5551 smartlist_get(env_vars_in_unixoid_env_block_sorted
, i
));
5556 smartlist_free(env_vars_in_unixoid_env_block_sorted
);
5557 smartlist_free(env_vars_sorted
);
5559 SMARTLIST_FOREACH(env_vars
, char *, x
, tor_free(x
));
5560 smartlist_free(env_vars
);
5562 process_environment_free(env
);
5565 /** Test set_environment_variable_in_smartlist */
5567 test_util_set_env_var_in_sl(void *ptr
)
5569 /* The environment variables in these strings are in arbitrary
5570 * order; we sort the resulting lists before comparing them.
5572 * (They *will not* end up in the order shown in
5573 * expected_resulting_env_vars_string.) */
5575 const char *base_env_vars_string
=
5576 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5577 "HOME=/home/foozer\n"
5586 const char *new_env_vars_string
=
5591 const char *expected_resulting_env_vars_string
=
5592 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
5593 "HOME=/home/foozer\n"
5603 smartlist_t
*merged_env_vars
=
5604 smartlist_new_from_text_lines(base_env_vars_string
);
5605 smartlist_t
*new_env_vars
=
5606 smartlist_new_from_text_lines(new_env_vars_string
);
5607 smartlist_t
*expected_resulting_env_vars
=
5608 smartlist_new_from_text_lines(expected_resulting_env_vars_string
);
5610 /* Elements of merged_env_vars are heap-allocated, and must be
5611 * freed. Some of them are (or should) be freed by
5612 * set_environment_variable_in_smartlist.
5614 * Elements of new_env_vars are heap-allocated, but are copied into
5615 * merged_env_vars, so they are not freed separately at the end of
5618 * Elements of expected_resulting_env_vars are heap-allocated, and
5623 SMARTLIST_FOREACH(new_env_vars
, char *, env_var
,
5624 set_environment_variable_in_smartlist(merged_env_vars
,
5629 smartlist_sort_strings(merged_env_vars
);
5630 smartlist_sort_strings(expected_resulting_env_vars
);
5632 tt_want_int_op(smartlist_len(merged_env_vars
), OP_EQ
,
5633 smartlist_len(expected_resulting_env_vars
));
5635 int len
= smartlist_len(merged_env_vars
);
5638 if (smartlist_len(expected_resulting_env_vars
) < len
) {
5639 len
= smartlist_len(expected_resulting_env_vars
);
5642 for (i
= 0; i
< len
; ++i
) {
5643 tt_want_str_op(smartlist_get(merged_env_vars
, i
), OP_EQ
,
5644 smartlist_get(expected_resulting_env_vars
, i
));
5649 SMARTLIST_FOREACH(merged_env_vars
, char *, x
, tor_free(x
));
5650 smartlist_free(merged_env_vars
);
5652 smartlist_free(new_env_vars
);
5654 SMARTLIST_FOREACH(expected_resulting_env_vars
, char *, x
, tor_free(x
));
5655 smartlist_free(expected_resulting_env_vars
);
5659 test_util_weak_random(void *arg
)
5665 tor_init_weak_random(&rng
, (unsigned)time(NULL
));
5667 for (i
= 1; i
<= 256; ++i
) {
5668 for (j
=0;j
<100;++j
) {
5669 int r
= tor_weak_random_range(&rng
, i
);
5670 tt_int_op(0, OP_LE
, r
);
5671 tt_int_op(r
, OP_LT
, i
);
5675 memset(n
,0,sizeof(n
));
5676 for (j
=0;j
<8192;++j
) {
5677 n
[tor_weak_random_range(&rng
, 16)]++;
5681 tt_int_op(n
[i
], OP_GT
, 0);
5687 test_util_mathlog(void *arg
)
5692 d
= tor_mathlog(2.718281828);
5693 tt_double_op(fabs(d
- 1.0), OP_LT
, .000001);
5694 d
= tor_mathlog(10);
5695 tt_double_op(fabs(d
- 2.30258509), OP_LT
, .000001);
5701 test_util_fraction(void *arg
)
5707 simplify_fraction64(&a
,&b
);
5708 tt_u64_op(a
, OP_EQ
, 33);
5709 tt_u64_op(b
, OP_EQ
, 10);
5711 a
= 3000000; b
= 10000000;
5712 simplify_fraction64(&a
,&b
);
5713 tt_u64_op(a
, OP_EQ
, 3);
5714 tt_u64_op(b
, OP_EQ
, 10);
5717 simplify_fraction64(&a
,&b
);
5718 tt_u64_op(a
, OP_EQ
, 0);
5719 tt_u64_op(b
, OP_EQ
, 1);
5726 test_util_round_to_next_multiple_of(void *arg
)
5730 tt_u64_op(round_uint64_to_next_multiple_of(0,1), OP_EQ
, 0);
5731 tt_u64_op(round_uint64_to_next_multiple_of(0,7), OP_EQ
, 0);
5733 tt_u64_op(round_uint64_to_next_multiple_of(99,1), OP_EQ
, 99);
5734 tt_u64_op(round_uint64_to_next_multiple_of(99,7), OP_EQ
, 105);
5735 tt_u64_op(round_uint64_to_next_multiple_of(99,9), OP_EQ
, 99);
5737 tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX
,2), OP_EQ
,
5740 tt_int_op(round_uint32_to_next_multiple_of(0,1), OP_EQ
, 0);
5741 tt_int_op(round_uint32_to_next_multiple_of(0,7), OP_EQ
, 0);
5743 tt_int_op(round_uint32_to_next_multiple_of(99,1), OP_EQ
, 99);
5744 tt_int_op(round_uint32_to_next_multiple_of(99,7), OP_EQ
, 105);
5745 tt_int_op(round_uint32_to_next_multiple_of(99,9), OP_EQ
, 99);
5747 tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX
,2), OP_EQ
,
5750 tt_uint_op(round_to_next_multiple_of(0,1), OP_EQ
, 0);
5751 tt_uint_op(round_to_next_multiple_of(0,7), OP_EQ
, 0);
5753 tt_uint_op(round_to_next_multiple_of(99,1), OP_EQ
, 99);
5754 tt_uint_op(round_to_next_multiple_of(99,7), OP_EQ
, 105);
5755 tt_uint_op(round_to_next_multiple_of(99,9), OP_EQ
, 99);
5757 tt_uint_op(round_to_next_multiple_of(UINT_MAX
,2), OP_EQ
,
5764 test_util_laplace(void *arg
)
5766 /* Sample values produced using Python's SciPy:
5768 * >>> from scipy.stats import laplace
5769 * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
5770 ... loc = 24, scale = 24)
5771 * array([ nan, -inf, -69.88855213, 24. ,
5772 * 24.48486498, 117.88855213, inf, nan])
5774 const double mu
= 24.0, b
= 24.0;
5775 const double delta_f
= 15.0, epsilon
= 0.3; /* b = 15.0 / 0.3 = 50.0 */
5778 tt_i64_op(INT64_MIN
, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.0));
5779 tt_i64_op(-69, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.01));
5780 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.5));
5781 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.51));
5782 tt_i64_op(117, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.99));
5784 /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
5785 * ... loc = 0, scale = 50)
5786 * array([ -inf, -80.47189562, -34.65735903, 0. ,
5787 * 34.65735903, 80.47189562, 195.60115027])
5789 tt_i64_op(INT64_MIN
+ 20, OP_EQ
,
5790 add_laplace_noise(20, 0.0, delta_f
, epsilon
));
5792 tt_i64_op(-60, OP_EQ
, add_laplace_noise(20, 0.1, delta_f
, epsilon
));
5793 tt_i64_op(-14, OP_EQ
, add_laplace_noise(20, 0.25, delta_f
, epsilon
));
5794 tt_i64_op(20, OP_EQ
, add_laplace_noise(20, 0.5, delta_f
, epsilon
));
5795 tt_i64_op(54, OP_EQ
, add_laplace_noise(20, 0.75, delta_f
, epsilon
));
5796 tt_i64_op(100, OP_EQ
, add_laplace_noise(20, 0.9, delta_f
, epsilon
));
5797 tt_i64_op(215, OP_EQ
, add_laplace_noise(20, 0.99, delta_f
, epsilon
));
5799 /* Test extreme values of signal with maximally negative values of noise
5800 * 1.0000000000000002 is the smallest number > 1
5801 * 0.0000000000000002 is the double epsilon (error when calculating near 1)
5802 * this is approximately 1/(2^52)
5803 * per https://en.wikipedia.org/wiki/Double_precision
5804 * (let's not descend into the world of subnormals)
5805 * >>> laplace.ppf([0, 0.0000000000000002], loc = 0, scale = 1)
5806 * array([ -inf, -35.45506713])
5808 const double noscale_df
= 1.0, noscale_eps
= 1.0;
5810 tt_i64_op(INT64_MIN
, OP_EQ
,
5811 add_laplace_noise(0, 0.0, noscale_df
, noscale_eps
));
5813 /* is it clipped to INT64_MIN? */
5814 tt_i64_op(INT64_MIN
, OP_EQ
,
5815 add_laplace_noise(-1, 0.0, noscale_df
, noscale_eps
));
5816 tt_i64_op(INT64_MIN
, OP_EQ
,
5817 add_laplace_noise(INT64_MIN
, 0.0,
5818 noscale_df
, noscale_eps
));
5819 /* ... even when scaled? */
5820 tt_i64_op(INT64_MIN
, OP_EQ
,
5821 add_laplace_noise(0, 0.0, delta_f
, epsilon
));
5822 tt_i64_op(INT64_MIN
, OP_EQ
,
5823 add_laplace_noise(0, 0.0,
5825 tt_i64_op(INT64_MIN
, OP_EQ
,
5826 add_laplace_noise(INT64_MIN
, 0.0,
5829 /* does it play nice with INT64_MAX? */
5830 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5831 add_laplace_noise(INT64_MAX
, 0.0,
5832 noscale_df
, noscale_eps
));
5834 /* do near-zero fractional values work? */
5835 const double min_dbl_error
= 0.0000000000000002;
5837 tt_i64_op(-35, OP_EQ
,
5838 add_laplace_noise(0, min_dbl_error
,
5839 noscale_df
, noscale_eps
));
5840 tt_i64_op(INT64_MIN
, OP_EQ
,
5841 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5842 noscale_df
, noscale_eps
));
5843 tt_i64_op((-35 + INT64_MAX
), OP_EQ
,
5844 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5845 noscale_df
, noscale_eps
));
5846 tt_i64_op(INT64_MIN
, OP_EQ
,
5847 add_laplace_noise(0, min_dbl_error
,
5849 tt_i64_op((INT64_MAX
+ INT64_MIN
), OP_EQ
,
5850 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5852 tt_i64_op(INT64_MIN
, OP_EQ
,
5853 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5856 /* does it play nice with INT64_MAX? */
5857 tt_i64_op((INT64_MAX
- 35), OP_EQ
,
5858 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5859 noscale_df
, noscale_eps
));
5861 /* Test extreme values of signal with maximally positive values of noise
5862 * 1.0000000000000002 is the smallest number > 1
5863 * 0.9999999999999998 is the greatest number < 1 by calculation
5864 * per https://en.wikipedia.org/wiki/Double_precision
5865 * >>> laplace.ppf([1.0, 0.9999999999999998], loc = 0, scale = 1)
5866 * array([inf, 35.35050621])
5867 * but the function rejects p == 1.0, so we just use max_dbl_lt_one
5869 const double max_dbl_lt_one
= 0.9999999999999998;
5871 /* do near-one fractional values work? */
5872 tt_i64_op(35, OP_EQ
,
5873 add_laplace_noise(0, max_dbl_lt_one
, noscale_df
, noscale_eps
));
5875 /* is it clipped to INT64_MAX? */
5876 tt_i64_op(INT64_MAX
, OP_EQ
,
5877 add_laplace_noise(INT64_MAX
- 35, max_dbl_lt_one
,
5878 noscale_df
, noscale_eps
));
5879 tt_i64_op(INT64_MAX
, OP_EQ
,
5880 add_laplace_noise(INT64_MAX
- 34, max_dbl_lt_one
,
5881 noscale_df
, noscale_eps
));
5882 tt_i64_op(INT64_MAX
, OP_EQ
,
5883 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5884 noscale_df
, noscale_eps
));
5885 /* ... even when scaled? */
5886 tt_i64_op(INT64_MAX
, OP_EQ
,
5887 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5889 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5890 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5892 tt_i64_op(INT64_MAX
, OP_EQ
,
5893 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5895 /* does it play nice with INT64_MIN? */
5896 tt_i64_op((INT64_MIN
+ 35), OP_EQ
,
5897 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5898 noscale_df
, noscale_eps
));
5905 test_util_clamp_double_to_int64(void *arg
)
5909 tt_i64_op(INT64_MIN
, OP_EQ
, clamp_double_to_int64(-INFINITY_DBL
));
5910 tt_i64_op(INT64_MIN
, OP_EQ
,
5911 clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0));
5912 tt_i64_op(INT64_MIN
, OP_EQ
,
5913 clamp_double_to_int64(-1.0 * pow(2.0, 63.0) - 1.0));
5914 tt_i64_op(((uint64_t) -1) << 53, OP_EQ
,
5915 clamp_double_to_int64(-1.0 * pow(2.0, 53.0)));
5916 tt_i64_op((((uint64_t) -1) << 53) + 1, OP_EQ
,
5917 clamp_double_to_int64(-1.0 * pow(2.0, 53.0) + 1.0));
5918 tt_i64_op(-1, OP_EQ
, clamp_double_to_int64(-1.0));
5919 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.9));
5920 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.1));
5921 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.0));
5922 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(NAN_DBL
));
5923 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.1));
5924 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.9));
5925 tt_i64_op(1, OP_EQ
, clamp_double_to_int64(1.0));
5926 tt_i64_op((((int64_t) 1) << 53) - 1, OP_EQ
,
5927 clamp_double_to_int64(pow(2.0, 53.0) - 1.0));
5928 tt_i64_op(((int64_t) 1) << 53, OP_EQ
,
5929 clamp_double_to_int64(pow(2.0, 53.0)));
5930 tt_i64_op(INT64_MAX
, OP_EQ
,
5931 clamp_double_to_int64(pow(2.0, 63.0)));
5932 tt_i64_op(INT64_MAX
, OP_EQ
,
5933 clamp_double_to_int64(pow(2.0, 64.0)));
5934 tt_i64_op(INT64_MAX
, OP_EQ
, clamp_double_to_int64(INFINITY_DBL
));
5941 #define CAN_CHECK_CLOEXEC
5943 fd_is_cloexec(tor_socket_t fd
)
5945 int flags
= fcntl(fd
, F_GETFD
, 0);
5946 return (flags
& FD_CLOEXEC
) != 0;
5948 #endif /* defined(FD_CLOEXEC) */
5951 #define CAN_CHECK_NONBLOCK
5953 fd_is_nonblocking(tor_socket_t fd
)
5955 int flags
= fcntl(fd
, F_GETFL
, 0);
5956 return (flags
& O_NONBLOCK
) != 0;
5958 #endif /* !defined(_WIN32) */
5960 #define ERRNO_IS_EPROTO(e) (e == SOCK_ERRNO(EPROTONOSUPPORT))
5961 #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s))
5963 /* Test for tor_open_socket*, using IPv4 or IPv6 depending on arg. */
5965 test_util_socket(void *arg
)
5967 const int domain
= !strcmp(arg
, "4") ? AF_INET
: AF_INET6
;
5968 tor_socket_t fd1
= TOR_INVALID_SOCKET
;
5969 tor_socket_t fd2
= TOR_INVALID_SOCKET
;
5970 tor_socket_t fd3
= TOR_INVALID_SOCKET
;
5971 tor_socket_t fd4
= TOR_INVALID_SOCKET
;
5972 int n
= get_n_open_sockets();
5974 TT_BLATHER(("Starting with %d open sockets.", n
));
5978 fd1
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 0);
5979 int err
= tor_socket_errno(fd1
);
5980 if (fd1
< 0 && (err
== SOCK_ERRNO(EPROTONOSUPPORT
) ||
5981 err
== SOCK_ERRNO(EAFNOSUPPORT
))) {
5982 /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */
5985 fd2
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 1);
5986 tt_assert(SOCKET_OK(fd1
));
5987 tt_assert(SOCKET_OK(fd2
));
5988 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5989 //fd3 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 0);
5990 //fd4 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 1);
5991 fd3
= tor_open_socket(domain
, SOCK_STREAM
, 0);
5992 fd4
= tor_open_socket_nonblocking(domain
, SOCK_STREAM
, 0);
5993 tt_assert(SOCKET_OK(fd3
));
5994 tt_assert(SOCKET_OK(fd4
));
5995 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 4);
5997 #ifdef CAN_CHECK_CLOEXEC
5998 tt_int_op(fd_is_cloexec(fd1
), OP_EQ
, 0);
5999 tt_int_op(fd_is_cloexec(fd2
), OP_EQ
, 0);
6000 tt_int_op(fd_is_cloexec(fd3
), OP_EQ
, 1);
6001 tt_int_op(fd_is_cloexec(fd4
), OP_EQ
, 1);
6002 #endif /* defined(CAN_CHECK_CLOEXEC) */
6003 #ifdef CAN_CHECK_NONBLOCK
6004 tt_int_op(fd_is_nonblocking(fd1
), OP_EQ
, 0);
6005 tt_int_op(fd_is_nonblocking(fd2
), OP_EQ
, 1);
6006 tt_int_op(fd_is_nonblocking(fd3
), OP_EQ
, 0);
6007 tt_int_op(fd_is_nonblocking(fd4
), OP_EQ
, 1);
6008 #endif /* defined(CAN_CHECK_NONBLOCK) */
6010 tor_assert(tor_close_socket
== tor_close_socket__real
);
6012 /* we use close_socket__real here so that coverity can tell that we are
6013 * really closing these sockets. */
6014 tor_close_socket__real(fd1
);
6015 tor_close_socket__real(fd2
);
6016 fd1
= fd2
= TOR_INVALID_SOCKET
;
6017 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
6018 tor_close_socket__real(fd3
);
6019 tor_close_socket__real(fd4
);
6020 fd3
= fd4
= TOR_INVALID_SOCKET
;
6021 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
6025 tor_close_socket__real(fd1
);
6027 tor_close_socket__real(fd2
);
6029 tor_close_socket__real(fd3
);
6031 tor_close_socket__real(fd4
);
6036 is_there_a_localhost(int family
)
6039 s
= tor_open_socket(family
, SOCK_STREAM
, IPPROTO_TCP
);
6040 tor_assert(SOCKET_OK(s
));
6043 if (family
== AF_INET
) {
6044 struct sockaddr_in s_in
;
6045 memset(&s_in
, 0, sizeof(s_in
));
6046 s_in
.sin_family
= AF_INET
;
6047 s_in
.sin_addr
.s_addr
= htonl(0x7f000001);
6050 if (bind(s
, (void*)&s_in
, sizeof(s_in
)) == 0) {
6053 } else if (family
== AF_INET6
) {
6054 struct sockaddr_in6 sin6
;
6055 memset(&sin6
, 0, sizeof(sin6
));
6056 sin6
.sin6_family
= AF_INET6
;
6057 sin6
.sin6_addr
.s6_addr
[15] = 1;
6060 tor_close_socket(s
);
6066 /* Test for socketpair and ersatz_socketpair(). We test them both, since
6067 * the latter is a tolerably good way to exercise tor_accept_socket(). */
6069 test_util_socketpair(void *arg
)
6071 const int ersatz
= !strcmp(arg
, "1");
6072 int (*const tor_socketpair_fn
)(int, int, int, tor_socket_t
[2]) =
6073 ersatz
? tor_ersatz_socketpair
: tor_socketpair
;
6074 int n
= get_n_open_sockets();
6075 tor_socket_t fds
[2] = {TOR_INVALID_SOCKET
, TOR_INVALID_SOCKET
};
6076 const int family
= AF_UNIX
;
6077 int socketpair_result
= 0;
6079 socketpair_result
= tor_socketpair_fn(family
, SOCK_STREAM
, 0, fds
);
6082 /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
6083 * Otherwise, we risk exposing a socketpair on a routable IP address. (Some
6084 * BSD jails use a routable address for localhost. Fortunately, they have
6085 * the real AF_UNIX socketpair.) */
6086 if (ersatz
&& socketpair_result
< 0) {
6087 /* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
6088 * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
6091 #endif /* defined(__FreeBSD__) */
6093 if (ersatz
&& socketpair_result
== -ENETUNREACH
) {
6094 /* We can also fail with -ENETUNREACH if we have no network stack at
6098 #endif /* defined(ENETUNREACH) */
6099 tt_int_op(0, OP_EQ
, socketpair_result
);
6101 tt_assert(SOCKET_OK(fds
[0]));
6102 tt_assert(SOCKET_OK(fds
[1]));
6104 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
6106 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
6107 #ifdef CAN_CHECK_CLOEXEC
6108 tt_int_op(fd_is_cloexec(fds
[0]), OP_EQ
, !ersatz
);
6109 tt_int_op(fd_is_cloexec(fds
[1]), OP_EQ
, !ersatz
);
6111 #ifdef CAN_CHECK_NONBLOCK
6112 tt_int_op(fd_is_nonblocking(fds
[0]), OP_EQ
, 0);
6113 tt_int_op(fd_is_nonblocking(fds
[1]), OP_EQ
, 0);
6118 if (SOCKET_OK(fds
[0]))
6119 tor_close_socket_simple(fds
[0]);
6120 if (SOCKET_OK(fds
[1]))
6121 tor_close_socket_simple(fds
[1]);
6123 if (SOCKET_OK(fds
[0]))
6124 tor_close_socket(fds
[0]);
6125 if (SOCKET_OK(fds
[1]))
6126 tor_close_socket(fds
[1]);
6130 #undef SOCKET_EPROTO
6133 test_util_max_mem(void *arg
)
6135 size_t memory1
, memory2
;
6139 r
= get_total_system_memory(&memory1
);
6140 r2
= get_total_system_memory(&memory2
);
6141 tt_int_op(r
, OP_EQ
, r2
);
6142 tt_uint_op(memory2
, OP_EQ
, memory1
);
6144 TT_BLATHER(("System memory: %"TOR_PRIuSZ
, (memory1
)));
6147 /* You have at least a megabyte. */
6148 tt_uint_op(memory1
, OP_GT
, (1<<20));
6150 /* You do not have a petabyte. */
6151 #if SIZEOF_SIZE_T >= 8
6152 tt_u64_op(memory1
, OP_LT
, (UINT64_C(1)<<50));
6161 test_util_dest_validation_edgecase(void *arg
)
6165 tt_assert(!string_is_valid_dest(NULL
));
6166 tt_assert(!string_is_valid_dest(""));
6173 test_util_hostname_validation(void *arg
)
6177 // Lets try valid hostnames first.
6178 tt_assert(string_is_valid_nonrfc_hostname("torproject.org"));
6179 tt_assert(string_is_valid_nonrfc_hostname("ocw.mit.edu"));
6180 tt_assert(string_is_valid_nonrfc_hostname("i.4cdn.org"));
6181 tt_assert(string_is_valid_nonrfc_hostname("stanford.edu"));
6182 tt_assert(string_is_valid_nonrfc_hostname("multiple-words-with-hypens.jp"));
6184 // Subdomain name cannot start with '-' or '_'.
6185 tt_assert(!string_is_valid_nonrfc_hostname("-torproject.org"));
6186 tt_assert(!string_is_valid_nonrfc_hostname("subdomain.-domain.org"));
6187 tt_assert(!string_is_valid_nonrfc_hostname("-subdomain.domain.org"));
6188 tt_assert(!string_is_valid_nonrfc_hostname("___abc.org"));
6190 // Hostnames cannot contain non-alphanumeric characters.
6191 tt_assert(!string_is_valid_nonrfc_hostname("%%domain.\\org."));
6192 tt_assert(!string_is_valid_nonrfc_hostname("***x.net"));
6193 tt_assert(!string_is_valid_nonrfc_hostname("\xff\xffxyz.org"));
6194 tt_assert(!string_is_valid_nonrfc_hostname("word1 word2.net"));
6196 // Test workaround for nytimes.com stupidity, technically invalid,
6197 // but we allow it since they are big, even though they are failing to
6198 // comply with a ~30 year old standard.
6199 tt_assert(string_is_valid_nonrfc_hostname("core3_euw1.fabrik.nytimes.com"));
6201 // Firefox passes FQDNs with trailing '.'s directly to the SOCKS proxy,
6202 // which is redundant since the spec states DOMAINNAME addresses are fully
6203 // qualified. While unusual, this should be tollerated.
6204 tt_assert(string_is_valid_nonrfc_hostname("core9_euw1.fabrik.nytimes.com."));
6205 tt_assert(!string_is_valid_nonrfc_hostname(
6206 "..washingtonpost.is.better.com"));
6207 tt_assert(!string_is_valid_nonrfc_hostname("so.is..ft.com"));
6208 tt_assert(!string_is_valid_nonrfc_hostname("..."));
6210 // XXX: do we allow single-label DNS names?
6211 // We shouldn't for SOCKS (spec says "contains a fully-qualified domain name"
6212 // but only test pathologically malformed trailing '.' cases for now.
6213 tt_assert(!string_is_valid_nonrfc_hostname("."));
6214 tt_assert(!string_is_valid_nonrfc_hostname(".."));
6216 // IP address strings are not hostnames.
6217 tt_assert(!string_is_valid_nonrfc_hostname("8.8.8.8"));
6218 tt_assert(!string_is_valid_nonrfc_hostname("[2a00:1450:401b:800::200e]"));
6219 tt_assert(!string_is_valid_nonrfc_hostname("2a00:1450:401b:800::200e"));
6221 // We allow alphanumeric TLDs. For discussion, see ticket #25055.
6222 tt_assert(string_is_valid_nonrfc_hostname("lucky.13"));
6223 tt_assert(string_is_valid_nonrfc_hostname("luck.y13"));
6224 tt_assert(string_is_valid_nonrfc_hostname("luck.y13."));
6226 // We allow punycode TLDs. For examples, see
6227 // https://data.iana.org/TLD/tlds-alpha-by-domain.txt
6228 tt_assert(string_is_valid_nonrfc_hostname("example.xn--l1acc"));
6235 test_util_ipv4_validation(void *arg
)
6239 tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
6240 tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
6242 tt_assert(!string_is_valid_ipv4_address("abcd"));
6243 tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
6244 tt_assert(!string_is_valid_ipv4_address("8.8."));
6251 test_util_ipv6_validation(void *arg
)
6255 tt_assert(string_is_valid_ipv6_address("2a00:1450:401b:800::200e"));
6256 tt_assert(!string_is_valid_ipv6_address("11:22::33:44:"));
6263 test_util_writepid(void *arg
)
6267 char *contents
= NULL
;
6268 const char *fname
= get_fname("tmp_pid");
6272 write_pidfile(fname
);
6274 contents
= read_file_to_str(fname
, 0, NULL
);
6275 tt_assert(contents
);
6277 int n
= tor_sscanf(contents
, "%lu\n%c", &pid
, &c
);
6278 tt_int_op(n
, OP_EQ
, 1);
6281 tt_uint_op(pid
, OP_EQ
, _getpid());
6283 tt_uint_op(pid
, OP_EQ
, getpid());
6291 test_util_get_avail_disk_space(void *arg
)
6296 /* No answer for nonexistent directory */
6297 val
= tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
6298 tt_i64_op(val
, OP_EQ
, -1);
6300 /* Try the current directory */
6301 val
= tor_get_avail_disk_space(".");
6303 #if !defined(HAVE_STATVFS) && !defined(_WIN32)
6304 tt_i64_op(val
, OP_EQ
, -1); /* You don't have an implementation for this */
6306 tt_i64_op(val
, OP_GT
, 0); /* You have some space. */
6307 tt_i64_op(val
, OP_LT
, ((int64_t)1)<<56); /* You don't have a zebibyte */
6308 #endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */
6314 /** Helper: Change the atime and mtime of a file. */
6316 set_file_mtime(const char *fname
, time_t when
)
6318 struct utimbuf u
= { when
, when
};
6320 tt_int_op(0, OP_EQ
, utime(fname
, &u
));
6321 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
6322 /* Let's hope that utime/stat give the same second as a round-trip? */
6323 tt_i64_op(st
.st_mtime
, OP_EQ
, when
);
6329 test_util_touch_file(void *arg
)
6332 const char *fname
= get_fname("touch");
6334 const time_t now
= time(NULL
);
6336 write_bytes_to_file(fname
, "abc", 3, 1);
6337 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
6338 /* A subtle point: the filesystem time is not necessarily equal to the
6339 * system clock time, since one can be using a monotonic clock, or coarse
6340 * monotonic clock, or whatever. So we might wind up with an mtime a few
6341 * microseconds ago. Let's just give it a lot of wiggle room. */
6342 tt_i64_op(st
.st_mtime
, OP_GE
, now
- 1);
6344 const time_t five_sec_ago
= now
- 5;
6345 set_file_mtime(fname
, five_sec_ago
);
6347 /* Finally we can touch the file */
6348 tt_int_op(0, OP_EQ
, touch_file(fname
));
6349 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
6350 tt_i64_op(st
.st_mtime
, OP_GE
, now
-1);
6356 #ifndef DISABLE_PWDB_TESTS
6358 test_util_pwdb(void *arg
)
6361 const struct passwd
*me
= NULL
, *me2
, *me3
;
6365 /* Uncached case. */
6366 /* Let's assume that we exist. */
6367 me
= tor_getpwuid(getuid());
6368 tt_ptr_op(me
, OP_NE
, NULL
);
6369 name
= tor_strdup(me
->pw_name
);
6372 me2
= tor_getpwnam(name
);
6373 tt_ptr_op(me2
, OP_NE
, NULL
);
6374 tt_int_op(me2
->pw_uid
, OP_EQ
, getuid());
6377 me3
= tor_getpwuid(getuid());
6378 tt_ptr_op(me3
, OP_NE
, NULL
);
6379 tt_str_op(me3
->pw_name
, OP_EQ
, name
);
6381 me3
= tor_getpwnam(name
);
6382 tt_ptr_op(me3
, OP_NE
, NULL
);
6383 tt_int_op(me3
->pw_uid
, OP_EQ
, getuid());
6385 dir
= get_user_homedir(name
);
6386 tt_ptr_op(dir
, OP_NE
, NULL
);
6388 /* Try failing cases. First find a user that doesn't exist by name */
6392 for (i
= 0; i
< 100; ++i
) {
6393 crypto_rand(randbytes
, sizeof(randbytes
));
6394 base16_encode(badname
, sizeof(badname
), randbytes
, sizeof(randbytes
));
6395 if (tor_getpwnam(badname
) == NULL
) {
6403 /* We should do a LOG_ERR */
6404 setup_full_capture_of_logs(LOG_ERR
);
6405 dir
= get_user_homedir(badname
);
6406 tt_ptr_op(dir
, OP_EQ
, NULL
);
6407 expect_log_msg_containing("not found");
6408 tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ
, 1);
6409 teardown_capture_of_logs();
6411 /* Now try to find a user that doesn't exist by ID. */
6413 for (i
= 0; i
< 1000; ++i
) {
6415 crypto_rand((char*)&u
, sizeof(u
));
6416 if (tor_getpwuid(u
) == NULL
) {
6426 teardown_capture_of_logs();
6428 #endif /* !defined(DISABLE_PWDB_TESTS) */
6431 test_util_calloc_check(void *arg
)
6434 /* Easy cases that are good. */
6435 tt_assert(size_mul_check(0,0));
6436 tt_assert(size_mul_check(0,100));
6437 tt_assert(size_mul_check(100,0));
6438 tt_assert(size_mul_check(100,100));
6440 /* Harder cases that are still good. */
6441 tt_assert(size_mul_check(SIZE_MAX
, 1));
6442 tt_assert(size_mul_check(1, SIZE_MAX
));
6443 tt_assert(size_mul_check(SIZE_MAX
/ 10, 9));
6444 tt_assert(size_mul_check(11, SIZE_MAX
/ 12));
6445 const size_t sqrt_size_max_p1
= ((size_t)1) << (sizeof(size_t) * 4);
6446 tt_assert(size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
- 1));
6448 /* Cases that overflow */
6449 tt_assert(! size_mul_check(SIZE_MAX
, 2));
6450 tt_assert(! size_mul_check(2, SIZE_MAX
));
6451 tt_assert(! size_mul_check(SIZE_MAX
/ 10, 11));
6452 tt_assert(! size_mul_check(11, SIZE_MAX
/ 10));
6453 tt_assert(! size_mul_check(SIZE_MAX
/ 8, 9));
6454 tt_assert(! size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
));
6461 test_util_monotonic_time(void *arg
)
6465 monotime_t mt1
, mt2
;
6466 monotime_coarse_t mtc1
, mtc2
;
6467 uint64_t nsec1
, nsec2
, usec1
, msec1
;
6468 uint64_t nsecc1
, nsecc2
, usecc1
, msecc1
;
6469 uint32_t stamp1
, stamp2
;
6474 monotime_coarse_get(&mtc1
);
6475 nsec1
= monotime_absolute_nsec();
6476 usec1
= monotime_absolute_usec();
6477 msec1
= monotime_absolute_msec();
6478 nsecc1
= monotime_coarse_absolute_nsec();
6479 usecc1
= monotime_coarse_absolute_usec();
6480 msecc1
= monotime_coarse_absolute_msec();
6481 stamp1
= monotime_coarse_to_stamp(&mtc1
);
6483 tor_sleep_msec(200);
6486 monotime_coarse_get(&mtc2
);
6487 nsec2
= monotime_absolute_nsec();
6488 nsecc2
= monotime_coarse_absolute_nsec();
6489 stamp2
= monotime_coarse_to_stamp(&mtc2
);
6491 /* We need to be a little careful here since we don't know the system load.
6493 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_GE
, 175);
6494 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_LT
, 1000);
6495 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_GE
, 125);
6496 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_LT
, 1000);
6497 tt_u64_op(nsec2
-nsec1
, OP_GE
, 175000000);
6498 tt_u64_op(nsec2
-nsec1
, OP_LT
, 1000000000);
6499 tt_u64_op(nsecc2
-nsecc1
, OP_GE
, 125000000);
6500 tt_u64_op(nsecc2
-nsecc1
, OP_LT
, 1000000000);
6502 tt_u64_op(msec1
, OP_GE
, nsec1
/ 1000000);
6503 tt_u64_op(usec1
, OP_GE
, nsec1
/ 1000);
6504 tt_u64_op(msecc1
, OP_GE
, nsecc1
/ 1000000);
6505 tt_u64_op(usecc1
, OP_GE
, nsecc1
/ 1000);
6506 tt_u64_op(msec1
, OP_LE
, nsec1
/ 1000000 + 10);
6507 tt_u64_op(usec1
, OP_LE
, nsec1
/ 1000 + 10000);
6508 tt_u64_op(msecc1
, OP_LE
, nsecc1
/ 1000000 + 10);
6509 tt_u64_op(usecc1
, OP_LE
, nsecc1
/ 1000 + 10000);
6511 uint64_t coarse_stamp_diff
=
6512 monotime_coarse_stamp_units_to_approx_msec(stamp2
-stamp1
);
6513 tt_u64_op(coarse_stamp_diff
, OP_GE
, 120);
6514 tt_u64_op(coarse_stamp_diff
, OP_LE
, 1200);
6517 uint64_t units
= monotime_msec_to_approx_coarse_stamp_units(5000);
6518 uint64_t ms
= monotime_coarse_stamp_units_to_approx_msec(units
);
6519 tt_u64_op(ms
, OP_GE
, 4950);
6520 tt_u64_op(ms
, OP_LT
, 5050);
6528 test_util_monotonic_time_ratchet(void *arg
)
6532 monotime_reset_ratchets_for_testing();
6534 /* win32, performance counter ratchet. */
6535 tt_i64_op(100, OP_EQ
, ratchet_performance_counter(100));
6536 tt_i64_op(101, OP_EQ
, ratchet_performance_counter(101));
6537 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(2000));
6538 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(100));
6539 tt_i64_op(2005, OP_EQ
, ratchet_performance_counter(105));
6540 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1105));
6541 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1000));
6542 tt_i64_op(3010, OP_EQ
, ratchet_performance_counter(1005));
6544 /* win32, GetTickCounts32 ratchet-and-rollover-detector. */
6545 const int64_t R
= ((int64_t)1) << 32;
6546 tt_i64_op(5, OP_EQ
, ratchet_coarse_performance_counter(5));
6547 tt_i64_op(1000, OP_EQ
, ratchet_coarse_performance_counter(1000));
6548 tt_i64_op(5+R
, OP_EQ
, ratchet_coarse_performance_counter(5));
6549 tt_i64_op(10+R
, OP_EQ
, ratchet_coarse_performance_counter(10));
6550 tt_i64_op(4+R
*2, OP_EQ
, ratchet_coarse_performance_counter(4));
6552 /* gettimeofday regular ratchet. */
6553 struct timeval tv_in
= {0,0}, tv_out
;
6554 tv_in
.tv_usec
= 9000;
6556 ratchet_timeval(&tv_in
, &tv_out
);
6557 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 9000);
6558 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 0);
6560 tv_in
.tv_sec
= 1337;
6562 ratchet_timeval(&tv_in
, &tv_out
);
6563 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
6564 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6566 tv_in
.tv_sec
= 1336;
6567 tv_in
.tv_usec
= 500000;
6568 ratchet_timeval(&tv_in
, &tv_out
);
6569 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
6570 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6572 tv_in
.tv_sec
= 1337;
6574 ratchet_timeval(&tv_in
, &tv_out
);
6575 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 500000);
6576 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
6578 tv_in
.tv_sec
= 1337;
6579 tv_in
.tv_usec
= 600000;
6580 ratchet_timeval(&tv_in
, &tv_out
);
6581 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
6582 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
6584 tv_in
.tv_sec
= 1000;
6585 tv_in
.tv_usec
= 1000;
6586 ratchet_timeval(&tv_in
, &tv_out
);
6587 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
6588 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
6590 tv_in
.tv_sec
= 2000;
6591 tv_in
.tv_usec
= 2000;
6592 ratchet_timeval(&tv_in
, &tv_out
);
6593 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 101000);
6594 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 2338);
6601 test_util_monotonic_time_zero(void *arg
)
6605 monotime_coarse_t ct1
;
6607 /* Check 1: The current time is not zero. */
6609 monotime_coarse_get(&ct1
);
6610 tt_assert(!monotime_is_zero(&t1
));
6611 tt_assert(!monotime_coarse_is_zero(&ct1
));
6613 /* Check 2: The _zero() makes the time zero. */
6615 monotime_coarse_zero(&ct1
);
6616 tt_assert(monotime_is_zero(&t1
));
6617 tt_assert(monotime_coarse_is_zero(&ct1
));
6623 test_util_monotonic_time_add_msec(void *arg
)
6627 monotime_coarse_t ct1
, ct2
;
6631 monotime_coarse_get(&ct1
);
6633 /* adding zero does nothing */
6634 monotime_add_msec(&t2
, &t1
, 0);
6635 monotime_coarse_add_msec(&ct2
, &ct1
, 0);
6636 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 0);
6637 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 0);
6639 /* Add 1337 msec; see if the diff function agree */
6640 monotime_add_msec(&t2
, &t1
, 1337);
6641 monotime_coarse_add_msec(&ct2
, &ct1
, 1337);
6642 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337);
6643 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337);
6644 // The 32-bit variant must be within 1% of the regular one.
6645 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 1323);
6646 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 1350);
6648 /* Add 1337 msec twice more; make sure that any second rollover issues
6650 monotime_add_msec(&t2
, &t2
, 1337);
6651 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
6652 monotime_add_msec(&t2
, &t2
, 1337);
6653 monotime_coarse_add_msec(&ct2
, &ct2
, 1337);
6654 tt_i64_op(monotime_diff_msec(&t1
, &t2
), OP_EQ
, 1337*3);
6655 tt_i64_op(monotime_coarse_diff_msec(&ct1
, &ct2
), OP_EQ
, 1337*3);
6656 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_GT
, 3970);
6657 tt_int_op(monotime_coarse_diff_msec32_(&ct1
, &ct2
), OP_LT
, 4051);
6664 test_util_nowrap_math(void *arg
)
6668 tt_u64_op(0, OP_EQ
, tor_add_u32_nowrap(0, 0));
6669 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(0, 1));
6670 tt_u64_op(1, OP_EQ
, tor_add_u32_nowrap(1, 0));
6671 tt_u64_op(4, OP_EQ
, tor_add_u32_nowrap(2, 2));
6672 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
-1, 2));
6673 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(2, UINT32_MAX
-1));
6674 tt_u64_op(UINT32_MAX
, OP_EQ
, tor_add_u32_nowrap(UINT32_MAX
, UINT32_MAX
));
6676 tt_u64_op(0, OP_EQ
, tor_mul_u64_nowrap(0, 0));
6677 tt_u64_op(1, OP_EQ
, tor_mul_u64_nowrap(1, 1));
6678 tt_u64_op(2, OP_EQ
, tor_mul_u64_nowrap(2, 1));
6679 tt_u64_op(4, OP_EQ
, tor_mul_u64_nowrap(2, 2));
6680 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_mul_u64_nowrap(UINT64_MAX
, 1));
6681 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_mul_u64_nowrap(2, UINT64_MAX
));
6682 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_mul_u64_nowrap(UINT64_MAX
, UINT64_MAX
));
6689 test_util_htonll(void *arg
)
6692 #ifdef WORDS_BIGENDIAN
6693 const uint64_t res_be
= 0x8877665544332211;
6695 const uint64_t res_le
= 0x1122334455667788;
6698 tt_u64_op(0, OP_EQ
, tor_htonll(0));
6699 tt_u64_op(0, OP_EQ
, tor_ntohll(0));
6700 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_htonll(UINT64_MAX
));
6701 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_ntohll(UINT64_MAX
));
6703 #ifdef WORDS_BIGENDIAN
6704 tt_u64_op(res_be
, OP_EQ
, tor_htonll(0x8877665544332211));
6705 tt_u64_op(res_be
, OP_EQ
, tor_ntohll(0x8877665544332211));
6707 tt_u64_op(res_le
, OP_EQ
, tor_htonll(0x8877665544332211));
6708 tt_u64_op(res_le
, OP_EQ
, tor_ntohll(0x8877665544332211));
6709 #endif /* defined(WORDS_BIGENDIAN) */
6716 test_util_get_unquoted_path(void *arg
)
6722 r
= get_unquoted_path("\""); // "
6723 tt_ptr_op(r
, OP_EQ
, NULL
);
6726 r
= get_unquoted_path("\"\"\""); // """
6727 tt_ptr_op(r
, OP_EQ
, NULL
);
6730 r
= get_unquoted_path("\\\""); // \"
6731 tt_ptr_op(r
, OP_EQ
, NULL
);
6734 r
= get_unquoted_path("\\\"\\\""); // \"\"
6735 tt_ptr_op(r
, OP_EQ
, NULL
);
6738 r
= get_unquoted_path("A\\B\\C\""); // A\B\C"
6739 tt_ptr_op(r
, OP_EQ
, NULL
);
6742 r
= get_unquoted_path("\"A\\B\\C"); // "A\B\C
6743 tt_ptr_op(r
, OP_EQ
, NULL
);
6746 r
= get_unquoted_path("\"A\\B\"C\""); // "A\B"C"
6747 tt_ptr_op(r
, OP_EQ
, NULL
);
6750 r
= get_unquoted_path("A\\B\"C"); // A\B"C
6751 tt_ptr_op(r
, OP_EQ
, NULL
);
6754 r
= get_unquoted_path("");
6755 tt_str_op(r
, OP_EQ
, "");
6758 r
= get_unquoted_path("\"\""); // ""
6759 tt_str_op(r
, OP_EQ
, "");
6762 r
= get_unquoted_path("A\\B\\C"); // A\B\C
6763 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6766 r
= get_unquoted_path("\"A\\B\\C\""); // "A\B\C"
6767 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
6770 r
= get_unquoted_path("\"\\\""); // "\"
6771 tt_str_op(r
, OP_EQ
, "\\"); // \ /* comment to prevent line continuation */
6774 r
= get_unquoted_path("\"\\\"\""); // "\""
6775 tt_str_op(r
, OP_EQ
, "\""); // "
6778 r
= get_unquoted_path("\"A\\B\\C\\\"\""); // "A\B\C\""
6779 tt_str_op(r
, OP_EQ
, "A\\B\\C\""); // A\B\C"
6782 r
= get_unquoted_path("A\\B\\\"C"); // A\B\"C
6783 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6786 r
= get_unquoted_path("\"A\\B\\\"C\""); // "A\B\"C"
6787 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
6794 test_util_map_anon(void *arg
)
6802 ptr
= tor_mmap_anonymous(sz
, 0, &inherit
);
6803 tt_ptr_op(ptr
, OP_NE
, 0);
6804 tt_int_op(inherit
, OP_EQ
, INHERIT_RES_KEEP
);
6806 tt_int_op(ptr
[0], OP_EQ
, 0);
6807 tt_int_op(ptr
[sz
-2], OP_EQ
, 0);
6808 tt_int_op(ptr
[sz
-1], OP_EQ
, 3);
6810 /* Try again, with a private (non-swappable) mapping. */
6811 tor_munmap_anonymous(ptr
, sz
);
6812 ptr
= tor_mmap_anonymous(sz
, ANONMAP_PRIVATE
, &inherit
);
6813 tt_ptr_op(ptr
, OP_NE
, 0);
6814 tt_int_op(inherit
, OP_EQ
, INHERIT_RES_KEEP
);
6816 tt_int_op(ptr
[0], OP_EQ
, 0);
6817 tt_int_op(ptr
[sz
/2], OP_EQ
, 0);
6818 tt_int_op(ptr
[sz
-1], OP_EQ
, 10);
6820 /* Now let's test a drop-on-fork mapping. */
6821 tor_munmap_anonymous(ptr
, sz
);
6822 ptr
= tor_mmap_anonymous(sz
, ANONMAP_NOINHERIT
, &inherit
);
6823 tt_ptr_op(ptr
, OP_NE
, 0);
6825 tt_int_op(ptr
[0], OP_EQ
, 0);
6826 tt_int_op(ptr
[sz
/2], OP_EQ
, 0);
6827 tt_int_op(ptr
[sz
-1], OP_EQ
, 10);
6830 tor_munmap_anonymous(ptr
, sz
);
6834 test_util_map_anon_nofork(void *arg
)
6838 /* The operating system doesn't support forking. */
6842 #else /* !defined(_WIN32) */
6843 /* We have the right OS support. We're going to try marking the buffer as
6844 * either zero-on-fork or as drop-on-fork, whichever is supported. Then we
6845 * will fork and send a byte back to the parent process. This will either
6846 * crash, or send zero. */
6849 const char TEST_VALUE
= 0xd0;
6851 int pipefd
[2] = {-1, -1};
6854 tor_munmap_anonymous(ptr
, sz
);
6855 ptr
= tor_mmap_anonymous(sz
, ANONMAP_NOINHERIT
, &inherit
);
6856 tt_ptr_op(ptr
, OP_NE
, 0);
6857 memset(ptr
, (uint8_t)TEST_VALUE
, sz
);
6859 tt_int_op(0, OP_EQ
, pipe(pipefd
));
6860 pid_t child
= fork();
6862 /* We're in the child. */
6864 ssize_t r
= write(pipefd
[1], &ptr
[sz
-1], 1); /* This may crash. */
6870 tt_int_op(child
, OP_GT
, 0);
6871 /* In the parent. */
6875 ssize_t r
= read(pipefd
[0], buf
, 1);
6877 if (inherit
== INHERIT_RES_ZERO
) {
6878 // We should be seeing clear-on-fork behavior.
6879 tt_int_op((int)r
, OP_EQ
, 1); // child should send us a byte.
6880 tt_int_op(buf
[0], OP_EQ
, 0); // that byte should be zero.
6881 } else if (inherit
== INHERIT_RES_DROP
) {
6882 // We should be seeing noinherit behavior.
6883 tt_int_op(r
, OP_LE
, 0); // child said nothing; it should have crashed.
6885 // noinherit isn't implemented.
6886 tt_int_op(inherit
, OP_EQ
, INHERIT_RES_KEEP
);
6887 tt_int_op((int)r
, OP_EQ
, 1); // child should send us a byte.
6888 tt_int_op(buf
[0], OP_EQ
, TEST_VALUE
); // that byte should be TEST_VALUE.
6892 waitpid(child
, &ws
, 0);
6894 #ifndef NOINHERIT_CAN_FAIL
6895 /* Only if NOINHERIT_CAN_FAIL should it be possible for us to get
6896 * INHERIT_KEEP behavior in this case. */
6897 tt_int_op(inherit
, OP_NE
, INHERIT_RES_KEEP
);
6899 if (inherit
== INHERIT_RES_KEEP
) {
6900 /* Call this test "skipped", not "passed", since noinherit wasn't
6904 #endif /* !defined(NOINHERIT_CAN_FAIL) */
6907 tor_munmap_anonymous(ptr
, sz
);
6908 if (pipefd
[0] >= 0) {
6911 if (pipefd
[1] >= 0) {
6914 #endif /* defined(_WIN32) */
6918 #define UTIL_LEGACY(name) \
6919 { (#name), test_util_ ## name , 0, NULL, NULL }
6921 #define UTIL_TEST(name, flags) \
6922 { (#name), test_util_ ## name, flags, NULL, NULL }
6924 #define COMPRESS(name, identifier) \
6925 { ("compress/" #name), test_util_compress, 0, &compress_setup, \
6926 (char*)(identifier) }
6928 #define COMPRESS_CONCAT(name, identifier) \
6929 { ("compress_concat/" #name), test_util_decompress_concatenated, 0, \
6931 (char*)(identifier) }
6933 #define COMPRESS_JUNK(name, identifier) \
6934 { ("compress_junk/" #name), test_util_decompress_junk, 0, \
6936 (char*)(identifier) }
6938 #define COMPRESS_DOS(name, identifier) \
6939 { ("compress_dos/" #name), test_util_decompress_dos, 0, \
6941 (char*)(identifier) }
6944 #define UTIL_TEST_WIN_ONLY(n, f) UTIL_TEST(n, (f))
6946 #define UTIL_TEST_WIN_ONLY(n, f) { (#n), NULL, TT_SKIP, NULL, NULL }
6949 #ifdef DISABLE_PWDB_TESTS
6950 #define UTIL_TEST_PWDB(n, f) { (#n), NULL, TT_SKIP, NULL, NULL }
6952 #define UTIL_TEST_PWDB(n, f) UTIL_TEST(n, (f))
6954 #endif /* !defined(COCCI) */
6956 struct testcase_t util_tests
[] = {
6958 UTIL_TEST(parse_http_time
, 0),
6959 UTIL_LEGACY(config_line
),
6960 UTIL_LEGACY(config_line_quotes
),
6961 UTIL_LEGACY(config_line_comment_character
),
6962 UTIL_LEGACY(config_line_escaped_content
),
6963 UTIL_LEGACY(config_line_crlf
),
6964 UTIL_TEST(config_line_partition
, 0),
6965 UTIL_TEST_PWDB(expand_filename
, 0),
6966 UTIL_LEGACY(escape_string_socks
),
6967 UTIL_LEGACY(string_is_key_value
),
6968 UTIL_LEGACY(strmisc
),
6969 UTIL_TEST(parse_integer
, 0),
6971 COMPRESS(zlib
, "deflate"),
6972 COMPRESS(gzip
, "gzip"),
6973 COMPRESS(lzma
, "x-tor-lzma"),
6974 COMPRESS(zstd
, "x-zstd"),
6975 COMPRESS(zstd_nostatic
, "x-zstd:nostatic"),
6976 COMPRESS(none
, "identity"),
6977 COMPRESS_CONCAT(zlib
, "deflate"),
6978 COMPRESS_CONCAT(gzip
, "gzip"),
6979 COMPRESS_CONCAT(lzma
, "x-tor-lzma"),
6980 COMPRESS_CONCAT(zstd
, "x-zstd"),
6981 COMPRESS_CONCAT(zstd_nostatic
, "x-zstd:nostatic"),
6982 COMPRESS_CONCAT(none
, "identity"),
6983 COMPRESS_JUNK(zlib
, "deflate"),
6984 COMPRESS_JUNK(gzip
, "gzip"),
6985 COMPRESS_JUNK(lzma
, "x-tor-lzma"),
6986 COMPRESS_DOS(zlib
, "deflate"),
6987 COMPRESS_DOS(gzip
, "gzip"),
6988 COMPRESS_DOS(lzma
, "x-tor-lzma"),
6989 COMPRESS_DOS(zstd
, "x-zstd"),
6990 COMPRESS_DOS(zstd_nostatic
, "x-zstd:nostatic"),
6991 UTIL_TEST(gzip_compression_bomb
, TT_FORK
),
6992 UTIL_LEGACY(datadir
),
6993 UTIL_LEGACY(memarea
),
6994 UTIL_LEGACY(control_formats
),
6996 UTIL_TEST(sscanf
, TT_FORK
),
6997 UTIL_LEGACY(format_time_interval
),
6998 UTIL_LEGACY(path_is_relative
),
6999 UTIL_LEGACY(strtok
),
7000 UTIL_LEGACY(di_ops
),
7001 UTIL_TEST(memcpy_iftrue_timei
, 0),
7002 UTIL_TEST(di_map
, 0),
7003 UTIL_TEST(round_to_next_multiple_of
, 0),
7004 UTIL_TEST(laplace
, 0),
7005 UTIL_TEST(clamp_double_to_int64
, 0),
7006 UTIL_TEST(find_str_at_start_of_line
, 0),
7007 UTIL_TEST(tor_strreplacechar
, 0),
7008 UTIL_TEST(string_is_C_identifier
, 0),
7009 UTIL_TEST(string_is_utf8
, 0),
7010 UTIL_TEST(asprintf
, 0),
7011 UTIL_TEST(listdir
, 0),
7013 UTIL_TEST(get_glob_opened_files
, 0),
7014 UTIL_TEST(parent_dir
, 0),
7015 UTIL_TEST(ftruncate
, 0),
7016 UTIL_TEST(nowrap_math
, 0),
7017 UTIL_TEST(num_cpus
, 0),
7018 UTIL_TEST_WIN_ONLY(load_win_lib
, 0),
7019 UTIL_TEST(format_hex_number
, 0),
7020 UTIL_TEST(format_dec_number
, 0),
7021 UTIL_TEST(n_bits_set
, 0),
7022 UTIL_TEST(eat_whitespace
, 0),
7023 UTIL_TEST(sl_new_from_text_lines
, 0),
7024 UTIL_TEST(envnames
, 0),
7025 UTIL_TEST(make_environment
, 0),
7026 UTIL_TEST(set_env_var_in_sl
, 0),
7027 UTIL_TEST(read_file_eof_tiny_limit
, 0),
7028 UTIL_TEST(read_file_eof_one_loop_a
, 0),
7029 UTIL_TEST(read_file_eof_one_loop_b
, 0),
7030 UTIL_TEST(read_file_eof_two_loops
, 0),
7031 UTIL_TEST(read_file_eof_two_loops_b
, 0),
7032 UTIL_TEST(read_file_eof_zero_bytes
, 0),
7033 UTIL_TEST(read_file_endlines
, 0),
7034 UTIL_TEST(write_chunks_to_file
, 0),
7035 UTIL_TEST(write_str_if_changed
, 0),
7036 UTIL_TEST(mathlog
, 0),
7037 UTIL_TEST(fraction
, 0),
7038 UTIL_TEST(weak_random
, 0),
7039 { "tor_isinf", test_tor_isinf
, TT_FORK
, NULL
, NULL
},
7040 { "socket_ipv4", test_util_socket
, TT_FORK
, &passthrough_setup
,
7042 { "socket_ipv6", test_util_socket
, TT_FORK
,
7043 &passthrough_setup
, (void*)"6" },
7044 { "socketpair", test_util_socketpair
, TT_FORK
, &passthrough_setup
,
7046 { "socketpair_ersatz", test_util_socketpair
, TT_FORK
,
7047 &passthrough_setup
, (void*)"1" },
7048 UTIL_TEST(max_mem
, 0),
7049 UTIL_TEST(hostname_validation
, 0),
7050 UTIL_TEST(dest_validation_edgecase
, 0),
7051 UTIL_TEST(ipv4_validation
, 0),
7052 UTIL_TEST(ipv6_validation
, 0),
7053 UTIL_TEST(writepid
, 0),
7054 UTIL_TEST(get_avail_disk_space
, 0),
7055 UTIL_TEST(touch_file
, 0),
7056 UTIL_TEST_PWDB(pwdb
, TT_FORK
),
7057 UTIL_TEST(calloc_check
, 0),
7058 UTIL_TEST(monotonic_time
, 0),
7059 UTIL_TEST(monotonic_time_ratchet
, TT_FORK
),
7060 UTIL_TEST(monotonic_time_zero
, 0),
7061 UTIL_TEST(monotonic_time_add_msec
, 0),
7062 UTIL_TEST(timegm_real
, 0),
7063 UTIL_TEST(htonll
, 0),
7064 UTIL_TEST(get_unquoted_path
, 0),
7065 UTIL_TEST(map_anon
, 0),
7066 UTIL_TEST(map_anon_nofork
, 0),