1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2017, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
8 #define COMPAT_TIME_PRIVATE
9 #define CONTROL_PRIVATE
17 #include "util_process.h"
18 #include "log_test_helpers.h"
23 #ifdef HAVE_SYS_UTIME_H
24 #include <sys/utime.h>
36 #define INFINITY_DBL ((double)INFINITY)
37 #define NAN_DBL ((double)NAN)
39 /* XXXX this is a minimal wrapper to make the unit tests compile with the
40 * changed tor_timegm interface. */
42 tor_timegm_wrapper(const struct tm
*tm
)
45 if (tor_timegm(tm
, &t
) < 0)
50 #define tor_timegm tor_timegm_wrapper
53 test_util_read_until_eof_impl(const char *fname
, size_t file_len
,
56 char *fifo_name
= NULL
;
57 char *test_str
= NULL
;
63 fifo_name
= tor_strdup(get_fname(fname
));
64 test_str
= tor_malloc(file_len
);
65 crypto_rand(test_str
, file_len
);
67 r
= write_bytes_to_file(fifo_name
, test_str
, file_len
, 1);
68 tt_int_op(r
, OP_EQ
, 0);
70 fd
= open(fifo_name
, O_RDONLY
|O_BINARY
);
71 tt_int_op(fd
, OP_GE
, 0);
72 str
= read_file_to_str_until_eof(fd
, read_limit
, &sz
);
73 tt_ptr_op(str
, OP_NE
, NULL
);
75 if (read_limit
< file_len
)
76 tt_int_op(sz
, OP_EQ
, read_limit
);
78 tt_int_op(sz
, OP_EQ
, file_len
);
80 tt_mem_op(test_str
, OP_EQ
, str
, sz
);
81 tt_int_op(str
[sz
], OP_EQ
, '\0');
93 test_util_read_file_eof_tiny_limit(void *arg
)
96 // purposely set limit shorter than what we wrote to the FIFO to
97 // test the maximum, and that it puts the NUL in the right spot
99 test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
103 test_util_read_file_eof_one_loop_a(void *arg
)
106 test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
110 test_util_read_file_eof_one_loop_b(void *arg
)
113 test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
117 test_util_read_file_eof_two_loops(void *arg
)
120 // write more than 1024 bytes to the FIFO to test two passes through
121 // the loop in the method; if the re-alloc size is changed this
122 // should be updated as well.
124 test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
128 test_util_read_file_eof_two_loops_b(void *arg
)
132 test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
136 test_util_read_file_eof_zero_bytes(void *arg
)
140 test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
143 /* Test the basic expected behaviour for write_chunks_to_file.
144 * NOTE: This will need to be updated if we ever change the tempfile location
147 test_util_write_chunks_to_file(void *arg
)
150 char *tempname
= NULL
;
155 /* These should be two different sizes to ensure the data is different
156 * between the data file and the temp file's 'known string' */
157 int temp_str_len
= 1024;
158 int data_str_len
= 512;
159 char *data_str
= tor_malloc(data_str_len
);
160 char *temp_str
= tor_malloc(temp_str_len
);
162 smartlist_t
*chunks
= smartlist_new();
163 sized_chunk_t c
= {data_str
, data_str_len
/2};
164 sized_chunk_t c2
= {data_str
+ data_str_len
/2, data_str_len
/2};
167 crypto_rand(temp_str
, temp_str_len
);
168 crypto_rand(data_str
, data_str_len
);
170 // Ensure it can write multiple chunks
172 smartlist_add(chunks
, &c
);
173 smartlist_add(chunks
, &c2
);
176 * Check if it writes using a tempfile
178 fname
= tor_strdup(get_fname("write_chunks_with_tempfile"));
179 tor_asprintf(&tempname
, "%s.tmp", fname
);
181 // write a known string to a file where the tempfile will be
182 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
183 tt_int_op(r
, OP_EQ
, 0);
185 // call write_chunks_to_file
186 r
= write_chunks_to_file(fname
, chunks
, 1, 0);
187 tt_int_op(r
, OP_EQ
, 0);
189 // assert the file has been written (expected size)
190 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
191 tt_assert(str
!= NULL
);
192 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
193 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
196 // assert that the tempfile is removed (should not leave artifacts)
197 str
= read_file_to_str(tempname
, RFTS_BIN
|RFTS_IGNORE_MISSING
, &st
);
198 tt_assert(str
== NULL
);
200 // Remove old testfile for second test
202 tt_int_op(r
, OP_EQ
, 0);
207 * Check if it skips using a tempfile with flags
209 fname
= tor_strdup(get_fname("write_chunks_with_no_tempfile"));
210 tor_asprintf(&tempname
, "%s.tmp", fname
);
212 // write a known string to a file where the tempfile will be
213 r
= write_bytes_to_file(tempname
, temp_str
, temp_str_len
, 1);
214 tt_int_op(r
, OP_EQ
, 0);
216 // call write_chunks_to_file with no_tempfile = true
217 r
= write_chunks_to_file(fname
, chunks
, 1, 1);
218 tt_int_op(r
, OP_EQ
, 0);
220 // assert the file has been written (expected size)
221 str
= read_file_to_str(fname
, RFTS_BIN
, &st
);
222 tt_assert(str
!= NULL
);
223 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, data_str_len
);
224 tt_mem_op(data_str
, OP_EQ
, str
, data_str_len
);
227 // assert the tempfile still contains the known string
228 str
= read_file_to_str(tempname
, RFTS_BIN
, &st
);
229 tt_assert(str
!= NULL
);
230 tt_u64_op((uint64_t)st
.st_size
, OP_EQ
, temp_str_len
);
231 tt_mem_op(temp_str
, OP_EQ
, str
, temp_str_len
);
236 smartlist_free(chunks
);
244 #define _TFE(a, b, f) tt_int_op((a).f, OP_EQ, (b).f)
245 /** test the minimum set of struct tm fields needed for a unique epoch value
246 * this is also the set we use to test tor_timegm */
247 #define TM_EQUAL(a, b) \
249 _TFE(a, b, tm_year); \
250 _TFE(a, b, tm_mon ); \
251 _TFE(a, b, tm_mday); \
252 _TFE(a, b, tm_hour); \
253 _TFE(a, b, tm_min ); \
254 _TFE(a, b, tm_sec ); \
258 test_util_time(void *arg
)
260 struct timeval start
, end
;
261 struct tm a_time
, b_time
;
267 /* Test tv_udiff and tv_mdiff */
271 start
.tv_usec
= 5000;
276 tt_int_op(0L,OP_EQ
, tv_udiff(&start
, &end
));
277 tt_int_op(0L,OP_EQ
, tv_mdiff(&start
, &end
));
278 tt_int_op(0L,OP_EQ
, tv_udiff(&end
, &start
));
279 tt_int_op(0L,OP_EQ
, tv_mdiff(&end
, &start
));
283 tt_int_op(2000L,OP_EQ
, tv_udiff(&start
, &end
));
284 tt_int_op(2L,OP_EQ
, tv_mdiff(&start
, &end
));
285 tt_int_op(-2000L,OP_EQ
, tv_udiff(&end
, &start
));
286 tt_int_op(-2L,OP_EQ
, tv_mdiff(&end
, &start
));
290 tt_int_op(1002000L,OP_EQ
, tv_udiff(&start
, &end
));
291 tt_int_op(1002L,OP_EQ
, tv_mdiff(&start
, &end
));
292 tt_int_op(-1002000L,OP_EQ
, tv_udiff(&end
, &start
));
293 tt_int_op(-1002L,OP_EQ
, tv_mdiff(&end
, &start
));
297 tt_int_op(995000L,OP_EQ
, tv_udiff(&start
, &end
));
298 tt_int_op(995L,OP_EQ
, tv_mdiff(&start
, &end
));
299 tt_int_op(-995000L,OP_EQ
, tv_udiff(&end
, &start
));
300 tt_int_op(-995L,OP_EQ
, tv_mdiff(&end
, &start
));
304 tt_int_op(-1005000L,OP_EQ
, tv_udiff(&start
, &end
));
305 tt_int_op(-1005L,OP_EQ
, tv_mdiff(&start
, &end
));
306 tt_int_op(1005000L,OP_EQ
, tv_udiff(&end
, &start
));
307 tt_int_op(1005L,OP_EQ
, tv_mdiff(&end
, &start
));
309 /* Negative tv_sec values, these will break on platforms where tv_sec is
314 tt_int_op(-15005000L,OP_EQ
, tv_udiff(&start
, &end
));
315 tt_int_op(-15005L,OP_EQ
, tv_mdiff(&start
, &end
));
316 tt_int_op(15005000L,OP_EQ
, tv_udiff(&end
, &start
));
317 tt_int_op(15005L,OP_EQ
, tv_mdiff(&end
, &start
));
321 tt_int_op(89995000L,OP_EQ
, tv_udiff(&start
, &end
));
322 tt_int_op(89995L,OP_EQ
, tv_mdiff(&start
, &end
));
323 tt_int_op(-89995000L,OP_EQ
, tv_udiff(&end
, &start
));
324 tt_int_op(-89995L,OP_EQ
, tv_mdiff(&end
, &start
));
326 /* Test that tv_usec values round away from zero when converted to msec */
332 tt_int_op(10000499L, OP_EQ
, tv_udiff(&start
, &end
));
333 tt_int_op(10000L, OP_EQ
, tv_mdiff(&start
, &end
));
334 tt_int_op(-10000499L, OP_EQ
, tv_udiff(&end
, &start
));
335 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
342 tt_int_op(10000500L, OP_EQ
, tv_udiff(&start
, &end
));
343 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
344 tt_int_op(-10000500L, OP_EQ
, tv_udiff(&end
, &start
));
345 tt_int_op(-10000L, OP_EQ
, tv_mdiff(&end
, &start
));
352 tt_int_op(10000501L, OP_EQ
, tv_udiff(&start
, &end
));
353 tt_int_op(10001L, OP_EQ
, tv_mdiff(&start
, &end
));
354 tt_int_op(-10000501L, OP_EQ
, tv_udiff(&end
, &start
));
355 tt_int_op(-10001L, OP_EQ
, tv_mdiff(&end
, &start
));
357 /* Overflow conditions */
360 /* Would you believe that tv_sec is a long on windows? Of course you would.*/
361 #define TV_SEC_MAX LONG_MAX
362 #define TV_SEC_MIN LONG_MIN
364 /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
365 * Which means TIME_MAX is not actually the maximum value of tv_sec.
366 * But that's ok for the moment, because the code correctly performs 64-bit
367 * calculations internally, then catches the overflow. */
368 #define TV_SEC_MAX TIME_MAX
369 #define TV_SEC_MIN TIME_MIN
370 #endif /* defined(_WIN32) */
372 /* Assume tv_usec is an unsigned integer until proven otherwise */
373 #define TV_USEC_MAX UINT_MAX
374 #define TOR_USEC_PER_SEC 1000000
376 /* Overflows in the result type */
378 /* All comparisons work */
381 end
.tv_sec
= LONG_MAX
/1000 - 2;
384 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
385 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
386 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
387 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
391 end
.tv_sec
= LONG_MAX
/1000000 - 1;
394 tt_int_op(end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&start
, &end
));
395 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
396 tt_int_op(-end
.tv_sec
*1000000L, OP_EQ
, tv_udiff(&end
, &start
));
397 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
399 /* No comparisons work */
402 end
.tv_sec
= LONG_MAX
/1000 + 1;
405 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
406 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
407 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
408 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
412 end
.tv_sec
= LONG_MAX
/1000000 + 1;
415 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
416 tt_int_op(end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
417 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
418 tt_int_op(-end
.tv_sec
*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
422 end
.tv_sec
= LONG_MAX
/1000;
423 end
.tv_usec
= TOR_USEC_PER_SEC
;
425 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
426 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
427 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
428 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
432 end
.tv_sec
= LONG_MAX
/1000000;
433 end
.tv_usec
= TOR_USEC_PER_SEC
;
435 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
436 tt_int_op((end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&start
, &end
));
437 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
438 tt_int_op(-(end
.tv_sec
+ 1)*1000L, OP_EQ
, tv_mdiff(&end
, &start
));
440 /* Overflows on comparison to zero */
445 end
.tv_sec
= TV_SEC_MAX
;
448 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
449 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
450 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
451 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
453 end
.tv_sec
= TV_SEC_MAX
;
454 end
.tv_usec
= TOR_USEC_PER_SEC
;
456 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
457 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
458 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
459 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
462 end
.tv_usec
= TV_USEC_MAX
;
464 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
465 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
466 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
467 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
469 end
.tv_sec
= TV_SEC_MAX
;
470 end
.tv_usec
= TV_USEC_MAX
;
472 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
473 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
474 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
475 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
480 start
.tv_sec
= TV_SEC_MIN
;
483 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
484 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
485 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
486 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
488 start
.tv_sec
= TV_SEC_MIN
;
489 start
.tv_usec
= TOR_USEC_PER_SEC
;
491 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
492 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
493 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
494 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
496 start
.tv_sec
= TV_SEC_MIN
;
497 start
.tv_usec
= TV_USEC_MAX
;
499 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
500 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
501 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
502 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
504 /* overflows on comparison to maxima / minima */
506 start
.tv_sec
= TV_SEC_MIN
;
509 end
.tv_sec
= TV_SEC_MAX
;
512 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
513 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
514 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
515 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
517 end
.tv_sec
= TV_SEC_MAX
;
518 end
.tv_usec
= TOR_USEC_PER_SEC
;
520 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
521 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
522 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
523 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
525 end
.tv_sec
= TV_SEC_MAX
;
528 start
.tv_sec
= TV_SEC_MIN
;
531 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
532 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
533 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
534 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
536 start
.tv_sec
= TV_SEC_MIN
;
537 start
.tv_usec
= TOR_USEC_PER_SEC
;
539 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
540 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
541 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
542 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
544 /* overflows on comparison to maxima / minima with extra usec */
546 start
.tv_sec
= TV_SEC_MIN
;
547 start
.tv_usec
= TOR_USEC_PER_SEC
;
549 end
.tv_sec
= TV_SEC_MAX
;
552 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
553 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
554 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
555 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
557 end
.tv_sec
= TV_SEC_MAX
;
558 end
.tv_usec
= TOR_USEC_PER_SEC
;
560 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
561 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
562 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
563 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
565 end
.tv_sec
= TV_SEC_MAX
;
566 end
.tv_usec
= TOR_USEC_PER_SEC
;
568 start
.tv_sec
= TV_SEC_MIN
;
571 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
572 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
573 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
574 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
576 start
.tv_sec
= TV_SEC_MIN
;
577 start
.tv_usec
= TOR_USEC_PER_SEC
;
579 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&start
, &end
));
580 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&start
, &end
));
581 tt_int_op(LONG_MAX
, OP_EQ
, tv_udiff(&end
, &start
));
582 tt_int_op(LONG_MAX
, OP_EQ
, tv_mdiff(&end
, &start
));
584 /* Test tor_timegm & tor_gmtime_r */
586 /* The test values here are confirmed to be correct on a platform
587 * with a working timegm & gmtime_r. */
589 /* Start with known-zero a_time and b_time.
590 * This avoids passing uninitialised values to TM_EQUAL in a_time.
591 * Zeroing may not be needed for b_time, as long as tor_gmtime_r
592 * never reads the existing values in the structure.
593 * But we really don't want intermittently failing tests. */
594 memset(&a_time
, 0, sizeof(struct tm
));
595 memset(&b_time
, 0, sizeof(struct tm
));
597 a_time
.tm_year
= 2003-1900;
603 t_res
= 1062224095UL;
604 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
605 tor_gmtime_r(&t_res
, &b_time
);
606 TM_EQUAL(a_time
, b_time
);
608 a_time
.tm_year
= 2004-1900; /* Try a leap year, after feb. */
609 t_res
= 1093846495UL;
610 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
611 tor_gmtime_r(&t_res
, &b_time
);
612 TM_EQUAL(a_time
, b_time
);
614 a_time
.tm_mon
= 1; /* Try a leap year, in feb. */
616 t_res
= 1076393695UL;
617 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
618 tor_gmtime_r(&t_res
, &b_time
);
619 TM_EQUAL(a_time
, b_time
);
622 t_res
= 1073715295UL;
623 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
624 tor_gmtime_r(&t_res
, &b_time
);
625 TM_EQUAL(a_time
, b_time
);
627 /* This value is in range with 32 bit and 64 bit time_t */
628 a_time
.tm_year
= 2037-1900;
629 t_res
= 2115180895UL;
630 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
631 tor_gmtime_r(&t_res
, &b_time
);
632 TM_EQUAL(a_time
, b_time
);
634 /* This value is out of range with 32 bit time_t, but in range for 64 bit
636 a_time
.tm_year
= 2039-1900;
637 #if SIZEOF_TIME_T == 4
638 setup_capture_of_logs(LOG_WARN
);
639 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
640 expect_single_log_msg_containing("Result does not fit in tor_timegm");
641 teardown_capture_of_logs();
642 #elif SIZEOF_TIME_T == 8
643 t_res
= 2178252895UL;
644 tt_int_op(t_res
, OP_EQ
, tor_timegm(&a_time
));
645 tor_gmtime_r(&t_res
, &b_time
);
646 TM_EQUAL(a_time
, b_time
);
647 #endif /* SIZEOF_TIME_T == 4 || ... */
649 /* Test tor_timegm out of range */
651 /* The below tests will all cause a BUG message, so we capture, suppress,
653 #define CAPTURE() do { \
654 setup_full_capture_of_logs(LOG_WARN); \
656 #define CHECK_TIMEGM_WARNING(msg) do { \
657 expect_log_msg_containing(msg); \
658 tt_int_op(1, OP_EQ, smartlist_len(mock_saved_logs())); \
659 teardown_capture_of_logs(); \
662 #define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
663 CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
667 /* Wrong year < 1970 */
668 a_time
.tm_year
= 1969-1900;
670 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
671 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
673 a_time
.tm_year
= -1-1900;
675 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
676 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
678 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
679 a_time
.tm_year
= -1*(1 << 16);
681 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
682 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
684 /* one of the smallest tm_year values my 64 bit system supports:
685 * t_res = -9223372036854775LL without clamping */
686 a_time
.tm_year
= -292275055-1900;
688 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
689 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
691 a_time
.tm_year
= INT32_MIN
;
693 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
694 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
695 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
698 a_time
.tm_year
= -1*(1 << 48);
700 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
701 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
703 /* while unlikely, the system's gmtime(_r) could return
704 * a "correct" retrospective gregorian negative year value,
705 * which I'm pretty sure is:
706 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
707 * 730485 is the number of days in two millenia, including leap days */
708 a_time
.tm_year
= -292277022657-1900;
710 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
711 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
713 a_time
.tm_year
= INT64_MIN
;
715 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
716 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
717 #endif /* SIZEOF_INT == 8 */
719 /* Wrong year >= INT32_MAX - 1900 */
720 #if SIZEOF_INT == 4 || SIZEOF_INT == 8
721 a_time
.tm_year
= INT32_MAX
-1900;
723 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
724 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
726 a_time
.tm_year
= INT32_MAX
;
728 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
729 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
730 #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
733 /* one of the largest tm_year values my 64 bit system supports */
734 a_time
.tm_year
= 292278994-1900;
736 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
737 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
739 /* while unlikely, the system's gmtime(_r) could return
740 * a "correct" proleptic gregorian year value,
741 * which I'm pretty sure is:
742 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
743 * 730485 is the number of days in two millenia, including leap days */
744 a_time
.tm_year
= 292277026596-1900;
746 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
747 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
749 a_time
.tm_year
= INT64_MAX
-1900;
751 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
752 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
754 a_time
.tm_year
= INT64_MAX
;
756 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
757 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
758 #endif /* SIZEOF_INT == 8 */
761 a_time
.tm_year
= 2007-1900; /* restore valid year */
763 a_time
.tm_mon
= 12; /* Wrong month, it's 0-based */
765 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
766 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
768 a_time
.tm_mon
= -1; /* Wrong month */
770 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
771 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
774 a_time
.tm_mon
= 6; /* Try July */
775 a_time
.tm_mday
= 32; /* Wrong day */
777 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
778 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
780 a_time
.tm_mon
= 5; /* Try June */
781 a_time
.tm_mday
= 31; /* Wrong day */
783 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
784 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
786 a_time
.tm_year
= 2008-1900; /* Try a leap year */
787 a_time
.tm_mon
= 1; /* in feb. */
788 a_time
.tm_mday
= 30; /* Wrong day */
790 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
791 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
793 a_time
.tm_year
= 2011-1900; /* Try a non-leap year */
794 a_time
.tm_mon
= 1; /* in feb. */
795 a_time
.tm_mday
= 29; /* Wrong day */
797 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
798 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
800 a_time
.tm_mday
= 0; /* Wrong day, it's 1-based (to be different) */
802 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
803 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
806 a_time
.tm_mday
= 3; /* restore valid month day */
808 a_time
.tm_hour
= 24; /* Wrong hour, it's 0-based */
810 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
811 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
813 a_time
.tm_hour
= -1; /* Wrong hour */
815 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
816 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
819 a_time
.tm_hour
= 22; /* restore valid hour */
821 a_time
.tm_min
= 60; /* Wrong minute, it's 0-based */
823 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
824 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
826 a_time
.tm_min
= -1; /* Wrong minute */
828 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
829 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
832 a_time
.tm_min
= 37; /* restore valid minute */
834 a_time
.tm_sec
= 61; /* Wrong second: 0-based with leap seconds */
836 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
837 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
839 a_time
.tm_sec
= -1; /* Wrong second */
841 tt_int_op((time_t) -1,OP_EQ
, tor_timegm(&a_time
));
842 CHECK_TIMEGM_ARG_OUT_OF_RANGE();
844 /* Test tor_gmtime_r out of range */
846 /* time_t < 0 yields a year clamped to 1 or 1970,
847 * depending on whether the implementation of the system gmtime(_r)
848 * sets struct tm (1) or not (1970) */
850 tor_gmtime_r(&t_res
, &b_time
);
851 tt_assert(b_time
.tm_year
== (1970-1900) ||
852 b_time
.tm_year
== (1969-1900));
854 if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
855 t_res
= -1*(1 << 30);
856 tor_gmtime_r(&t_res
, &b_time
);
857 tt_assert(b_time
.tm_year
== (1970-1900) ||
858 b_time
.tm_year
== (1935-1900));
861 tor_gmtime_r(&t_res
, &b_time
);
862 tt_assert(b_time
.tm_year
== (1970-1900) ||
863 b_time
.tm_year
== (1901-1900));
866 #if SIZEOF_TIME_T == 8
868 /* one of the smallest tm_year values my 64 bit system supports:
869 * b_time.tm_year == (-292275055LL-1900LL) without clamping */
870 t_res
= -9223372036854775LL;
871 tor_gmtime_r(&t_res
, &b_time
);
872 tt_assert(b_time
.tm_year
== (1970-1900) ||
873 b_time
.tm_year
== (1-1900));
875 /* while unlikely, the system's gmtime(_r) could return
876 * a "correct" retrospective gregorian negative year value,
877 * which I'm pretty sure is:
878 * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
879 * 730485 is the number of days in two millenia, including leap days
880 * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
883 tor_gmtime_r(&t_res
, &b_time
);
884 if (! (b_time
.tm_year
== (1970-1900) ||
885 b_time
.tm_year
== (1-1900))) {
886 tt_int_op(b_time
.tm_year
, OP_EQ
, 1970-1900);
888 if (b_time
.tm_year
!= 1970-1900) {
889 CHECK_TIMEGM_WARNING("Rounding up to ");
891 teardown_capture_of_logs();
894 #endif /* SIZEOF_TIME_T == 8 */
896 /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
897 * depending on whether the implementation of the system gmtime(_r)
898 * sets struct tm (9999) or not (2037) */
899 #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
902 tor_gmtime_r(&t_res
, &b_time
);
903 tt_assert(b_time
.tm_year
== (2021-1900));
906 tor_gmtime_r(&t_res
, &b_time
);
907 tt_assert(b_time
.tm_year
== (2037-1900) ||
908 b_time
.tm_year
== (2038-1900));
910 #endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
912 #if SIZEOF_TIME_T == 8
914 /* one of the largest tm_year values my 64 bit system supports:
915 * b_time.tm_year == (292278994L-1900L) without clamping */
916 t_res
= 9223372036854775LL;
917 tor_gmtime_r(&t_res
, &b_time
);
918 tt_assert(b_time
.tm_year
== (2037-1900) ||
919 b_time
.tm_year
== (9999-1900));
921 /* while unlikely, the system's gmtime(_r) could return
922 * a "correct" proleptic gregorian year value,
923 * which I'm pretty sure is:
924 * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
925 * 730485 is the number of days in two millenia, including leap days
926 * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
929 tor_gmtime_r(&t_res
, &b_time
);
930 CHECK_TIMEGM_WARNING("Rounding down to ");
932 tt_assert(b_time
.tm_year
== (2037-1900) ||
933 b_time
.tm_year
== (9999-1900));
935 #endif /* SIZEOF_TIME_T == 8 */
937 /* Test {format,parse}_rfc1123_time */
939 format_rfc1123_time(timestr
, 0);
940 tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ
, timestr
);
941 format_rfc1123_time(timestr
, (time_t)1091580502UL);
942 tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ
, timestr
);
945 i
= parse_rfc1123_time(timestr
, &t_res
);
946 tt_int_op(0,OP_EQ
, i
);
947 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
949 /* This value is in range with 32 bit and 64 bit time_t */
950 format_rfc1123_time(timestr
, (time_t)2080000000UL);
951 tt_str_op("Fri, 30 Nov 2035 01:46:40 GMT",OP_EQ
, timestr
);
954 i
= parse_rfc1123_time(timestr
, &t_res
);
955 tt_int_op(0,OP_EQ
, i
);
956 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
958 /* This value is out of range with 32 bit time_t, but in range for 64 bit
960 format_rfc1123_time(timestr
, (time_t)2150000000UL);
961 #if SIZEOF_TIME_T == 4
963 /* Wrapping around will have made it this. */
964 /* On windows, at least, this is clipped to 1 Jan 1970. ??? */
965 tt_str_op("Sat, 11 Jan 1902 23:45:04 GMT",OP_EQ
, timestr
);
967 /* Make sure that the right date doesn't parse. */
968 strlcpy(timestr
, "Wed, 17 Feb 2038 06:13:20 GMT", sizeof(timestr
));
972 i
= parse_rfc1123_time(timestr
, &t_res
);
973 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
974 tt_int_op(-1,OP_EQ
, i
);
975 #elif SIZEOF_TIME_T == 8
976 tt_str_op("Wed, 17 Feb 2038 06:13:20 GMT",OP_EQ
, timestr
);
979 i
= parse_rfc1123_time(timestr
, &t_res
);
980 tt_int_op(0,OP_EQ
, i
);
981 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
982 #endif /* SIZEOF_TIME_T == 4 || ... */
984 /* The timezone doesn't matter */
987 parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res
));
988 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
990 parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res
));
992 parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res
));
994 parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res
));
996 parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res
));
998 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res
));
1000 parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res
));
1002 parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res
));
1004 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res
));
1006 parse_rfc1123_time("Wed, 30 Mar 1900 23:59:59 GMT", &t_res
));
1010 parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res
));
1012 parse_rfc1123_time("Wed, 29 Feb 2012 16:00:00 GMT", &t_res
));
1014 /* Leap second plus one */
1016 parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res
));
1018 /* Test parse_iso_time */
1021 i
= parse_iso_time("", &t_res
);
1022 tt_int_op(-1,OP_EQ
, i
);
1024 i
= parse_iso_time("2004-08-32 00:48:22", &t_res
);
1025 tt_int_op(-1,OP_EQ
, i
);
1027 i
= parse_iso_time("1969-08-03 00:48:22", &t_res
);
1028 tt_int_op(-1,OP_EQ
, i
);
1031 i
= parse_iso_time("2004-08-04 00:48:22", &t_res
);
1032 tt_int_op(0,OP_EQ
, i
);
1033 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1035 i
= parse_iso_time("2004-8-4 0:48:22", &t_res
);
1036 tt_int_op(0,OP_EQ
, i
);
1037 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1039 /* This value is in range with 32 bit and 64 bit time_t */
1041 i
= parse_iso_time("2035-11-30 01:46:40", &t_res
);
1042 tt_int_op(0,OP_EQ
, i
);
1043 tt_int_op(t_res
,OP_EQ
, (time_t)2080000000UL);
1045 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1048 i
= parse_iso_time("2038-02-17 06:13:20", &t_res
);
1049 #if SIZEOF_TIME_T == 4
1051 tt_int_op(-1,OP_EQ
, i
);
1052 CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
1053 #elif SIZEOF_TIME_T == 8
1054 tt_int_op(0,OP_EQ
, i
);
1055 tt_int_op(t_res
,OP_EQ
, (time_t)2150000000UL);
1056 #endif /* SIZEOF_TIME_T == 4 || ... */
1058 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-zz 99-99x99", &t_res
));
1059 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-32 00:00:00", &t_res
));
1060 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 24:00:00", &t_res
));
1061 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:60:00", &t_res
));
1062 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59:62", &t_res
));
1063 tt_int_op(-1,OP_EQ
, parse_iso_time("1969-03-30 23:59:59", &t_res
));
1064 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-00-30 23:59:59", &t_res
));
1065 tt_int_op(-1,OP_EQ
, parse_iso_time("2147483647-08-29 14:00:00", &t_res
));
1066 tt_int_op(-1,OP_EQ
, parse_iso_time("2011-03-30 23:59", &t_res
));
1067 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22.100", &t_res
));
1068 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res
));
1070 /* but... that _is_ acceptable if we aren't being strict. */
1072 i
= parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res
, 0, 0);
1073 tt_int_op(0,OP_EQ
, i
);
1074 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1076 /* try nospace variant. */
1078 i
= parse_iso_time_nospace("2004-08-04T00:48:22", &t_res
);
1079 tt_int_op(0,OP_EQ
, i
);
1080 tt_int_op(t_res
,OP_EQ
, (time_t)1091580502UL);
1082 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04T00:48:22", &t_res
));
1083 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res
));
1084 tt_int_op(-1,OP_EQ
, parse_iso_time("2004-08-04x00:48:22", &t_res
));
1085 tt_int_op(-1,OP_EQ
, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res
));
1087 /* Test tor_gettimeofday */
1090 end
.tv_usec
= 999990;
1092 start
.tv_usec
= 500;
1094 tor_gettimeofday(&start
);
1095 /* now make sure time works. */
1096 tor_gettimeofday(&end
);
1097 /* We might've timewarped a little. */
1098 tt_int_op(tv_udiff(&start
, &end
), OP_GE
, -5000);
1100 /* Test format_iso_time */
1102 tv
.tv_sec
= (time_t)1326296338UL;
1104 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1105 tt_str_op("2012-01-11 15:38:58",OP_EQ
, timestr
);
1106 /* The output of format_local_iso_time will vary by timezone, and setting
1107 our timezone for testing purposes would be a nontrivial flaky pain.
1108 Skip this test for now.
1109 format_local_iso_time(timestr, tv.tv_sec);
1110 test_streq("2012-01-11 10:38:58", timestr);
1112 format_iso_time_nospace(timestr
, (time_t)tv
.tv_sec
);
1113 tt_str_op("2012-01-11T15:38:58",OP_EQ
, timestr
);
1114 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_LEN
);
1115 format_iso_time_nospace_usec(timestr
, &tv
);
1116 tt_str_op("2012-01-11T15:38:58.003060",OP_EQ
, timestr
);
1117 tt_int_op(strlen(timestr
),OP_EQ
, ISO_TIME_USEC_LEN
);
1120 /* This value is in range with 32 bit and 64 bit time_t */
1121 tv
.tv_sec
= (time_t)2080000000UL;
1122 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1123 tt_str_op("2035-11-30 01:46:40",OP_EQ
, timestr
);
1125 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1127 tv
.tv_sec
= (time_t)2150000000UL;
1128 format_iso_time(timestr
, (time_t)tv
.tv_sec
);
1129 #if SIZEOF_TIME_T == 4
1130 /* format_iso_time should indicate failure on overflow, but it doesn't yet.
1131 * Hopefully #18480 will improve the failure semantics in this case.
1132 tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
1134 #elif SIZEOF_TIME_T == 8
1136 /* This SHOULD work on windows too; see bug #18665 */
1137 tt_str_op("2038-02-17 06:13:20",OP_EQ
, timestr
);
1139 #endif /* SIZEOF_TIME_T == 4 || ... */
1142 #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
1145 teardown_capture_of_logs();
1149 test_util_parse_http_time(void *arg
)
1152 char b
[ISO_TIME_LEN
+1];
1156 format_iso_time(b, tor_timegm(&a_time)); \
1157 tt_str_op(b, OP_EQ, (s)); \
1161 /* Test parse_http_time */
1164 parse_http_time("", &a_time
));
1166 parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time
));
1168 parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time
));
1170 parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time
));
1172 parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time
));
1174 parse_http_time("Sunday, August the third", &a_time
));
1176 parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time
));
1179 parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time
));
1180 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1181 T("1994-08-04 00:48:22");
1183 parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time
));
1184 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1185 T("1994-08-04 00:48:22");
1187 parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time
));
1188 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1189 T("1994-08-04 00:48:22");
1191 parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time
));
1192 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1193 T("1994-08-04 00:48:22");
1195 parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time
));
1196 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1197 T("1994-08-04 00:48:22");
1199 parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time
));
1200 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1201 T("1994-08-04 00:48:22");
1202 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time
));
1203 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1204 T("1994-08-04 00:48:22");
1205 tt_int_op(0,OP_EQ
, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time
));
1206 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1207 T("1994-08-04 00:48:22");
1208 tt_int_op(0,OP_EQ
, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time
));
1209 tt_int_op((time_t)775961302UL,OP_EQ
, tor_timegm(&a_time
));
1210 T("1994-08-04 00:48:22");
1211 tt_int_op(0,OP_EQ
,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time
));
1212 tt_int_op((time_t)1325376000UL,OP_EQ
, tor_timegm(&a_time
));
1213 T("2012-01-01 00:00:00");
1214 tt_int_op(0,OP_EQ
,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time
));
1215 tt_int_op((time_t)1356912000UL,OP_EQ
, tor_timegm(&a_time
));
1216 T("2012-12-31 00:00:00");
1218 /* This value is in range with 32 bit and 64 bit time_t */
1219 tt_int_op(0,OP_EQ
,parse_http_time("Fri, 30 Nov 2035 01:46:40 GMT", &a_time
));
1220 tt_int_op((time_t)2080000000UL,OP_EQ
, tor_timegm(&a_time
));
1221 T("2035-11-30 01:46:40");
1223 /* This value is out of range with 32 bit time_t, but in range for 64 bit
1225 #if SIZEOF_TIME_T == 4
1226 /* parse_http_time should indicate failure on overflow, but it doesn't yet.
1227 * Hopefully #18480 will improve the failure semantics in this case. */
1228 setup_capture_of_logs(LOG_WARN
);
1229 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1230 tt_int_op((time_t)-1,OP_EQ
, tor_timegm(&a_time
));
1231 expect_single_log_msg_containing("does not fit in tor_timegm");
1232 teardown_capture_of_logs();
1233 #elif SIZEOF_TIME_T == 8
1234 tt_int_op(0,OP_EQ
,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time
));
1235 tt_int_op((time_t)2150000000UL,OP_EQ
, tor_timegm(&a_time
));
1236 T("2038-02-17 06:13:20");
1237 #endif /* SIZEOF_TIME_T == 4 || ... */
1239 tt_int_op(-1,OP_EQ
, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time
));
1240 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-32 00:00:00 GMT", &a_time
));
1241 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 24:00:00 GMT", &a_time
));
1242 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:60:00 GMT", &a_time
));
1243 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59:62 GMT", &a_time
));
1244 tt_int_op(-1,OP_EQ
, parse_http_time("1969-03-30 23:59:59 GMT", &a_time
));
1245 tt_int_op(-1,OP_EQ
, parse_http_time("2011-00-30 23:59:59 GMT", &a_time
));
1246 tt_int_op(-1,OP_EQ
, parse_http_time("2011-03-30 23:59", &a_time
));
1250 teardown_capture_of_logs();
1254 test_util_config_line(void *arg
)
1257 char *k
=NULL
, *v
=NULL
;
1260 /* Test parse_config_line_from_str */
1262 strlcpy(buf
, "k v\n" " key value with spaces \n" "keykey val\n"
1264 "k3 \n" "\n" " \n" "#comment\n"
1265 "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
1266 "kseven \"a quoted 'string\"\n"
1267 "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
1268 "k9 a line that\\\n spans two lines.\n\n"
1269 "k10 more than\\\n one contin\\\nuation\n"
1270 "k11 \\\ncontinuation at the start\n"
1271 "k12 line with a\\\n#comment\n embedded\n"
1272 "k13\\\ncontinuation at the very start\n"
1273 "k14 a line that has a comment and # ends with a slash \\\n"
1274 "k15 this should be the next new line\n"
1275 "k16 a line that has a comment and # ends without a slash \n"
1276 "k17 this should be the next new line\n"
1280 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1281 tt_str_op(k
,OP_EQ
, "k");
1282 tt_str_op(v
,OP_EQ
, "v");
1283 tor_free(k
); tor_free(v
);
1284 tt_assert(!strcmpstart(str
, "key value with"));
1286 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1287 tt_str_op(k
,OP_EQ
, "key");
1288 tt_str_op(v
,OP_EQ
, "value with spaces");
1289 tor_free(k
); tor_free(v
);
1290 tt_assert(!strcmpstart(str
, "keykey"));
1292 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1293 tt_str_op(k
,OP_EQ
, "keykey");
1294 tt_str_op(v
,OP_EQ
, "val");
1295 tor_free(k
); tor_free(v
);
1296 tt_assert(!strcmpstart(str
, "k2\n"));
1298 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1299 tt_str_op(k
,OP_EQ
, "k2");
1300 tt_str_op(v
,OP_EQ
, "");
1301 tor_free(k
); tor_free(v
);
1302 tt_assert(!strcmpstart(str
, "k3 \n"));
1304 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1305 tt_str_op(k
,OP_EQ
, "k3");
1306 tt_str_op(v
,OP_EQ
, "");
1307 tor_free(k
); tor_free(v
);
1308 tt_assert(!strcmpstart(str
, "#comment"));
1310 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1311 tt_str_op(k
,OP_EQ
, "k4");
1312 tt_str_op(v
,OP_EQ
, "");
1313 tor_free(k
); tor_free(v
);
1314 tt_assert(!strcmpstart(str
, "k5#abc"));
1316 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1317 tt_str_op(k
,OP_EQ
, "k5");
1318 tt_str_op(v
,OP_EQ
, "");
1319 tor_free(k
); tor_free(v
);
1320 tt_assert(!strcmpstart(str
, "k6"));
1322 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1323 tt_str_op(k
,OP_EQ
, "k6");
1324 tt_str_op(v
,OP_EQ
, "val");
1325 tor_free(k
); tor_free(v
);
1326 tt_assert(!strcmpstart(str
, "kseven"));
1328 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1329 tt_str_op(k
,OP_EQ
, "kseven");
1330 tt_str_op(v
,OP_EQ
, "a quoted \'string");
1331 tor_free(k
); tor_free(v
);
1332 tt_assert(!strcmpstart(str
, "k8 "));
1334 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1335 tt_str_op(k
,OP_EQ
, "k8");
1336 tt_str_op(v
,OP_EQ
, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
1337 tor_free(k
); tor_free(v
);
1339 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1340 tt_str_op(k
,OP_EQ
, "k9");
1341 tt_str_op(v
,OP_EQ
, "a line that spans two lines.");
1342 tor_free(k
); tor_free(v
);
1344 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1345 tt_str_op(k
,OP_EQ
, "k10");
1346 tt_str_op(v
,OP_EQ
, "more than one continuation");
1347 tor_free(k
); tor_free(v
);
1349 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1350 tt_str_op(k
,OP_EQ
, "k11");
1351 tt_str_op(v
,OP_EQ
, "continuation at the start");
1352 tor_free(k
); tor_free(v
);
1354 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1355 tt_str_op(k
,OP_EQ
, "k12");
1356 tt_str_op(v
,OP_EQ
, "line with a embedded");
1357 tor_free(k
); tor_free(v
);
1359 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1360 tt_str_op(k
,OP_EQ
, "k13");
1361 tt_str_op(v
,OP_EQ
, "continuation at the very start");
1362 tor_free(k
); tor_free(v
);
1364 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1365 tt_str_op(k
,OP_EQ
, "k14");
1366 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1367 tor_free(k
); tor_free(v
);
1369 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1370 tt_str_op(k
,OP_EQ
, "k15");
1371 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1372 tor_free(k
); tor_free(v
);
1374 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1375 tt_str_op(k
,OP_EQ
, "k16");
1376 tt_str_op(v
,OP_EQ
, "a line that has a comment and" );
1377 tor_free(k
); tor_free(v
);
1379 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1380 tt_str_op(k
,OP_EQ
, "k17");
1381 tt_str_op(v
,OP_EQ
, "this should be the next new line");
1382 tor_free(k
); tor_free(v
);
1384 tt_str_op(str
,OP_EQ
, "");
1392 test_util_config_line_quotes(void *arg
)
1398 char *k
=NULL
, *v
=NULL
;
1401 /* Test parse_config_line_from_str */
1403 strlcpy(buf1
, "kTrailingSpace \"quoted value\" \n"
1404 "kTrailingGarbage \"quoted value\"trailing garbage\n"
1406 strlcpy(buf2
, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
1408 strlcpy(buf3
, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
1410 strlcpy(buf4
, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
1414 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1415 tt_str_op(k
,OP_EQ
, "kTrailingSpace");
1416 tt_str_op(v
,OP_EQ
, "quoted value");
1417 tor_free(k
); tor_free(v
);
1419 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1420 tt_ptr_op(str
,OP_EQ
, NULL
);
1421 tor_free(k
); tor_free(v
);
1425 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1426 tt_ptr_op(str
,OP_EQ
, NULL
);
1427 tor_free(k
); tor_free(v
);
1431 const char *err
= NULL
;
1432 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1433 tt_ptr_op(str
,OP_EQ
, NULL
);
1434 tor_free(k
); tor_free(v
);
1435 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1440 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1441 tt_ptr_op(str
,OP_EQ
, NULL
);
1442 tor_free(k
); tor_free(v
);
1443 tt_str_op(err
, OP_EQ
, "Invalid escape sequence in quoted string");
1451 test_util_config_line_comment_character(void *arg
)
1454 char *k
=NULL
, *v
=NULL
;
1457 /* Test parse_config_line_from_str */
1459 strlcpy(buf
, "k1 \"# in quotes\"\n"
1460 "k2 some value # some comment\n"
1461 "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
1465 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1466 tt_str_op(k
,OP_EQ
, "k1");
1467 tt_str_op(v
,OP_EQ
, "# in quotes");
1468 tor_free(k
); tor_free(v
);
1470 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1471 tt_str_op(k
,OP_EQ
, "k2");
1472 tt_str_op(v
,OP_EQ
, "some value");
1473 tor_free(k
); tor_free(v
);
1475 tt_str_op(str
,OP_EQ
, "k3 /home/user/myTorNetwork#2\n");
1478 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1479 test_streq(k
, "k3");
1480 test_streq(v
, "/home/user/myTorNetwork#2");
1481 tor_free(k
); tor_free(v
);
1483 test_streq(str
, "");
1492 test_util_config_line_escaped_content(void *arg
)
1500 char *k
=NULL
, *v
=NULL
;
1503 /* Test parse_config_line_from_str */
1505 strlcpy(buf1
, "HexadecimalLower \"\\x2a\"\n"
1506 "HexadecimalUpper \"\\x2A\"\n"
1507 "HexadecimalUpperX \"\\X2A\"\n"
1511 "CarriageReturn \"\\r\"\n"
1512 "DoubleQuote \"\\\"\"\n"
1513 "SimpleQuote \"\\'\"\n"
1514 "Backslash \"\\\\\"\n"
1515 "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
1518 strlcpy(buf2
, "BrokenEscapedContent \"\\a\"\n"
1521 strlcpy(buf3
, "BrokenEscapedContent \"\\x\"\n"
1524 strlcpy(buf4
, "BrokenOctal \"\\8\"\n"
1527 strlcpy(buf5
, "BrokenHex \"\\xg4\"\n"
1530 strlcpy(buf6
, "BrokenEscape \"\\"
1535 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1536 tt_str_op(k
,OP_EQ
, "HexadecimalLower");
1537 tt_str_op(v
,OP_EQ
, "*");
1538 tor_free(k
); tor_free(v
);
1540 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1541 tt_str_op(k
,OP_EQ
, "HexadecimalUpper");
1542 tt_str_op(v
,OP_EQ
, "*");
1543 tor_free(k
); tor_free(v
);
1545 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1546 tt_str_op(k
,OP_EQ
, "HexadecimalUpperX");
1547 tt_str_op(v
,OP_EQ
, "*");
1548 tor_free(k
); tor_free(v
);
1550 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1551 tt_str_op(k
,OP_EQ
, "Octal");
1552 tt_str_op(v
,OP_EQ
, "*");
1553 tor_free(k
); tor_free(v
);
1555 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1556 tt_str_op(k
,OP_EQ
, "Newline");
1557 tt_str_op(v
,OP_EQ
, "\n");
1558 tor_free(k
); tor_free(v
);
1560 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1561 tt_str_op(k
,OP_EQ
, "Tab");
1562 tt_str_op(v
,OP_EQ
, "\t");
1563 tor_free(k
); tor_free(v
);
1565 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1566 tt_str_op(k
,OP_EQ
, "CarriageReturn");
1567 tt_str_op(v
,OP_EQ
, "\r");
1568 tor_free(k
); tor_free(v
);
1570 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1571 tt_str_op(k
,OP_EQ
, "DoubleQuote");
1572 tt_str_op(v
,OP_EQ
, "\"");
1573 tor_free(k
); tor_free(v
);
1575 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1576 tt_str_op(k
,OP_EQ
, "SimpleQuote");
1577 tt_str_op(v
,OP_EQ
, "'");
1578 tor_free(k
); tor_free(v
);
1580 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1581 tt_str_op(k
,OP_EQ
, "Backslash");
1582 tt_str_op(v
,OP_EQ
, "\\");
1583 tor_free(k
); tor_free(v
);
1585 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1586 tt_str_op(k
,OP_EQ
, "Mix");
1587 tt_str_op(v
,OP_EQ
, "This is a \"star\":\t'*'\nAnd second line");
1588 tor_free(k
); tor_free(v
);
1589 tt_str_op(str
,OP_EQ
, "");
1593 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1594 tt_ptr_op(str
,OP_EQ
, NULL
);
1595 tor_free(k
); tor_free(v
);
1599 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1600 tt_ptr_op(str
,OP_EQ
, NULL
);
1601 tor_free(k
); tor_free(v
);
1605 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1606 tt_ptr_op(str
,OP_EQ
, NULL
);
1607 tor_free(k
); tor_free(v
);
1612 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1613 tt_ptr_op(str
, OP_EQ
, NULL
);
1614 tor_free(k
); tor_free(v
);
1619 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1620 tt_ptr_op(str
,OP_EQ
, NULL
);
1621 tor_free(k
); tor_free(v
);
1623 /* more things to try. */
1625 strlcpy(buf1
, "Foo \"\\x9g\"\n", sizeof(buf1
));
1626 strlcpy(buf2
, "Foo \"\\xg0\"\n", sizeof(buf2
));
1627 strlcpy(buf3
, "Foo \"\\xf\"\n", sizeof(buf3
));
1629 strlcpy(buf4
, "Foo \"\\q\"\n", sizeof(buf4
));
1630 /* missing endquote */
1631 strlcpy(buf5
, "Foo \"hello\n", sizeof(buf5
));
1633 strlcpy(buf6
, "Foo \"hello\" world\n", sizeof(buf6
));
1636 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1637 tt_ptr_op(str
,OP_EQ
, NULL
);
1638 tor_free(k
); tor_free(v
);
1641 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1642 tt_ptr_op(str
,OP_EQ
, NULL
);
1643 tor_free(k
); tor_free(v
);
1646 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1647 tt_ptr_op(str
,OP_EQ
, NULL
);
1648 tor_free(k
); tor_free(v
);
1651 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1652 tt_ptr_op(str
,OP_EQ
, NULL
);
1653 tor_free(k
); tor_free(v
);
1657 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, NULL
);
1658 tt_ptr_op(str
,OP_EQ
, NULL
);
1659 tor_free(k
); tor_free(v
);
1662 const char *err
= NULL
;
1663 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1664 tt_ptr_op(str
,OP_EQ
, NULL
);
1665 tor_free(k
); tor_free(v
);
1666 tt_str_op(err
,OP_EQ
, "Excess data after quoted string");
1674 test_util_config_line_crlf(void *arg
)
1676 char *k
=NULL
, *v
=NULL
;
1677 const char *err
= NULL
;
1681 "Hello \"nice big world\"\r\n";
1683 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1685 tt_str_op(k
,OP_EQ
,"Hello");
1686 tt_str_op(v
,OP_EQ
,"world");
1687 tt_ptr_op(err
, OP_EQ
, NULL
);
1688 tor_free(k
); tor_free(v
);
1690 str
= parse_config_line_from_str_verbose(str
, &k
, &v
, &err
);
1692 tt_str_op(k
,OP_EQ
,"Hello");
1693 tt_str_op(v
,OP_EQ
,"nice big world");
1694 tt_ptr_op(err
, OP_EQ
, NULL
);
1695 tor_free(k
); tor_free(v
);
1696 tt_str_op(str
,OP_EQ
, "");
1699 tor_free(k
); tor_free(v
);
1704 test_util_expand_filename(void *arg
)
1709 setenv("HOME", "/home/itv", 1); /* For "internal test value" */
1711 str
= expand_filename("");
1712 tt_str_op("",OP_EQ
, str
);
1715 str
= expand_filename("/normal/path");
1716 tt_str_op("/normal/path",OP_EQ
, str
);
1719 str
= expand_filename("/normal/trailing/path/");
1720 tt_str_op("/normal/trailing/path/",OP_EQ
, str
);
1723 str
= expand_filename("~");
1724 tt_str_op("/home/itv/",OP_EQ
, str
);
1727 str
= expand_filename("$HOME/nodice");
1728 tt_str_op("$HOME/nodice",OP_EQ
, str
);
1731 str
= expand_filename("~/");
1732 tt_str_op("/home/itv/",OP_EQ
, str
);
1735 str
= expand_filename("~/foobarqux");
1736 tt_str_op("/home/itv/foobarqux",OP_EQ
, str
);
1739 str
= expand_filename("~/../../etc/passwd");
1740 tt_str_op("/home/itv/../../etc/passwd",OP_EQ
, str
);
1743 str
= expand_filename("~/trailing/");
1744 tt_str_op("/home/itv/trailing/",OP_EQ
, str
);
1746 /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
1747 have to somehow inject/fake the get_user_homedir call) */
1749 /* $HOME ending in a trailing slash */
1750 setenv("HOME", "/home/itv/", 1);
1752 str
= expand_filename("~");
1753 tt_str_op("/home/itv/",OP_EQ
, str
);
1756 str
= expand_filename("~/");
1757 tt_str_op("/home/itv/",OP_EQ
, str
);
1760 str
= expand_filename("~/foo");
1761 tt_str_op("/home/itv/foo",OP_EQ
, str
);
1764 /* Try with empty $HOME */
1766 setenv("HOME", "", 1);
1768 str
= expand_filename("~");
1769 tt_str_op("/",OP_EQ
, str
);
1772 str
= expand_filename("~/");
1773 tt_str_op("/",OP_EQ
, str
);
1776 str
= expand_filename("~/foobar");
1777 tt_str_op("/foobar",OP_EQ
, str
);
1780 /* Try with $HOME unset */
1784 str
= expand_filename("~");
1785 tt_str_op("/",OP_EQ
, str
);
1788 str
= expand_filename("~/");
1789 tt_str_op("/",OP_EQ
, str
);
1792 str
= expand_filename("~/foobar");
1793 tt_str_op("/foobar",OP_EQ
, str
);
1799 #endif /* !defined(_WIN32) */
1801 /** Test tor_escape_str_for_pt_args(). */
1803 test_util_escape_string_socks(void *arg
)
1805 char *escaped_string
= NULL
;
1807 /** Simple backslash escape. */
1809 escaped_string
= tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
1810 tt_assert(escaped_string
);
1811 tt_str_op(escaped_string
,OP_EQ
, "This is a backslash: \\\\");
1812 tor_free(escaped_string
);
1814 /** Simple semicolon escape. */
1815 escaped_string
= tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
1816 tt_assert(escaped_string
);
1817 tt_str_op(escaped_string
,OP_EQ
, "First rule:Do not use \\;");
1818 tor_free(escaped_string
);
1820 /** Empty string. */
1821 escaped_string
= tor_escape_str_for_pt_args("", ";\\");
1822 tt_assert(escaped_string
);
1823 tt_str_op(escaped_string
,OP_EQ
, "");
1824 tor_free(escaped_string
);
1826 /** Escape all characters. */
1827 escaped_string
= tor_escape_str_for_pt_args(";\\;\\", ";\\");
1828 tt_assert(escaped_string
);
1829 tt_str_op(escaped_string
,OP_EQ
, "\\;\\\\\\;\\\\");
1830 tor_free(escaped_string
);
1832 escaped_string
= tor_escape_str_for_pt_args(";", ";\\");
1833 tt_assert(escaped_string
);
1834 tt_str_op(escaped_string
,OP_EQ
, "\\;");
1835 tor_free(escaped_string
);
1838 tor_free(escaped_string
);
1842 test_util_string_is_key_value(void *ptr
)
1845 tt_assert(string_is_key_value(LOG_WARN
, "key=value"));
1846 tt_assert(string_is_key_value(LOG_WARN
, "k=v"));
1847 tt_assert(string_is_key_value(LOG_WARN
, "key="));
1848 tt_assert(string_is_key_value(LOG_WARN
, "x="));
1849 tt_assert(string_is_key_value(LOG_WARN
, "xx="));
1850 tt_assert(!string_is_key_value(LOG_WARN
, "=value"));
1851 tt_assert(!string_is_key_value(LOG_WARN
, "=x"));
1852 tt_assert(!string_is_key_value(LOG_WARN
, "="));
1855 /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
1860 /** Test basic string functionality. */
1862 test_util_strmisc(void *arg
)
1865 char *cp_tmp
= NULL
;
1867 /* Test strl operations */
1869 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 0));
1870 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 10));
1871 tt_str_op(buf
,OP_EQ
, "Hello");
1872 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 6));
1873 tt_str_op(buf
,OP_EQ
, "Hello");
1874 tt_int_op(5,OP_EQ
, strlcpy(buf
, "Hello", 5));
1875 tt_str_op(buf
,OP_EQ
, "Hell");
1876 strlcpy(buf
, "Hello", sizeof(buf
));
1877 tt_int_op(10,OP_EQ
, strlcat(buf
, "Hello", 5));
1879 /* Test strstrip() */
1880 strlcpy(buf
, "Testing 1 2 3", sizeof(buf
));
1881 tor_strstrip(buf
, ",!");
1882 tt_str_op(buf
,OP_EQ
, "Testing 1 2 3");
1883 strlcpy(buf
, "!Testing 1 2 3?", sizeof(buf
));
1884 tor_strstrip(buf
, "!? ");
1885 tt_str_op(buf
,OP_EQ
, "Testing123");
1886 strlcpy(buf
, "!!!Testing 1 2 3??", sizeof(buf
));
1887 tor_strstrip(buf
, "!? ");
1888 tt_str_op(buf
,OP_EQ
, "Testing123");
1891 /* Returning -1 when there's not enough room in the output buffer */
1892 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 0, "Foo"));
1893 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 2, "Foo"));
1894 tt_int_op(-1,OP_EQ
, tor_snprintf(buf
, 3, "Foo"));
1895 tt_int_op(-1,OP_NE
, tor_snprintf(buf
, 4, "Foo"));
1896 /* Always NUL-terminate the output */
1897 tor_snprintf(buf
, 5, "abcdef");
1898 tt_int_op(0,OP_EQ
, buf
[4]);
1899 tor_snprintf(buf
, 10, "abcdef");
1900 tt_int_op(0,OP_EQ
, buf
[6]);
1902 tor_snprintf(buf
, sizeof(buf
), "x!"U64_FORMAT
"!x",
1903 U64_PRINTF_ARG(U64_LITERAL(12345678901)));
1904 tt_str_op("x!12345678901!x",OP_EQ
, buf
);
1906 /* Test str{,case}cmpstart */
1907 tt_assert(strcmpstart("abcdef", "abcdef")==0);
1908 tt_assert(strcmpstart("abcdef", "abc")==0);
1909 tt_assert(strcmpstart("abcdef", "abd")<0);
1910 tt_assert(strcmpstart("abcdef", "abb")>0);
1911 tt_assert(strcmpstart("ab", "abb")<0);
1912 tt_assert(strcmpstart("ab", "")==0);
1913 tt_assert(strcmpstart("ab", "ab ")<0);
1914 tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
1915 tt_assert(strcasecmpstart("abcDeF", "abc")==0);
1916 tt_assert(strcasecmpstart("abcdef", "Abd")<0);
1917 tt_assert(strcasecmpstart("Abcdef", "abb")>0);
1918 tt_assert(strcasecmpstart("ab", "Abb")<0);
1919 tt_assert(strcasecmpstart("ab", "")==0);
1920 tt_assert(strcasecmpstart("ab", "ab ")<0);
1922 /* Test str{,case}cmpend */
1923 tt_assert(strcmpend("abcdef", "abcdef")==0);
1924 tt_assert(strcmpend("abcdef", "def")==0);
1925 tt_assert(strcmpend("abcdef", "deg")<0);
1926 tt_assert(strcmpend("abcdef", "dee")>0);
1927 tt_assert(strcmpend("ab", "aab")>0);
1928 tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
1929 tt_assert(strcasecmpend("abcdef", "dEF")==0);
1930 tt_assert(strcasecmpend("abcdef", "Deg")<0);
1931 tt_assert(strcasecmpend("abcDef", "dee")>0);
1932 tt_assert(strcasecmpend("AB", "abb")<0);
1934 /* Test digest_is_zero */
1937 tt_assert(tor_digest_is_zero(buf
));
1939 tt_assert(!tor_digest_is_zero(buf
));
1941 /* Test mem_is_zero */
1944 tt_assert(tor_mem_is_zero(buf
, 10));
1945 tt_assert(tor_mem_is_zero(buf
, 20));
1946 tt_assert(tor_mem_is_zero(buf
, 128));
1947 tt_assert(!tor_mem_is_zero(buf
, 129));
1948 buf
[60] = (char)255;
1949 tt_assert(!tor_mem_is_zero(buf
, 128));
1951 tt_assert(!tor_mem_is_zero(buf
, 10));
1953 /* Test 'escaped' */
1954 tt_ptr_op(escaped(NULL
), OP_EQ
, NULL
);
1955 tt_str_op("\"\"",OP_EQ
, escaped(""));
1956 tt_str_op("\"abcd\"",OP_EQ
, escaped("abcd"));
1957 tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ
, escaped("\\ \n\r\t\"'"));
1958 tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ
,
1959 escaped("unnecessary \'backslashes\'"));
1960 /* Non-printable characters appear as octal */
1961 tt_str_op("\"z\\001abc\\277d\"",OP_EQ
, escaped("z\001abc\277d"));
1962 tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ
, escaped("z\xde\xad\x20;foo"));
1964 /* Other cases of esc_for_log{,_len} */
1965 cp_tmp
= esc_for_log(NULL
);
1966 tt_str_op(cp_tmp
, OP_EQ
, "(null)");
1968 cp_tmp
= esc_for_log_len("abcdefg", 3);
1969 tt_str_op(cp_tmp
, OP_EQ
, "\"abc\"");
1971 cp_tmp
= esc_for_log_len("abcdefg", 100);
1972 tt_str_op(cp_tmp
, OP_EQ
, "\"abcdefg\"");
1975 /* Test strndup and memdup */
1977 const char *s
= "abcdefghijklmnopqrstuvwxyz";
1978 cp_tmp
= tor_strndup(s
, 30);
1979 tt_str_op(cp_tmp
,OP_EQ
, s
); /* same string, */
1980 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
1983 cp_tmp
= tor_strndup(s
, 5);
1984 tt_str_op(cp_tmp
,OP_EQ
, "abcde");
1987 s
= "a\0b\0c\0d\0e\0";
1988 cp_tmp
= tor_memdup(s
,10);
1989 tt_mem_op(cp_tmp
,OP_EQ
, s
, 10); /* same ram, */
1990 tt_ptr_op(cp_tmp
,OP_NE
,s
); /* but different pointers. */
1994 /* Test str-foo functions */
1995 cp_tmp
= tor_strdup("abcdef");
1996 tt_assert(tor_strisnonupper(cp_tmp
));
1998 tt_assert(!tor_strisnonupper(cp_tmp
));
1999 tor_strupper(cp_tmp
);
2000 tt_str_op(cp_tmp
,OP_EQ
, "ABCDEF");
2001 tor_strlower(cp_tmp
);
2002 tt_str_op(cp_tmp
,OP_EQ
, "abcdef");
2003 tt_assert(tor_strisnonupper(cp_tmp
));
2004 tt_assert(tor_strisprint(cp_tmp
));
2006 tt_assert(!tor_strisprint(cp_tmp
));
2009 /* Test memmem and memstr */
2011 const char *haystack
= "abcde";
2012 tt_ptr_op(tor_memmem(haystack
, 5, "ef", 2), OP_EQ
, NULL
);
2013 tt_ptr_op(tor_memmem(haystack
, 5, "cd", 2),OP_EQ
, haystack
+ 2);
2014 tt_ptr_op(tor_memmem(haystack
, 5, "cde", 3),OP_EQ
, haystack
+ 2);
2015 tt_ptr_op(tor_memmem(haystack
, 4, "cde", 3), OP_EQ
, NULL
);
2016 haystack
= "ababcad";
2017 tt_ptr_op(tor_memmem(haystack
, 7, "abc", 3),OP_EQ
, haystack
+ 2);
2018 tt_ptr_op(tor_memmem(haystack
, 7, "ad", 2),OP_EQ
, haystack
+ 5);
2019 tt_ptr_op(tor_memmem(haystack
, 7, "cad", 3),OP_EQ
, haystack
+ 4);
2020 tt_ptr_op(tor_memmem(haystack
, 7, "dadad", 5), OP_EQ
, NULL
);
2021 tt_ptr_op(tor_memmem(haystack
, 7, "abcdefghij", 10), OP_EQ
, NULL
);
2023 tt_ptr_op(tor_memstr(haystack
, 7, "abc"),OP_EQ
, haystack
+ 2);
2024 tt_ptr_op(tor_memstr(haystack
, 7, "cad"),OP_EQ
, haystack
+ 4);
2025 tt_ptr_op(tor_memstr(haystack
, 6, "cad"), OP_EQ
, NULL
);
2026 tt_ptr_op(tor_memstr(haystack
, 7, "cadd"), OP_EQ
, NULL
);
2027 tt_ptr_op(tor_memstr(haystack
, 7, "fe"), OP_EQ
, NULL
);
2028 tt_ptr_op(tor_memstr(haystack
, 7, "ababcade"), OP_EQ
, NULL
);
2033 char binary_data
[68];
2035 for (idx
= 0; idx
< sizeof(binary_data
); ++idx
)
2036 binary_data
[idx
] = idx
;
2037 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2038 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2039 tt_str_op(hex_str(binary_data
, 17),OP_EQ
,
2040 "000102030405060708090A0B0C0D0E0F10");
2041 tt_str_op(hex_str(binary_data
, 32),OP_EQ
,
2042 "000102030405060708090A0B0C0D0E0F"
2043 "101112131415161718191A1B1C1D1E1F");
2044 tt_str_op(hex_str(binary_data
, 34),OP_EQ
,
2045 "000102030405060708090A0B0C0D0E0F"
2046 "101112131415161718191A1B1C1D1E1F");
2047 /* Repeat these tests for shorter strings after longer strings
2048 have been tried, to make sure we're correctly terminating strings */
2049 tt_str_op(hex_str(binary_data
, 1),OP_EQ
, "00");
2050 tt_str_op(hex_str(binary_data
, 0),OP_EQ
, "");
2053 /* Test strcmp_opt */
2054 tt_int_op(strcmp_opt("", "foo"), OP_LT
, 0);
2055 tt_int_op(strcmp_opt("", ""), OP_EQ
, 0);
2056 tt_int_op(strcmp_opt("foo", ""), OP_GT
, 0);
2058 tt_int_op(strcmp_opt(NULL
, ""), OP_LT
, 0);
2059 tt_int_op(strcmp_opt(NULL
, NULL
), OP_EQ
, 0);
2060 tt_int_op(strcmp_opt("", NULL
), OP_GT
, 0);
2062 tt_int_op(strcmp_opt(NULL
, "foo"), OP_LT
, 0);
2063 tt_int_op(strcmp_opt("foo", NULL
), OP_GT
, 0);
2065 /* Test strcmp_len */
2066 tt_int_op(strcmp_len("foo", "bar", 3), OP_GT
, 0);
2067 tt_int_op(strcmp_len("foo", "bar", 2), OP_LT
, 0);
2068 tt_int_op(strcmp_len("foo2", "foo1", 4), OP_GT
, 0);
2069 tt_int_op(strcmp_len("foo2", "foo1", 3), OP_LT
, 0); /* Really stop at len */
2070 tt_int_op(strcmp_len("foo2", "foo", 3), OP_EQ
, 0); /* Really stop at len */
2071 tt_int_op(strcmp_len("blah", "", 4), OP_GT
, 0);
2072 tt_int_op(strcmp_len("blah", "", 0), OP_EQ
, 0);
2079 test_util_parse_integer(void *arg
)
2085 /* Test parse_long */
2086 /* Empty/zero input */
2087 tt_int_op(0L,OP_EQ
, tor_parse_long("",10,0,100,&i
,NULL
));
2088 tt_int_op(0,OP_EQ
, i
);
2089 tt_int_op(0L,OP_EQ
, tor_parse_long("0",10,0,100,&i
,NULL
));
2090 tt_int_op(1,OP_EQ
, i
);
2092 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,100,&i
,NULL
));
2093 tt_int_op(1,OP_EQ
, i
);
2094 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,0,10,&i
,NULL
));
2095 tt_int_op(1,OP_EQ
, i
);
2096 tt_int_op(10L,OP_EQ
, tor_parse_long("10",10,10,100,&i
,NULL
));
2097 tt_int_op(1,OP_EQ
, i
);
2098 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,100,&i
,NULL
));
2099 tt_int_op(1,OP_EQ
, i
);
2100 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-100,0,&i
,NULL
));
2101 tt_int_op(1,OP_EQ
, i
);
2102 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50",10,-50,0,&i
,NULL
));
2103 tt_int_op(1,OP_EQ
, i
);
2105 tt_int_op(0L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,NULL
));
2106 tt_int_op(0,OP_EQ
, i
);
2107 tt_int_op(0L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,NULL
));
2108 tt_int_op(0,OP_EQ
, i
);
2109 tt_int_op(10L,OP_EQ
, tor_parse_long("10m",10,0,100,&i
,&cp
));
2110 tt_int_op(1,OP_EQ
, i
);
2111 tt_str_op(cp
,OP_EQ
, "m");
2112 tt_int_op(-50L,OP_EQ
, tor_parse_long("-50 plus garbage",10,-100,100,&i
,&cp
));
2113 tt_int_op(1,OP_EQ
, i
);
2114 tt_str_op(cp
,OP_EQ
, " plus garbage");
2115 /* Illogical min max */
2116 tor_capture_bugs_(1);
2117 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,4,&i
,NULL
));
2118 tt_int_op(0,OP_EQ
, i
);
2119 tt_int_op(1, OP_EQ
, smartlist_len(tor_get_captured_bug_log_()));
2120 tt_str_op("!(max < min)", OP_EQ
,
2121 smartlist_get(tor_get_captured_bug_log_(), 0));
2122 tor_end_capture_bugs_();
2123 tor_capture_bugs_(1);
2124 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,100,-100,&i
,NULL
));
2125 tt_int_op(0,OP_EQ
, i
);
2126 tt_int_op(1, OP_EQ
, smartlist_len(tor_get_captured_bug_log_()));
2127 tt_str_op("!(max < min)", OP_EQ
,
2128 smartlist_get(tor_get_captured_bug_log_(), 0));
2129 tor_end_capture_bugs_();
2131 tt_int_op(0L,OP_EQ
, tor_parse_long("10",10,50,100,&i
,NULL
));
2132 tt_int_op(0,OP_EQ
, i
);
2133 tt_int_op(0L,OP_EQ
, tor_parse_long("-50",10,0,100,&i
,NULL
));
2134 tt_int_op(0,OP_EQ
, i
);
2135 /* Base different than 10 */
2136 tt_int_op(2L,OP_EQ
, tor_parse_long("10",2,0,100,NULL
,NULL
));
2137 tt_int_op(0L,OP_EQ
, tor_parse_long("2",2,0,100,NULL
,NULL
));
2138 tt_int_op(68284L,OP_EQ
, tor_parse_long("10abc",16,0,70000,NULL
,NULL
));
2139 tt_int_op(68284L,OP_EQ
, tor_parse_long("10ABC",16,0,70000,NULL
,NULL
));
2140 tor_capture_bugs_(2);
2141 tt_int_op(0L,OP_EQ
, tor_parse_long("10",-2,0,100,NULL
,NULL
));
2142 tt_int_op(0,OP_EQ
, tor_parse_long("10ABC",-1,0,70000,&i
,NULL
));
2143 tt_int_op(2, OP_EQ
, smartlist_len(tor_get_captured_bug_log_()));
2144 tor_end_capture_bugs_();
2145 tt_int_op(i
,OP_EQ
, 0);
2147 /* Test parse_ulong */
2148 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("",10,0,100,NULL
,NULL
));
2149 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("0",10,0,100,NULL
,NULL
));
2150 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,100,NULL
,NULL
));
2151 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("10",10,50,100,NULL
,NULL
));
2152 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,0,10,NULL
,NULL
));
2153 tt_int_op(10UL,OP_EQ
, tor_parse_ulong("10",10,10,100,NULL
,NULL
));
2154 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("8",8,0,100,NULL
,NULL
));
2155 tt_int_op(50UL,OP_EQ
, tor_parse_ulong("50",10,50,100,NULL
,NULL
));
2156 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,NULL
,NULL
));
2157 tor_capture_bugs_(1);
2158 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("50",-1,50,100,&i
,NULL
));
2159 tt_int_op(1, OP_EQ
, smartlist_len(tor_get_captured_bug_log_()));
2160 tor_end_capture_bugs_();
2161 tt_int_op(0,OP_EQ
, i
);
2162 tt_int_op(0UL,OP_EQ
, tor_parse_ulong("-50",10,0,100,&i
,NULL
));
2163 tt_int_op(0,OP_EQ
, i
);
2165 /* Test parse_uint64 */
2166 tt_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i
, &cp
));
2167 tt_int_op(1,OP_EQ
, i
);
2168 tt_str_op(cp
,OP_EQ
, " x");
2169 tt_assert(U64_LITERAL(12345678901) ==
2170 tor_parse_uint64("12345678901",10,0,UINT64_MAX
, &i
, &cp
));
2171 tt_int_op(1,OP_EQ
, i
);
2172 tt_str_op(cp
,OP_EQ
, "");
2173 tt_assert(U64_LITERAL(0) ==
2174 tor_parse_uint64("12345678901",10,500,INT32_MAX
, &i
, &cp
));
2175 tt_int_op(0,OP_EQ
, i
);
2176 tor_capture_bugs_(1);
2177 tt_assert(U64_LITERAL(0) ==
2178 tor_parse_uint64("123",-1,0,INT32_MAX
, &i
, &cp
));
2179 tt_int_op(1, OP_EQ
, smartlist_len(tor_get_captured_bug_log_()));
2180 tor_end_capture_bugs_();
2181 tt_int_op(0,OP_EQ
, i
);
2184 /* Test parse_double */
2185 double d
= tor_parse_double("10", 0, (double)UINT64_MAX
,&i
,NULL
);
2186 tt_int_op(1,OP_EQ
, i
);
2187 tt_assert(DBL_TO_U64(d
) == 10);
2188 d
= tor_parse_double("0", 0, (double)UINT64_MAX
,&i
,NULL
);
2189 tt_int_op(1,OP_EQ
, i
);
2190 tt_assert(DBL_TO_U64(d
) == 0);
2191 d
= tor_parse_double(" ", 0, (double)UINT64_MAX
,&i
,NULL
);
2192 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2193 tt_int_op(0,OP_EQ
, i
);
2194 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,NULL
);
2195 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2196 tt_int_op(0,OP_EQ
, i
);
2197 d
= tor_parse_double(".0a", 0, (double)UINT64_MAX
,&i
,&cp
);
2198 tt_double_op(fabs(d
), OP_LT
, 1e-10);
2199 tt_int_op(1,OP_EQ
, i
);
2200 d
= tor_parse_double("-.0", 0, (double)UINT64_MAX
,&i
,NULL
);
2201 tt_int_op(1,OP_EQ
, i
);
2202 tt_assert(DBL_TO_U64(d
) == 0);
2203 d
= tor_parse_double("-10", -100.0, 100.0,&i
,NULL
);
2204 tt_int_op(1,OP_EQ
, i
);
2205 tt_double_op(fabs(d
- -10.0),OP_LT
, 1E-12);
2209 /* Test tor_parse_* where we overflow/underflow the underlying type. */
2210 /* This string should overflow 64-bit ints. */
2211 #define TOOBIG "100000000000000000000000000"
2212 tt_int_op(0L, OP_EQ
,
2213 tor_parse_long(TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2214 tt_int_op(i
,OP_EQ
, 0);
2216 tor_parse_long("-"TOOBIG
, 10, LONG_MIN
, LONG_MAX
, &i
, NULL
));
2217 tt_int_op(i
,OP_EQ
, 0);
2218 tt_int_op(0UL,OP_EQ
, tor_parse_ulong(TOOBIG
, 10, 0, ULONG_MAX
, &i
, NULL
));
2219 tt_int_op(i
,OP_EQ
, 0);
2220 tt_u64_op(U64_LITERAL(0), OP_EQ
, tor_parse_uint64(TOOBIG
, 10,
2221 0, UINT64_MAX
, &i
, NULL
));
2222 tt_int_op(i
,OP_EQ
, 0);
2225 tor_end_capture_bugs_();
2229 test_util_pow2(void *arg
)
2231 /* Test tor_log2(). */
2233 tt_int_op(tor_log2(64),OP_EQ
, 6);
2234 tt_int_op(tor_log2(65),OP_EQ
, 6);
2235 tt_int_op(tor_log2(63),OP_EQ
, 5);
2236 /* incorrect mathematically, but as specified: */
2237 tt_int_op(tor_log2(0),OP_EQ
, 0);
2238 tt_int_op(tor_log2(1),OP_EQ
, 0);
2239 tt_int_op(tor_log2(2),OP_EQ
, 1);
2240 tt_int_op(tor_log2(3),OP_EQ
, 1);
2241 tt_int_op(tor_log2(4),OP_EQ
, 2);
2242 tt_int_op(tor_log2(5),OP_EQ
, 2);
2243 tt_int_op(tor_log2(U64_LITERAL(40000000000000000)),OP_EQ
, 55);
2244 tt_int_op(tor_log2(UINT64_MAX
),OP_EQ
, 63);
2246 /* Test round_to_power_of_2 */
2247 tt_u64_op(round_to_power_of_2(120), OP_EQ
, 128);
2248 tt_u64_op(round_to_power_of_2(128), OP_EQ
, 128);
2249 tt_u64_op(round_to_power_of_2(130), OP_EQ
, 128);
2250 tt_u64_op(round_to_power_of_2(U64_LITERAL(40000000000000000)), OP_EQ
,
2251 U64_LITERAL(1)<<55);
2252 tt_u64_op(round_to_power_of_2(U64_LITERAL(0xffffffffffffffff)), OP_EQ
,
2253 U64_LITERAL(1)<<63);
2254 tt_u64_op(round_to_power_of_2(0), OP_EQ
, 1);
2255 tt_u64_op(round_to_power_of_2(1), OP_EQ
, 1);
2256 tt_u64_op(round_to_power_of_2(2), OP_EQ
, 2);
2257 tt_u64_op(round_to_power_of_2(3), OP_EQ
, 2);
2258 tt_u64_op(round_to_power_of_2(4), OP_EQ
, 4);
2259 tt_u64_op(round_to_power_of_2(5), OP_EQ
, 4);
2260 tt_u64_op(round_to_power_of_2(6), OP_EQ
, 4);
2261 tt_u64_op(round_to_power_of_2(7), OP_EQ
, 8);
2268 test_util_compress_impl(compress_method_t method
)
2270 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
;
2273 tt_assert(tor_compress_supports_method(method
));
2275 if (method
!= NO_METHOD
) {
2276 tt_ptr_op(tor_compress_version_str(method
), OP_NE
, NULL
);
2277 tt_ptr_op(tor_compress_header_version_str(method
), OP_NE
, NULL
);
2280 buf1
= tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
2281 tt_assert(detect_compression_method(buf1
, strlen(buf1
)) == UNKNOWN_METHOD
);
2283 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, strlen(buf1
)+1, method
));
2284 tt_ptr_op(buf2
, OP_NE
, NULL
);
2285 if (method
== NO_METHOD
) {
2286 // The identity transform doesn't actually compress, and it isn't
2287 // detectable as "the identity transform."
2288 tt_int_op(len1
, OP_EQ
, strlen(buf1
)+1);
2289 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, UNKNOWN_METHOD
);
2291 tt_int_op(len1
, OP_LT
, strlen(buf1
));
2292 tt_int_op(detect_compression_method(buf2
, len1
), OP_EQ
, method
);
2295 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
, method
, 1, LOG_INFO
));
2296 tt_ptr_op(buf3
, OP_NE
, NULL
);
2297 tt_int_op(strlen(buf1
) + 1, OP_EQ
, len2
);
2298 tt_str_op(buf1
, OP_EQ
, buf3
);
2299 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2301 /* Check whether we can uncompress concatenated, compressed strings. */
2303 buf2
= tor_reallocarray(buf2
, len1
, 2);
2304 memcpy(buf2
+len1
, buf2
, len1
);
2305 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
*2, method
, 1, LOG_INFO
));
2306 tt_int_op((strlen(buf1
)+1)*2, OP_EQ
, len2
);
2307 tt_mem_op(buf3
, OP_EQ
,
2308 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
2309 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
2310 (strlen(buf1
)+1)*2);
2311 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2313 /* Check whether we can uncompress partial strings */
2319 size_t b1len
= 1<<10;
2320 if (method
== ZSTD_METHOD
) {
2321 // zstd needs a big input before it starts generating output that it
2322 // can partially decompress.
2325 buf1
= tor_malloc(b1len
);
2326 crypto_rand(buf1
, b1len
);
2327 tt_assert(!tor_compress(&buf2
, &len1
, buf1
, b1len
, method
));
2328 tt_int_op(len1
, OP_GT
, 16);
2329 /* when we allow an incomplete output we should succeed.*/
2330 tt_assert(!tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2331 method
, 0, LOG_INFO
));
2332 tt_int_op(len2
, OP_GT
, 5);
2333 tt_int_op(len2
, OP_LE
, len1
);
2334 tt_assert(fast_memeq(buf1
, buf3
, len2
));
2335 tt_int_op(buf3
[len2
], OP_EQ
, 0);
2337 /* when we demand a complete output from a real compression method, this
2340 if (method
!= NO_METHOD
) {
2341 tt_assert(tor_uncompress(&buf3
, &len2
, buf2
, len1
-16,
2342 method
, 1, LOG_INFO
));
2343 tt_ptr_op(buf3
, OP_EQ
, NULL
);
2353 test_util_compress_stream_impl(compress_method_t method
,
2354 compression_level_t level
)
2356 char *buf1
=NULL
, *buf2
=NULL
, *buf3
=NULL
, *cp1
, *cp2
;
2360 tor_compress_state_t
*state
= NULL
;
2361 state
= tor_compress_new(1, method
, level
);
2363 cp1
= buf1
= tor_malloc(1024);
2365 ccp2
= "ABCDEFGHIJABCDEFGHIJ";
2367 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 0),
2368 OP_EQ
, TOR_COMPRESS_OK
);
2369 tt_int_op(0, OP_EQ
, len2
); /* Make sure we compressed it all. */
2370 tt_assert(cp1
> buf1
);
2374 tt_int_op(tor_compress_process(state
, &cp1
, &len1
, &ccp2
, &len2
, 1),
2375 OP_EQ
, TOR_COMPRESS_DONE
);
2376 tt_int_op(0, OP_EQ
, len2
);
2377 if (method
== NO_METHOD
) {
2378 tt_ptr_op(cp1
, OP_EQ
, cp2
);
2380 tt_assert(cp1
> cp2
); /* Make sure we really added something. */
2383 tt_int_op(tor_compress_state_size(state
), OP_GT
, 0);
2385 tt_assert(!tor_uncompress(&buf3
, &len2
, buf1
, 1024-len1
,
2386 method
, 1, LOG_WARN
));
2387 /* Make sure it compressed right. */
2388 tt_str_op(buf3
, OP_EQ
, "ABCDEFGHIJABCDEFGHIJ");
2389 tt_int_op(21, OP_EQ
, len2
);
2393 tor_compress_free(state
);
2399 /** Run unit tests for compression functions */
2401 test_util_compress(void *arg
)
2403 const char *methodname
= arg
;
2404 tt_assert(methodname
);
2406 compress_method_t method
= compression_method_get_by_name(methodname
);
2407 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2409 if (! tor_compress_supports_method(method
)) {
2413 compression_level_t levels
[] = {
2420 test_util_compress_impl(method
);
2422 for (unsigned l
= 0; l
< ARRAY_LENGTH(levels
); ++l
) {
2423 compression_level_t level
= levels
[l
];
2424 test_util_compress_stream_impl(method
, level
);
2431 test_util_decompress_concatenated_impl(compress_method_t method
)
2434 char *c1
= NULL
, *c2
= NULL
, *c3
= NULL
;
2435 char *result
= NULL
;
2436 size_t sz1
, sz2
, sz3
, szr
;
2439 crypto_rand(input
, sizeof(input
));
2441 /* Compress the input in two chunks. */
2442 r
= tor_compress(&c1
, &sz1
, input
, 2048, method
);
2443 tt_int_op(r
, OP_EQ
, 0);
2444 r
= tor_compress(&c2
, &sz2
, input
+2048, 2048, method
);
2445 tt_int_op(r
, OP_EQ
, 0);
2447 /* concatenate the chunks. */
2449 c3
= tor_malloc(sz3
);
2450 memcpy(c3
, c1
, sz1
);
2451 memcpy(c3
+sz1
, c2
, sz2
);
2453 /* decompress the concatenated result */
2454 r
= tor_uncompress(&result
, &szr
, c3
, sz3
, method
, 0, LOG_WARN
);
2455 tt_int_op(r
, OP_EQ
, 0);
2456 tt_int_op(szr
, OP_EQ
, sizeof(input
));
2457 tt_mem_op(result
, OP_EQ
, input
, sizeof(input
));
2467 test_util_decompress_concatenated(void *arg
)
2469 const char *methodname
= arg
;
2470 tt_assert(methodname
);
2472 compress_method_t method
= compression_method_get_by_name(methodname
);
2473 tt_int_op(method
, OP_NE
, UNKNOWN_METHOD
);
2474 if (! tor_compress_supports_method(method
)) {
2478 test_util_decompress_concatenated_impl(method
);
2484 test_util_gzip_compression_bomb(void *arg
)
2486 /* A 'compression bomb' is a very small object that uncompresses to a huge
2487 * one. Most compression formats support them, but they can be a DOS vector.
2488 * In Tor we try not to generate them, and we don't accept them.
2491 size_t one_million
= 1<<20;
2492 char *one_mb
= tor_malloc_zero(one_million
);
2493 char *result
= NULL
;
2494 size_t result_len
= 0;
2495 tor_compress_state_t
*state
= NULL
;
2497 /* Make sure we can't produce a compression bomb */
2498 setup_full_capture_of_logs(LOG_WARN
);
2499 tt_int_op(-1, OP_EQ
, tor_compress(&result
, &result_len
,
2500 one_mb
, one_million
,
2502 expect_single_log_msg_containing(
2503 "We compressed something and got an insanely high "
2504 "compression factor; other Tors would think this "
2505 "was a compression bomb.");
2506 teardown_capture_of_logs();
2508 /* Here's a compression bomb that we made manually. */
2509 const char compression_bomb
[1039] =
2510 { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2,
2511 0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ };
2512 tt_int_op(-1, OP_EQ
, tor_uncompress(&result
, &result_len
,
2513 compression_bomb
, 1039,
2514 ZLIB_METHOD
, 0, LOG_WARN
));
2516 /* Now try streaming that. */
2517 state
= tor_compress_new(0, ZLIB_METHOD
, HIGH_COMPRESSION
);
2518 tor_compress_output_t r
;
2519 const char *inp
= compression_bomb
;
2520 size_t inlen
= 1039;
2522 char *outp
= one_mb
;
2523 size_t outleft
= 4096; /* small on purpose */
2524 r
= tor_compress_process(state
, &outp
, &outleft
, &inp
, &inlen
, 0);
2525 tt_int_op(inlen
, OP_NE
, 0);
2526 } while (r
== TOR_COMPRESS_BUFFER_FULL
);
2528 tt_int_op(r
, OP_EQ
, TOR_COMPRESS_ERROR
);
2532 tor_compress_free(state
);
2535 /** Run unit tests for mmap() wrapper functionality. */
2537 test_util_mmap(void *arg
)
2539 char *fname1
= tor_strdup(get_fname("mapped_1"));
2540 char *fname2
= tor_strdup(get_fname("mapped_2"));
2541 char *fname3
= tor_strdup(get_fname("mapped_3"));
2542 const size_t buflen
= 17000;
2543 char *buf
= tor_malloc(17000);
2544 tor_mmap_t
*mapping
= NULL
;
2547 crypto_rand(buf
, buflen
);
2549 mapping
= tor_mmap_file(fname1
);
2550 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2552 write_str_to_file(fname1
, "Short file.", 1);
2554 mapping
= tor_mmap_file(fname1
);
2556 tt_int_op(mapping
->size
,OP_EQ
, strlen("Short file."));
2557 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
2559 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2561 tt_assert(unlink(fname1
) == 0);
2563 /* make sure we can unlink. */
2564 tt_assert(unlink(fname1
) == 0);
2565 tt_str_op(mapping
->data
,OP_EQ
, "Short file.");
2566 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2568 #endif /* defined(_WIN32) */
2570 /* Now a zero-length file. */
2571 write_str_to_file(fname1
, "", 1);
2572 mapping
= tor_mmap_file(fname1
);
2573 tt_ptr_op(mapping
,OP_EQ
, NULL
);
2574 tt_int_op(ERANGE
,OP_EQ
, errno
);
2577 /* Make sure that we fail to map a no-longer-existent file. */
2578 mapping
= tor_mmap_file(fname1
);
2579 tt_ptr_op(mapping
, OP_EQ
, NULL
);
2581 /* Now try a big file that stretches across a few pages and isn't aligned */
2582 write_bytes_to_file(fname2
, buf
, buflen
, 1);
2583 mapping
= tor_mmap_file(fname2
);
2585 tt_int_op(mapping
->size
,OP_EQ
, buflen
);
2586 tt_mem_op(mapping
->data
,OP_EQ
, buf
, buflen
);
2587 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2590 /* Now try a big aligned file. */
2591 write_bytes_to_file(fname3
, buf
, 16384, 1);
2592 mapping
= tor_mmap_file(fname3
);
2594 tt_int_op(mapping
->size
,OP_EQ
, 16384);
2595 tt_mem_op(mapping
->data
,OP_EQ
, buf
, 16384);
2596 tt_int_op(0, OP_EQ
, tor_munmap_file(mapping
));
2609 tor_munmap_file(mapping
);
2612 /** Run unit tests for escaping/unescaping data for use by controllers. */
2614 test_util_control_formats(void *arg
)
2618 "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
2622 sz
= read_escaped_data(inp
, strlen(inp
), &out
);
2623 tt_str_op(out
,OP_EQ
,
2624 ".This is a test\nof the emergency \n.system.\n\rZ.\n");
2625 tt_int_op(sz
,OP_EQ
, strlen(out
));
2631 #define test_feq(value1,value2) do { \
2632 double v1 = (value1), v2=(value2); \
2633 double tf_diff = v1-v2; \
2634 double tf_tolerance = ((v1+v2)/2.0)/1e8; \
2635 if (tf_diff<0) tf_diff=-tf_diff; \
2636 if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
2637 if (tf_diff<tf_tolerance) { \
2638 TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
2640 TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
2645 test_util_sscanf(void *arg
)
2647 unsigned u1
, u2
, u3
;
2649 char s1
[20], s2
[10], s3
[10], ch
, *huge
= NULL
;
2655 /* Simple tests (malformed patterns, literal matching, ...) */
2657 tt_int_op(-1,OP_EQ
, tor_sscanf("123", "%i", &r
)); /* %i is not supported */
2659 tor_sscanf("wrong", "%5c", s1
)); /* %c cannot have a number. */
2660 tt_int_op(-1,OP_EQ
, tor_sscanf("hello", "%s", s1
)); /* %s needs a number. */
2661 /* this will fail because we don't allow widths longer than 9999 */
2663 huge
= tor_malloc(1000000);
2664 r
= tor_sscanf("prettylongstring", "%99999s", huge
);
2666 tt_int_op(-1,OP_EQ
, r
);
2669 /* GCC thinks these two are illegal. */
2670 test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1
));
2671 test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL
));
2673 /* No '%'-strings: always "success" */
2674 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "hello world"));
2675 tt_int_op(0,OP_EQ
, tor_sscanf("hello world", "good bye"));
2678 tor_sscanf("hello 3", "%u", &u1
)); /* have to match the start */
2679 tt_int_op(0,OP_EQ
, tor_sscanf(" 3 hello", "%u", &u1
));
2681 tor_sscanf(" 3 hello", "%2u", &u1
)); /* not even in this case */
2683 tor_sscanf("3 hello", "%u", &u1
)); /* but trailing is alright */
2685 /* Numbers (ie. %u) */
2687 tor_sscanf("hello world 3", "hello worlb %u", &u1
)); /* d vs b */
2688 tt_int_op(1,OP_EQ
, tor_sscanf("12345", "%u", &u1
));
2689 tt_int_op(12345u,OP_EQ
, u1
);
2690 tt_int_op(1,OP_EQ
, tor_sscanf("12346 ", "%u", &u1
));
2691 tt_int_op(12346u,OP_EQ
, u1
);
2692 tt_int_op(0,OP_EQ
, tor_sscanf(" 12347", "%u", &u1
));
2693 tt_int_op(1,OP_EQ
, tor_sscanf(" 12348", " %u", &u1
));
2694 tt_int_op(12348u,OP_EQ
, u1
);
2695 tt_int_op(1,OP_EQ
, tor_sscanf("0", "%u", &u1
));
2696 tt_int_op(0u,OP_EQ
, u1
);
2697 tt_int_op(1,OP_EQ
, tor_sscanf("0000", "%u", &u2
));
2698 tt_int_op(0u,OP_EQ
, u2
);
2699 tt_int_op(0,OP_EQ
, tor_sscanf("", "%u", &u1
)); /* absent number */
2700 tt_int_op(0,OP_EQ
, tor_sscanf("A", "%u", &u1
)); /* bogus number */
2701 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%u", &u1
)); /* negative number */
2703 /* Numbers with size (eg. %2u) */
2704 tt_int_op(0,OP_EQ
, tor_sscanf("-1", "%2u", &u1
));
2705 tt_int_op(2,OP_EQ
, tor_sscanf("123456", "%2u%u", &u1
, &u2
));
2706 tt_int_op(12u,OP_EQ
, u1
);
2707 tt_int_op(3456u,OP_EQ
, u2
);
2708 tt_int_op(1,OP_EQ
, tor_sscanf("123456", "%8u", &u1
));
2709 tt_int_op(123456u,OP_EQ
, u1
);
2710 tt_int_op(1,OP_EQ
, tor_sscanf("123457 ", "%8u", &u1
));
2711 tt_int_op(123457u,OP_EQ
, u1
);
2712 tt_int_op(0,OP_EQ
, tor_sscanf(" 123456", "%8u", &u1
));
2713 tt_int_op(3,OP_EQ
, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1
, &u2
, &u3
));
2714 tt_int_op(12u,OP_EQ
, u1
);
2715 tt_int_op(3u,OP_EQ
, u2
);
2716 tt_int_op(456u,OP_EQ
, u3
);
2718 tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1
, &u2
, &u3
)); /* 0s */
2719 tt_int_op(67u,OP_EQ
, u1
);
2720 tt_int_op(8u,OP_EQ
, u2
);
2721 tt_int_op(99u,OP_EQ
, u3
);
2722 /* %u does not match space.*/
2723 tt_int_op(2,OP_EQ
, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
2724 tt_int_op(12u,OP_EQ
, u1
);
2725 tt_int_op(3u,OP_EQ
, u2
);
2726 /* %u does not match negative numbers. */
2727 tt_int_op(2,OP_EQ
, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1
, &u2
, &u3
));
2728 tt_int_op(67u,OP_EQ
, u1
);
2729 tt_int_op(8u,OP_EQ
, u2
);
2730 /* Arbitrary amounts of 0-padding are okay */
2731 tt_int_op(3,OP_EQ
, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
2733 tt_int_op(12u,OP_EQ
, u1
);
2734 tt_int_op(3u,OP_EQ
, u2
);
2735 tt_int_op(99u,OP_EQ
, u3
);
2739 tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1
, &u2
, &u3
));
2740 tt_int_op(0x1234,OP_EQ
, u1
);
2741 tt_int_op(0x2ABCDEF,OP_EQ
, u2
);
2742 tt_int_op(0xFF,OP_EQ
, u3
);
2743 /* Width works on %x */
2744 tt_int_op(3,OP_EQ
, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1
, &u2
, &u3
));
2745 tt_int_op(0xf00d,OP_EQ
, u1
);
2746 tt_int_op(0xcafe,OP_EQ
, u2
);
2747 tt_int_op(444,OP_EQ
, u3
);
2749 /* Literal '%' (ie. '%%') */
2750 tt_int_op(1,OP_EQ
, tor_sscanf("99% fresh", "%3u%% fresh", &u1
));
2751 tt_int_op(99,OP_EQ
, u1
);
2752 tt_int_op(0,OP_EQ
, tor_sscanf("99 fresh", "%% %3u %s", &u1
, s1
));
2753 tt_int_op(1,OP_EQ
, tor_sscanf("99 fresh", "%3u%% %s", &u1
, s1
));
2754 tt_int_op(2,OP_EQ
, tor_sscanf("99 fresh", "%3u %5s %%", &u1
, s1
));
2755 tt_int_op(99,OP_EQ
, u1
);
2756 tt_str_op(s1
,OP_EQ
, "fresh");
2757 tt_int_op(1,OP_EQ
, tor_sscanf("% boo", "%% %3s", s1
));
2758 tt_str_op("boo",OP_EQ
, s1
);
2760 /* Strings (ie. %s) */
2761 tt_int_op(2,OP_EQ
, tor_sscanf("hello", "%3s%7s", s1
, s2
));
2762 tt_str_op(s1
,OP_EQ
, "hel");
2763 tt_str_op(s2
,OP_EQ
, "lo");
2764 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%2s%u", s3
, &u1
)); /* %s%u */
2765 tt_str_op(s3
,OP_EQ
, "WD");
2766 tt_int_op(40,OP_EQ
, u1
);
2767 tt_int_op(2,OP_EQ
, tor_sscanf("WD40", "%3s%u", s3
, &u1
)); /* %s%u */
2768 tt_str_op(s3
,OP_EQ
, "WD4");
2769 tt_int_op(0,OP_EQ
, u1
);
2770 tt_int_op(2,OP_EQ
, tor_sscanf("76trombones", "%6u%9s", &u1
, s1
)); /* %u%s */
2771 tt_int_op(76,OP_EQ
, u1
);
2772 tt_str_op(s1
,OP_EQ
, "trombones");
2774 huge
= tor_malloc(1000);
2775 r
= tor_sscanf("prettylongstring", "%999s", huge
);
2776 tt_int_op(1,OP_EQ
, r
);
2777 tt_str_op(huge
,OP_EQ
, "prettylongstring");
2780 /* %s doesn't eat spaces */
2781 tt_int_op(2,OP_EQ
, tor_sscanf("hello world", "%9s %9s", s1
, s2
));
2782 tt_str_op(s1
,OP_EQ
, "hello");
2783 tt_str_op(s2
,OP_EQ
, "world");
2784 tt_int_op(2,OP_EQ
, tor_sscanf("bye world?", "%9s %9s", s1
, s2
));
2785 tt_str_op(s1
,OP_EQ
, "bye");
2786 tt_str_op(s2
,OP_EQ
, "");
2788 tor_sscanf("hi", "%9s%9s%3s", s1
, s2
, s3
)); /* %s can be empty. */
2789 tt_str_op(s1
,OP_EQ
, "hi");
2790 tt_str_op(s2
,OP_EQ
, "");
2791 tt_str_op(s3
,OP_EQ
, "");
2793 tt_int_op(3,OP_EQ
, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
2795 tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1
, &u2
, &u3
, &ch
));
2796 tt_int_op(' ',OP_EQ
, ch
);
2798 r
= tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1
, &lng1
, &int2
);
2799 tt_int_op(r
,OP_EQ
, 3);
2800 tt_int_op(int1
,OP_EQ
, 12345);
2801 tt_int_op(lng1
,OP_EQ
, -67890);
2802 tt_int_op(int2
,OP_EQ
, -1);
2806 /* UINT32_MAX should work */
2807 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%u", &u1
));
2808 tt_int_op(4294967295U,OP_EQ
, u1
);
2810 /* But UINT32_MAX + 1 shouldn't work */
2811 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%u", &u1
));
2812 /* but parsing only 9... */
2813 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9u", &u1
));
2814 tt_int_op(429496729U,OP_EQ
, u1
);
2817 /* UINT32_MAX should work */
2818 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%x", &u1
));
2819 tt_int_op(0xFFFFFFFF,OP_EQ
, u1
);
2821 /* But UINT32_MAX + 1 shouldn't work */
2822 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%x", &u1
));
2825 /* INT32_MIN and INT32_MAX should work */
2826 r
= tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1
, &int2
);
2827 tt_int_op(r
,OP_EQ
, 2);
2828 tt_int_op(int1
,OP_EQ
, -2147483647 - 1);
2829 tt_int_op(int2
,OP_EQ
, 2147483647);
2831 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
2832 r
= tor_sscanf("-2147483649.", "%d.", &int1
);
2833 tt_int_op(r
,OP_EQ
, 0);
2835 r
= tor_sscanf("2147483648.", "%d.", &int1
);
2836 tt_int_op(r
,OP_EQ
, 0);
2838 /* and the first failure stops further processing */
2839 r
= tor_sscanf("-2147483648. 2147483648.",
2840 "%d. %d.", &int1
, &int2
);
2841 tt_int_op(r
,OP_EQ
, 1);
2843 r
= tor_sscanf("-2147483649. 2147483647.",
2844 "%d. %d.", &int1
, &int2
);
2845 tt_int_op(r
,OP_EQ
, 0);
2847 r
= tor_sscanf("2147483648. -2147483649.",
2848 "%d. %d.", &int1
, &int2
);
2849 tt_int_op(r
,OP_EQ
, 0);
2850 #elif SIZEOF_INT == 8
2852 /* UINT64_MAX should work */
2853 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%u", &u1
));
2854 tt_int_op(18446744073709551615U,OP_EQ
, u1
);
2856 /* But UINT64_MAX + 1 shouldn't work */
2857 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%u", &u1
));
2858 /* but parsing only 19... */
2859 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19u", &u1
));
2860 tt_int_op(1844674407370955161U,OP_EQ
, u1
);
2863 /* UINT64_MAX should work */
2864 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1
));
2865 tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ
, u1
);
2867 /* But UINT64_MAX + 1 shouldn't work */
2868 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%x", &u1
));
2871 /* INT64_MIN and INT64_MAX should work */
2872 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
2873 "%d. %d.", &int1
, &int2
);
2874 tt_int_op(r
,OP_EQ
, 2);
2875 tt_int_op(int1
,OP_EQ
, -9223372036854775807 - 1);
2876 tt_int_op(int2
,OP_EQ
, 9223372036854775807);
2878 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
2879 r
= tor_sscanf("-9223372036854775809.", "%d.", &int1
);
2880 tt_int_op(r
,OP_EQ
, 0);
2882 r
= tor_sscanf("9223372036854775808.", "%d.", &int1
);
2883 tt_int_op(r
,OP_EQ
, 0);
2885 /* and the first failure stops further processing */
2886 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
2887 "%d. %d.", &int1
, &int2
);
2888 tt_int_op(r
,OP_EQ
, 1);
2890 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
2891 "%d. %d.", &int1
, &int2
);
2892 tt_int_op(r
,OP_EQ
, 0);
2894 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
2895 "%d. %d.", &int1
, &int2
);
2896 tt_int_op(r
,OP_EQ
, 0);
2897 #endif /* SIZEOF_INT == 4 || ... */
2899 #if SIZEOF_LONG == 4
2901 /* UINT32_MAX should work */
2902 tt_int_op(1,OP_EQ
, tor_sscanf("4294967295", "%lu", &ulng
));
2903 tt_int_op(4294967295UL,OP_EQ
, ulng
);
2905 /* But UINT32_MAX + 1 shouldn't work */
2906 tt_int_op(0,OP_EQ
, tor_sscanf("4294967296", "%lu", &ulng
));
2907 /* but parsing only 9... */
2908 tt_int_op(1,OP_EQ
, tor_sscanf("4294967296", "%9lu", &ulng
));
2909 tt_int_op(429496729UL,OP_EQ
, ulng
);
2912 /* UINT32_MAX should work */
2913 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFF", "%lx", &ulng
));
2914 tt_int_op(0xFFFFFFFFUL
,OP_EQ
, ulng
);
2916 /* But UINT32_MAX + 1 shouldn't work */
2917 tt_int_op(0,OP_EQ
, tor_sscanf("100000000", "%lx", &ulng
));
2920 /* INT32_MIN and INT32_MAX should work */
2921 r
= tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1
, &lng2
);
2922 tt_int_op(r
,OP_EQ
, 2);
2923 tt_int_op(lng1
,OP_EQ
, -2147483647L - 1L);
2924 tt_int_op(lng2
,OP_EQ
, 2147483647L);
2926 /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
2927 r
= tor_sscanf("-2147483649.", "%ld.", &lng1
);
2928 tt_int_op(r
,OP_EQ
, 0);
2930 r
= tor_sscanf("2147483648.", "%ld.", &lng1
);
2931 tt_int_op(r
,OP_EQ
, 0);
2933 /* and the first failure stops further processing */
2934 r
= tor_sscanf("-2147483648. 2147483648.",
2935 "%ld. %ld.", &lng1
, &lng2
);
2936 tt_int_op(r
,OP_EQ
, 1);
2938 r
= tor_sscanf("-2147483649. 2147483647.",
2939 "%ld. %ld.", &lng1
, &lng2
);
2940 tt_int_op(r
,OP_EQ
, 0);
2942 r
= tor_sscanf("2147483648. -2147483649.",
2943 "%ld. %ld.", &lng1
, &lng2
);
2944 tt_int_op(r
,OP_EQ
, 0);
2945 #elif SIZEOF_LONG == 8
2947 /* UINT64_MAX should work */
2948 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551615", "%lu", &ulng
));
2949 tt_int_op(18446744073709551615UL,OP_EQ
, ulng
);
2951 /* But UINT64_MAX + 1 shouldn't work */
2952 tt_int_op(0,OP_EQ
, tor_sscanf("18446744073709551616", "%lu", &ulng
));
2953 /* but parsing only 19... */
2954 tt_int_op(1,OP_EQ
, tor_sscanf("18446744073709551616", "%19lu", &ulng
));
2955 tt_int_op(1844674407370955161UL,OP_EQ
, ulng
);
2958 /* UINT64_MAX should work */
2959 tt_int_op(1,OP_EQ
, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng
));
2960 tt_int_op(0xFFFFFFFFFFFFFFFFUL
,OP_EQ
, ulng
);
2962 /* But UINT64_MAX + 1 shouldn't work */
2963 tt_int_op(0,OP_EQ
, tor_sscanf("10000000000000000", "%lx", &ulng
));
2966 /* INT64_MIN and INT64_MAX should work */
2967 r
= tor_sscanf("-9223372036854775808. 9223372036854775807.",
2968 "%ld. %ld.", &lng1
, &lng2
);
2969 tt_int_op(r
,OP_EQ
, 2);
2970 tt_int_op(lng1
,OP_EQ
, -9223372036854775807L - 1L);
2971 tt_int_op(lng2
,OP_EQ
, 9223372036854775807L);
2973 /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
2974 r
= tor_sscanf("-9223372036854775809.", "%ld.", &lng1
);
2975 tt_int_op(r
,OP_EQ
, 0);
2977 r
= tor_sscanf("9223372036854775808.", "%ld.", &lng1
);
2978 tt_int_op(r
,OP_EQ
, 0);
2980 /* and the first failure stops further processing */
2981 r
= tor_sscanf("-9223372036854775808. 9223372036854775808.",
2982 "%ld. %ld.", &lng1
, &lng2
);
2983 tt_int_op(r
,OP_EQ
, 1);
2985 r
= tor_sscanf("-9223372036854775809. 9223372036854775807.",
2986 "%ld. %ld.", &lng1
, &lng2
);
2987 tt_int_op(r
,OP_EQ
, 0);
2989 r
= tor_sscanf("9223372036854775808. -9223372036854775809.",
2990 "%ld. %ld.", &lng1
, &lng2
);
2991 tt_int_op(r
,OP_EQ
, 0);
2992 #endif /* SIZEOF_LONG == 4 || ... */
2994 r
= tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
2995 "%lf %lf %lf %lf", &d1
,&d2
,&d3
,&d4
);
2996 tt_int_op(r
,OP_EQ
, 4);
2997 test_feq(d1
, 123.456);
2998 test_feq(d2
, .000007);
2999 test_feq(d3
, -900123123.2000787);
3006 #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
3007 #define tt_ci_char_op(a,op,b) \
3008 tt_char_op(TOR_TOLOWER((int)a),op,TOR_TOLOWER((int)b))
3010 #ifndef HAVE_STRNLEN
3012 strnlen(const char *s
, size_t len
)
3014 const char *p
= memchr(s
, 0, len
);
3019 #endif /* !defined(HAVE_STRNLEN) */
3022 test_util_format_time_interval(void *arg
)
3024 /* use the same sized buffer and integers as tor uses */
3025 #define DBUF_SIZE 64
3026 char dbuf
[DBUF_SIZE
];
3028 long sec
, min
, hour
, day
;
3030 /* we don't care about the exact spelling of the
3031 * second(s), minute(s), hour(s), day(s) labels */
3032 #define LABEL_SIZE 21
3034 char label_s
[LABEL_SIZE
];
3035 char label_m
[LABEL_SIZE
];
3036 char label_h
[LABEL_SIZE
];
3037 char label_d
[LABEL_SIZE
];
3039 #define TL_ T_ " " L_
3045 /* In these tests, we're not picky about
3046 * spelling or abbreviations */
3048 /* seconds: 0, 1, 9, 10, 59 */
3050 /* ignore exact spelling of "second(s)"*/
3051 format_time_interval(dbuf
, sizeof(dbuf
), 0);
3052 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3053 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3054 tt_int_op(r
,OP_EQ
, 2);
3055 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3056 tt_int_op(sec
,OP_EQ
, 0);
3058 format_time_interval(dbuf
, sizeof(dbuf
), 1);
3059 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3060 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3061 tt_int_op(r
,OP_EQ
, 2);
3062 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3063 tt_int_op(sec
,OP_EQ
, 1);
3065 format_time_interval(dbuf
, sizeof(dbuf
), 10);
3066 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3067 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3068 tt_int_op(r
,OP_EQ
, 2);
3069 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3070 tt_int_op(sec
,OP_EQ
, 10);
3072 format_time_interval(dbuf
, sizeof(dbuf
), 59);
3073 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3074 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3075 tt_int_op(r
,OP_EQ
, 2);
3076 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3077 tt_int_op(sec
,OP_EQ
, 59);
3079 /* negative seconds are reported as their absolute value */
3081 format_time_interval(dbuf
, sizeof(dbuf
), -4);
3082 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3083 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3084 tt_int_op(r
,OP_EQ
, 2);
3085 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3086 tt_int_op(sec
,OP_EQ
, 4);
3087 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3089 format_time_interval(dbuf
, sizeof(dbuf
), -32);
3090 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3091 r
= tor_sscanf(dbuf
, TL_
, &sec
, label_s
);
3092 tt_int_op(r
,OP_EQ
, 2);
3093 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3094 tt_int_op(sec
,OP_EQ
, 32);
3095 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3097 /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
3099 /* ignore trailing "0 second(s)", if present */
3100 format_time_interval(dbuf
, sizeof(dbuf
), 60);
3101 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3102 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3103 tt_int_op(r
,OP_EQ
, 2);
3104 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3105 tt_int_op(min
,OP_EQ
, 1);
3106 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3108 /* ignore exact spelling of "minute(s)," and "second(s)" */
3109 format_time_interval(dbuf
, sizeof(dbuf
), 60 + 1);
3110 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3111 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3112 &min
, label_m
, &sec
, label_s
);
3113 tt_int_op(r
,OP_EQ
, 4);
3114 tt_int_op(min
,OP_EQ
, 1);
3115 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3116 tt_int_op(sec
,OP_EQ
, 1);
3117 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3118 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3120 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 - 1);
3121 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3122 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3123 &min
, label_m
, &sec
, label_s
);
3124 tt_int_op(r
,OP_EQ
, 4);
3125 tt_int_op(min
,OP_EQ
, 1);
3126 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3127 tt_int_op(sec
,OP_EQ
, 59);
3128 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3130 /* ignore trailing "0 second(s)", if present */
3131 format_time_interval(dbuf
, sizeof(dbuf
), 60*2);
3132 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3133 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3134 tt_int_op(r
,OP_EQ
, 2);
3135 tt_int_op(min
,OP_EQ
, 2);
3136 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3138 /* ignore exact spelling of "minute(s)," and "second(s)" */
3139 format_time_interval(dbuf
, sizeof(dbuf
), 60*2 + 1);
3140 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3141 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3142 &min
, label_m
, &sec
, label_s
);
3143 tt_int_op(r
,OP_EQ
, 4);
3144 tt_int_op(min
,OP_EQ
, 2);
3145 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3146 tt_int_op(sec
,OP_EQ
, 1);
3147 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3149 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 - 1);
3150 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3151 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3152 &min
, label_m
, &sec
, label_s
);
3153 tt_int_op(r
,OP_EQ
, 4);
3154 tt_int_op(min
,OP_EQ
, 59);
3155 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3156 tt_int_op(sec
,OP_EQ
, 59);
3157 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3159 /* negative minutes are reported as their absolute value */
3161 /* ignore trailing "0 second(s)", if present */
3162 format_time_interval(dbuf
, sizeof(dbuf
), -3*60);
3163 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3164 r
= tor_sscanf(dbuf
, TL_
, &min
, label_m
);
3165 tt_int_op(r
,OP_EQ
, 2);
3166 tt_int_op(min
,OP_EQ
, 3);
3167 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3169 /* ignore exact spelling of "minute(s)," and "second(s)" */
3170 format_time_interval(dbuf
, sizeof(dbuf
), -96);
3171 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3172 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3173 &min
, label_m
, &sec
, label_s
);
3174 tt_int_op(r
,OP_EQ
, 4);
3175 tt_int_op(min
,OP_EQ
, 1);
3176 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3177 tt_int_op(sec
,OP_EQ
, 36);
3178 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3180 format_time_interval(dbuf
, sizeof(dbuf
), -2815);
3181 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3182 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3183 &min
, label_m
, &sec
, label_s
);
3184 tt_int_op(r
,OP_EQ
, 4);
3185 tt_int_op(min
,OP_EQ
, 46);
3186 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3187 tt_int_op(sec
,OP_EQ
, 55);
3188 tt_ci_char_op(label_s
[0],OP_EQ
, 's');
3190 /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
3191 /* always ignore trailing seconds, if present */
3193 /* ignore trailing "0 minute(s)" etc., if present */
3194 format_time_interval(dbuf
, sizeof(dbuf
), 60*60);
3195 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3196 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3197 tt_int_op(r
,OP_EQ
, 2);
3198 tt_int_op(hour
,OP_EQ
, 1);
3199 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3201 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 1);
3202 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3203 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3204 tt_int_op(r
,OP_EQ
, 2);
3205 tt_int_op(hour
,OP_EQ
, 1);
3206 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3208 /* ignore exact spelling of "hour(s)," etc. */
3209 format_time_interval(dbuf
, sizeof(dbuf
), 60*60 + 60);
3210 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3211 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3212 &hour
, label_h
, &min
, label_m
);
3213 tt_int_op(r
,OP_EQ
, 4);
3214 tt_int_op(hour
,OP_EQ
, 1);
3215 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3216 tt_int_op(min
,OP_EQ
, 1);
3217 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3219 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 60);
3220 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3221 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3222 &hour
, label_h
, &min
, label_m
);
3223 tt_int_op(r
,OP_EQ
, 4);
3224 tt_int_op(hour
,OP_EQ
, 23);
3225 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3226 tt_int_op(min
,OP_EQ
, 59);
3227 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3229 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 - 1);
3230 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3231 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3232 &hour
, label_h
, &min
, label_m
);
3233 tt_int_op(r
,OP_EQ
, 4);
3234 tt_int_op(hour
,OP_EQ
, 23);
3235 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3236 tt_int_op(min
,OP_EQ
, 59);
3237 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3239 /* negative hours are reported as their absolute value */
3241 /* ignore exact spelling of "hour(s)," etc., if present */
3242 format_time_interval(dbuf
, sizeof(dbuf
), -2*60*60);
3243 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3244 r
= tor_sscanf(dbuf
, TL_
, &hour
, label_h
);
3245 tt_int_op(r
,OP_EQ
, 2);
3246 tt_int_op(hour
,OP_EQ
, 2);
3247 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3249 format_time_interval(dbuf
, sizeof(dbuf
), -75804);
3250 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3251 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3252 &hour
, label_h
, &min
, label_m
);
3253 tt_int_op(r
,OP_EQ
, 4);
3254 tt_int_op(hour
,OP_EQ
, 21);
3255 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3256 tt_int_op(min
,OP_EQ
, 3);
3257 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3259 /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
3260 /* always ignore trailing seconds, if present */
3262 /* ignore trailing "0 hours(s)" etc., if present */
3263 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60);
3264 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3265 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3266 tt_int_op(r
,OP_EQ
, 2);
3267 tt_int_op(day
,OP_EQ
, 1);
3268 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3270 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 1);
3271 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3272 r
= tor_sscanf(dbuf
, TL_
, &day
, label_d
);
3273 tt_int_op(r
,OP_EQ
, 2);
3274 tt_int_op(day
,OP_EQ
, 1);
3275 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3277 /* ignore exact spelling of "days(s)," etc. */
3278 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60);
3279 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3280 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3281 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3283 /* ignore 0 hours(s), if present */
3284 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3285 &day
, label_d
, &min
, label_m
);
3287 tt_assert(r
== 4 || r
== 6);
3288 tt_int_op(day
,OP_EQ
, 1);
3289 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3291 tt_int_op(hour
,OP_EQ
, 0);
3292 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3294 tt_int_op(min
,OP_EQ
, 1);
3295 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3297 /* ignore trailing "0 minutes(s)" etc., if present */
3298 format_time_interval(dbuf
, sizeof(dbuf
), 24*60*60 + 60*60);
3299 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3300 r
= tor_sscanf(dbuf
, TL_
" " TL_
,
3301 &day
, label_d
, &hour
, label_h
);
3302 tt_int_op(r
,OP_EQ
, 4);
3303 tt_int_op(day
,OP_EQ
, 1);
3304 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3305 tt_int_op(hour
,OP_EQ
, 1);
3306 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3308 /* negative days are reported as their absolute value */
3310 format_time_interval(dbuf
, sizeof(dbuf
), -21936184);
3311 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3312 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3313 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3314 tt_int_op(r
,OP_EQ
, 6);
3315 tt_int_op(day
,OP_EQ
, 253);
3316 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3317 tt_int_op(hour
,OP_EQ
, 21);
3318 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3319 tt_int_op(min
,OP_EQ
, 23);
3320 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3322 /* periods > 1 year are reported in days (warn?) */
3324 /* ignore exact spelling of "days(s)," etc., if present */
3325 format_time_interval(dbuf
, sizeof(dbuf
), 758635154);
3326 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3327 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3328 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3329 tt_int_op(r
,OP_EQ
, 6);
3330 tt_int_op(day
,OP_EQ
, 8780);
3331 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3332 tt_int_op(hour
,OP_EQ
, 11);
3333 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3334 tt_int_op(min
,OP_EQ
, 59);
3335 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3337 /* negative periods > 1 year are reported in days (warn?) */
3339 format_time_interval(dbuf
, sizeof(dbuf
), -1427014922);
3340 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3341 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3342 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3343 tt_int_op(r
,OP_EQ
, 6);
3344 tt_int_op(day
,OP_EQ
, 16516);
3345 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3346 tt_int_op(hour
,OP_EQ
, 9);
3347 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3348 tt_int_op(min
,OP_EQ
, 2);
3349 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3351 #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
3353 /* We can try INT32_MIN/MAX */
3354 /* Always ignore second(s) */
3357 format_time_interval(dbuf
, sizeof(dbuf
), 2147483647);
3358 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3359 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3360 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3361 tt_int_op(r
,OP_EQ
, 6);
3362 tt_int_op(day
,OP_EQ
, 24855);
3363 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3364 tt_int_op(hour
,OP_EQ
, 3);
3365 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3366 tt_int_op(min
,OP_EQ
, 14);
3367 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3368 /* and 7 seconds - ignored */
3370 /* INT32_MIN: check that we get the absolute value of interval,
3371 * which doesn't actually fit in int32_t.
3372 * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
3373 format_time_interval(dbuf
, sizeof(dbuf
), -2147483647L - 1L);
3374 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3375 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3376 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3377 tt_int_op(r
,OP_EQ
, 6);
3378 tt_int_op(day
,OP_EQ
, 24855);
3379 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3380 tt_int_op(hour
,OP_EQ
, 3);
3381 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3382 tt_int_op(min
,OP_EQ
, 14);
3383 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3384 /* and 7 or 8 seconds - ignored */
3386 #endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */
3388 #if SIZEOF_LONG == 8
3390 /* We can try INT64_MIN/MAX */
3391 /* Always ignore second(s) */
3394 format_time_interval(dbuf
, sizeof(dbuf
), 9223372036854775807L);
3395 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3396 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3397 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3398 tt_int_op(r
,OP_EQ
, 6);
3399 tt_int_op(day
,OP_EQ
, 106751991167300L);
3400 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3401 tt_int_op(hour
,OP_EQ
, 15);
3402 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3403 tt_int_op(min
,OP_EQ
, 30);
3404 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3405 /* and 7 seconds - ignored */
3407 /* INT64_MIN: check that we get the absolute value of interval,
3408 * which doesn't actually fit in int64_t.
3409 * We expect INT64_MAX */
3410 format_time_interval(dbuf
, sizeof(dbuf
),
3411 -9223372036854775807L - 1L);
3412 tt_int_op(strnlen(dbuf
, DBUF_SIZE
),OP_LE
, DBUF_SIZE
- 1);
3413 r
= tor_sscanf(dbuf
, TL_
" " TL_
" " TL_
,
3414 &day
, label_d
, &hour
, label_h
, &min
, label_m
);
3415 tt_int_op(r
,OP_EQ
, 6);
3416 tt_int_op(day
,OP_EQ
, 106751991167300L);
3417 tt_ci_char_op(label_d
[0],OP_EQ
, 'd');
3418 tt_int_op(hour
,OP_EQ
, 15);
3419 tt_ci_char_op(label_h
[0],OP_EQ
, 'h');
3420 tt_int_op(min
,OP_EQ
, 30);
3421 tt_ci_char_op(label_m
[0],OP_EQ
, 'm');
3422 /* and 7 or 8 seconds - ignored */
3424 #endif /* SIZEOF_LONG == 8 */
3431 #undef tt_ci_char_op
3439 test_util_path_is_relative(void *arg
)
3441 /* OS-independent tests */
3443 tt_int_op(1,OP_EQ
, path_is_relative(""));
3444 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3445 tt_int_op(1,OP_EQ
, path_is_relative("dir/"));
3446 tt_int_op(1,OP_EQ
, path_is_relative("./dir"));
3447 tt_int_op(1,OP_EQ
, path_is_relative("../dir"));
3449 tt_int_op(0,OP_EQ
, path_is_relative("/"));
3450 tt_int_op(0,OP_EQ
, path_is_relative("/dir"));
3451 tt_int_op(0,OP_EQ
, path_is_relative("/dir/"));
3455 /* I don't have Windows so I can't test this, hence the "#ifdef
3456 0". These are tests that look useful, so please try to get them
3457 running and uncomment if it all works as it should */
3458 tt_int_op(1,OP_EQ
, path_is_relative("dir"));
3459 tt_int_op(1,OP_EQ
, path_is_relative("dir\\"));
3460 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:"));
3461 tt_int_op(1,OP_EQ
, path_is_relative("dir\\a:\\"));
3462 tt_int_op(1,OP_EQ
, path_is_relative("http:\\dir"));
3464 tt_int_op(0,OP_EQ
, path_is_relative("\\dir"));
3465 tt_int_op(0,OP_EQ
, path_is_relative("a:\\dir"));
3466 tt_int_op(0,OP_EQ
, path_is_relative("z:\\dir"));
3467 #endif /* defined(_WIN32) */
3473 /** Run unittests for memory area allocator */
3475 test_util_memarea(void *arg
)
3477 memarea_t
*area
= memarea_new();
3478 char *p1
, *p2
, *p3
, *p1_orig
;
3479 void *malloced_ptr
= NULL
;
3482 #ifdef DISABLE_MEMORY_SENTINELS
3483 /* If memory sentinels are disabled, this whole module is just an alias for
3484 malloc(), which is free to lay out memory most any way it wants. */
3487 #endif /* defined(DISABLE_MEMORY_SENTINELS) */
3492 p1_orig
= p1
= memarea_alloc(area
,64);
3493 p2
= memarea_alloc_zero(area
,52);
3494 p3
= memarea_alloc(area
,11);
3496 tt_assert(memarea_owns_ptr(area
, p1
));
3497 tt_assert(memarea_owns_ptr(area
, p2
));
3498 tt_assert(memarea_owns_ptr(area
, p3
));
3499 /* Make sure we left enough space. */
3500 tt_assert(p1
+64 <= p2
);
3501 tt_assert(p2
+52 <= p3
);
3502 /* Make sure we aligned. */
3503 tt_int_op(((uintptr_t)p1
) % sizeof(void*),OP_EQ
, 0);
3504 tt_int_op(((uintptr_t)p2
) % sizeof(void*),OP_EQ
, 0);
3505 tt_int_op(((uintptr_t)p3
) % sizeof(void*),OP_EQ
, 0);
3506 tt_assert(!memarea_owns_ptr(area
, p3
+8192));
3507 tt_assert(!memarea_owns_ptr(area
, p3
+30));
3508 tt_assert(tor_mem_is_zero(p2
, 52));
3509 /* Make sure we don't overalign. */
3510 p1
= memarea_alloc(area
, 1);
3511 p2
= memarea_alloc(area
, 1);
3512 tt_ptr_op(p1
+sizeof(void*),OP_EQ
, p2
);
3514 malloced_ptr
= tor_malloc(64);
3515 tt_assert(!memarea_owns_ptr(area
, malloced_ptr
));
3516 tor_free(malloced_ptr
);
3519 /* memarea_memdup */
3521 malloced_ptr
= tor_malloc(64);
3522 crypto_rand((char*)malloced_ptr
, 64);
3523 p1
= memarea_memdup(area
, malloced_ptr
, 64);
3524 tt_assert(p1
!= malloced_ptr
);
3525 tt_mem_op(p1
,OP_EQ
, malloced_ptr
, 64);
3526 tor_free(malloced_ptr
);
3529 /* memarea_strdup. */
3530 p1
= memarea_strdup(area
,"");
3531 p2
= memarea_strdup(area
, "abcd");
3534 tt_str_op(p1
,OP_EQ
, "");
3535 tt_str_op(p2
,OP_EQ
, "abcd");
3537 /* memarea_strndup. */
3539 const char *s
= "Ad ogni porta batte la morte e grida: il nome!";
3540 /* (From Turandot, act 3.) */
3541 size_t len
= strlen(s
);
3542 p1
= memarea_strndup(area
, s
, 1000);
3543 p2
= memarea_strndup(area
, s
, 10);
3544 tt_str_op(p1
,OP_EQ
, s
);
3545 tt_assert(p2
>= p1
+ len
+ 1);
3546 tt_mem_op(s
,OP_EQ
, p2
, 10);
3547 tt_int_op(p2
[10],OP_EQ
, '\0');
3548 p3
= memarea_strndup(area
, s
, len
);
3549 tt_str_op(p3
,OP_EQ
, s
);
3550 p3
= memarea_strndup(area
, s
, len
-1);
3551 tt_mem_op(s
,OP_EQ
, p3
, len
-1);
3552 tt_int_op(p3
[len
-1],OP_EQ
, '\0');
3555 memarea_clear(area
);
3556 p1
= memarea_alloc(area
, 1);
3557 tt_ptr_op(p1
,OP_EQ
, p1_orig
);
3558 memarea_clear(area
);
3559 size_t total
= 0, initial_allocation
, allocation2
, dummy
;
3560 memarea_get_stats(area
, &initial_allocation
, &dummy
);
3562 /* Check for running over an area's size. */
3563 for (i
= 0; i
< 4096; ++i
) {
3564 size_t n
= crypto_rand_int(6);
3565 p1
= memarea_alloc(area
, n
);
3567 tt_assert(memarea_owns_ptr(area
, p1
));
3569 memarea_assert_ok(area
);
3570 memarea_get_stats(area
, &allocation2
, &dummy
);
3571 /* Make sure we can allocate a too-big object. */
3572 p1
= memarea_alloc_zero(area
, 9000);
3573 p2
= memarea_alloc_zero(area
, 16);
3576 tt_assert(memarea_owns_ptr(area
, p1
));
3577 tt_assert(memarea_owns_ptr(area
, p2
));
3579 /* Now test stats... */
3580 size_t allocated
= 0, used
= 0;
3581 memarea_get_stats(area
, &allocated
, &used
);
3582 tt_int_op(used
, OP_LE
, allocated
);
3583 tt_int_op(used
, OP_GE
, total
); /* not EQ, because of alignment and headers*/
3584 tt_int_op(allocated
, OP_GT
, allocation2
);
3586 tt_int_op(allocation2
, OP_GT
, initial_allocation
);
3588 memarea_clear(area
);
3589 memarea_get_stats(area
, &allocated
, &used
);
3590 tt_int_op(used
, OP_LT
, 128); /* Not 0, because of header */
3591 tt_int_op(allocated
, OP_EQ
, initial_allocation
);
3594 memarea_drop_all(area
);
3595 tor_free(malloced_ptr
);
3598 /** Run unit tests for utility functions to get file names relative to
3599 * the data directory. */
3601 test_util_datadir(void *arg
)
3605 char *temp_dir
= NULL
;
3608 temp_dir
= get_datadir_fname(NULL
);
3609 f
= get_datadir_fname("state");
3610 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"state", temp_dir
);
3611 tt_str_op(f
,OP_EQ
, buf
);
3613 f
= get_datadir_fname2("cache", "thingy");
3614 tor_snprintf(buf
, sizeof(buf
),
3615 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy", temp_dir
);
3616 tt_str_op(f
,OP_EQ
, buf
);
3618 f
= get_datadir_fname2_suffix("cache", "thingy", ".foo");
3619 tor_snprintf(buf
, sizeof(buf
),
3620 "%s"PATH_SEPARATOR
"cache"PATH_SEPARATOR
"thingy.foo", temp_dir
);
3621 tt_str_op(f
,OP_EQ
, buf
);
3623 f
= get_datadir_fname_suffix("cache", ".foo");
3624 tor_snprintf(buf
, sizeof(buf
), "%s"PATH_SEPARATOR
"cache.foo",
3626 tt_str_op(f
,OP_EQ
, buf
);
3634 test_util_strtok(void *arg
)
3642 for (i
= 0; i
< 3; i
++) {
3643 const char *pad1
="", *pad2
="";
3656 tor_snprintf(buf
, sizeof(buf
), "%s", pad1
);
3657 tor_snprintf(buf2
, sizeof(buf2
), "%s", pad2
);
3658 tt_ptr_op(tor_strtok_r_impl(buf
, " ", &cp1
), OP_EQ
, NULL
);
3659 tt_ptr_op(tor_strtok_r_impl(buf2
, ".!..;!", &cp2
), OP_EQ
, NULL
);
3661 tor_snprintf(buf
, sizeof(buf
),
3662 "%sGraved on the dark in gestures of descent%s", pad1
, pad1
);
3663 tor_snprintf(buf2
, sizeof(buf2
),
3664 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2
,pad2
);
3665 /* -- "Year's End", Richard Wilbur */
3667 tt_str_op("Graved",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3668 tt_str_op("they",OP_EQ
, tor_strtok_r_impl(buf2
, ".!..;!", &cp2
));
3669 #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
3670 #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
3671 tt_str_op("on",OP_EQ
, S1());
3672 tt_str_op("the",OP_EQ
, S1());
3673 tt_str_op("dark",OP_EQ
, S1());
3674 tt_str_op("seemed",OP_EQ
, S2());
3675 tt_str_op("their",OP_EQ
, S2());
3676 tt_str_op("own",OP_EQ
, S2());
3677 tt_str_op("in",OP_EQ
, S1());
3678 tt_str_op("gestures",OP_EQ
, S1());
3679 tt_str_op("of",OP_EQ
, S1());
3680 tt_str_op("most",OP_EQ
, S2());
3681 tt_str_op("perfect",OP_EQ
, S2());
3682 tt_str_op("descent",OP_EQ
, S1());
3683 tt_str_op("monument",OP_EQ
, S2());
3684 tt_ptr_op(NULL
,OP_EQ
, S1());
3685 tt_ptr_op(NULL
,OP_EQ
, S2());
3689 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3690 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
3692 strlcpy(buf
, "Howdy!", sizeof(buf
));
3693 tt_str_op("Howdy",OP_EQ
, tor_strtok_r_impl(buf
, "!", &cp1
));
3694 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, "!", &cp1
));
3696 strlcpy(buf
, " ", sizeof(buf
));
3697 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3698 strlcpy(buf
, " ", sizeof(buf
));
3699 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3701 strlcpy(buf
, "something ", sizeof(buf
));
3702 tt_str_op("something",OP_EQ
, tor_strtok_r_impl(buf
, " ", &cp1
));
3703 tt_ptr_op(NULL
,OP_EQ
, tor_strtok_r_impl(NULL
, ";", &cp1
));
3709 test_util_find_str_at_start_of_line(void *ptr
)
3711 const char *long_string
=
3712 "howdy world. how are you? i hope it's fine.\n"
3715 char *line2
= strchr(long_string
,'\n')+1;
3716 char *line3
= strchr(line2
,'\n')+1;
3717 const char *short_string
= "hello kitty\n"
3719 char *short_line2
= strchr(short_string
,'\n')+1;
3723 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, ""));
3724 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(short_string
, "nonsense"));
3725 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "nonsense"));
3726 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "\n"));
3727 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "how "));
3728 tt_ptr_op(NULL
,OP_EQ
, find_str_at_start_of_line(long_string
, "kitty"));
3729 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "h"));
3730 tt_ptr_op(long_string
,OP_EQ
, find_str_at_start_of_line(long_string
, "how"));
3731 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "he"));
3732 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hell"));
3733 tt_ptr_op(line2
,OP_EQ
, find_str_at_start_of_line(long_string
, "hello k"));
3734 tt_ptr_op(line2
,OP_EQ
,
3735 find_str_at_start_of_line(long_string
, "hello kitty\n"));
3736 tt_ptr_op(line2
,OP_EQ
,
3737 find_str_at_start_of_line(long_string
, "hello kitty\nt"));
3738 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third"));
3739 tt_ptr_op(line3
,OP_EQ
, find_str_at_start_of_line(long_string
, "third line"));
3740 tt_ptr_op(NULL
, OP_EQ
,
3741 find_str_at_start_of_line(long_string
, "third line\n"));
3742 tt_ptr_op(short_line2
,OP_EQ
, find_str_at_start_of_line(short_string
,
3749 test_util_string_is_C_identifier(void *ptr
)
3753 tt_int_op(1,OP_EQ
, string_is_C_identifier("string_is_C_identifier"));
3754 tt_int_op(1,OP_EQ
, string_is_C_identifier("_string_is_C_identifier"));
3755 tt_int_op(1,OP_EQ
, string_is_C_identifier("_"));
3756 tt_int_op(1,OP_EQ
, string_is_C_identifier("i"));
3757 tt_int_op(1,OP_EQ
, string_is_C_identifier("_____"));
3758 tt_int_op(1,OP_EQ
, string_is_C_identifier("__00__"));
3759 tt_int_op(1,OP_EQ
, string_is_C_identifier("__init__"));
3760 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
3761 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0string_is_C_identifier"));
3762 tt_int_op(1,OP_EQ
, string_is_C_identifier("_0"));
3764 tt_int_op(0,OP_EQ
, string_is_C_identifier("0_string_is_C_identifier"));
3765 tt_int_op(0,OP_EQ
, string_is_C_identifier("0"));
3766 tt_int_op(0,OP_EQ
, string_is_C_identifier(""));
3767 tt_int_op(0,OP_EQ
, string_is_C_identifier(";"));
3768 tt_int_op(0,OP_EQ
, string_is_C_identifier("i;"));
3769 tt_int_op(0,OP_EQ
, string_is_C_identifier("_;"));
3770 tt_int_op(0,OP_EQ
, string_is_C_identifier("Ã"));
3771 tt_int_op(0,OP_EQ
, string_is_C_identifier("ñ"));
3778 test_util_asprintf(void *ptr
)
3780 #define LOREMIPSUM \
3781 "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
3782 char *cp
=NULL
, *cp2
=NULL
;
3787 r
= tor_asprintf(&cp
, "simple string 100%% safe");
3789 tt_str_op("simple string 100% safe",OP_EQ
, cp
);
3790 tt_int_op(strlen(cp
),OP_EQ
, r
);
3794 r
= tor_asprintf(&cp
, "%s", "");
3796 tt_str_op("",OP_EQ
, cp
);
3797 tt_int_op(strlen(cp
),OP_EQ
, r
);
3801 r
= tor_asprintf(&cp
, "I like numbers-%2i, %i, etc.", -1, 2);
3803 tt_str_op("I like numbers--1, 2, etc.",OP_EQ
, cp
);
3804 tt_int_op(strlen(cp
),OP_EQ
, r
);
3805 /* don't free cp; next test uses it. */
3808 r
= tor_asprintf(&cp2
, "First=%d, Second=%d", 101, 202);
3810 tt_int_op(strlen(cp2
),OP_EQ
, r
);
3811 tt_str_op("First=101, Second=202",OP_EQ
, cp2
);
3812 tt_assert(cp
!= cp2
);
3816 /* Glass-box test: a string exactly 128 characters long. */
3817 r
= tor_asprintf(&cp
, "Lorem1: %sLorem2: %s", LOREMIPSUM
, LOREMIPSUM
);
3819 tt_int_op(128,OP_EQ
, r
);
3820 tt_int_op(cp
[128], OP_EQ
, '\0');
3821 tt_str_op("Lorem1: "LOREMIPSUM
"Lorem2: "LOREMIPSUM
,OP_EQ
, cp
);
3824 /* String longer than 128 characters */
3825 r
= tor_asprintf(&cp
, "1: %s 2: %s 3: %s",
3826 LOREMIPSUM
, LOREMIPSUM
, LOREMIPSUM
);
3828 tt_int_op(strlen(cp
),OP_EQ
, r
);
3829 tt_str_op("1: "LOREMIPSUM
" 2: "LOREMIPSUM
" 3: "LOREMIPSUM
,OP_EQ
, cp
);
3837 test_util_listdir(void *ptr
)
3839 smartlist_t
*dir_contents
= NULL
;
3840 char *fname1
=NULL
, *fname2
=NULL
, *fname3
=NULL
, *dir1
=NULL
, *dirname
=NULL
;
3844 fname1
= tor_strdup(get_fname("hopscotch"));
3845 fname2
= tor_strdup(get_fname("mumblety-peg"));
3846 fname3
= tor_strdup(get_fname(".hidden-file"));
3847 dir1
= tor_strdup(get_fname("some-directory"));
3848 dirname
= tor_strdup(get_fname(NULL
));
3850 tt_int_op(0,OP_EQ
, write_str_to_file(fname1
, "X\n", 0));
3851 tt_int_op(0,OP_EQ
, write_str_to_file(fname2
, "Y\n", 0));
3852 tt_int_op(0,OP_EQ
, write_str_to_file(fname3
, "Z\n", 0));
3856 r
= mkdir(dir1
, 0700);
3859 fprintf(stderr
, "Can't create directory %s:", dir1
);
3864 dir_contents
= tor_listdir(dirname
);
3865 tt_assert(dir_contents
);
3866 /* make sure that each filename is listed. */
3867 tt_assert(smartlist_contains_string_case(dir_contents
, "hopscotch"));
3868 tt_assert(smartlist_contains_string_case(dir_contents
, "mumblety-peg"));
3869 tt_assert(smartlist_contains_string_case(dir_contents
, ".hidden-file"));
3870 tt_assert(smartlist_contains_string_case(dir_contents
, "some-directory"));
3872 tt_assert(!smartlist_contains_string(dir_contents
, "."));
3873 tt_assert(!smartlist_contains_string(dir_contents
, ".."));
3882 SMARTLIST_FOREACH(dir_contents
, char *, cp
, tor_free(cp
));
3883 smartlist_free(dir_contents
);
3888 test_util_parent_dir(void *ptr
)
3893 #define T(output,expect_ok,input) \
3896 cp = tor_strdup(input); \
3897 ok = get_parent_directory(cp); \
3898 tt_int_op(expect_ok, OP_EQ, ok); \
3900 tt_str_op(output, OP_EQ, cp); \
3904 T("/home/wombat", 0, "/home/wombat/knish");
3905 T("/home/wombat", 0, "/home/wombat/knish/");
3906 T("/home/wombat", 0, "/home/wombat/knish///");
3907 T("./home/wombat", 0, "./home/wombat/knish/");
3909 T("/", 0, "/home//");
3910 T(".", 0, "./wombat");
3911 T(".", 0, "./wombat/");
3912 T(".", 0, "./wombat//");
3913 T("wombat", 0, "wombat/foo");
3914 T("wombat/..", 0, "wombat/../foo");
3915 T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
3916 T("wombat/.", 0, "wombat/./foo");
3917 T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
3918 T("wombat", 0, "wombat/..//");
3919 T("wombat", 0, "wombat/foo/");
3920 T("wombat", 0, "wombat/.foo");
3921 T("wombat", 0, "wombat/.foo/");
3923 T("wombat", -1, "");
3925 T("wombat", 0, "wombat/knish");
3935 test_util_ftruncate(void *ptr
)
3940 const char *message
= "Hello world";
3941 const char *message2
= "Hola mundo";
3946 fname
= get_fname("ftruncate");
3948 fd
= tor_open_cloexec(fname
, O_WRONLY
|O_CREAT
, 0600);
3949 tt_int_op(fd
, OP_GE
, 0);
3951 /* Make the file be there. */
3952 tt_int_op(strlen(message
), OP_EQ
, write_all(fd
, message
, strlen(message
),0));
3953 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message
));
3954 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
3955 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message
));
3957 /* Truncate and see if it got truncated */
3958 tt_int_op(0, OP_EQ
, tor_ftruncate(fd
));
3959 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, 0);
3960 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
3961 tt_int_op((int)st
.st_size
, OP_EQ
, 0);
3963 /* Replace, and see if it got replaced */
3964 tt_int_op(strlen(message2
), OP_EQ
,
3965 write_all(fd
, message2
, strlen(message2
), 0));
3966 tt_int_op((int)tor_fd_getpos(fd
), OP_EQ
, strlen(message2
));
3967 tt_int_op(0, OP_EQ
, fstat(fd
, &st
));
3968 tt_int_op((int)st
.st_size
, OP_EQ
, strlen(message2
));
3973 buf
= read_file_to_str(fname
, 0, NULL
);
3974 tt_str_op(message2
, OP_EQ
, buf
);
3983 test_util_num_cpus(void *arg
)
3986 int num
= compute_num_cpus();
3990 tt_int_op(num
, OP_GE
, 1);
3991 tt_int_op(num
, OP_LE
, 16);
3999 test_util_load_win_lib(void *ptr
)
4001 HANDLE h
= load_windows_system_library(_T("advapi32.dll"));
4009 #endif /* defined(_WIN32) */
4013 clear_hex_errno(char *hex_errno
)
4015 memset(hex_errno
, '\0', HEX_ERRNO_SIZE
+ 1);
4019 test_util_exit_status(void *ptr
)
4021 /* Leave an extra byte for a \0 so we can do string comparison */
4022 char hex_errno
[HEX_ERRNO_SIZE
+ 1];
4027 clear_hex_errno(hex_errno
);
4028 tt_str_op("",OP_EQ
, hex_errno
);
4030 clear_hex_errno(hex_errno
);
4031 n
= format_helper_exit_status(0, 0, hex_errno
);
4032 tt_str_op("0/0\n",OP_EQ
, hex_errno
);
4033 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4037 clear_hex_errno(hex_errno
);
4038 n
= format_helper_exit_status(0, 0x7FFFFFFF, hex_errno
);
4039 tt_str_op("0/7FFFFFFF\n",OP_EQ
, hex_errno
);
4040 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4042 clear_hex_errno(hex_errno
);
4043 n
= format_helper_exit_status(0xFF, -0x80000000, hex_errno
);
4044 tt_str_op("FF/-80000000\n",OP_EQ
, hex_errno
);
4045 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4046 tt_int_op(n
,OP_EQ
, HEX_ERRNO_SIZE
);
4048 #elif SIZEOF_INT == 8
4050 clear_hex_errno(hex_errno
);
4051 n
= format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno
);
4052 tt_str_op("0/7FFFFFFFFFFFFFFF\n",OP_EQ
, hex_errno
);
4053 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4055 clear_hex_errno(hex_errno
);
4056 n
= format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno
);
4057 tt_str_op("FF/-8000000000000000\n",OP_EQ
, hex_errno
);
4058 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4059 tt_int_op(n
,OP_EQ
, HEX_ERRNO_SIZE
);
4061 #endif /* SIZEOF_INT == 4 || ... */
4063 clear_hex_errno(hex_errno
);
4064 n
= format_helper_exit_status(0x7F, 0, hex_errno
);
4065 tt_str_op("7F/0\n",OP_EQ
, hex_errno
);
4066 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4068 clear_hex_errno(hex_errno
);
4069 n
= format_helper_exit_status(0x08, -0x242, hex_errno
);
4070 tt_str_op("8/-242\n",OP_EQ
, hex_errno
);
4071 tt_int_op(n
,OP_EQ
, strlen(hex_errno
));
4073 clear_hex_errno(hex_errno
);
4074 tt_str_op("",OP_EQ
, hex_errno
);
4079 #endif /* !defined(_WIN32) */
4083 test_util_string_from_pipe(void *ptr
)
4085 int test_pipe
[2] = {-1, -1};
4087 enum stream_status status
= IO_STREAM_TERM
;
4089 char buf
[4] = { 0 };
4095 /* Set up a pipe to test on */
4096 retval
= pipe(test_pipe
);
4097 tt_int_op(retval
, OP_EQ
, 0);
4099 /* Send in a string. */
4100 retlen
= write(test_pipe
[1], "ABC", 3);
4101 tt_int_op(retlen
, OP_EQ
, 3);
4103 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4104 tt_int_op(errno
, OP_EQ
, 0);
4105 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4106 tt_str_op(buf
, OP_EQ
, "ABC");
4109 /* Send in a string that contains a nul. */
4110 retlen
= write(test_pipe
[1], "AB\0", 3);
4111 tt_int_op(retlen
, OP_EQ
, 3);
4113 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4114 tt_int_op(errno
, OP_EQ
, 0);
4115 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4116 tt_str_op(buf
, OP_EQ
, "AB");
4119 /* Send in a string that contains a nul only. */
4120 retlen
= write(test_pipe
[1], "\0", 1);
4121 tt_int_op(retlen
, OP_EQ
, 1);
4123 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4124 tt_int_op(errno
, OP_EQ
, 0);
4125 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4126 tt_str_op(buf
, OP_EQ
, "");
4129 /* Send in a string that contains a trailing newline. */
4130 retlen
= write(test_pipe
[1], "AB\n", 3);
4131 tt_int_op(retlen
, OP_EQ
, 3);
4133 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4134 tt_int_op(errno
, OP_EQ
, 0);
4135 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4136 tt_str_op(buf
, OP_EQ
, "AB");
4139 /* Send in a string that contains a newline only. */
4140 retlen
= write(test_pipe
[1], "\n", 1);
4141 tt_int_op(retlen
, OP_EQ
, 1);
4143 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4144 tt_int_op(errno
, OP_EQ
, 0);
4145 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4146 tt_str_op(buf
, OP_EQ
, "");
4149 /* Send in a string and check that we nul terminate return values. */
4150 retlen
= write(test_pipe
[1], "AAA", 3);
4151 tt_int_op(retlen
, OP_EQ
, 3);
4153 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4154 tt_int_op(errno
, OP_EQ
, 0);
4155 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4156 tt_str_op(buf
, OP_EQ
, "AAA");
4157 tt_mem_op(buf
, OP_EQ
, "AAA\0", sizeof(buf
));
4160 retlen
= write(test_pipe
[1], "B", 1);
4161 tt_int_op(retlen
, OP_EQ
, 1);
4163 memset(buf
, '\xff', sizeof(buf
));
4164 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4165 tt_int_op(errno
, OP_EQ
, 0);
4166 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4167 tt_str_op(buf
, OP_EQ
, "B");
4168 tt_mem_op(buf
, OP_EQ
, "B\0\xff\xff", sizeof(buf
));
4171 /* Send in multiple lines. */
4172 retlen
= write(test_pipe
[1], "A\nB", 3);
4173 tt_int_op(retlen
, OP_EQ
, 3);
4175 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4176 tt_int_op(errno
, OP_EQ
, 0);
4177 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4178 tt_str_op(buf
, OP_EQ
, "A\nB");
4181 /* Send in a line and close */
4182 retlen
= write(test_pipe
[1], "AB", 2);
4183 tt_int_op(retlen
, OP_EQ
, 2);
4184 retval
= close(test_pipe
[1]);
4185 tt_int_op(retval
, OP_EQ
, 0);
4188 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4189 tt_int_op(errno
, OP_EQ
, 0);
4190 tt_int_op(status
, OP_EQ
, IO_STREAM_OKAY
);
4191 tt_str_op(buf
, OP_EQ
, "AB");
4195 status
= get_string_from_pipe(test_pipe
[0], buf
, sizeof(buf
)-1);
4196 tt_int_op(errno
, OP_EQ
, 0);
4197 tt_int_op(status
, OP_EQ
, IO_STREAM_CLOSED
);
4201 if (test_pipe
[0] != -1)
4202 close(test_pipe
[0]);
4203 if (test_pipe
[1] != -1)
4204 close(test_pipe
[1]);
4207 #endif /* !defined(_WIN32) */
4210 * Test for format_hex_number_sigsafe()
4214 test_util_format_hex_number(void *ptr
)
4226 {"7FFFFFFF", 0x7fffffff},
4227 {"FFFFFFFF", 0xffffffff},
4228 #if UINT_MAX >= 0xffffffff
4229 {"31BC421D", 0x31bc421d},
4230 {"FFFFFFFF", 0xffffffff},
4237 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
4238 len
= format_hex_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
4239 tt_int_op(len
,OP_NE
, 0);
4240 tt_int_op(len
,OP_EQ
, strlen(buf
));
4241 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4244 tt_int_op(4,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 5));
4245 tt_str_op(buf
,OP_EQ
, "FFFF");
4246 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0xffff, buf
, 4));
4247 tt_int_op(0,OP_EQ
, format_hex_number_sigsafe(0, buf
, 1));
4254 * Test for format_hex_number_sigsafe()
4258 test_util_format_dec_number(void *ptr
)
4269 {"12345678", 12345678},
4270 {"99999999", 99999999},
4271 {"100000000", 100000000},
4272 {"4294967295", 4294967295u},
4273 #if UINT_MAX > 0xffffffff
4274 {"18446744073709551615", 18446744073709551615u },
4281 for (i
= 0; test_data
[i
].str
!= NULL
; ++i
) {
4282 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
, sizeof(buf
));
4283 tt_int_op(len
,OP_NE
, 0);
4284 tt_int_op(len
,OP_EQ
, strlen(buf
));
4285 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4287 len
= format_dec_number_sigsafe(test_data
[i
].x
, buf
,
4288 (int)(strlen(test_data
[i
].str
) + 1));
4289 tt_int_op(len
,OP_EQ
, strlen(buf
));
4290 tt_str_op(buf
,OP_EQ
, test_data
[i
].str
);
4293 tt_int_op(4,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 5));
4294 tt_str_op(buf
,OP_EQ
, "7331");
4295 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(7331, buf
, 4));
4296 tt_int_op(1,OP_EQ
, format_dec_number_sigsafe(0, buf
, 2));
4297 tt_int_op(0,OP_EQ
, format_dec_number_sigsafe(0, buf
, 1));
4304 * Test that we can properly format a Windows command line
4307 test_util_join_win_cmdline(void *ptr
)
4309 /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
4310 * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
4311 * will try to only generate simple cases for the child process to parse;
4312 * i.e. we never embed quoted strings in arguments. */
4314 const char *argvs
[][4] = {
4315 {"a", "bb", "CCC", NULL
}, // Normal
4316 {NULL
, NULL
, NULL
, NULL
}, // Empty argument list
4317 {"", NULL
, NULL
, NULL
}, // Empty argument
4318 {"\"a", "b\"b", "CCC\"", NULL
}, // Quotes
4319 {"a\tbc", "dd dd", "E", NULL
}, // Whitespace
4320 {"a\\\\\\b", "de fg", "H", NULL
}, // Backslashes
4321 {"a\\\"b", "\\c", "D\\", NULL
}, // Backslashes before quote
4322 {"a\\\\b c", "d", "E", NULL
}, // Backslashes not before quote
4323 { NULL
} // Terminator
4326 const char *cmdlines
[] = {
4330 "\\\"a b\\\"b CCC\\\"",
4331 "\"a\tbc\" \"dd dd\" E",
4332 "a\\\\\\b \"de fg\" H",
4333 "a\\\\\\\"b \\c D\\",
4339 char *joined_argv
= NULL
;
4343 for (i
=0; cmdlines
[i
]!=NULL
; i
++) {
4344 log_info(LD_GENERAL
, "Joining argvs[%d], expecting <%s>", i
, cmdlines
[i
]);
4345 joined_argv
= tor_join_win_cmdline(argvs
[i
]);
4346 tt_str_op(cmdlines
[i
],OP_EQ
, joined_argv
);
4347 tor_free(joined_argv
);
4351 tor_free(joined_argv
);
4354 #define MAX_SPLIT_LINE_COUNT 4
4355 struct split_lines_test_t
{
4356 const char *orig_line
; // Line to be split (may contain \0's)
4357 int orig_length
; // Length of orig_line
4358 const char *split_line
[MAX_SPLIT_LINE_COUNT
]; // Split lines
4362 * Test that we properly split a buffer into lines
4365 test_util_split_lines(void *ptr
)
4367 /* Test cases. orig_line of last test case must be NULL.
4368 * The last element of split_line[i] must be NULL. */
4369 struct split_lines_test_t tests
[] = {
4371 {"foo", 3, {"foo", NULL
}},
4372 {"\n\rfoo\n\rbar\r\n", 12, {"foo", "bar", NULL
}},
4373 {"fo o\r\nb\tar", 10, {"fo o", "b.ar", NULL
}},
4374 {"\x0f""f\0o\0\n\x01""b\0r\0\r", 12, {".f.o.", ".b.r.", NULL
}},
4375 {"line 1\r\nline 2", 14, {"line 1", "line 2", NULL
}},
4376 {"line 1\r\n\r\nline 2", 16, {"line 1", "line 2", NULL
}},
4377 {"line 1\r\n\r\r\r\nline 2", 18, {"line 1", "line 2", NULL
}},
4378 {"line 1\r\n\n\n\n\rline 2", 18, {"line 1", "line 2", NULL
}},
4379 {"line 1\r\n\r\t\r\nline 3", 18, {"line 1", ".", "line 3", NULL
}},
4380 {"\n\t\r\t\nline 3", 11, {".", ".", "line 3", NULL
}},
4385 char *orig_line
=NULL
;
4386 smartlist_t
*sl
=NULL
;
4390 for (i
=0; tests
[i
].orig_line
; i
++) {
4391 sl
= smartlist_new();
4392 /* Allocate space for string and trailing NULL */
4393 orig_line
= tor_memdup(tests
[i
].orig_line
, tests
[i
].orig_length
+ 1);
4394 tor_split_lines(sl
, orig_line
, tests
[i
].orig_length
);
4397 log_info(LD_GENERAL
, "Splitting test %d of length %d",
4398 i
, tests
[i
].orig_length
);
4399 SMARTLIST_FOREACH_BEGIN(sl
, const char *, line
) {
4400 /* Check we have not got too many lines */
4401 tt_int_op(MAX_SPLIT_LINE_COUNT
, OP_GT
, j
);
4402 /* Check that there actually should be a line here */
4403 tt_ptr_op(tests
[i
].split_line
[j
], OP_NE
, NULL
);
4404 log_info(LD_GENERAL
, "Line %d of test %d, should be <%s>",
4405 j
, i
, tests
[i
].split_line
[j
]);
4406 /* Check that the line is as expected */
4407 tt_str_op(line
,OP_EQ
, tests
[i
].split_line
[j
]);
4409 } SMARTLIST_FOREACH_END(line
);
4410 /* Check that we didn't miss some lines */
4411 tt_ptr_op(NULL
,OP_EQ
, tests
[i
].split_line
[j
]);
4412 tor_free(orig_line
);
4418 tor_free(orig_line
);
4423 test_util_di_ops(void *arg
)
4429 const char *a
; int want_sign
; const char *b
;
4431 { "Foo", EQ
, "Foo" },
4432 { "foo", GT
, "bar", },
4433 { "foobar", EQ
,"foobar" },
4434 { "foobar", LT
, "foobaw" },
4435 { "foobar", GT
, "f00bar" },
4436 { "foobar", GT
, "boobar" },
4444 for (i
= 0; examples
[i
].a
; ++i
) {
4445 size_t len
= strlen(examples
[i
].a
);
4446 int eq1
, eq2
, neq1
, neq2
, cmp1
, cmp2
;
4447 tt_int_op(len
,OP_EQ
, strlen(examples
[i
].b
));
4448 /* We do all of the operations, with operands in both orders. */
4449 eq1
= tor_memeq(examples
[i
].a
, examples
[i
].b
, len
);
4450 eq2
= tor_memeq(examples
[i
].b
, examples
[i
].a
, len
);
4451 neq1
= tor_memneq(examples
[i
].a
, examples
[i
].b
, len
);
4452 neq2
= tor_memneq(examples
[i
].b
, examples
[i
].a
, len
);
4453 cmp1
= tor_memcmp(examples
[i
].a
, examples
[i
].b
, len
);
4454 cmp2
= tor_memcmp(examples
[i
].b
, examples
[i
].a
, len
);
4456 /* Check for correctness of cmp1 */
4457 if (cmp1
< 0 && examples
[i
].want_sign
!= LT
)
4458 TT_DIE(("Assertion failed."));
4459 else if (cmp1
> 0 && examples
[i
].want_sign
!= GT
)
4460 TT_DIE(("Assertion failed."));
4461 else if (cmp1
== 0 && examples
[i
].want_sign
!= EQ
)
4462 TT_DIE(("Assertion failed."));
4464 /* Check for consistency of everything else with cmp1 */
4465 tt_int_op(eq1
,OP_EQ
, eq2
);
4466 tt_int_op(neq1
,OP_EQ
, neq2
);
4467 tt_int_op(cmp1
,OP_EQ
, -cmp2
);
4468 tt_int_op(eq1
,OP_EQ
, cmp1
== 0);
4469 tt_int_op(neq1
,OP_EQ
, !eq1
);
4477 /* exhaustively test tor_memeq and tor_memcmp
4478 * against each possible single-byte numeric difference
4479 * some arithmetic bugs only appear with certain bit patterns */
4480 for (z
= 0; z
< 256; z
++) {
4481 for (i
= 0; i
< 256; i
++) {
4484 tt_int_op(tor_memeq(&zz
, &ii
, 1),OP_EQ
, zz
== ii
);
4485 tt_int_op(tor_memcmp(&zz
, &ii
, 1) > 0 ? GT
: EQ
,OP_EQ
,
4487 tt_int_op(tor_memcmp(&ii
, &zz
, 1) < 0 ? LT
: EQ
,OP_EQ
,
4493 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 0));
4494 tt_int_op(1, OP_EQ
, safe_mem_is_zero("", 1));
4495 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 1));
4496 tt_int_op(0, OP_EQ
, safe_mem_is_zero("a", 2));
4497 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0a", 2));
4498 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0a", 2));
4499 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
4500 tt_int_op(1, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
4501 tt_int_op(0, OP_EQ
, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
4508 test_util_di_map(void *arg
)
4511 di_digest256_map_t
*dimap
= NULL
;
4512 uint8_t key1
[] = "Robert Anton Wilson ";
4513 uint8_t key2
[] = "Martin Gardner, _Fads&fallacies";
4514 uint8_t key3
[] = "Tom Lehrer, _Be Prepared_. ";
4515 uint8_t key4
[] = "Ursula Le Guin,_A Wizard of... ";
4517 char dflt_entry
[] = "'You have made a good beginning', but no more";
4519 tt_int_op(32, OP_EQ
, sizeof(key1
));
4520 tt_int_op(32, OP_EQ
, sizeof(key2
));
4521 tt_int_op(32, OP_EQ
, sizeof(key3
));
4523 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
4525 char *str1
= tor_strdup("You are precisely as big as what you love"
4526 " and precisely as small as what you allow"
4528 char *str2
= tor_strdup("Let us hope that Lysenko's success in Russia will"
4529 " serve for many generations to come as another"
4530 " reminder to the world of how quickly and easily"
4531 " a science can be corrupted when ignorant"
4532 " political leaders deem themselves competent"
4533 " to arbitrate scientific disputes");
4534 char *str3
= tor_strdup("Don't write naughty words on walls "
4535 "if you can't spell.");
4537 dimap_add_entry(&dimap
, key1
, str1
);
4538 dimap_add_entry(&dimap
, key2
, str2
);
4539 dimap_add_entry(&dimap
, key3
, str3
);
4541 tt_ptr_op(str1
, OP_EQ
, dimap_search(dimap
, key1
, dflt_entry
));
4542 tt_ptr_op(str3
, OP_EQ
, dimap_search(dimap
, key3
, dflt_entry
));
4543 tt_ptr_op(str2
, OP_EQ
, dimap_search(dimap
, key2
, dflt_entry
));
4544 tt_ptr_op(dflt_entry
, OP_EQ
, dimap_search(dimap
, key4
, dflt_entry
));
4547 dimap_free(dimap
, tor_free_
);
4551 * Test counting high bits
4554 test_util_n_bits_set(void *ptr
)
4557 tt_int_op(0,OP_EQ
, n_bits_set_u8(0));
4558 tt_int_op(1,OP_EQ
, n_bits_set_u8(1));
4559 tt_int_op(3,OP_EQ
, n_bits_set_u8(7));
4560 tt_int_op(1,OP_EQ
, n_bits_set_u8(8));
4561 tt_int_op(2,OP_EQ
, n_bits_set_u8(129));
4562 tt_int_op(8,OP_EQ
, n_bits_set_u8(255));
4568 * Test LHS whitespace (and comment) eater
4571 test_util_eat_whitespace(void *ptr
)
4573 const char ws
[] = { ' ', '\t', '\r' }; /* Except NL */
4579 /* Try one leading ws */
4580 strlcpy(str
, "fuubaar", sizeof(str
));
4581 for (i
= 0; i
< sizeof(ws
); ++i
) {
4583 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
4584 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4585 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
4586 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4589 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace(str
));
4590 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4591 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4592 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4595 strlcpy(str
, "", sizeof(str
));
4596 tt_ptr_op(str
,OP_EQ
, eat_whitespace(str
));
4597 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos(str
, str
));
4598 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4599 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
));
4602 strlcpy(str
, " \t\r\n", sizeof(str
));
4603 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4604 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4605 eat_whitespace_eos(str
, str
+ strlen(str
)));
4606 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
4607 eat_whitespace_no_nl(str
));
4608 tt_ptr_op(str
+ strlen(str
) - 1,OP_EQ
,
4609 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4611 strlcpy(str
, " \t\r ", sizeof(str
));
4612 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4613 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4614 eat_whitespace_eos(str
, str
+ strlen(str
)));
4615 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace_no_nl(str
));
4616 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4617 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4620 strlcpy(str
, "fuubaar", sizeof(str
));
4621 for (i
= 0; i
< sizeof(ws
); ++i
)
4623 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace(str
));
4624 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
4625 eat_whitespace_eos(str
, str
+ strlen(str
)));
4626 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
, eat_whitespace_no_nl(str
));
4627 tt_ptr_op(str
+ sizeof(ws
),OP_EQ
,
4628 eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4631 strlcpy(str
, "# Comment \n No Comment", sizeof(str
));
4632 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
4633 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4634 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4635 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4637 /* Eat comment & ws mix */
4638 strlcpy(str
, " # \t Comment \n\t\nNo Comment", sizeof(str
));
4639 tt_str_op("No Comment",OP_EQ
, eat_whitespace(str
));
4640 tt_str_op("No Comment",OP_EQ
, eat_whitespace_eos(str
, str
+ strlen(str
)));
4641 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_no_nl(str
));
4642 tt_ptr_op(str
+ 1,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4644 /* Eat entire comment */
4645 strlcpy(str
, "#Comment", sizeof(str
));
4646 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4647 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4648 eat_whitespace_eos(str
, str
+ strlen(str
)));
4649 tt_ptr_op(str
,OP_EQ
, eat_whitespace_no_nl(str
));
4650 tt_ptr_op(str
,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4652 /* Blank line, then comment */
4653 strlcpy(str
, " \t\n # Comment", sizeof(str
));
4654 tt_ptr_op(str
+ strlen(str
),OP_EQ
, eat_whitespace(str
));
4655 tt_ptr_op(str
+ strlen(str
),OP_EQ
,
4656 eat_whitespace_eos(str
, str
+ strlen(str
)));
4657 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_no_nl(str
));
4658 tt_ptr_op(str
+ 2,OP_EQ
, eat_whitespace_eos_no_nl(str
, str
+ strlen(str
)));
4664 /** Return a newly allocated smartlist containing the lines of text in
4665 * <b>lines</b>. The returned strings are heap-allocated, and must be
4666 * freed by the caller.
4668 * XXXX? Move to container.[hc] ? */
4669 static smartlist_t
*
4670 smartlist_new_from_text_lines(const char *lines
)
4672 smartlist_t
*sl
= smartlist_new();
4675 smartlist_split_string(sl
, lines
, "\n", 0, 0);
4677 last_line
= smartlist_pop_last(sl
);
4678 if (last_line
!= NULL
&& *last_line
!= '\0') {
4679 smartlist_add(sl
, last_line
);
4681 tor_free(last_line
);
4687 /** Test smartlist_new_from_text_lines */
4689 test_util_sl_new_from_text_lines(void *ptr
)
4693 { /* Normal usage */
4694 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz\n");
4695 int sl_len
= smartlist_len(sl
);
4697 tt_want_int_op(sl_len
, OP_EQ
, 3);
4699 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
4700 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
4701 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
4703 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4707 { /* No final newline */
4708 smartlist_t
*sl
= smartlist_new_from_text_lines("foo\nbar\nbaz");
4709 int sl_len
= smartlist_len(sl
);
4711 tt_want_int_op(sl_len
, OP_EQ
, 3);
4713 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
4714 if (sl_len
> 1) tt_want_str_op(smartlist_get(sl
, 1), OP_EQ
, "bar");
4715 if (sl_len
> 2) tt_want_str_op(smartlist_get(sl
, 2), OP_EQ
, "baz");
4717 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4722 smartlist_t
*sl
= smartlist_new_from_text_lines("foo");
4723 int sl_len
= smartlist_len(sl
);
4725 tt_want_int_op(sl_len
, OP_EQ
, 1);
4727 if (sl_len
> 0) tt_want_str_op(smartlist_get(sl
, 0), OP_EQ
, "foo");
4729 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4733 { /* No text at all */
4734 smartlist_t
*sl
= smartlist_new_from_text_lines("");
4735 int sl_len
= smartlist_len(sl
);
4737 tt_want_int_op(sl_len
, OP_EQ
, 0);
4739 SMARTLIST_FOREACH(sl
, void *, x
, tor_free(x
));
4745 test_util_envnames(void *ptr
)
4749 tt_assert(environment_variable_names_equal("abc", "abc"));
4750 tt_assert(environment_variable_names_equal("abc", "abc="));
4751 tt_assert(environment_variable_names_equal("abc", "abc=def"));
4752 tt_assert(environment_variable_names_equal("abc=def", "abc"));
4753 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
4755 tt_assert(environment_variable_names_equal("abc", "abc"));
4756 tt_assert(environment_variable_names_equal("abc", "abc="));
4757 tt_assert(environment_variable_names_equal("abc", "abc=def"));
4758 tt_assert(environment_variable_names_equal("abc=def", "abc"));
4759 tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
4761 tt_assert(!environment_variable_names_equal("abc", "abcd"));
4762 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
4763 tt_assert(!environment_variable_names_equal("abc=", "abcd"));
4764 tt_assert(!environment_variable_names_equal("abc=", "def"));
4765 tt_assert(!environment_variable_names_equal("abc=", "def="));
4766 tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
4768 tt_assert(!environment_variable_names_equal("", "a=def"));
4769 /* A bit surprising. */
4770 tt_assert(environment_variable_names_equal("", "=def"));
4771 tt_assert(environment_variable_names_equal("=y", "=x"));
4777 /** Test process_environment_make */
4779 test_util_make_environment(void *ptr
)
4781 const char *env_vars_string
=
4782 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
4783 "HOME=/home/foozer\n";
4784 const char expected_windows_env_block
[] =
4785 "HOME=/home/foozer\000"
4786 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
4788 size_t expected_windows_env_block_len
=
4789 sizeof(expected_windows_env_block
) - 1;
4791 smartlist_t
*env_vars
= smartlist_new_from_text_lines(env_vars_string
);
4792 smartlist_t
*env_vars_sorted
= smartlist_new();
4793 smartlist_t
*env_vars_in_unixoid_env_block_sorted
= smartlist_new();
4795 process_environment_t
*env
;
4799 env
= process_environment_make(env_vars
);
4801 /* Check that the Windows environment block is correct. */
4802 tt_want(tor_memeq(expected_windows_env_block
, env
->windows_environment_block
,
4803 expected_windows_env_block_len
));
4805 /* Now for the Unixoid environment block. We don't care which order
4806 * these environment variables are in, so we sort both lists first. */
4808 smartlist_add_all(env_vars_sorted
, env_vars
);
4812 for (v
= env
->unixoid_environment_block
; *v
; ++v
) {
4813 smartlist_add(env_vars_in_unixoid_env_block_sorted
, *v
);
4817 smartlist_sort_strings(env_vars_sorted
);
4818 smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted
);
4820 tt_want_int_op(smartlist_len(env_vars_sorted
), OP_EQ
,
4821 smartlist_len(env_vars_in_unixoid_env_block_sorted
));
4823 int len
= smartlist_len(env_vars_sorted
);
4826 if (smartlist_len(env_vars_in_unixoid_env_block_sorted
) < len
) {
4827 len
= smartlist_len(env_vars_in_unixoid_env_block_sorted
);
4830 for (i
= 0; i
< len
; ++i
) {
4831 tt_want_str_op(smartlist_get(env_vars_sorted
, i
), OP_EQ
,
4832 smartlist_get(env_vars_in_unixoid_env_block_sorted
, i
));
4837 smartlist_free(env_vars_in_unixoid_env_block_sorted
);
4838 smartlist_free(env_vars_sorted
);
4840 SMARTLIST_FOREACH(env_vars
, char *, x
, tor_free(x
));
4841 smartlist_free(env_vars
);
4843 process_environment_free(env
);
4846 /** Test set_environment_variable_in_smartlist */
4848 test_util_set_env_var_in_sl(void *ptr
)
4850 /* The environment variables in these strings are in arbitrary
4851 * order; we sort the resulting lists before comparing them.
4853 * (They *will not* end up in the order shown in
4854 * expected_resulting_env_vars_string.) */
4856 const char *base_env_vars_string
=
4857 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
4858 "HOME=/home/foozer\n"
4867 const char *new_env_vars_string
=
4872 const char *expected_resulting_env_vars_string
=
4873 "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
4874 "HOME=/home/foozer\n"
4884 smartlist_t
*merged_env_vars
=
4885 smartlist_new_from_text_lines(base_env_vars_string
);
4886 smartlist_t
*new_env_vars
=
4887 smartlist_new_from_text_lines(new_env_vars_string
);
4888 smartlist_t
*expected_resulting_env_vars
=
4889 smartlist_new_from_text_lines(expected_resulting_env_vars_string
);
4891 /* Elements of merged_env_vars are heap-allocated, and must be
4892 * freed. Some of them are (or should) be freed by
4893 * set_environment_variable_in_smartlist.
4895 * Elements of new_env_vars are heap-allocated, but are copied into
4896 * merged_env_vars, so they are not freed separately at the end of
4899 * Elements of expected_resulting_env_vars are heap-allocated, and
4904 SMARTLIST_FOREACH(new_env_vars
, char *, env_var
,
4905 set_environment_variable_in_smartlist(merged_env_vars
,
4910 smartlist_sort_strings(merged_env_vars
);
4911 smartlist_sort_strings(expected_resulting_env_vars
);
4913 tt_want_int_op(smartlist_len(merged_env_vars
), OP_EQ
,
4914 smartlist_len(expected_resulting_env_vars
));
4916 int len
= smartlist_len(merged_env_vars
);
4919 if (smartlist_len(expected_resulting_env_vars
) < len
) {
4920 len
= smartlist_len(expected_resulting_env_vars
);
4923 for (i
= 0; i
< len
; ++i
) {
4924 tt_want_str_op(smartlist_get(merged_env_vars
, i
), OP_EQ
,
4925 smartlist_get(expected_resulting_env_vars
, i
));
4930 SMARTLIST_FOREACH(merged_env_vars
, char *, x
, tor_free(x
));
4931 smartlist_free(merged_env_vars
);
4933 smartlist_free(new_env_vars
);
4935 SMARTLIST_FOREACH(expected_resulting_env_vars
, char *, x
, tor_free(x
));
4936 smartlist_free(expected_resulting_env_vars
);
4940 test_util_weak_random(void *arg
)
4946 tor_init_weak_random(&rng
, (unsigned)time(NULL
));
4948 for (i
= 1; i
<= 256; ++i
) {
4949 for (j
=0;j
<100;++j
) {
4950 int r
= tor_weak_random_range(&rng
, i
);
4951 tt_int_op(0, OP_LE
, r
);
4952 tt_int_op(r
, OP_LT
, i
);
4956 memset(n
,0,sizeof(n
));
4957 for (j
=0;j
<8192;++j
) {
4958 n
[tor_weak_random_range(&rng
, 16)]++;
4962 tt_int_op(n
[i
], OP_GT
, 0);
4968 test_util_mathlog(void *arg
)
4973 d
= tor_mathlog(2.718281828);
4974 tt_double_op(fabs(d
- 1.0), OP_LT
, .000001);
4975 d
= tor_mathlog(10);
4976 tt_double_op(fabs(d
- 2.30258509), OP_LT
, .000001);
4982 test_util_fraction(void *arg
)
4988 simplify_fraction64(&a
,&b
);
4989 tt_u64_op(a
, OP_EQ
, 33);
4990 tt_u64_op(b
, OP_EQ
, 10);
4992 a
= 3000000; b
= 10000000;
4993 simplify_fraction64(&a
,&b
);
4994 tt_u64_op(a
, OP_EQ
, 3);
4995 tt_u64_op(b
, OP_EQ
, 10);
4998 simplify_fraction64(&a
,&b
);
4999 tt_u64_op(a
, OP_EQ
, 0);
5000 tt_u64_op(b
, OP_EQ
, 1);
5007 test_util_round_to_next_multiple_of(void *arg
)
5011 tt_u64_op(round_uint64_to_next_multiple_of(0,1), OP_EQ
, 0);
5012 tt_u64_op(round_uint64_to_next_multiple_of(0,7), OP_EQ
, 0);
5014 tt_u64_op(round_uint64_to_next_multiple_of(99,1), OP_EQ
, 99);
5015 tt_u64_op(round_uint64_to_next_multiple_of(99,7), OP_EQ
, 105);
5016 tt_u64_op(round_uint64_to_next_multiple_of(99,9), OP_EQ
, 99);
5018 tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX
,2), OP_EQ
,
5021 tt_int_op(round_uint32_to_next_multiple_of(0,1), OP_EQ
, 0);
5022 tt_int_op(round_uint32_to_next_multiple_of(0,7), OP_EQ
, 0);
5024 tt_int_op(round_uint32_to_next_multiple_of(99,1), OP_EQ
, 99);
5025 tt_int_op(round_uint32_to_next_multiple_of(99,7), OP_EQ
, 105);
5026 tt_int_op(round_uint32_to_next_multiple_of(99,9), OP_EQ
, 99);
5028 tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX
,2), OP_EQ
,
5031 tt_uint_op(round_to_next_multiple_of(0,1), OP_EQ
, 0);
5032 tt_uint_op(round_to_next_multiple_of(0,7), OP_EQ
, 0);
5034 tt_uint_op(round_to_next_multiple_of(99,1), OP_EQ
, 99);
5035 tt_uint_op(round_to_next_multiple_of(99,7), OP_EQ
, 105);
5036 tt_uint_op(round_to_next_multiple_of(99,9), OP_EQ
, 99);
5038 tt_uint_op(round_to_next_multiple_of(UINT_MAX
,2), OP_EQ
,
5045 test_util_laplace(void *arg
)
5047 /* Sample values produced using Python's SciPy:
5049 * >>> from scipy.stats import laplace
5050 * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
5051 ... loc = 24, scale = 24)
5052 * array([ nan, -inf, -69.88855213, 24. ,
5053 * 24.48486498, 117.88855213, inf, nan])
5055 const double mu
= 24.0, b
= 24.0;
5056 const double delta_f
= 15.0, epsilon
= 0.3; /* b = 15.0 / 0.3 = 50.0 */
5059 tt_i64_op(INT64_MIN
, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.0));
5060 tt_i64_op(-69, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.01));
5061 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.5));
5062 tt_i64_op(24, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.51));
5063 tt_i64_op(117, OP_EQ
, sample_laplace_distribution(mu
, b
, 0.99));
5065 /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
5066 * ... loc = 0, scale = 50)
5067 * array([ -inf, -80.47189562, -34.65735903, 0. ,
5068 * 34.65735903, 80.47189562, 195.60115027])
5070 tt_i64_op(INT64_MIN
+ 20, OP_EQ
,
5071 add_laplace_noise(20, 0.0, delta_f
, epsilon
));
5073 tt_i64_op(-60, OP_EQ
, add_laplace_noise(20, 0.1, delta_f
, epsilon
));
5074 tt_i64_op(-14, OP_EQ
, add_laplace_noise(20, 0.25, delta_f
, epsilon
));
5075 tt_i64_op(20, OP_EQ
, add_laplace_noise(20, 0.5, delta_f
, epsilon
));
5076 tt_i64_op(54, OP_EQ
, add_laplace_noise(20, 0.75, delta_f
, epsilon
));
5077 tt_i64_op(100, OP_EQ
, add_laplace_noise(20, 0.9, delta_f
, epsilon
));
5078 tt_i64_op(215, OP_EQ
, add_laplace_noise(20, 0.99, delta_f
, epsilon
));
5080 /* Test extreme values of signal with maximally negative values of noise
5081 * 1.0000000000000002 is the smallest number > 1
5082 * 0.0000000000000002 is the double epsilon (error when calculating near 1)
5083 * this is approximately 1/(2^52)
5084 * per https://en.wikipedia.org/wiki/Double_precision
5085 * (let's not descend into the world of subnormals)
5086 * >>> laplace.ppf([0, 0.0000000000000002], loc = 0, scale = 1)
5087 * array([ -inf, -35.45506713])
5089 const double noscale_df
= 1.0, noscale_eps
= 1.0;
5091 tt_i64_op(INT64_MIN
, OP_EQ
,
5092 add_laplace_noise(0, 0.0, noscale_df
, noscale_eps
));
5094 /* is it clipped to INT64_MIN? */
5095 tt_i64_op(INT64_MIN
, OP_EQ
,
5096 add_laplace_noise(-1, 0.0, noscale_df
, noscale_eps
));
5097 tt_i64_op(INT64_MIN
, OP_EQ
,
5098 add_laplace_noise(INT64_MIN
, 0.0,
5099 noscale_df
, noscale_eps
));
5100 /* ... even when scaled? */
5101 tt_i64_op(INT64_MIN
, OP_EQ
,
5102 add_laplace_noise(0, 0.0, delta_f
, epsilon
));
5103 tt_i64_op(INT64_MIN
, OP_EQ
,
5104 add_laplace_noise(0, 0.0,
5106 tt_i64_op(INT64_MIN
, OP_EQ
,
5107 add_laplace_noise(INT64_MIN
, 0.0,
5110 /* does it play nice with INT64_MAX? */
5111 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5112 add_laplace_noise(INT64_MAX
, 0.0,
5113 noscale_df
, noscale_eps
));
5115 /* do near-zero fractional values work? */
5116 const double min_dbl_error
= 0.0000000000000002;
5118 tt_i64_op(-35, OP_EQ
,
5119 add_laplace_noise(0, min_dbl_error
,
5120 noscale_df
, noscale_eps
));
5121 tt_i64_op(INT64_MIN
, OP_EQ
,
5122 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5123 noscale_df
, noscale_eps
));
5124 tt_i64_op((-35 + INT64_MAX
), OP_EQ
,
5125 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5126 noscale_df
, noscale_eps
));
5127 tt_i64_op(INT64_MIN
, OP_EQ
,
5128 add_laplace_noise(0, min_dbl_error
,
5130 tt_i64_op((INT64_MAX
+ INT64_MIN
), OP_EQ
,
5131 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5133 tt_i64_op(INT64_MIN
, OP_EQ
,
5134 add_laplace_noise(INT64_MIN
, min_dbl_error
,
5137 /* does it play nice with INT64_MAX? */
5138 tt_i64_op((INT64_MAX
- 35), OP_EQ
,
5139 add_laplace_noise(INT64_MAX
, min_dbl_error
,
5140 noscale_df
, noscale_eps
));
5142 /* Test extreme values of signal with maximally positive values of noise
5143 * 1.0000000000000002 is the smallest number > 1
5144 * 0.9999999999999998 is the greatest number < 1 by calculation
5145 * per https://en.wikipedia.org/wiki/Double_precision
5146 * >>> laplace.ppf([1.0, 0.9999999999999998], loc = 0, scale = 1)
5147 * array([inf, 35.35050621])
5148 * but the function rejects p == 1.0, so we just use max_dbl_lt_one
5150 const double max_dbl_lt_one
= 0.9999999999999998;
5152 /* do near-one fractional values work? */
5153 tt_i64_op(35, OP_EQ
,
5154 add_laplace_noise(0, max_dbl_lt_one
, noscale_df
, noscale_eps
));
5156 /* is it clipped to INT64_MAX? */
5157 tt_i64_op(INT64_MAX
, OP_EQ
,
5158 add_laplace_noise(INT64_MAX
- 35, max_dbl_lt_one
,
5159 noscale_df
, noscale_eps
));
5160 tt_i64_op(INT64_MAX
, OP_EQ
,
5161 add_laplace_noise(INT64_MAX
- 34, max_dbl_lt_one
,
5162 noscale_df
, noscale_eps
));
5163 tt_i64_op(INT64_MAX
, OP_EQ
,
5164 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5165 noscale_df
, noscale_eps
));
5166 /* ... even when scaled? */
5167 tt_i64_op(INT64_MAX
, OP_EQ
,
5168 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5170 tt_i64_op((INT64_MIN
+ INT64_MAX
), OP_EQ
,
5171 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5173 tt_i64_op(INT64_MAX
, OP_EQ
,
5174 add_laplace_noise(INT64_MAX
, max_dbl_lt_one
,
5176 /* does it play nice with INT64_MIN? */
5177 tt_i64_op((INT64_MIN
+ 35), OP_EQ
,
5178 add_laplace_noise(INT64_MIN
, max_dbl_lt_one
,
5179 noscale_df
, noscale_eps
));
5186 test_util_clamp_double_to_int64(void *arg
)
5190 tt_i64_op(INT64_MIN
, OP_EQ
, clamp_double_to_int64(-INFINITY_DBL
));
5191 tt_i64_op(INT64_MIN
, OP_EQ
,
5192 clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0));
5193 tt_i64_op(INT64_MIN
, OP_EQ
,
5194 clamp_double_to_int64(-1.0 * pow(2.0, 63.0) - 1.0));
5195 tt_i64_op(((uint64_t) -1) << 53, OP_EQ
,
5196 clamp_double_to_int64(-1.0 * pow(2.0, 53.0)));
5197 tt_i64_op((((uint64_t) -1) << 53) + 1, OP_EQ
,
5198 clamp_double_to_int64(-1.0 * pow(2.0, 53.0) + 1.0));
5199 tt_i64_op(-1, OP_EQ
, clamp_double_to_int64(-1.0));
5200 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.9));
5201 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(-0.1));
5202 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.0));
5203 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(NAN_DBL
));
5204 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.1));
5205 tt_i64_op(0, OP_EQ
, clamp_double_to_int64(0.9));
5206 tt_i64_op(1, OP_EQ
, clamp_double_to_int64(1.0));
5207 tt_i64_op((((int64_t) 1) << 53) - 1, OP_EQ
,
5208 clamp_double_to_int64(pow(2.0, 53.0) - 1.0));
5209 tt_i64_op(((int64_t) 1) << 53, OP_EQ
,
5210 clamp_double_to_int64(pow(2.0, 53.0)));
5211 tt_i64_op(INT64_MAX
, OP_EQ
,
5212 clamp_double_to_int64(pow(2.0, 63.0)));
5213 tt_i64_op(INT64_MAX
, OP_EQ
,
5214 clamp_double_to_int64(pow(2.0, 64.0)));
5215 tt_i64_op(INT64_MAX
, OP_EQ
, clamp_double_to_int64(INFINITY_DBL
));
5222 #define CAN_CHECK_CLOEXEC
5224 fd_is_cloexec(tor_socket_t fd
)
5226 int flags
= fcntl(fd
, F_GETFD
, 0);
5227 return (flags
& FD_CLOEXEC
) == FD_CLOEXEC
;
5229 #endif /* defined(FD_CLOEXEC) */
5232 #define CAN_CHECK_NONBLOCK
5234 fd_is_nonblocking(tor_socket_t fd
)
5236 int flags
= fcntl(fd
, F_GETFL
, 0);
5237 return (flags
& O_NONBLOCK
) == O_NONBLOCK
;
5239 #endif /* !defined(_WIN32) */
5241 #define ERRNO_IS_EPROTO(e) (e == SOCK_ERRNO(EPROTONOSUPPORT))
5242 #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s))
5244 /* Test for tor_open_socket*, using IPv4 or IPv6 depending on arg. */
5246 test_util_socket(void *arg
)
5248 const int domain
= !strcmp(arg
, "4") ? AF_INET
: AF_INET6
;
5249 tor_socket_t fd1
= TOR_INVALID_SOCKET
;
5250 tor_socket_t fd2
= TOR_INVALID_SOCKET
;
5251 tor_socket_t fd3
= TOR_INVALID_SOCKET
;
5252 tor_socket_t fd4
= TOR_INVALID_SOCKET
;
5253 int n
= get_n_open_sockets();
5255 TT_BLATHER(("Starting with %d open sockets.", n
));
5259 fd1
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 0);
5260 int err
= tor_socket_errno(fd1
);
5261 if (fd1
< 0 && (err
== SOCK_ERRNO(EPROTONOSUPPORT
) ||
5262 err
== SOCK_ERRNO(EAFNOSUPPORT
))) {
5263 /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */
5266 fd2
= tor_open_socket_with_extensions(domain
, SOCK_STREAM
, 0, 0, 1);
5267 tt_assert(SOCKET_OK(fd1
));
5268 tt_assert(SOCKET_OK(fd2
));
5269 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5270 //fd3 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 0);
5271 //fd4 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 1);
5272 fd3
= tor_open_socket(domain
, SOCK_STREAM
, 0);
5273 fd4
= tor_open_socket_nonblocking(domain
, SOCK_STREAM
, 0);
5274 tt_assert(SOCKET_OK(fd3
));
5275 tt_assert(SOCKET_OK(fd4
));
5276 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 4);
5278 #ifdef CAN_CHECK_CLOEXEC
5279 tt_int_op(fd_is_cloexec(fd1
), OP_EQ
, 0);
5280 tt_int_op(fd_is_cloexec(fd2
), OP_EQ
, 0);
5281 tt_int_op(fd_is_cloexec(fd3
), OP_EQ
, 1);
5282 tt_int_op(fd_is_cloexec(fd4
), OP_EQ
, 1);
5283 #endif /* defined(CAN_CHECK_CLOEXEC) */
5284 #ifdef CAN_CHECK_NONBLOCK
5285 tt_int_op(fd_is_nonblocking(fd1
), OP_EQ
, 0);
5286 tt_int_op(fd_is_nonblocking(fd2
), OP_EQ
, 1);
5287 tt_int_op(fd_is_nonblocking(fd3
), OP_EQ
, 0);
5288 tt_int_op(fd_is_nonblocking(fd4
), OP_EQ
, 1);
5289 #endif /* defined(CAN_CHECK_NONBLOCK) */
5291 tor_assert(tor_close_socket
== tor_close_socket__real
);
5293 /* we use close_socket__real here so that coverity can tell that we are
5294 * really closing these sockets. */
5295 tor_close_socket__real(fd1
);
5296 tor_close_socket__real(fd2
);
5297 fd1
= fd2
= TOR_INVALID_SOCKET
;
5298 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5299 tor_close_socket__real(fd3
);
5300 tor_close_socket__real(fd4
);
5301 fd3
= fd4
= TOR_INVALID_SOCKET
;
5302 tt_int_op(get_n_open_sockets(), OP_EQ
, n
);
5306 tor_close_socket__real(fd1
);
5308 tor_close_socket__real(fd2
);
5310 tor_close_socket__real(fd3
);
5312 tor_close_socket__real(fd4
);
5317 is_there_a_localhost(int family
)
5320 s
= tor_open_socket(family
, SOCK_STREAM
, IPPROTO_TCP
);
5321 tor_assert(SOCKET_OK(s
));
5324 if (family
== AF_INET
) {
5325 struct sockaddr_in s_in
;
5326 memset(&s_in
, 0, sizeof(s_in
));
5327 s_in
.sin_family
= AF_INET
;
5328 s_in
.sin_addr
.s_addr
= htonl(0x7f000001);
5331 if (bind(s
, (void*)&s_in
, sizeof(s_in
)) == 0) {
5334 } else if (family
== AF_INET6
) {
5335 struct sockaddr_in6 sin6
;
5336 memset(&sin6
, 0, sizeof(sin6
));
5337 sin6
.sin6_family
= AF_INET6
;
5338 sin6
.sin6_addr
.s6_addr
[15] = 1;
5341 tor_close_socket(s
);
5347 /* Test for socketpair and ersatz_socketpair(). We test them both, since
5348 * the latter is a tolerably good way to exersize tor_accept_socket(). */
5350 test_util_socketpair(void *arg
)
5352 const int ersatz
= !strcmp(arg
, "1");
5353 int (*const tor_socketpair_fn
)(int, int, int, tor_socket_t
[2]) =
5354 ersatz
? tor_ersatz_socketpair
: tor_socketpair
;
5355 int n
= get_n_open_sockets();
5356 tor_socket_t fds
[2] = {TOR_INVALID_SOCKET
, TOR_INVALID_SOCKET
};
5357 const int family
= AF_UNIX
;
5358 int socketpair_result
= 0;
5360 socketpair_result
= tor_socketpair_fn(family
, SOCK_STREAM
, 0, fds
);
5363 /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
5364 * Otherwise, we risk exposing a socketpair on a routable IP address. (Some
5365 * BSD jails use a routable address for localhost. Fortunately, they have
5366 * the real AF_UNIX socketpair.) */
5367 if (ersatz
&& socketpair_result
< 0) {
5368 /* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
5369 * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
5372 #endif /* defined(__FreeBSD__) */
5373 tt_int_op(0, OP_EQ
, socketpair_result
);
5375 tt_assert(SOCKET_OK(fds
[0]));
5376 tt_assert(SOCKET_OK(fds
[1]));
5377 tt_int_op(get_n_open_sockets(), OP_EQ
, n
+ 2);
5378 #ifdef CAN_CHECK_CLOEXEC
5379 tt_int_op(fd_is_cloexec(fds
[0]), OP_EQ
, 1);
5380 tt_int_op(fd_is_cloexec(fds
[1]), OP_EQ
, 1);
5382 #ifdef CAN_CHECK_NONBLOCK
5383 tt_int_op(fd_is_nonblocking(fds
[0]), OP_EQ
, 0);
5384 tt_int_op(fd_is_nonblocking(fds
[1]), OP_EQ
, 0);
5388 if (SOCKET_OK(fds
[0]))
5389 tor_close_socket(fds
[0]);
5390 if (SOCKET_OK(fds
[1]))
5391 tor_close_socket(fds
[1]);
5394 #undef SOCKET_EPROTO
5397 test_util_max_mem(void *arg
)
5399 size_t memory1
, memory2
;
5403 r
= get_total_system_memory(&memory1
);
5404 r2
= get_total_system_memory(&memory2
);
5405 tt_int_op(r
, OP_EQ
, r2
);
5406 tt_uint_op(memory2
, OP_EQ
, memory1
);
5408 TT_BLATHER(("System memory: "U64_FORMAT
, U64_PRINTF_ARG(memory1
)));
5411 /* You have at least a megabyte. */
5412 tt_uint_op(memory1
, OP_GT
, (1<<20));
5414 /* You do not have a petabyte. */
5415 #if SIZEOF_SIZE_T == SIZEOF_UINT64_T
5416 tt_u64_op(memory1
, OP_LT
, (U64_LITERAL(1)<<50));
5425 test_util_hostname_validation(void *arg
)
5429 // Lets try valid hostnames first.
5430 tt_assert(string_is_valid_hostname("torproject.org"));
5431 tt_assert(string_is_valid_hostname("ocw.mit.edu"));
5432 tt_assert(string_is_valid_hostname("i.4cdn.org"));
5433 tt_assert(string_is_valid_hostname("stanford.edu"));
5434 tt_assert(string_is_valid_hostname("multiple-words-with-hypens.jp"));
5436 // Subdomain name cannot start with '-' or '_'.
5437 tt_assert(!string_is_valid_hostname("-torproject.org"));
5438 tt_assert(!string_is_valid_hostname("subdomain.-domain.org"));
5439 tt_assert(!string_is_valid_hostname("-subdomain.domain.org"));
5440 tt_assert(!string_is_valid_hostname("___abc.org"));
5442 // Hostnames cannot contain non-alphanumeric characters.
5443 tt_assert(!string_is_valid_hostname("%%domain.\\org."));
5444 tt_assert(!string_is_valid_hostname("***x.net"));
5445 tt_assert(!string_is_valid_hostname("\xff\xffxyz.org"));
5446 tt_assert(!string_is_valid_hostname("word1 word2.net"));
5448 // Test workaround for nytimes.com stupidity, technically invalid,
5449 // but we allow it since they are big, even though they are failing to
5450 // comply with a ~30 year old standard.
5451 tt_assert(string_is_valid_hostname("core3_euw1.fabrik.nytimes.com"));
5453 // Firefox passes FQDNs with trailing '.'s directly to the SOCKS proxy,
5454 // which is redundant since the spec states DOMAINNAME addresses are fully
5455 // qualified. While unusual, this should be tollerated.
5456 tt_assert(string_is_valid_hostname("core9_euw1.fabrik.nytimes.com."));
5457 tt_assert(!string_is_valid_hostname("..washingtonpost.is.better.com"));
5458 tt_assert(!string_is_valid_hostname("so.is..ft.com"));
5459 tt_assert(!string_is_valid_hostname("..."));
5461 // XXX: do we allow single-label DNS names?
5462 // We shouldn't for SOCKS (spec says "contains a fully-qualified domain name"
5463 // but only test pathologically malformed traling '.' cases for now.
5464 tt_assert(!string_is_valid_hostname("."));
5465 tt_assert(!string_is_valid_hostname(".."));
5472 test_util_ipv4_validation(void *arg
)
5476 tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
5477 tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
5479 tt_assert(!string_is_valid_ipv4_address("abcd"));
5480 tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
5481 tt_assert(!string_is_valid_ipv4_address("8.8."));
5488 test_util_writepid(void *arg
)
5492 char *contents
= NULL
;
5493 const char *fname
= get_fname("tmp_pid");
5497 write_pidfile(fname
);
5499 contents
= read_file_to_str(fname
, 0, NULL
);
5500 tt_assert(contents
);
5502 int n
= tor_sscanf(contents
, "%lu\n%c", &pid
, &c
);
5503 tt_int_op(n
, OP_EQ
, 1);
5506 tt_uint_op(pid
, OP_EQ
, _getpid());
5508 tt_uint_op(pid
, OP_EQ
, getpid());
5516 test_util_get_avail_disk_space(void *arg
)
5521 /* No answer for nonexistent directory */
5522 val
= tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
5523 tt_i64_op(val
, OP_EQ
, -1);
5525 /* Try the current directory */
5526 val
= tor_get_avail_disk_space(".");
5528 #if !defined(HAVE_STATVFS) && !defined(_WIN32)
5529 tt_i64_op(val
, OP_EQ
, -1); /* You don't have an implementation for this */
5531 tt_i64_op(val
, OP_GT
, 0); /* You have some space. */
5532 tt_i64_op(val
, OP_LT
, ((int64_t)1)<<56); /* You don't have a zebibyte */
5533 #endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */
5540 test_util_touch_file(void *arg
)
5543 const char *fname
= get_fname("touch");
5545 const time_t now
= time(NULL
);
5547 write_bytes_to_file(fname
, "abc", 3, 1);
5548 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5549 /* A subtle point: the filesystem time is not necessarily equal to the
5550 * system clock time, since one can be using a monotonic clock, or coarse
5551 * monotonic clock, or whatever. So we might wind up with an mtime a few
5552 * microseconds ago. Let's just give it a lot of wiggle room. */
5553 tt_i64_op(st
.st_mtime
, OP_GE
, now
- 1);
5555 const time_t five_sec_ago
= now
- 5;
5556 struct utimbuf u
= { five_sec_ago
, five_sec_ago
};
5557 tt_int_op(0, OP_EQ
, utime(fname
, &u
));
5558 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5559 /* Let's hope that utime/stat give the same second as a round-trip? */
5560 tt_i64_op(st
.st_mtime
, OP_EQ
, five_sec_ago
);
5562 /* Finally we can touch the file */
5563 tt_int_op(0, OP_EQ
, touch_file(fname
));
5564 tt_int_op(0, OP_EQ
, stat(fname
, &st
));
5565 tt_i64_op(st
.st_mtime
, OP_GE
, now
-1);
5573 test_util_pwdb(void *arg
)
5576 const struct passwd
*me
= NULL
, *me2
, *me3
;
5580 /* Uncached case. */
5581 /* Let's assume that we exist. */
5582 me
= tor_getpwuid(getuid());
5583 tt_ptr_op(me
, OP_NE
, NULL
);
5584 name
= tor_strdup(me
->pw_name
);
5587 me2
= tor_getpwnam(name
);
5588 tt_ptr_op(me2
, OP_NE
, NULL
);
5589 tt_int_op(me2
->pw_uid
, OP_EQ
, getuid());
5592 me3
= tor_getpwuid(getuid());
5593 tt_ptr_op(me3
, OP_NE
, NULL
);
5594 tt_str_op(me3
->pw_name
, OP_EQ
, name
);
5596 me3
= tor_getpwnam(name
);
5597 tt_ptr_op(me3
, OP_NE
, NULL
);
5598 tt_int_op(me3
->pw_uid
, OP_EQ
, getuid());
5600 dir
= get_user_homedir(name
);
5601 tt_ptr_op(dir
, OP_NE
, NULL
);
5603 /* Try failing cases. First find a user that doesn't exist by name */
5607 for (i
= 0; i
< 100; ++i
) {
5608 crypto_rand(randbytes
, sizeof(randbytes
));
5609 base16_encode(badname
, sizeof(badname
), randbytes
, sizeof(randbytes
));
5610 if (tor_getpwnam(badname
) == NULL
) {
5618 /* We should do a LOG_ERR */
5619 setup_full_capture_of_logs(LOG_ERR
);
5620 dir
= get_user_homedir(badname
);
5621 tt_ptr_op(dir
, OP_EQ
, NULL
);
5622 expect_log_msg_containing("not found");
5623 tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ
, 1);
5624 teardown_capture_of_logs();
5626 /* Now try to find a user that doesn't exist by ID. */
5628 for (i
= 0; i
< 1000; ++i
) {
5630 crypto_rand((char*)&u
, sizeof(u
));
5631 if (tor_getpwuid(u
) == NULL
) {
5641 teardown_capture_of_logs();
5643 #endif /* !defined(_WIN32) */
5646 test_util_calloc_check(void *arg
)
5649 /* Easy cases that are good. */
5650 tt_assert(size_mul_check(0,0));
5651 tt_assert(size_mul_check(0,100));
5652 tt_assert(size_mul_check(100,0));
5653 tt_assert(size_mul_check(100,100));
5655 /* Harder cases that are still good. */
5656 tt_assert(size_mul_check(SIZE_MAX
, 1));
5657 tt_assert(size_mul_check(1, SIZE_MAX
));
5658 tt_assert(size_mul_check(SIZE_MAX
/ 10, 9));
5659 tt_assert(size_mul_check(11, SIZE_MAX
/ 12));
5660 const size_t sqrt_size_max_p1
= ((size_t)1) << (sizeof(size_t) * 4);
5661 tt_assert(size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
- 1));
5663 /* Cases that overflow */
5664 tt_assert(! size_mul_check(SIZE_MAX
, 2));
5665 tt_assert(! size_mul_check(2, SIZE_MAX
));
5666 tt_assert(! size_mul_check(SIZE_MAX
/ 10, 11));
5667 tt_assert(! size_mul_check(11, SIZE_MAX
/ 10));
5668 tt_assert(! size_mul_check(SIZE_MAX
/ 8, 9));
5669 tt_assert(! size_mul_check(sqrt_size_max_p1
, sqrt_size_max_p1
));
5676 test_util_monotonic_time(void *arg
)
5680 monotime_t mt1
, mt2
;
5681 monotime_coarse_t mtc1
, mtc2
;
5682 uint64_t nsec1
, nsec2
, usec1
, msec1
;
5683 uint64_t nsecc1
, nsecc2
, usecc1
, msecc1
;
5688 monotime_coarse_get(&mtc1
);
5689 nsec1
= monotime_absolute_nsec();
5690 usec1
= monotime_absolute_usec();
5691 msec1
= monotime_absolute_msec();
5692 nsecc1
= monotime_coarse_absolute_nsec();
5693 usecc1
= monotime_coarse_absolute_usec();
5694 msecc1
= monotime_coarse_absolute_msec();
5696 tor_sleep_msec(200);
5699 monotime_coarse_get(&mtc2
);
5700 nsec2
= monotime_absolute_nsec();
5701 nsecc2
= monotime_coarse_absolute_nsec();
5703 /* We need to be a little careful here since we don't know the system load.
5705 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_GE
, 175);
5706 tt_i64_op(monotime_diff_msec(&mt1
, &mt2
), OP_LT
, 1000);
5707 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_GE
, 125);
5708 tt_i64_op(monotime_coarse_diff_msec(&mtc1
, &mtc2
), OP_LT
, 1000);
5709 tt_u64_op(nsec2
-nsec1
, OP_GE
, 175000000);
5710 tt_u64_op(nsec2
-nsec1
, OP_LT
, 1000000000);
5711 tt_u64_op(nsecc2
-nsecc1
, OP_GE
, 125000000);
5712 tt_u64_op(nsecc2
-nsecc1
, OP_LT
, 1000000000);
5714 tt_u64_op(msec1
, OP_GE
, nsec1
/ 1000000);
5715 tt_u64_op(usec1
, OP_GE
, nsec1
/ 1000);
5716 tt_u64_op(msecc1
, OP_GE
, nsecc1
/ 1000000);
5717 tt_u64_op(usecc1
, OP_GE
, nsecc1
/ 1000);
5718 tt_u64_op(msec1
, OP_LE
, nsec1
/ 1000000 + 1);
5719 tt_u64_op(usec1
, OP_LE
, nsec1
/ 1000 + 1000);
5720 tt_u64_op(msecc1
, OP_LE
, nsecc1
/ 1000000 + 1);
5721 tt_u64_op(usecc1
, OP_LE
, nsecc1
/ 1000 + 1000);
5728 test_util_monotonic_time_ratchet(void *arg
)
5732 monotime_reset_ratchets_for_testing();
5734 /* win32, performance counter ratchet. */
5735 tt_i64_op(100, OP_EQ
, ratchet_performance_counter(100));
5736 tt_i64_op(101, OP_EQ
, ratchet_performance_counter(101));
5737 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(2000));
5738 tt_i64_op(2000, OP_EQ
, ratchet_performance_counter(100));
5739 tt_i64_op(2005, OP_EQ
, ratchet_performance_counter(105));
5740 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1105));
5741 tt_i64_op(3005, OP_EQ
, ratchet_performance_counter(1000));
5742 tt_i64_op(3010, OP_EQ
, ratchet_performance_counter(1005));
5744 /* win32, GetTickCounts32 ratchet-and-rollover-detector. */
5745 const int64_t R
= ((int64_t)1) << 32;
5746 tt_i64_op(5, OP_EQ
, ratchet_coarse_performance_counter(5));
5747 tt_i64_op(1000, OP_EQ
, ratchet_coarse_performance_counter(1000));
5748 tt_i64_op(5+R
, OP_EQ
, ratchet_coarse_performance_counter(5));
5749 tt_i64_op(10+R
, OP_EQ
, ratchet_coarse_performance_counter(10));
5750 tt_i64_op(4+R
*2, OP_EQ
, ratchet_coarse_performance_counter(4));
5752 /* gettimeofday regular ratchet. */
5753 struct timeval tv_in
= {0,0}, tv_out
;
5754 tv_in
.tv_usec
= 9000;
5756 ratchet_timeval(&tv_in
, &tv_out
);
5757 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 9000);
5758 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 0);
5760 tv_in
.tv_sec
= 1337;
5762 ratchet_timeval(&tv_in
, &tv_out
);
5763 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
5764 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
5766 tv_in
.tv_sec
= 1336;
5767 tv_in
.tv_usec
= 500000;
5768 ratchet_timeval(&tv_in
, &tv_out
);
5769 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 0);
5770 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
5772 tv_in
.tv_sec
= 1337;
5774 ratchet_timeval(&tv_in
, &tv_out
);
5775 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 500000);
5776 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1337);
5778 tv_in
.tv_sec
= 1337;
5779 tv_in
.tv_usec
= 600000;
5780 ratchet_timeval(&tv_in
, &tv_out
);
5781 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
5782 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
5784 tv_in
.tv_sec
= 1000;
5785 tv_in
.tv_usec
= 1000;
5786 ratchet_timeval(&tv_in
, &tv_out
);
5787 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 100000);
5788 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 1338);
5790 tv_in
.tv_sec
= 2000;
5791 tv_in
.tv_usec
= 2000;
5792 ratchet_timeval(&tv_in
, &tv_out
);
5793 tt_int_op(tv_out
.tv_usec
, OP_EQ
, 101000);
5794 tt_i64_op(tv_out
.tv_sec
, OP_EQ
, 2338);
5801 test_util_htonll(void *arg
)
5804 #ifdef WORDS_BIGENDIAN
5805 const uint64_t res_be
= 0x8877665544332211;
5807 const uint64_t res_le
= 0x1122334455667788;
5810 tt_u64_op(0, OP_EQ
, tor_htonll(0));
5811 tt_u64_op(0, OP_EQ
, tor_ntohll(0));
5812 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_htonll(UINT64_MAX
));
5813 tt_u64_op(UINT64_MAX
, OP_EQ
, tor_ntohll(UINT64_MAX
));
5815 #ifdef WORDS_BIGENDIAN
5816 tt_u64_op(res_be
, OP_EQ
, tor_htonll(0x8877665544332211));
5817 tt_u64_op(res_be
, OP_EQ
, tor_ntohll(0x8877665544332211));
5819 tt_u64_op(res_le
, OP_EQ
, tor_htonll(0x8877665544332211));
5820 tt_u64_op(res_le
, OP_EQ
, tor_ntohll(0x8877665544332211));
5821 #endif /* defined(WORDS_BIGENDIAN) */
5828 test_util_get_unquoted_path(void *arg
)
5834 r
= get_unquoted_path("\""); // "
5835 tt_ptr_op(r
, OP_EQ
, NULL
);
5838 r
= get_unquoted_path("\"\"\""); // """
5839 tt_ptr_op(r
, OP_EQ
, NULL
);
5842 r
= get_unquoted_path("\\\""); // \"
5843 tt_ptr_op(r
, OP_EQ
, NULL
);
5846 r
= get_unquoted_path("\\\"\\\""); // \"\"
5847 tt_ptr_op(r
, OP_EQ
, NULL
);
5850 r
= get_unquoted_path("A\\B\\C\""); // A\B\C"
5851 tt_ptr_op(r
, OP_EQ
, NULL
);
5854 r
= get_unquoted_path("\"A\\B\\C"); // "A\B\C
5855 tt_ptr_op(r
, OP_EQ
, NULL
);
5858 r
= get_unquoted_path("\"A\\B\"C\""); // "A\B"C"
5859 tt_ptr_op(r
, OP_EQ
, NULL
);
5862 r
= get_unquoted_path("A\\B\"C"); // A\B"C
5863 tt_ptr_op(r
, OP_EQ
, NULL
);
5866 r
= get_unquoted_path("");
5867 tt_str_op(r
, OP_EQ
, "");
5870 r
= get_unquoted_path("\"\""); // ""
5871 tt_str_op(r
, OP_EQ
, "");
5874 r
= get_unquoted_path("A\\B\\C"); // A\B\C
5875 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
5878 r
= get_unquoted_path("\"A\\B\\C\""); // "A\B\C"
5879 tt_str_op(r
, OP_EQ
, "A\\B\\C"); // A\B\C
5882 r
= get_unquoted_path("\"\\\""); // "\"
5883 tt_str_op(r
, OP_EQ
, "\\"); // \ /* comment to prevent line continuation */
5886 r
= get_unquoted_path("\"\\\"\""); // "\""
5887 tt_str_op(r
, OP_EQ
, "\""); // "
5890 r
= get_unquoted_path("\"A\\B\\C\\\"\""); // "A\B\C\""
5891 tt_str_op(r
, OP_EQ
, "A\\B\\C\""); // A\B\C"
5894 r
= get_unquoted_path("A\\B\\\"C"); // A\B\"C
5895 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
5898 r
= get_unquoted_path("\"A\\B\\\"C\""); // "A\B\"C"
5899 tt_str_op(r
, OP_EQ
, "A\\B\"C"); // A\B"C
5905 #define UTIL_LEGACY(name) \
5906 { #name, test_util_ ## name , 0, NULL, NULL }
5908 #define UTIL_TEST(name, flags) \
5909 { #name, test_util_ ## name, flags, NULL, NULL }
5911 #define COMPRESS(name, identifier) \
5912 { "compress/" #name, test_util_compress, 0, &passthrough_setup, \
5913 (char*)(identifier) }
5915 #define COMPRESS_CONCAT(name, identifier) \
5916 { "compress_concat/" #name, test_util_decompress_concatenated, 0, \
5917 &passthrough_setup, \
5918 (char*)(identifier) }
5921 #define UTIL_TEST_NO_WIN(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
5922 #define UTIL_TEST_WIN_ONLY(n, f) UTIL_TEST(n, (f))
5923 #define UTIL_LEGACY_NO_WIN(n) UTIL_TEST_NO_WIN(n, 0)
5925 #define UTIL_TEST_NO_WIN(n, f) UTIL_TEST(n, (f))
5926 #define UTIL_TEST_WIN_ONLY(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
5927 #define UTIL_LEGACY_NO_WIN(n) UTIL_LEGACY(n)
5928 #endif /* defined(_WIN32) */
5930 struct testcase_t util_tests
[] = {
5932 UTIL_TEST(parse_http_time
, 0),
5933 UTIL_LEGACY(config_line
),
5934 UTIL_LEGACY(config_line_quotes
),
5935 UTIL_LEGACY(config_line_comment_character
),
5936 UTIL_LEGACY(config_line_escaped_content
),
5937 UTIL_LEGACY(config_line_crlf
),
5938 UTIL_LEGACY_NO_WIN(expand_filename
),
5939 UTIL_LEGACY(escape_string_socks
),
5940 UTIL_LEGACY(string_is_key_value
),
5941 UTIL_LEGACY(strmisc
),
5942 UTIL_TEST(parse_integer
, 0),
5944 COMPRESS(zlib
, "deflate"),
5945 COMPRESS(gzip
, "gzip"),
5946 COMPRESS(lzma
, "x-tor-lzma"),
5947 COMPRESS(zstd
, "x-zstd"),
5948 COMPRESS(none
, "identity"),
5949 COMPRESS_CONCAT(zlib
, "deflate"),
5950 COMPRESS_CONCAT(gzip
, "gzip"),
5951 COMPRESS_CONCAT(lzma
, "x-tor-lzma"),
5952 COMPRESS_CONCAT(zstd
, "x-zstd"),
5953 COMPRESS_CONCAT(none
, "identity"),
5954 UTIL_TEST(gzip_compression_bomb
, TT_FORK
),
5955 UTIL_LEGACY(datadir
),
5956 UTIL_LEGACY(memarea
),
5957 UTIL_LEGACY(control_formats
),
5959 UTIL_TEST(sscanf
, TT_FORK
),
5960 UTIL_LEGACY(format_time_interval
),
5961 UTIL_LEGACY(path_is_relative
),
5962 UTIL_LEGACY(strtok
),
5963 UTIL_LEGACY(di_ops
),
5964 UTIL_TEST(di_map
, 0),
5965 UTIL_TEST(round_to_next_multiple_of
, 0),
5966 UTIL_TEST(laplace
, 0),
5967 UTIL_TEST(clamp_double_to_int64
, 0),
5968 UTIL_TEST(find_str_at_start_of_line
, 0),
5969 UTIL_TEST(string_is_C_identifier
, 0),
5970 UTIL_TEST(asprintf
, 0),
5971 UTIL_TEST(listdir
, 0),
5972 UTIL_TEST(parent_dir
, 0),
5973 UTIL_TEST(ftruncate
, 0),
5974 UTIL_TEST(num_cpus
, 0),
5975 UTIL_TEST_WIN_ONLY(load_win_lib
, 0),
5976 UTIL_TEST_NO_WIN(exit_status
, 0),
5977 UTIL_TEST_NO_WIN(string_from_pipe
, 0),
5978 UTIL_TEST(format_hex_number
, 0),
5979 UTIL_TEST(format_dec_number
, 0),
5980 UTIL_TEST(join_win_cmdline
, 0),
5981 UTIL_TEST(split_lines
, 0),
5982 UTIL_TEST(n_bits_set
, 0),
5983 UTIL_TEST(eat_whitespace
, 0),
5984 UTIL_TEST(sl_new_from_text_lines
, 0),
5985 UTIL_TEST(envnames
, 0),
5986 UTIL_TEST(make_environment
, 0),
5987 UTIL_TEST(set_env_var_in_sl
, 0),
5988 UTIL_TEST(read_file_eof_tiny_limit
, 0),
5989 UTIL_TEST(read_file_eof_one_loop_a
, 0),
5990 UTIL_TEST(read_file_eof_one_loop_b
, 0),
5991 UTIL_TEST(read_file_eof_two_loops
, 0),
5992 UTIL_TEST(read_file_eof_two_loops_b
, 0),
5993 UTIL_TEST(read_file_eof_zero_bytes
, 0),
5994 UTIL_TEST(write_chunks_to_file
, 0),
5995 UTIL_TEST(mathlog
, 0),
5996 UTIL_TEST(fraction
, 0),
5997 UTIL_TEST(weak_random
, 0),
5998 { "socket_ipv4", test_util_socket
, TT_FORK
, &passthrough_setup
,
6000 { "socket_ipv6", test_util_socket
, TT_FORK
,
6001 &passthrough_setup
, (void*)"6" },
6002 { "socketpair", test_util_socketpair
, TT_FORK
, &passthrough_setup
,
6004 { "socketpair_ersatz", test_util_socketpair
, TT_FORK
,
6005 &passthrough_setup
, (void*)"1" },
6006 UTIL_TEST(max_mem
, 0),
6007 UTIL_TEST(hostname_validation
, 0),
6008 UTIL_TEST(ipv4_validation
, 0),
6009 UTIL_TEST(writepid
, 0),
6010 UTIL_TEST(get_avail_disk_space
, 0),
6011 UTIL_TEST(touch_file
, 0),
6012 UTIL_TEST_NO_WIN(pwdb
, TT_FORK
),
6013 UTIL_TEST(calloc_check
, 0),
6014 UTIL_TEST(monotonic_time
, 0),
6015 UTIL_TEST(monotonic_time_ratchet
, TT_FORK
),
6016 UTIL_TEST(htonll
, 0),
6017 UTIL_TEST(get_unquoted_path
, 0),