diff options
-rw-r--r-- | src/common/util.c | 18 | ||||
-rw-r--r-- | src/common/util.h | 2 | ||||
-rw-r--r-- | src/test/test_logging.c | 38 | ||||
-rw-r--r-- | src/test/test_util.c | 142 |
4 files changed, 150 insertions, 50 deletions
diff --git a/src/common/util.c b/src/common/util.c index 0589cec8e6..2f7cc4f892 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1921,6 +1921,8 @@ rate_limit_log(ratelim_t *lim, time_t now) return tor_strdup(""); } else { char *cp=NULL; + /* XXXX this is not exactly correct: the messages could have occurred + * any time between the old value of lim->allowed and now. */ tor_asprintf(&cp, " [%d similar message(s) suppressed in last %d seconds]", n-1, lim->rate); @@ -2821,7 +2823,7 @@ unescape_string(const char *s, char **result, size_t *size_out) if (size_out) *size_out = out - *result; return cp+1; case '\0': - /* LCOV_EXCL_START */ + /* LCOV_EXCL_START -- we caught this in parse_config_from_line. */ tor_fragile_assert(); tor_free(*result); return NULL; @@ -2839,8 +2841,12 @@ unescape_string(const char *s, char **result, size_t *size_out) x1 = hex_decode_digit(cp[2]); x2 = hex_decode_digit(cp[3]); if (x1 == -1 || x2 == -1) { - tor_free(*result); - return NULL; + /* LCOV_EXCL_START */ + /* we caught this above in the initial loop. */ + tor_assert_nonfatal_unreached(); + tor_free(*result); + return NULL; + /* LCOV_EXCL_STOP */ } *out++ = ((x1<<4) + x2); @@ -2866,7 +2872,11 @@ unescape_string(const char *s, char **result, size_t *size_out) cp += 2; break; default: + /* LCOV_EXCL_START */ + /* we caught this above in the initial loop. */ + tor_assert_nonfatal_unreached(); tor_free(*result); return NULL; + /* LCOV_EXCL_STOP */ } break; default: @@ -3785,7 +3795,7 @@ format_number_sigsafe(unsigned long x, char *buf, int buf_len, /* NOT tor_assert; see above. */ if (cp != buf) { - abort(); + abort(); // LCOV_EXCL_LINE } return len; diff --git a/src/common/util.h b/src/common/util.h index 3a056bcd7d..7cb33dc680 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -371,8 +371,6 @@ char *read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, const char *parse_config_line_from_str_verbose(const char *line, char **key_out, char **value_out, const char **err_out); -#define parse_config_line_from_str(line,key_out,value_out) \ - parse_config_line_from_str_verbose((line),(key_out),(value_out),NULL) char *expand_filename(const char *filename); struct smartlist_t *tor_listdir(const char *dirname); int path_is_relative(const char *filename); diff --git a/src/test/test_logging.c b/src/test/test_logging.c index eb294fe6f8..15471e46d0 100644 --- a/src/test/test_logging.c +++ b/src/test/test_logging.c @@ -127,9 +127,47 @@ test_sigsafe_err(void *arg) smartlist_free(lines); } +static void +test_ratelim(void *arg) +{ + (void) arg; + ratelim_t ten_min = RATELIM_INIT(10*60); + + const time_t start = 1466091600; + time_t now = start; + /* Initially, we're ready. */ + + char *msg = NULL; + + msg = rate_limit_log(&ten_min, now); + tt_assert(msg != NULL); + tt_str_op(msg, OP_EQ, ""); /* nothing was suppressed. */ + + tt_int_op(ten_min.last_allowed, OP_EQ, now); + tor_free(msg); + + int i; + for (i = 0; i < 9; ++i) { + now += 60; /* one minute has passed. */ + msg = rate_limit_log(&ten_min, now); + tt_assert(msg == NULL); + tt_int_op(ten_min.last_allowed, OP_EQ, start); + tt_int_op(ten_min.n_calls_since_last_time, OP_EQ, i + 1); + } + + now += 240; /* Okay, we can be done. */ + msg = rate_limit_log(&ten_min, now); + tt_assert(msg != NULL); + tt_str_op(msg, OP_EQ, + " [9 similar message(s) suppressed in last 600 seconds]"); + done: + tor_free(msg); +} + struct testcase_t logging_tests[] = { { "sigsafe_err_fds", test_get_sigsafe_err_fds, TT_FORK, NULL, NULL }, { "sigsafe_err", test_sigsafe_err, TT_FORK, NULL, NULL }, + { "ratelim", test_ratelim, 0, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_util.c b/src/test/test_util.c index d99cedf41a..0720822df3 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -293,7 +293,12 @@ test_util_time(void *arg) tt_int_op(-1005000L,OP_EQ, tv_udiff(&start, &end)); tt_int_op(-1005L,OP_EQ, tv_mdiff(&start, &end)); +#ifdef _WIN32 + /* Would you believe that tv_sec is a long on windows? Of course you would.*/ + end.tv_sec = LONG_MAX; +#else end.tv_sec = TIME_MAX; +#endif tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end)); tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end)); @@ -884,106 +889,106 @@ test_util_config_line(void *arg) , sizeof(buf)); str = buf; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k"); tt_str_op(v,OP_EQ, "v"); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "key value with")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "key"); tt_str_op(v,OP_EQ, "value with spaces"); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "keykey")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "keykey"); tt_str_op(v,OP_EQ, "val"); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "k2\n")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k2"); tt_str_op(v,OP_EQ, ""); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "k3 \n")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k3"); tt_str_op(v,OP_EQ, ""); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "#comment")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k4"); tt_str_op(v,OP_EQ, ""); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "k5#abc")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k5"); tt_str_op(v,OP_EQ, ""); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "k6")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k6"); tt_str_op(v,OP_EQ, "val"); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "kseven")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "kseven"); tt_str_op(v,OP_EQ, "a quoted \'string"); tor_free(k); tor_free(v); tt_assert(!strcmpstart(str, "k8 ")); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k8"); tt_str_op(v,OP_EQ, "a quoted\n\"str\\ing\t\x01\x01\x01\""); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k9"); tt_str_op(v,OP_EQ, "a line that spans two lines."); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k10"); tt_str_op(v,OP_EQ, "more than one continuation"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k11"); tt_str_op(v,OP_EQ, "continuation at the start"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k12"); tt_str_op(v,OP_EQ, "line with a embedded"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k13"); tt_str_op(v,OP_EQ, "continuation at the very start"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k14"); tt_str_op(v,OP_EQ, "a line that has a comment and" ); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k15"); tt_str_op(v,OP_EQ, "this should be the next new line"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k16"); tt_str_op(v,OP_EQ, "a line that has a comment and" ); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k17"); tt_str_op(v,OP_EQ, "this should be the next new line"); tor_free(k); tor_free(v); @@ -1018,32 +1023,36 @@ test_util_config_line_quotes(void *arg) , sizeof(buf4)); str = buf1; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "kTrailingSpace"); tt_str_op(v,OP_EQ, "quoted value"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); str = buf2; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); str = buf3; - str = parse_config_line_from_str(str, &k, &v); + const char *err = NULL; + str = parse_config_line_from_str_verbose(str, &k, &v, &err); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); + tt_str_op(err, OP_EQ, "Invalid escape sequence in quoted string"); str = buf4; - str = parse_config_line_from_str(str, &k, &v); + err = NULL; + str = parse_config_line_from_str_verbose(str, &k, &v, &err); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); + tt_str_op(err, OP_EQ, "Invalid escape sequence in quoted string"); done: tor_free(k); @@ -1065,12 +1074,12 @@ test_util_config_line_comment_character(void *arg) , sizeof(buf)); str = buf; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k1"); tt_str_op(v,OP_EQ, "# in quotes"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "k2"); tt_str_op(v,OP_EQ, "some value"); tor_free(k); tor_free(v); @@ -1078,7 +1087,7 @@ test_util_config_line_comment_character(void *arg) tt_str_op(str,OP_EQ, "k3 /home/user/myTorNetwork#2\n"); #if 0 - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); test_streq(k, "k3"); test_streq(v, "/home/user/myTorNetwork#2"); tor_free(k); tor_free(v); @@ -1135,57 +1144,57 @@ test_util_config_line_escaped_content(void *arg) str = buf1; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "HexadecimalLower"); tt_str_op(v,OP_EQ, "*"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "HexadecimalUpper"); tt_str_op(v,OP_EQ, "*"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "HexadecimalUpperX"); tt_str_op(v,OP_EQ, "*"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "Octal"); tt_str_op(v,OP_EQ, "*"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "Newline"); tt_str_op(v,OP_EQ, "\n"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "Tab"); tt_str_op(v,OP_EQ, "\t"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "CarriageReturn"); tt_str_op(v,OP_EQ, "\r"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "DoubleQuote"); tt_str_op(v,OP_EQ, "\""); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "SimpleQuote"); tt_str_op(v,OP_EQ, "'"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "Backslash"); tt_str_op(v,OP_EQ, "\\"); tor_free(k); tor_free(v); - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_str_op(k,OP_EQ, "Mix"); tt_str_op(v,OP_EQ, "This is a \"star\":\t'*'\nAnd second line"); tor_free(k); tor_free(v); @@ -1193,35 +1202,80 @@ test_util_config_line_escaped_content(void *arg) str = buf2; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); str = buf3; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); str = buf4; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); #if 0 str = buf5; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_ptr_op(str, OP_EQ, NULL); tor_free(k); tor_free(v); #endif str = buf6; - str = parse_config_line_from_str(str, &k, &v); + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); + tt_ptr_op(str,OP_EQ, NULL); + tor_free(k); tor_free(v); + + /* more things to try. */ + /* Bad hex: */ + strlcpy(buf1, "Foo \"\\x9g\"\n", sizeof(buf1)); + strlcpy(buf2, "Foo \"\\xg0\"\n", sizeof(buf2)); + strlcpy(buf3, "Foo \"\\xf\"\n", sizeof(buf3)); + /* bad escape */ + strlcpy(buf4, "Foo \"\\q\"\n", sizeof(buf4)); + /* missing endquote */ + strlcpy(buf5, "Foo \"hello\n", sizeof(buf5)); + /* extra stuff */ + strlcpy(buf6, "Foo \"hello\" world\n", sizeof(buf6)); + + str=buf1; + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); + tt_ptr_op(str,OP_EQ, NULL); + tor_free(k); tor_free(v); + + str=buf2; + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); + tt_ptr_op(str,OP_EQ, NULL); + tor_free(k); tor_free(v); + + str=buf3; + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); + tt_ptr_op(str,OP_EQ, NULL); + tor_free(k); tor_free(v); + + str=buf4; + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); + tt_ptr_op(str,OP_EQ, NULL); + tor_free(k); tor_free(v); + + str=buf5; + + str = parse_config_line_from_str_verbose(str, &k, &v, NULL); + tt_ptr_op(str,OP_EQ, NULL); + tor_free(k); tor_free(v); + + str=buf6; + const char *err = NULL; + str = parse_config_line_from_str_verbose(str, &k, &v, &err); tt_ptr_op(str,OP_EQ, NULL); tor_free(k); tor_free(v); + tt_str_op(err,OP_EQ, "Excess data after quoted string"); done: tor_free(k); @@ -2876,7 +2930,7 @@ test_util_memarea(void *arg) memarea_get_stats(area, &initial_allocation, &dummy); /* Check for running over an area's size. */ - for (i = 0; i < 512; ++i) { + for (i = 0; i < 4096; ++i) { size_t n = crypto_rand_int(6); p1 = memarea_alloc(area, n); total += n; |