tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2018
- 16 participants
- 2190 discussions

26 Jun '18
commit 0932f322911f41e72b5155d06775658039814a39
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Jun 21 17:35:56 2018 -0400
Remove compat.h as unneeded from log.c and torlog.h
---
src/common/log.c | 2 +-
src/common/torlog.h | 4 +++-
src/common/util_format.c | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/common/log.c b/src/common/log.c
index f452c7413..bb4b1e121 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -29,12 +29,12 @@
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#include "common/compat.h"
#include "common/util.h"
#define LOG_PRIVATE
#include "common/torlog.h"
#include "lib/container/smartlist.h"
#include "lib/err/torerr.h"
+#include "lib/malloc/util_malloc.h"
#include "lib/wallclock/tor_gettimeofday.h"
#include "lib/wallclock/approx_time.h"
diff --git a/src/common/torlog.h b/src/common/torlog.h
index 66141ab0a..6814cc9d0 100644
--- a/src/common/torlog.h
+++ b/src/common/torlog.h
@@ -12,7 +12,9 @@
#ifndef TOR_TORLOG_H
-#include "common/compat.h"
+#include <stdarg.h>
+#include "lib/cc/torint.h"
+#include "lib/cc/compat_compiler.h"
#include "lib/testsupport/testsupport.h"
#ifdef HAVE_SYSLOG_H
diff --git a/src/common/util_format.c b/src/common/util_format.c
index 420d8a1a8..713e87129 100644
--- a/src/common/util_format.c
+++ b/src/common/util_format.c
@@ -12,6 +12,7 @@
*/
#include "orconfig.h"
+#include <stddef.h>
#include "common/torlog.h"
#include "common/util.h"
#include "common/util_format.h"
@@ -532,4 +533,3 @@ base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
return (int) (dest-dest_orig);
}
-
1
0

[tor/master] Extract key string manipulation functions into a new library.
by nickm@torproject.org 26 Jun '18
by nickm@torproject.org 26 Jun '18
26 Jun '18
commit 1abadee3fd1c15f3720003c411ec6043c29d7c09
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 09:23:30 2018 -0400
Extract key string manipulation functions into a new library.
---
.gitignore | 2 +
Makefile.am | 2 +
src/common/compat.c | 202 -----------
src/common/compat.h | 34 +-
src/common/util.c | 629 ---------------------------------
src/common/util.h | 35 +-
src/common/util_format.c | 37 +-
src/common/util_format.h | 2 -
src/include.am | 1 +
src/lib/container/.may_include | 1 +
src/lib/container/map.c | 3 +-
src/lib/container/smartlist.c | 3 +-
src/lib/crypt_ops/.may_include | 1 +
src/lib/crypt_ops/crypto_format.c | 1 +
src/lib/crypt_ops/crypto_openssl_mgt.c | 2 +-
src/lib/string/.may_include | 6 +
src/lib/string/compat_ctype.c | 67 ++++
src/lib/string/compat_ctype.h | 60 ++++
src/lib/string/include.am | 23 ++
src/lib/string/printf.c | 152 ++++++++
src/lib/string/printf.h | 25 ++
src/lib/string/scanf.c | 312 ++++++++++++++++
src/lib/string/scanf.h | 19 +
src/lib/string/util_string.c | 340 ++++++++++++++++++
src/lib/string/util_string.h | 42 +++
25 files changed, 1068 insertions(+), 933 deletions(-)
diff --git a/.gitignore b/.gitignore
index 343517fdf..d03e1136d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -175,6 +175,8 @@ uptime-*.json
/src/lib/libtor-err-testing.a
/src/lib/libtor-malloc.a
/src/lib/libtor-malloc-testing.a
+/src/lib/libtor-string.a
+/src/lib/libtor-string-testing.a
/src/lib/libtor-tls.a
/src/lib/libtor-tls-testing.a
/src/lib/libtor-trace.a
diff --git a/Makefile.am b/Makefile.am
index a83041fbe..50d1408fe 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -41,6 +41,7 @@ endif
TOR_UTIL_LIBS = \
src/common/libor.a \
src/lib/libtor-container.a \
+ src/lib/libtor-string.a \
src/lib/libtor-malloc.a \
src/lib/libtor-wallclock.a \
src/lib/libtor-err.a \
@@ -51,6 +52,7 @@ TOR_UTIL_LIBS = \
TOR_UTIL_TESTING_LIBS = \
src/common/libor-testing.a \
src/lib/libtor-container-testing.a \
+ src/lib/libtor-string-testing.a \
src/lib/libtor-malloc-testing.a \
src/lib/libtor-wallclock-testing.a \
src/lib/libtor-err-testing.a \
diff --git a/src/common/compat.c b/src/common/compat.c
index 9462195ba..8929f2f3d 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -404,147 +404,6 @@ tor_munmap_file(tor_mmap_t *handle)
#error "cannot implement tor_mmap_file"
#endif /* defined(HAVE_MMAP) || ... || ... */
-/** Replacement for snprintf. Differs from platform snprintf in two
- * ways: First, always NUL-terminates its output. Second, always
- * returns -1 if the result is truncated. (Note that this return
- * behavior does <i>not</i> conform to C99; it just happens to be
- * easier to emulate "return -1" with conformant implementations than
- * it is to emulate "return number that would be written" with
- * non-conformant implementations.) */
-int
-tor_snprintf(char *str, size_t size, const char *format, ...)
-{
- va_list ap;
- int r;
- va_start(ap,format);
- r = tor_vsnprintf(str,size,format,ap);
- va_end(ap);
- return r;
-}
-
-/** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
- * snprintf.
- */
-int
-tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
-{
- int r;
- if (size == 0)
- return -1; /* no place for the NUL */
- if (size > SIZE_T_CEILING)
- return -1;
-#ifdef _WIN32
- r = _vsnprintf(str, size, format, args);
-#else
- r = vsnprintf(str, size, format, args);
-#endif
- str[size-1] = '\0';
- if (r < 0 || r >= (ssize_t)size)
- return -1;
- return r;
-}
-
-/**
- * Portable asprintf implementation. Does a printf() into a newly malloc'd
- * string. Sets *<b>strp</b> to this string, and returns its length (not
- * including the terminating NUL character).
- *
- * You can treat this function as if its implementation were something like
- <pre>
- char buf[_INFINITY_];
- tor_snprintf(buf, sizeof(buf), fmt, args);
- *strp = tor_strdup(buf);
- return strlen(*strp):
- </pre>
- * Where _INFINITY_ is an imaginary constant so big that any string can fit
- * into it.
- */
-int
-tor_asprintf(char **strp, const char *fmt, ...)
-{
- int r;
- va_list args;
- va_start(args, fmt);
- r = tor_vasprintf(strp, fmt, args);
- va_end(args);
- if (!*strp || r < 0) {
- /* LCOV_EXCL_START */
- log_err(LD_BUG, "Internal error in asprintf");
- tor_assert(0);
- /* LCOV_EXCL_STOP */
- }
- return r;
-}
-
-/**
- * Portable vasprintf implementation. Does a printf() into a newly malloc'd
- * string. Differs from regular vasprintf in the same ways that
- * tor_asprintf() differs from regular asprintf.
- */
-int
-tor_vasprintf(char **strp, const char *fmt, va_list args)
-{
- /* use a temporary variable in case *strp is in args. */
- char *strp_tmp=NULL;
-#ifdef HAVE_VASPRINTF
- /* If the platform gives us one, use it. */
- int r = vasprintf(&strp_tmp, fmt, args);
- if (r < 0)
- *strp = NULL;
- else
- *strp = strp_tmp;
- return r;
-#elif defined(HAVE__VSCPRINTF)
- /* On Windows, _vsnprintf won't tell us the length of the string if it
- * overflows, so we need to use _vcsprintf to tell how much to allocate */
- int len, r;
- va_list tmp_args;
- va_copy(tmp_args, args);
- len = _vscprintf(fmt, tmp_args);
- va_end(tmp_args);
- if (len < 0) {
- *strp = NULL;
- return -1;
- }
- strp_tmp = tor_malloc(len + 1);
- r = _vsnprintf(strp_tmp, len+1, fmt, args);
- if (r != len) {
- tor_free(strp_tmp);
- *strp = NULL;
- return -1;
- }
- *strp = strp_tmp;
- return len;
-#else
- /* Everywhere else, we have a decent vsnprintf that tells us how many
- * characters we need. We give it a try on a short buffer first, since
- * it might be nice to avoid the second vsnprintf call.
- */
- char buf[128];
- int len, r;
- va_list tmp_args;
- va_copy(tmp_args, args);
- /* vsnprintf() was properly checked but tor_vsnprintf() available so
- * why not use it? */
- len = tor_vsnprintf(buf, sizeof(buf), fmt, tmp_args);
- va_end(tmp_args);
- if (len < (int)sizeof(buf)) {
- *strp = tor_strdup(buf);
- return len;
- }
- strp_tmp = tor_malloc(len+1);
- /* use of tor_vsnprintf() will ensure string is null terminated */
- r = tor_vsnprintf(strp_tmp, len+1, fmt, args);
- if (r != len) {
- tor_free(strp_tmp);
- *strp = NULL;
- return -1;
- }
- *strp = strp_tmp;
- return len;
-#endif /* defined(HAVE_VASPRINTF) || ... */
-}
-
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
* <b>needle</b>, return a pointer to the first occurrence of the needle
* within the haystack, or NULL if there is no such occurrence.
@@ -591,67 +450,6 @@ tor_memmem(const void *_haystack, size_t hlen,
#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
}
-/**
- * Tables to implement ctypes-replacement TOR_IS*() functions. Each table
- * has 256 bits to look up whether a character is in some set or not. This
- * fails on non-ASCII platforms, but it is hard to find a platform whose
- * character set is not a superset of ASCII nowadays. */
-
-/**@{*/
-const uint32_t TOR_ISALPHA_TABLE[8] =
- { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
-const uint32_t TOR_ISALNUM_TABLE[8] =
- { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
-const uint32_t TOR_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
-const uint32_t TOR_ISXDIGIT_TABLE[8] =
- { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
-const uint32_t TOR_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
-const uint32_t TOR_ISPRINT_TABLE[8] =
- { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
-const uint32_t TOR_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
-const uint32_t TOR_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
-
-/** Upper-casing and lowercasing tables to map characters to upper/lowercase
- * equivalents. Used by tor_toupper() and tor_tolower(). */
-/**@{*/
-const uint8_t TOR_TOUPPER_TABLE[256] = {
- 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
- 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
- 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
- 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
- 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
- 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
- 96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
- 80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
-};
-const uint8_t TOR_TOLOWER_TABLE[256] = {
- 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
- 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
- 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
- 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
- 64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
- 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
-};
-/**@}*/
-
/** Helper for tor_strtok_r_impl: Advances cp past all characters in
* <b>sep</b>, and returns its new value. */
static char *
diff --git a/src/common/compat.h b/src/common/compat.h
index dff29a42b..21fd0211a 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -47,6 +47,8 @@
#include "lib/cc/compat_compiler.h"
#include "common/compat_time.h"
+#include "lib/string/compat_ctype.h"
+#include "lib/string/printf.h"
#include <stdio.h>
#include <errno.h>
@@ -97,16 +99,6 @@ typedef struct tor_mmap_t {
tor_mmap_t *tor_mmap_file(const char *filename) ATTR_NONNULL((1));
int tor_munmap_file(tor_mmap_t *handle) ATTR_NONNULL((1));
-int tor_snprintf(char *str, size_t size, const char *format, ...)
- CHECK_PRINTF(3,4) ATTR_NONNULL((1,3));
-int tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
- CHECK_PRINTF(3,0) ATTR_NONNULL((1,3));
-
-int tor_asprintf(char **strp, const char *fmt, ...)
- CHECK_PRINTF(2,3);
-int tor_vasprintf(char **strp, const char *fmt, va_list args)
- CHECK_PRINTF(2,0);
-
const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
size_t nlen) ATTR_NONNULL((1,3));
static const void *tor_memstr(const void *haystack, size_t hlen,
@@ -117,28 +109,6 @@ tor_memstr(const void *haystack, size_t hlen, const char *needle)
return tor_memmem(haystack, hlen, needle, strlen(needle));
}
-/* Much of the time when we're checking ctypes, we're doing spec compliance,
- * which all assumes we're doing ASCII. */
-#define DECLARE_CTYPE_FN(name) \
- static int TOR_##name(char c); \
- extern const uint32_t TOR_##name##_TABLE[]; \
- static inline int TOR_##name(char c) { \
- uint8_t u = c; \
- return !!(TOR_##name##_TABLE[(u >> 5) & 7] & (1u << (u & 31))); \
- }
-DECLARE_CTYPE_FN(ISALPHA)
-DECLARE_CTYPE_FN(ISALNUM)
-DECLARE_CTYPE_FN(ISSPACE)
-DECLARE_CTYPE_FN(ISDIGIT)
-DECLARE_CTYPE_FN(ISXDIGIT)
-DECLARE_CTYPE_FN(ISPRINT)
-DECLARE_CTYPE_FN(ISLOWER)
-DECLARE_CTYPE_FN(ISUPPER)
-extern const uint8_t TOR_TOUPPER_TABLE[];
-extern const uint8_t TOR_TOLOWER_TABLE[];
-#define TOR_TOLOWER(c) (TOR_TOLOWER_TABLE[(uint8_t)c])
-#define TOR_TOUPPER(c) (TOR_TOUPPER_TABLE[(uint8_t)c])
-
char *tor_strtok_r_impl(char *str, const char *sep, char **lasts);
#ifdef HAVE_STRTOK_R
#define tor_strtok_r(str, sep, lasts) strtok_r(str, sep, lasts)
diff --git a/src/common/util.c b/src/common/util.c
index 358a68fd7..597ff2c42 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -385,22 +385,6 @@ n_bits_set_u8(uint8_t v)
* String manipulation
* ===== */
-/** Remove from the string <b>s</b> every character which appears in
- * <b>strip</b>. */
-void
-tor_strstrip(char *s, const char *strip)
-{
- char *readp = s;
- while (*readp) {
- if (strchr(strip, *readp)) {
- ++readp;
- } else {
- *s++ = *readp++;
- }
- }
- *s = '\0';
-}
-
/** Return a pointer to a NUL-terminated hexadecimal string encoding
* the first <b>fromlen</b> bytes of <b>from</b>. (fromlen must be \<= 32.) The
* result does not need to be deallocated, but repeated calls to
@@ -416,145 +400,6 @@ hex_str(const char *from, size_t fromlen)
return buf;
}
-/** Convert all alphabetic characters in the nul-terminated string <b>s</b> to
- * lowercase. */
-void
-tor_strlower(char *s)
-{
- while (*s) {
- *s = TOR_TOLOWER(*s);
- ++s;
- }
-}
-
-/** Convert all alphabetic characters in the nul-terminated string <b>s</b> to
- * lowercase. */
-void
-tor_strupper(char *s)
-{
- while (*s) {
- *s = TOR_TOUPPER(*s);
- ++s;
- }
-}
-
-/** Return 1 if every character in <b>s</b> is printable, else return 0.
- */
-int
-tor_strisprint(const char *s)
-{
- while (*s) {
- if (!TOR_ISPRINT(*s))
- return 0;
- s++;
- }
- return 1;
-}
-
-/** Return 1 if no character in <b>s</b> is uppercase, else return 0.
- */
-int
-tor_strisnonupper(const char *s)
-{
- while (*s) {
- if (TOR_ISUPPER(*s))
- return 0;
- s++;
- }
- return 1;
-}
-
-/** Return true iff every character in <b>s</b> is whitespace space; else
- * return false. */
-int
-tor_strisspace(const char *s)
-{
- while (*s) {
- if (!TOR_ISSPACE(*s))
- return 0;
- s++;
- }
- return 1;
-}
-
-/** As strcmp, except that either string may be NULL. The NULL string is
- * considered to be before any non-NULL string. */
-int
-strcmp_opt(const char *s1, const char *s2)
-{
- if (!s1) {
- if (!s2)
- return 0;
- else
- return -1;
- } else if (!s2) {
- return 1;
- } else {
- return strcmp(s1, s2);
- }
-}
-
-/** Compares the first strlen(s2) characters of s1 with s2. Returns as for
- * strcmp.
- */
-int
-strcmpstart(const char *s1, const char *s2)
-{
- size_t n = strlen(s2);
- return strncmp(s1, s2, n);
-}
-
-/** Compare the s1_len-byte string <b>s1</b> with <b>s2</b>,
- * without depending on a terminating nul in s1. Sorting order is first by
- * length, then lexically; return values are as for strcmp.
- */
-int
-strcmp_len(const char *s1, const char *s2, size_t s1_len)
-{
- size_t s2_len = strlen(s2);
- if (s1_len < s2_len)
- return -1;
- if (s1_len > s2_len)
- return 1;
- return fast_memcmp(s1, s2, s2_len);
-}
-
-/** Compares the first strlen(s2) characters of s1 with s2. Returns as for
- * strcasecmp.
- */
-int
-strcasecmpstart(const char *s1, const char *s2)
-{
- size_t n = strlen(s2);
- return strncasecmp(s1, s2, n);
-}
-
-/** Compares the last strlen(s2) characters of s1 with s2. Returns as for
- * strcmp.
- */
-int
-strcmpend(const char *s1, const char *s2)
-{
- size_t n1 = strlen(s1), n2 = strlen(s2);
- if (n2>n1)
- return strcmp(s1,s2);
- else
- return strncmp(s1+(n1-n2), s2, n2);
-}
-
-/** Compares the last strlen(s2) characters of s1 with s2. Returns as for
- * strcasecmp.
- */
-int
-strcasecmpend(const char *s1, const char *s2)
-{
- size_t n1 = strlen(s1), n2 = strlen(s2);
- if (n2>n1) /* then they can't be the same; figure out which is bigger */
- return strcasecmp(s1,s2);
- else
- return strncasecmp(s1+(n1-n2), s2, n2);
-}
-
/** Compare the value of the string <b>prefix</b> with the start of the
* <b>memlen</b>-byte memory chunk at <b>mem</b>. Return as for strcmp.
*
@@ -571,179 +416,6 @@ fast_memcmpstart(const void *mem, size_t memlen,
return fast_memcmp(mem, prefix, plen);
}
-/** Return a pointer to the first char of s that is not whitespace and
- * not a comment, or to the terminating NUL if no such character exists.
- */
-const char *
-eat_whitespace(const char *s)
-{
- tor_assert(s);
-
- while (1) {
- switch (*s) {
- case '\0':
- default:
- return s;
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- ++s;
- break;
- case '#':
- ++s;
- while (*s && *s != '\n')
- ++s;
- }
- }
-}
-
-/** Return a pointer to the first char of s that is not whitespace and
- * not a comment, or to the terminating NUL if no such character exists.
- */
-const char *
-eat_whitespace_eos(const char *s, const char *eos)
-{
- tor_assert(s);
- tor_assert(eos && s <= eos);
-
- while (s < eos) {
- switch (*s) {
- case '\0':
- default:
- return s;
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- ++s;
- break;
- case '#':
- ++s;
- while (s < eos && *s && *s != '\n')
- ++s;
- }
- }
- return s;
-}
-
-/** Return a pointer to the first char of s that is not a space or a tab
- * or a \\r, or to the terminating NUL if no such character exists. */
-const char *
-eat_whitespace_no_nl(const char *s)
-{
- while (*s == ' ' || *s == '\t' || *s == '\r')
- ++s;
- return s;
-}
-
-/** As eat_whitespace_no_nl, but stop at <b>eos</b> whether we have
- * found a non-whitespace character or not. */
-const char *
-eat_whitespace_eos_no_nl(const char *s, const char *eos)
-{
- while (s < eos && (*s == ' ' || *s == '\t' || *s == '\r'))
- ++s;
- return s;
-}
-
-/** Return a pointer to the first char of s that is whitespace or <b>#</b>,
- * or to the terminating NUL if no such character exists.
- */
-const char *
-find_whitespace(const char *s)
-{
- /* tor_assert(s); */
- while (1) {
- switch (*s)
- {
- case '\0':
- case '#':
- case ' ':
- case '\r':
- case '\n':
- case '\t':
- return s;
- default:
- ++s;
- }
- }
-}
-
-/** As find_whitespace, but stop at <b>eos</b> whether we have found a
- * whitespace or not. */
-const char *
-find_whitespace_eos(const char *s, const char *eos)
-{
- /* tor_assert(s); */
- while (s < eos) {
- switch (*s)
- {
- case '\0':
- case '#':
- case ' ':
- case '\r':
- case '\n':
- case '\t':
- return s;
- default:
- ++s;
- }
- }
- return s;
-}
-
-/** Return the first occurrence of <b>needle</b> in <b>haystack</b> that
- * occurs at the start of a line (that is, at the beginning of <b>haystack</b>
- * or immediately after a newline). Return NULL if no such string is found.
- */
-const char *
-find_str_at_start_of_line(const char *haystack, const char *needle)
-{
- size_t needle_len = strlen(needle);
-
- do {
- if (!strncmp(haystack, needle, needle_len))
- return haystack;
-
- haystack = strchr(haystack, '\n');
- if (!haystack)
- return NULL;
- else
- ++haystack;
- } while (*haystack);
-
- return NULL;
-}
-
-/** Returns true if <b>string</b> could be a C identifier.
- A C identifier must begin with a letter or an underscore and the
- rest of its characters can be letters, numbers or underscores. No
- length limit is imposed. */
-int
-string_is_C_identifier(const char *string)
-{
- size_t iter;
- size_t length = strlen(string);
- if (!length)
- return 0;
-
- for (iter = 0; iter < length ; iter++) {
- if (iter == 0) {
- if (!(TOR_ISALPHA(string[iter]) ||
- string[iter] == '_'))
- return 0;
- } else {
- if (!(TOR_ISALPHA(string[iter]) ||
- TOR_ISDIGIT(string[iter]) ||
- string[iter] == '_'))
- return 0;
- }
- }
-
- return 1;
-}
-
/** Return true iff the 'len' bytes at 'mem' are all zero. */
int
tor_mem_is_zero(const char *mem, size_t len)
@@ -2923,307 +2595,6 @@ expand_filename(const char *filename)
#endif /* defined(_WIN32) */
}
-#define MAX_SCANF_WIDTH 9999
-
-/** Helper: given an ASCII-encoded decimal digit, return its numeric value.
- * NOTE: requires that its input be in-bounds. */
-static int
-digit_to_num(char d)
-{
- int num = ((int)d) - (int)'0';
- tor_assert(num <= 9 && num >= 0);
- return num;
-}
-
-/** Helper: Read an unsigned int from *<b>bufp</b> of up to <b>width</b>
- * characters. (Handle arbitrary width if <b>width</b> is less than 0.) On
- * success, store the result in <b>out</b>, advance bufp to the next
- * character, and return 0. On failure, return -1. */
-static int
-scan_unsigned(const char **bufp, unsigned long *out, int width, unsigned base)
-{
- unsigned long result = 0;
- int scanned_so_far = 0;
- const int hex = base==16;
- tor_assert(base == 10 || base == 16);
- if (!bufp || !*bufp || !out)
- return -1;
- if (width<0)
- width=MAX_SCANF_WIDTH;
-
- while (**bufp && (hex?TOR_ISXDIGIT(**bufp):TOR_ISDIGIT(**bufp))
- && scanned_so_far < width) {
- unsigned digit = hex?hex_decode_digit(*(*bufp)++):digit_to_num(*(*bufp)++);
- // Check for overflow beforehand, without actually causing any overflow
- // This preserves functionality on compilers that don't wrap overflow
- // (i.e. that trap or optimise away overflow)
- // result * base + digit > ULONG_MAX
- // result * base > ULONG_MAX - digit
- if (result > (ULONG_MAX - digit)/base)
- return -1; /* Processing this digit would overflow */
- result = result * base + digit;
- ++scanned_so_far;
- }
-
- if (!scanned_so_far) /* No actual digits scanned */
- return -1;
-
- *out = result;
- return 0;
-}
-
-/** Helper: Read an signed int from *<b>bufp</b> of up to <b>width</b>
- * characters. (Handle arbitrary width if <b>width</b> is less than 0.) On
- * success, store the result in <b>out</b>, advance bufp to the next
- * character, and return 0. On failure, return -1. */
-static int
-scan_signed(const char **bufp, long *out, int width)
-{
- int neg = 0;
- unsigned long result = 0;
-
- if (!bufp || !*bufp || !out)
- return -1;
- if (width<0)
- width=MAX_SCANF_WIDTH;
-
- if (**bufp == '-') {
- neg = 1;
- ++*bufp;
- --width;
- }
-
- if (scan_unsigned(bufp, &result, width, 10) < 0)
- return -1;
-
- if (neg && result > 0) {
- if (result > ((unsigned long)LONG_MAX) + 1)
- return -1; /* Underflow */
- else if (result == ((unsigned long)LONG_MAX) + 1)
- *out = LONG_MIN;
- else {
- /* We once had a far more clever no-overflow conversion here, but
- * some versions of GCC apparently ran it into the ground. Now
- * we just check for LONG_MIN explicitly.
- */
- *out = -(long)result;
- }
- } else {
- if (result > LONG_MAX)
- return -1; /* Overflow */
- *out = (long)result;
- }
-
- return 0;
-}
-
-/** Helper: Read a decimal-formatted double from *<b>bufp</b> of up to
- * <b>width</b> characters. (Handle arbitrary width if <b>width</b> is less
- * than 0.) On success, store the result in <b>out</b>, advance bufp to the
- * next character, and return 0. On failure, return -1. */
-static int
-scan_double(const char **bufp, double *out, int width)
-{
- int neg = 0;
- double result = 0;
- int scanned_so_far = 0;
-
- if (!bufp || !*bufp || !out)
- return -1;
- if (width<0)
- width=MAX_SCANF_WIDTH;
-
- if (**bufp == '-') {
- neg = 1;
- ++*bufp;
- }
-
- while (**bufp && TOR_ISDIGIT(**bufp) && scanned_so_far < width) {
- const int digit = digit_to_num(*(*bufp)++);
- result = result * 10 + digit;
- ++scanned_so_far;
- }
- if (**bufp == '.') {
- double fracval = 0, denominator = 1;
- ++*bufp;
- ++scanned_so_far;
- while (**bufp && TOR_ISDIGIT(**bufp) && scanned_so_far < width) {
- const int digit = digit_to_num(*(*bufp)++);
- fracval = fracval * 10 + digit;
- denominator *= 10;
- ++scanned_so_far;
- }
- result += fracval / denominator;
- }
-
- if (!scanned_so_far) /* No actual digits scanned */
- return -1;
-
- *out = neg ? -result : result;
- return 0;
-}
-
-/** Helper: copy up to <b>width</b> non-space characters from <b>bufp</b> to
- * <b>out</b>. Make sure <b>out</b> is nul-terminated. Advance <b>bufp</b>
- * to the next non-space character or the EOS. */
-static int
-scan_string(const char **bufp, char *out, int width)
-{
- int scanned_so_far = 0;
- if (!bufp || !out || width < 0)
- return -1;
- while (**bufp && ! TOR_ISSPACE(**bufp) && scanned_so_far < width) {
- *out++ = *(*bufp)++;
- ++scanned_so_far;
- }
- *out = '\0';
- return 0;
-}
-
-/** Locale-independent, minimal, no-surprises scanf variant, accepting only a
- * restricted pattern format. For more info on what it supports, see
- * tor_sscanf() documentation. */
-int
-tor_vsscanf(const char *buf, const char *pattern, va_list ap)
-{
- int n_matched = 0;
-
- while (*pattern) {
- if (*pattern != '%') {
- if (*buf == *pattern) {
- ++buf;
- ++pattern;
- continue;
- } else {
- return n_matched;
- }
- } else {
- int width = -1;
- int longmod = 0;
- ++pattern;
- if (TOR_ISDIGIT(*pattern)) {
- width = digit_to_num(*pattern++);
- while (TOR_ISDIGIT(*pattern)) {
- width *= 10;
- width += digit_to_num(*pattern++);
- if (width > MAX_SCANF_WIDTH)
- return -1;
- }
- if (!width) /* No zero-width things. */
- return -1;
- }
- if (*pattern == 'l') {
- longmod = 1;
- ++pattern;
- }
- if (*pattern == 'u' || *pattern == 'x') {
- unsigned long u;
- const int base = (*pattern == 'u') ? 10 : 16;
- if (!*buf)
- return n_matched;
- if (scan_unsigned(&buf, &u, width, base)<0)
- return n_matched;
- if (longmod) {
- unsigned long *out = va_arg(ap, unsigned long *);
- *out = u;
- } else {
- unsigned *out = va_arg(ap, unsigned *);
- if (u > UINT_MAX)
- return n_matched;
- *out = (unsigned) u;
- }
- ++pattern;
- ++n_matched;
- } else if (*pattern == 'f') {
- double *d = va_arg(ap, double *);
- if (!longmod)
- return -1; /* float not supported */
- if (!*buf)
- return n_matched;
- if (scan_double(&buf, d, width)<0)
- return n_matched;
- ++pattern;
- ++n_matched;
- } else if (*pattern == 'd') {
- long lng=0;
- if (scan_signed(&buf, &lng, width)<0)
- return n_matched;
- if (longmod) {
- long *out = va_arg(ap, long *);
- *out = lng;
- } else {
- int *out = va_arg(ap, int *);
-#if LONG_MAX > INT_MAX
- if (lng < INT_MIN || lng > INT_MAX)
- return n_matched;
-#endif
- *out = (int)lng;
- }
- ++pattern;
- ++n_matched;
- } else if (*pattern == 's') {
- char *s = va_arg(ap, char *);
- if (longmod)
- return -1;
- if (width < 0)
- return -1;
- if (scan_string(&buf, s, width)<0)
- return n_matched;
- ++pattern;
- ++n_matched;
- } else if (*pattern == 'c') {
- char *ch = va_arg(ap, char *);
- if (longmod)
- return -1;
- if (width != -1)
- return -1;
- if (!*buf)
- return n_matched;
- *ch = *buf++;
- ++pattern;
- ++n_matched;
- } else if (*pattern == '%') {
- if (*buf != '%')
- return n_matched;
- if (longmod)
- return -1;
- ++buf;
- ++pattern;
- } else {
- return -1; /* Unrecognized pattern component. */
- }
- }
- }
-
- return n_matched;
-}
-
-/** Minimal sscanf replacement: parse <b>buf</b> according to <b>pattern</b>
- * and store the results in the corresponding argument fields. Differs from
- * sscanf in that:
- * <ul><li>It only handles %u, %lu, %x, %lx, %[NUM]s, %d, %ld, %lf, and %c.
- * <li>It only handles decimal inputs for %lf. (12.3, not 1.23e1)
- * <li>It does not handle arbitrarily long widths.
- * <li>Numbers do not consume any space characters.
- * <li>It is locale-independent.
- * <li>%u and %x do not consume any space.
- * <li>It returns -1 on malformed patterns.</ul>
- *
- * (As with other locale-independent functions, we need this to parse data that
- * is in ASCII without worrying that the C library's locale-handling will make
- * miscellaneous characters look like numbers, spaces, and so on.)
- */
-int
-tor_sscanf(const char *buf, const char *pattern, ...)
-{
- int r;
- va_list ap;
- va_start(ap, pattern);
- r = tor_vsscanf(buf, pattern, ap);
- va_end(ap);
- return r;
-}
-
/** Append the string produced by tor_asprintf(<b>pattern</b>, <b>...</b>)
* to <b>sl</b>. */
void
diff --git a/src/common/util.h b/src/common/util.h
index 8977b460b..5833fe567 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -25,6 +25,8 @@
#include "lib/err/torerr.h"
#include "lib/malloc/util_malloc.h"
#include "lib/wallclock/approx_time.h"
+#include "lib/string/util_string.h"
+#include "lib/string/scanf.h"
#include "common/util_bug.h"
#ifndef O_BINARY
@@ -96,22 +98,6 @@ uint32_t tor_add_u32_nowrap(uint32_t a, uint32_t b);
/* String manipulation */
-/** Allowable characters in a hexadecimal string. */
-#define HEX_CHARACTERS "0123456789ABCDEFabcdef"
-void tor_strlower(char *s) ATTR_NONNULL((1));
-void tor_strupper(char *s) ATTR_NONNULL((1));
-int tor_strisprint(const char *s) ATTR_NONNULL((1));
-int tor_strisnonupper(const char *s) ATTR_NONNULL((1));
-int tor_strisspace(const char *s);
-int strcmp_opt(const char *s1, const char *s2);
-int strcmpstart(const char *s1, const char *s2) ATTR_NONNULL((1,2));
-int strcmp_len(const char *s1, const char *s2, size_t len) ATTR_NONNULL((1,2));
-int strcasecmpstart(const char *s1, const char *s2) ATTR_NONNULL((1,2));
-int strcmpend(const char *s1, const char *s2) ATTR_NONNULL((1,2));
-int strcasecmpend(const char *s1, const char *s2) ATTR_NONNULL((1,2));
-int fast_memcmpstart(const void *mem, size_t memlen, const char *prefix);
-
-void tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2));
long tor_parse_long(const char *s, int base, long min,
long max, int *ok, char **next);
unsigned long tor_parse_ulong(const char *s, int base, unsigned long min,
@@ -120,16 +106,9 @@ double tor_parse_double(const char *s, double min, double max, int *ok,
char **next);
uint64_t tor_parse_uint64(const char *s, int base, uint64_t min,
uint64_t max, int *ok, char **next);
+
const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
-const char *eat_whitespace(const char *s);
-const char *eat_whitespace_eos(const char *s, const char *eos);
-const char *eat_whitespace_no_nl(const char *s);
-const char *eat_whitespace_eos_no_nl(const char *s, const char *eos);
-const char *find_whitespace(const char *s);
-const char *find_whitespace_eos(const char *s, const char *eos);
-const char *find_str_at_start_of_line(const char *haystack,
- const char *needle);
-int string_is_C_identifier(const char *string);
+
int string_is_key_value(int severity, const char *string);
int string_is_valid_dest(const char *string);
int string_is_valid_nonrfc_hostname(const char *string);
@@ -139,6 +118,7 @@ int string_is_valid_ipv6_address(const char *string);
int tor_mem_is_zero(const char *mem, size_t len);
int tor_digest_is_zero(const char *digest);
int tor_digest256_is_zero(const char *digest);
+
char *esc_for_log(const char *string) ATTR_MALLOC;
char *esc_for_log_len(const char *chars, size_t n) ATTR_MALLOC;
const char *escaped(const char *string);
@@ -147,11 +127,6 @@ char *tor_escape_str_for_pt_args(const char *string,
const char *chars_to_escape);
struct smartlist_t;
-int tor_vsscanf(const char *buf, const char *pattern, va_list ap) \
- CHECK_SCANF(2, 0);
-int tor_sscanf(const char *buf, const char *pattern, ...)
- CHECK_SCANF(2, 3);
-
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...)
CHECK_PRINTF(2, 3);
void smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern,
diff --git a/src/common/util_format.c b/src/common/util_format.c
index 713e87129..8b299725a 100644
--- a/src/common/util_format.c
+++ b/src/common/util_format.c
@@ -465,39 +465,6 @@ base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
*cp = '\0';
}
-/** Helper: given a hex digit, return its value, or -1 if it isn't hex. */
-static inline int
-hex_decode_digit_(char c)
-{
- switch (c) {
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'A': case 'a': return 10;
- case 'B': case 'b': return 11;
- case 'C': case 'c': return 12;
- case 'D': case 'd': return 13;
- case 'E': case 'e': return 14;
- case 'F': case 'f': return 15;
- default:
- return -1;
- }
-}
-
-/** Helper: given a hex digit, return its value, or -1 if it isn't hex. */
-int
-hex_decode_digit(char c)
-{
- return hex_decode_digit_(c);
-}
-
/** Given a hexadecimal string of <b>srclen</b> bytes in <b>src</b>, decode
* it and store the result in the <b>destlen</b>-byte buffer at <b>dest</b>.
* Return the number of bytes decoded on success, -1 on failure. If
@@ -520,8 +487,8 @@ base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
end = src+srclen;
while (src<end) {
- v1 = hex_decode_digit_(*src);
- v2 = hex_decode_digit_(*(src+1));
+ v1 = hex_decode_digit(*src);
+ v2 = hex_decode_digit(*(src+1));
if (v1<0||v2<0)
return -1;
*(uint8_t*)dest = (v1<<4)|v2;
diff --git a/src/common/util_format.h b/src/common/util_format.h
index 3580c2863..713fd0d00 100644
--- a/src/common/util_format.h
+++ b/src/common/util_format.h
@@ -44,9 +44,7 @@ void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen);
int base32_decode(char *dest, size_t destlen, const char *src, size_t srclen);
size_t base32_encoded_size(size_t srclen);
-int hex_decode_digit(char c);
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
#endif /* !defined(TOR_UTIL_FORMAT_H) */
-
diff --git a/src/include.am b/src/include.am
index a2c0cc88b..5676a2359 100644
--- a/src/include.am
+++ b/src/include.am
@@ -8,6 +8,7 @@ include src/lib/crypt_ops/include.am
include src/lib/defs/include.am
include src/lib/include.libdonna.am
include src/lib/malloc/include.am
+include src/lib/string/include.am
include src/lib/testsupport/include.am
include src/lib/tls/include.am
include src/lib/trace/include.am
diff --git a/src/lib/container/.may_include b/src/lib/container/.may_include
index 2dfa85b20..eaa020bf5 100644
--- a/src/lib/container/.may_include
+++ b/src/lib/container/.may_include
@@ -5,6 +5,7 @@ lib/ctime/*.h
lib/defs/*.h
lib/malloc/*.h
lib/err/*.h
+lib/string/*.h
lib/testsupport/testsupport.h
ht.h
diff --git a/src/lib/container/map.c b/src/lib/container/map.c
index f6b0f73c1..ba59e37d6 100644
--- a/src/lib/container/map.c
+++ b/src/lib/container/map.c
@@ -14,9 +14,10 @@
#include "lib/container/map.h"
#include "lib/ctime/di_ops.h"
#include "lib/defs/digest_sizes.h"
+#include "lib/string/util_string.h"
+#include "lib/malloc/util_malloc.h"
#include "common/util_bug.h"
-#include "common/util.h" // For strlower
#include <stdlib.h>
#include <string.h>
diff --git a/src/lib/container/smartlist.c b/src/lib/container/smartlist.c
index 2d861f566..3a0a2d106 100644
--- a/src/lib/container/smartlist.c
+++ b/src/lib/container/smartlist.c
@@ -14,9 +14,10 @@
#include "lib/malloc/util_malloc.h"
#include "lib/container/smartlist.h"
#include "lib/err/torerr.h"
-#include "common/util.h" // For strstrip.
+#include "lib/malloc/util_malloc.h"
#include "lib/defs/digest_sizes.h"
#include "lib/ctime/di_ops.h"
+#include "lib/string/util_string.h"
#include <stdlib.h>
#include <string.h>
diff --git a/src/lib/crypt_ops/.may_include b/src/lib/crypt_ops/.may_include
index 438e5fcdc..0a9a0dda2 100644
--- a/src/lib/crypt_ops/.may_include
+++ b/src/lib/crypt_ops/.may_include
@@ -6,6 +6,7 @@ lib/ctime/*.h
lib/defs/*.h
lib/malloc/*.h
lib/err/*.h
+lib/string/*.h
lib/testsupport/testsupport.h
trunnel/pwbox.h
diff --git a/src/lib/crypt_ops/crypto_format.c b/src/lib/crypt_ops/crypto_format.c
index 2d28090aa..e4237653f 100644
--- a/src/lib/crypt_ops/crypto_format.c
+++ b/src/lib/crypt_ops/crypto_format.c
@@ -20,6 +20,7 @@
#include "lib/crypt_ops/crypto_ed25519.h"
#include "lib/crypt_ops/crypto_format.h"
#include "lib/crypt_ops/crypto_util.h"
+#include "lib/string/util_string.h"
#include "common/util.h"
#include "common/util_format.h"
#include "common/torlog.h"
diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.c b/src/lib/crypt_ops/crypto_openssl_mgt.c
index b18717a11..2c2c2048e 100644
--- a/src/lib/crypt_ops/crypto_openssl_mgt.c
+++ b/src/lib/crypt_ops/crypto_openssl_mgt.c
@@ -12,6 +12,7 @@
#include "lib/crypt_ops/compat_openssl.h"
#include "lib/crypt_ops/crypto_openssl_mgt.h"
+#include "lib/string/util_string.h"
DISABLE_GCC_WARNING(redundant-decls)
@@ -158,4 +159,3 @@ crypto_openssl_free_all(void)
}
#endif /* !defined(NEW_THREAD_API) */
}
-
diff --git a/src/lib/string/.may_include b/src/lib/string/.may_include
new file mode 100644
index 000000000..8781566d9
--- /dev/null
+++ b/src/lib/string/.may_include
@@ -0,0 +1,6 @@
+orconfig.h
+lib/cc/*.h
+lib/err/*.h
+lib/malloc/*.h
+lib/ctime/*.h
+lib/string/*.h
diff --git a/src/lib/string/compat_ctype.c b/src/lib/string/compat_ctype.c
new file mode 100644
index 000000000..d1d4ce0ff
--- /dev/null
+++ b/src/lib/string/compat_ctype.c
@@ -0,0 +1,67 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/string/compat_ctype.h"
+
+/**
+ * Tables to implement ctypes-replacement TOR_IS*() functions. Each table
+ * has 256 bits to look up whether a character is in some set or not. This
+ * fails on non-ASCII platforms, but it is hard to find a platform whose
+ * character set is not a superset of ASCII nowadays. */
+
+/**@{*/
+const uint32_t TOR_ISALPHA_TABLE[8] =
+ { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
+const uint32_t TOR_ISALNUM_TABLE[8] =
+ { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
+const uint32_t TOR_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
+const uint32_t TOR_ISXDIGIT_TABLE[8] =
+ { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
+const uint32_t TOR_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
+const uint32_t TOR_ISPRINT_TABLE[8] =
+ { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
+const uint32_t TOR_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
+const uint32_t TOR_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
+
+/** Upper-casing and lowercasing tables to map characters to upper/lowercase
+ * equivalents. Used by tor_toupper() and tor_tolower(). */
+/**@{*/
+const uint8_t TOR_TOUPPER_TABLE[256] = {
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
+ 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
+ 96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
+ 80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
+};
+const uint8_t TOR_TOLOWER_TABLE[256] = {
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+ 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
+ 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
+ 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
+ 64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
+ 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
+};
+/**@}*/
diff --git a/src/lib/string/compat_ctype.h b/src/lib/string/compat_ctype.h
new file mode 100644
index 000000000..32f314f33
--- /dev/null
+++ b/src/lib/string/compat_ctype.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_COMPAT_CTYPE_H
+#define TOR_COMPAT_CTYPE_H
+
+#include "orconfig.h"
+#include "lib/cc/torint.h"
+
+/* Much of the time when we're checking ctypes, we're doing spec compliance,
+ * which all assumes we're doing ASCII. */
+#define DECLARE_CTYPE_FN(name) \
+ static int TOR_##name(char c); \
+ extern const uint32_t TOR_##name##_TABLE[]; \
+ static inline int TOR_##name(char c) { \
+ uint8_t u = c; \
+ return !!(TOR_##name##_TABLE[(u >> 5) & 7] & (1u << (u & 31))); \
+ }
+DECLARE_CTYPE_FN(ISALPHA)
+DECLARE_CTYPE_FN(ISALNUM)
+DECLARE_CTYPE_FN(ISSPACE)
+DECLARE_CTYPE_FN(ISDIGIT)
+DECLARE_CTYPE_FN(ISXDIGIT)
+DECLARE_CTYPE_FN(ISPRINT)
+DECLARE_CTYPE_FN(ISLOWER)
+DECLARE_CTYPE_FN(ISUPPER)
+extern const uint8_t TOR_TOUPPER_TABLE[];
+extern const uint8_t TOR_TOLOWER_TABLE[];
+#define TOR_TOLOWER(c) (TOR_TOLOWER_TABLE[(uint8_t)c])
+#define TOR_TOUPPER(c) (TOR_TOUPPER_TABLE[(uint8_t)c])
+
+/** Helper: given a hex digit, return its value, or -1 if it isn't hex. */
+inline int
+hex_decode_digit(char c)
+{
+ switch (c) {
+ case '0': return 0;
+ case '1': return 1;
+ case '2': return 2;
+ case '3': return 3;
+ case '4': return 4;
+ case '5': return 5;
+ case '6': return 6;
+ case '7': return 7;
+ case '8': return 8;
+ case '9': return 9;
+ case 'A': case 'a': return 10;
+ case 'B': case 'b': return 11;
+ case 'C': case 'c': return 12;
+ case 'D': case 'd': return 13;
+ case 'E': case 'e': return 14;
+ case 'F': case 'f': return 15;
+ default:
+ return -1;
+ }
+}
+
+#endif /* !defined(TOR_COMPAT_CTYPE_H) */
diff --git a/src/lib/string/include.am b/src/lib/string/include.am
new file mode 100644
index 000000000..d458515d2
--- /dev/null
+++ b/src/lib/string/include.am
@@ -0,0 +1,23 @@
+
+noinst_LIBRARIES += src/lib/libtor-string.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-string-testing.a
+endif
+
+src_lib_libtor_string_a_SOURCES = \
+ src/lib/string/compat_ctype.c \
+ src/lib/string/util_string.c \
+ src/lib/string/printf.c \
+ src/lib/string/scanf.c
+
+src_lib_libtor_string_testing_a_SOURCES = \
+ $(src_lib_libtor_string_a_SOURCES)
+src_lib_libtor_string_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_string_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS += \
+ src/lib/string/compat_ctype.h \
+ src/lib/string/util_string.h \
+ src/lib/string/printf.h \
+ src/lib/string/scanf.h
diff --git a/src/lib/string/printf.c b/src/lib/string/printf.c
new file mode 100644
index 000000000..4443e25fb
--- /dev/null
+++ b/src/lib/string/printf.c
@@ -0,0 +1,152 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/string/printf.h"
+#include "lib/err/torerr.h"
+#include "lib/cc/torint.h"
+#include "lib/malloc/util_malloc.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/** Replacement for snprintf. Differs from platform snprintf in two
+ * ways: First, always NUL-terminates its output. Second, always
+ * returns -1 if the result is truncated. (Note that this return
+ * behavior does <i>not</i> conform to C99; it just happens to be
+ * easier to emulate "return -1" with conformant implementations than
+ * it is to emulate "return number that would be written" with
+ * non-conformant implementations.) */
+int
+tor_snprintf(char *str, size_t size, const char *format, ...)
+{
+ va_list ap;
+ int r;
+ va_start(ap,format);
+ r = tor_vsnprintf(str,size,format,ap);
+ va_end(ap);
+ return r;
+}
+
+/** Replacement for vsnprintf; behavior differs as tor_snprintf differs from
+ * snprintf.
+ */
+int
+tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
+{
+ int r;
+ if (size == 0)
+ return -1; /* no place for the NUL */
+ if (size > SIZE_T_CEILING)
+ return -1;
+#ifdef _WIN32
+ r = _vsnprintf(str, size, format, args);
+#else
+ r = vsnprintf(str, size, format, args);
+#endif
+ str[size-1] = '\0';
+ if (r < 0 || r >= (ssize_t)size)
+ return -1;
+ return r;
+}
+
+/**
+ * Portable asprintf implementation. Does a printf() into a newly malloc'd
+ * string. Sets *<b>strp</b> to this string, and returns its length (not
+ * including the terminating NUL character).
+ *
+ * You can treat this function as if its implementation were something like
+ <pre>
+ char buf[_INFINITY_];
+ tor_snprintf(buf, sizeof(buf), fmt, args);
+ *strp = tor_strdup(buf);
+ return strlen(*strp):
+ </pre>
+ * Where _INFINITY_ is an imaginary constant so big that any string can fit
+ * into it.
+ */
+int
+tor_asprintf(char **strp, const char *fmt, ...)
+{
+ int r;
+ va_list args;
+ va_start(args, fmt);
+ r = tor_vasprintf(strp, fmt, args);
+ va_end(args);
+ if (!*strp || r < 0) {
+ /* LCOV_EXCL_START */
+ raw_assert_unreached_msg("Internal error in asprintf");
+ /* LCOV_EXCL_STOP */
+ }
+ return r;
+}
+
+/**
+ * Portable vasprintf implementation. Does a printf() into a newly malloc'd
+ * string. Differs from regular vasprintf in the same ways that
+ * tor_asprintf() differs from regular asprintf.
+ */
+int
+tor_vasprintf(char **strp, const char *fmt, va_list args)
+{
+ /* use a temporary variable in case *strp is in args. */
+ char *strp_tmp=NULL;
+#ifdef HAVE_VASPRINTF
+ /* If the platform gives us one, use it. */
+ int r = vasprintf(&strp_tmp, fmt, args);
+ if (r < 0)
+ *strp = NULL;
+ else
+ *strp = strp_tmp;
+ return r;
+#elif defined(HAVE__VSCPRINTF)
+ /* On Windows, _vsnprintf won't tell us the length of the string if it
+ * overflows, so we need to use _vcsprintf to tell how much to allocate */
+ int len, r;
+ va_list tmp_args;
+ va_copy(tmp_args, args);
+ len = _vscprintf(fmt, tmp_args);
+ va_end(tmp_args);
+ if (len < 0) {
+ *strp = NULL;
+ return -1;
+ }
+ strp_tmp = tor_malloc(len + 1);
+ r = _vsnprintf(strp_tmp, len+1, fmt, args);
+ if (r != len) {
+ tor_free(strp_tmp);
+ *strp = NULL;
+ return -1;
+ }
+ *strp = strp_tmp;
+ return len;
+#else
+ /* Everywhere else, we have a decent vsnprintf that tells us how many
+ * characters we need. We give it a try on a short buffer first, since
+ * it might be nice to avoid the second vsnprintf call.
+ */
+ char buf[128];
+ int len, r;
+ va_list tmp_args;
+ va_copy(tmp_args, args);
+ /* vsnprintf() was properly checked but tor_vsnprintf() available so
+ * why not use it? */
+ len = tor_vsnprintf(buf, sizeof(buf), fmt, tmp_args);
+ va_end(tmp_args);
+ if (len < (int)sizeof(buf)) {
+ *strp = tor_strdup(buf);
+ return len;
+ }
+ strp_tmp = tor_malloc(len+1);
+ /* use of tor_vsnprintf() will ensure string is null terminated */
+ r = tor_vsnprintf(strp_tmp, len+1, fmt, args);
+ if (r != len) {
+ tor_free(strp_tmp);
+ *strp = NULL;
+ return -1;
+ }
+ *strp = strp_tmp;
+ return len;
+#endif /* defined(HAVE_VASPRINTF) || ... */
+}
diff --git a/src/lib/string/printf.h b/src/lib/string/printf.h
new file mode 100644
index 000000000..2f4620654
--- /dev/null
+++ b/src/lib/string/printf.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_UTIL_PRINTF_H
+#define TOR_UTIL_PRINTF_H
+
+#include "orconfig.h"
+#include "lib/cc/compat_compiler.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+
+int tor_snprintf(char *str, size_t size, const char *format, ...)
+ CHECK_PRINTF(3,4) ATTR_NONNULL((1,3));
+int tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
+ CHECK_PRINTF(3,0) ATTR_NONNULL((1,3));
+
+int tor_asprintf(char **strp, const char *fmt, ...)
+ CHECK_PRINTF(2,3);
+int tor_vasprintf(char **strp, const char *fmt, va_list args)
+ CHECK_PRINTF(2,0);
+
+#endif /* !defined(TOR_UTIL_STRING_H) */
diff --git a/src/lib/string/scanf.c b/src/lib/string/scanf.c
new file mode 100644
index 000000000..0c5082799
--- /dev/null
+++ b/src/lib/string/scanf.c
@@ -0,0 +1,312 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/string/scanf.h"
+#include "lib/string/compat_ctype.h"
+#include "lib/cc/torint.h"
+#include "lib/err/torerr.h"
+
+#include <stdlib.h>
+
+#define MAX_SCANF_WIDTH 9999
+
+/** Helper: given an ASCII-encoded decimal digit, return its numeric value.
+ * NOTE: requires that its input be in-bounds. */
+static int
+digit_to_num(char d)
+{
+ int num = ((int)d) - (int)'0';
+ raw_assert(num <= 9 && num >= 0);
+ return num;
+}
+
+/** Helper: Read an unsigned int from *<b>bufp</b> of up to <b>width</b>
+ * characters. (Handle arbitrary width if <b>width</b> is less than 0.) On
+ * success, store the result in <b>out</b>, advance bufp to the next
+ * character, and return 0. On failure, return -1. */
+static int
+scan_unsigned(const char **bufp, unsigned long *out, int width, unsigned base)
+{
+ unsigned long result = 0;
+ int scanned_so_far = 0;
+ const int hex = base==16;
+ raw_assert(base == 10 || base == 16);
+ if (!bufp || !*bufp || !out)
+ return -1;
+ if (width<0)
+ width=MAX_SCANF_WIDTH;
+
+ while (**bufp && (hex?TOR_ISXDIGIT(**bufp):TOR_ISDIGIT(**bufp))
+ && scanned_so_far < width) {
+ unsigned digit = hex?hex_decode_digit(*(*bufp)++):digit_to_num(*(*bufp)++);
+ // Check for overflow beforehand, without actually causing any overflow
+ // This preserves functionality on compilers that don't wrap overflow
+ // (i.e. that trap or optimise away overflow)
+ // result * base + digit > ULONG_MAX
+ // result * base > ULONG_MAX - digit
+ if (result > (ULONG_MAX - digit)/base)
+ return -1; /* Processing this digit would overflow */
+ result = result * base + digit;
+ ++scanned_so_far;
+ }
+
+ if (!scanned_so_far) /* No actual digits scanned */
+ return -1;
+
+ *out = result;
+ return 0;
+}
+
+/** Helper: Read an signed int from *<b>bufp</b> of up to <b>width</b>
+ * characters. (Handle arbitrary width if <b>width</b> is less than 0.) On
+ * success, store the result in <b>out</b>, advance bufp to the next
+ * character, and return 0. On failure, return -1. */
+static int
+scan_signed(const char **bufp, long *out, int width)
+{
+ int neg = 0;
+ unsigned long result = 0;
+
+ if (!bufp || !*bufp || !out)
+ return -1;
+ if (width<0)
+ width=MAX_SCANF_WIDTH;
+
+ if (**bufp == '-') {
+ neg = 1;
+ ++*bufp;
+ --width;
+ }
+
+ if (scan_unsigned(bufp, &result, width, 10) < 0)
+ return -1;
+
+ if (neg && result > 0) {
+ if (result > ((unsigned long)LONG_MAX) + 1)
+ return -1; /* Underflow */
+ else if (result == ((unsigned long)LONG_MAX) + 1)
+ *out = LONG_MIN;
+ else {
+ /* We once had a far more clever no-overflow conversion here, but
+ * some versions of GCC apparently ran it into the ground. Now
+ * we just check for LONG_MIN explicitly.
+ */
+ *out = -(long)result;
+ }
+ } else {
+ if (result > LONG_MAX)
+ return -1; /* Overflow */
+ *out = (long)result;
+ }
+
+ return 0;
+}
+
+/** Helper: Read a decimal-formatted double from *<b>bufp</b> of up to
+ * <b>width</b> characters. (Handle arbitrary width if <b>width</b> is less
+ * than 0.) On success, store the result in <b>out</b>, advance bufp to the
+ * next character, and return 0. On failure, return -1. */
+static int
+scan_double(const char **bufp, double *out, int width)
+{
+ int neg = 0;
+ double result = 0;
+ int scanned_so_far = 0;
+
+ if (!bufp || !*bufp || !out)
+ return -1;
+ if (width<0)
+ width=MAX_SCANF_WIDTH;
+
+ if (**bufp == '-') {
+ neg = 1;
+ ++*bufp;
+ }
+
+ while (**bufp && TOR_ISDIGIT(**bufp) && scanned_so_far < width) {
+ const int digit = digit_to_num(*(*bufp)++);
+ result = result * 10 + digit;
+ ++scanned_so_far;
+ }
+ if (**bufp == '.') {
+ double fracval = 0, denominator = 1;
+ ++*bufp;
+ ++scanned_so_far;
+ while (**bufp && TOR_ISDIGIT(**bufp) && scanned_so_far < width) {
+ const int digit = digit_to_num(*(*bufp)++);
+ fracval = fracval * 10 + digit;
+ denominator *= 10;
+ ++scanned_so_far;
+ }
+ result += fracval / denominator;
+ }
+
+ if (!scanned_so_far) /* No actual digits scanned */
+ return -1;
+
+ *out = neg ? -result : result;
+ return 0;
+}
+
+/** Helper: copy up to <b>width</b> non-space characters from <b>bufp</b> to
+ * <b>out</b>. Make sure <b>out</b> is nul-terminated. Advance <b>bufp</b>
+ * to the next non-space character or the EOS. */
+static int
+scan_string(const char **bufp, char *out, int width)
+{
+ int scanned_so_far = 0;
+ if (!bufp || !out || width < 0)
+ return -1;
+ while (**bufp && ! TOR_ISSPACE(**bufp) && scanned_so_far < width) {
+ *out++ = *(*bufp)++;
+ ++scanned_so_far;
+ }
+ *out = '\0';
+ return 0;
+}
+
+/** Locale-independent, minimal, no-surprises scanf variant, accepting only a
+ * restricted pattern format. For more info on what it supports, see
+ * tor_sscanf() documentation. */
+int
+tor_vsscanf(const char *buf, const char *pattern, va_list ap)
+{
+ int n_matched = 0;
+
+ while (*pattern) {
+ if (*pattern != '%') {
+ if (*buf == *pattern) {
+ ++buf;
+ ++pattern;
+ continue;
+ } else {
+ return n_matched;
+ }
+ } else {
+ int width = -1;
+ int longmod = 0;
+ ++pattern;
+ if (TOR_ISDIGIT(*pattern)) {
+ width = digit_to_num(*pattern++);
+ while (TOR_ISDIGIT(*pattern)) {
+ width *= 10;
+ width += digit_to_num(*pattern++);
+ if (width > MAX_SCANF_WIDTH)
+ return -1;
+ }
+ if (!width) /* No zero-width things. */
+ return -1;
+ }
+ if (*pattern == 'l') {
+ longmod = 1;
+ ++pattern;
+ }
+ if (*pattern == 'u' || *pattern == 'x') {
+ unsigned long u;
+ const int base = (*pattern == 'u') ? 10 : 16;
+ if (!*buf)
+ return n_matched;
+ if (scan_unsigned(&buf, &u, width, base)<0)
+ return n_matched;
+ if (longmod) {
+ unsigned long *out = va_arg(ap, unsigned long *);
+ *out = u;
+ } else {
+ unsigned *out = va_arg(ap, unsigned *);
+ if (u > UINT_MAX)
+ return n_matched;
+ *out = (unsigned) u;
+ }
+ ++pattern;
+ ++n_matched;
+ } else if (*pattern == 'f') {
+ double *d = va_arg(ap, double *);
+ if (!longmod)
+ return -1; /* float not supported */
+ if (!*buf)
+ return n_matched;
+ if (scan_double(&buf, d, width)<0)
+ return n_matched;
+ ++pattern;
+ ++n_matched;
+ } else if (*pattern == 'd') {
+ long lng=0;
+ if (scan_signed(&buf, &lng, width)<0)
+ return n_matched;
+ if (longmod) {
+ long *out = va_arg(ap, long *);
+ *out = lng;
+ } else {
+ int *out = va_arg(ap, int *);
+#if LONG_MAX > INT_MAX
+ if (lng < INT_MIN || lng > INT_MAX)
+ return n_matched;
+#endif
+ *out = (int)lng;
+ }
+ ++pattern;
+ ++n_matched;
+ } else if (*pattern == 's') {
+ char *s = va_arg(ap, char *);
+ if (longmod)
+ return -1;
+ if (width < 0)
+ return -1;
+ if (scan_string(&buf, s, width)<0)
+ return n_matched;
+ ++pattern;
+ ++n_matched;
+ } else if (*pattern == 'c') {
+ char *ch = va_arg(ap, char *);
+ if (longmod)
+ return -1;
+ if (width != -1)
+ return -1;
+ if (!*buf)
+ return n_matched;
+ *ch = *buf++;
+ ++pattern;
+ ++n_matched;
+ } else if (*pattern == '%') {
+ if (*buf != '%')
+ return n_matched;
+ if (longmod)
+ return -1;
+ ++buf;
+ ++pattern;
+ } else {
+ return -1; /* Unrecognized pattern component. */
+ }
+ }
+ }
+
+ return n_matched;
+}
+
+/** Minimal sscanf replacement: parse <b>buf</b> according to <b>pattern</b>
+ * and store the results in the corresponding argument fields. Differs from
+ * sscanf in that:
+ * <ul><li>It only handles %u, %lu, %x, %lx, %[NUM]s, %d, %ld, %lf, and %c.
+ * <li>It only handles decimal inputs for %lf. (12.3, not 1.23e1)
+ * <li>It does not handle arbitrarily long widths.
+ * <li>Numbers do not consume any space characters.
+ * <li>It is locale-independent.
+ * <li>%u and %x do not consume any space.
+ * <li>It returns -1 on malformed patterns.</ul>
+ *
+ * (As with other locale-independent functions, we need this to parse data that
+ * is in ASCII without worrying that the C library's locale-handling will make
+ * miscellaneous characters look like numbers, spaces, and so on.)
+ */
+int
+tor_sscanf(const char *buf, const char *pattern, ...)
+{
+ int r;
+ va_list ap;
+ va_start(ap, pattern);
+ r = tor_vsscanf(buf, pattern, ap);
+ va_end(ap);
+ return r;
+}
diff --git a/src/lib/string/scanf.h b/src/lib/string/scanf.h
new file mode 100644
index 000000000..9cfa9cc6c
--- /dev/null
+++ b/src/lib/string/scanf.h
@@ -0,0 +1,19 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_UTIL_SCANF_H
+#define TOR_UTIL_SCANF_H
+
+#include "orconfig.h"
+#include "lib/cc/compat_compiler.h"
+
+#include <stdarg.h>
+
+int tor_vsscanf(const char *buf, const char *pattern, va_list ap) \
+ CHECK_SCANF(2, 0);
+int tor_sscanf(const char *buf, const char *pattern, ...)
+ CHECK_SCANF(2, 3);
+
+#endif /* !defined(TOR_UTIL_STRING_H) */
diff --git a/src/lib/string/util_string.c b/src/lib/string/util_string.c
new file mode 100644
index 000000000..aba37fcc0
--- /dev/null
+++ b/src/lib/string/util_string.c
@@ -0,0 +1,340 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/string/util_string.h"
+#include "lib/string/compat_ctype.h"
+#include "lib/err/torerr.h"
+#include "lib/ctime/di_ops.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+/** Remove from the string <b>s</b> every character which appears in
+ * <b>strip</b>. */
+void
+tor_strstrip(char *s, const char *strip)
+{
+ char *readp = s;
+ while (*readp) {
+ if (strchr(strip, *readp)) {
+ ++readp;
+ } else {
+ *s++ = *readp++;
+ }
+ }
+ *s = '\0';
+}
+
+/** Convert all alphabetic characters in the nul-terminated string <b>s</b> to
+ * lowercase. */
+void
+tor_strlower(char *s)
+{
+ while (*s) {
+ *s = TOR_TOLOWER(*s);
+ ++s;
+ }
+}
+
+/** Convert all alphabetic characters in the nul-terminated string <b>s</b> to
+ * lowercase. */
+void
+tor_strupper(char *s)
+{
+ while (*s) {
+ *s = TOR_TOUPPER(*s);
+ ++s;
+ }
+}
+
+/** Return 1 if every character in <b>s</b> is printable, else return 0.
+ */
+int
+tor_strisprint(const char *s)
+{
+ while (*s) {
+ if (!TOR_ISPRINT(*s))
+ return 0;
+ s++;
+ }
+ return 1;
+}
+
+/** Return 1 if no character in <b>s</b> is uppercase, else return 0.
+ */
+int
+tor_strisnonupper(const char *s)
+{
+ while (*s) {
+ if (TOR_ISUPPER(*s))
+ return 0;
+ s++;
+ }
+ return 1;
+}
+
+/** Return true iff every character in <b>s</b> is whitespace space; else
+ * return false. */
+int
+tor_strisspace(const char *s)
+{
+ while (*s) {
+ if (!TOR_ISSPACE(*s))
+ return 0;
+ s++;
+ }
+ return 1;
+}
+
+/** As strcmp, except that either string may be NULL. The NULL string is
+ * considered to be before any non-NULL string. */
+int
+strcmp_opt(const char *s1, const char *s2)
+{
+ if (!s1) {
+ if (!s2)
+ return 0;
+ else
+ return -1;
+ } else if (!s2) {
+ return 1;
+ } else {
+ return strcmp(s1, s2);
+ }
+}
+
+/** Compares the first strlen(s2) characters of s1 with s2. Returns as for
+ * strcmp.
+ */
+int
+strcmpstart(const char *s1, const char *s2)
+{
+ size_t n = strlen(s2);
+ return strncmp(s1, s2, n);
+}
+
+/** Compare the s1_len-byte string <b>s1</b> with <b>s2</b>,
+ * without depending on a terminating nul in s1. Sorting order is first by
+ * length, then lexically; return values are as for strcmp.
+ */
+int
+strcmp_len(const char *s1, const char *s2, size_t s1_len)
+{
+ size_t s2_len = strlen(s2);
+ if (s1_len < s2_len)
+ return -1;
+ if (s1_len > s2_len)
+ return 1;
+ return fast_memcmp(s1, s2, s2_len);
+}
+
+/** Compares the first strlen(s2) characters of s1 with s2. Returns as for
+ * strcasecmp.
+ */
+int
+strcasecmpstart(const char *s1, const char *s2)
+{
+ size_t n = strlen(s2);
+ return strncasecmp(s1, s2, n);
+}
+
+/** Compares the last strlen(s2) characters of s1 with s2. Returns as for
+ * strcmp.
+ */
+int
+strcmpend(const char *s1, const char *s2)
+{
+ size_t n1 = strlen(s1), n2 = strlen(s2);
+ if (n2>n1)
+ return strcmp(s1,s2);
+ else
+ return strncmp(s1+(n1-n2), s2, n2);
+}
+
+/** Compares the last strlen(s2) characters of s1 with s2. Returns as for
+ * strcasecmp.
+ */
+int
+strcasecmpend(const char *s1, const char *s2)
+{
+ size_t n1 = strlen(s1), n2 = strlen(s2);
+ if (n2>n1) /* then they can't be the same; figure out which is bigger */
+ return strcasecmp(s1,s2);
+ else
+ return strncasecmp(s1+(n1-n2), s2, n2);
+}
+
+/** Return a pointer to the first char of s that is not whitespace and
+ * not a comment, or to the terminating NUL if no such character exists.
+ */
+const char *
+eat_whitespace(const char *s)
+{
+ raw_assert(s);
+
+ while (1) {
+ switch (*s) {
+ case '\0':
+ default:
+ return s;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ ++s;
+ break;
+ case '#':
+ ++s;
+ while (*s && *s != '\n')
+ ++s;
+ }
+ }
+}
+
+/** Return a pointer to the first char of s that is not whitespace and
+ * not a comment, or to the terminating NUL if no such character exists.
+ */
+const char *
+eat_whitespace_eos(const char *s, const char *eos)
+{
+ raw_assert(s);
+ raw_assert(eos && s <= eos);
+
+ while (s < eos) {
+ switch (*s) {
+ case '\0':
+ default:
+ return s;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ ++s;
+ break;
+ case '#':
+ ++s;
+ while (s < eos && *s && *s != '\n')
+ ++s;
+ }
+ }
+ return s;
+}
+
+/** Return a pointer to the first char of s that is not a space or a tab
+ * or a \\r, or to the terminating NUL if no such character exists. */
+const char *
+eat_whitespace_no_nl(const char *s)
+{
+ while (*s == ' ' || *s == '\t' || *s == '\r')
+ ++s;
+ return s;
+}
+
+/** As eat_whitespace_no_nl, but stop at <b>eos</b> whether we have
+ * found a non-whitespace character or not. */
+const char *
+eat_whitespace_eos_no_nl(const char *s, const char *eos)
+{
+ while (s < eos && (*s == ' ' || *s == '\t' || *s == '\r'))
+ ++s;
+ return s;
+}
+
+/** Return a pointer to the first char of s that is whitespace or <b>#</b>,
+ * or to the terminating NUL if no such character exists.
+ */
+const char *
+find_whitespace(const char *s)
+{
+ /* tor_assert(s); */
+ while (1) {
+ switch (*s)
+ {
+ case '\0':
+ case '#':
+ case ' ':
+ case '\r':
+ case '\n':
+ case '\t':
+ return s;
+ default:
+ ++s;
+ }
+ }
+}
+
+/** As find_whitespace, but stop at <b>eos</b> whether we have found a
+ * whitespace or not. */
+const char *
+find_whitespace_eos(const char *s, const char *eos)
+{
+ /* tor_assert(s); */
+ while (s < eos) {
+ switch (*s)
+ {
+ case '\0':
+ case '#':
+ case ' ':
+ case '\r':
+ case '\n':
+ case '\t':
+ return s;
+ default:
+ ++s;
+ }
+ }
+ return s;
+}
+
+/** Return the first occurrence of <b>needle</b> in <b>haystack</b> that
+ * occurs at the start of a line (that is, at the beginning of <b>haystack</b>
+ * or immediately after a newline). Return NULL if no such string is found.
+ */
+const char *
+find_str_at_start_of_line(const char *haystack, const char *needle)
+{
+ size_t needle_len = strlen(needle);
+
+ do {
+ if (!strncmp(haystack, needle, needle_len))
+ return haystack;
+
+ haystack = strchr(haystack, '\n');
+ if (!haystack)
+ return NULL;
+ else
+ ++haystack;
+ } while (*haystack);
+
+ return NULL;
+}
+
+/** Returns true if <b>string</b> could be a C identifier.
+ A C identifier must begin with a letter or an underscore and the
+ rest of its characters can be letters, numbers or underscores. No
+ length limit is imposed. */
+int
+string_is_C_identifier(const char *string)
+{
+ size_t iter;
+ size_t length = strlen(string);
+ if (!length)
+ return 0;
+
+ for (iter = 0; iter < length ; iter++) {
+ if (iter == 0) {
+ if (!(TOR_ISALPHA(string[iter]) ||
+ string[iter] == '_'))
+ return 0;
+ } else {
+ if (!(TOR_ISALPHA(string[iter]) ||
+ TOR_ISDIGIT(string[iter]) ||
+ string[iter] == '_'))
+ return 0;
+ }
+ }
+
+ return 1;
+}
diff --git a/src/lib/string/util_string.h b/src/lib/string/util_string.h
new file mode 100644
index 000000000..f194c3637
--- /dev/null
+++ b/src/lib/string/util_string.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_UTIL_STRING_H
+#define TOR_UTIL_STRING_H
+
+#include "orconfig.h"
+#include "lib/cc/compat_compiler.h"
+
+#include <stddef.h>
+
+/** Allowable characters in a hexadecimal string. */
+#define HEX_CHARACTERS "0123456789ABCDEFabcdef"
+void tor_strlower(char *s) ATTR_NONNULL((1));
+void tor_strupper(char *s) ATTR_NONNULL((1));
+int tor_strisprint(const char *s) ATTR_NONNULL((1));
+int tor_strisnonupper(const char *s) ATTR_NONNULL((1));
+int tor_strisspace(const char *s);
+int strcmp_opt(const char *s1, const char *s2);
+int strcmpstart(const char *s1, const char *s2) ATTR_NONNULL((1,2));
+int strcmp_len(const char *s1, const char *s2, size_t len) ATTR_NONNULL((1,2));
+int strcasecmpstart(const char *s1, const char *s2) ATTR_NONNULL((1,2));
+int strcmpend(const char *s1, const char *s2) ATTR_NONNULL((1,2));
+int strcasecmpend(const char *s1, const char *s2) ATTR_NONNULL((1,2));
+int fast_memcmpstart(const void *mem, size_t memlen, const char *prefix);
+
+void tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2));
+
+const char *eat_whitespace(const char *s);
+const char *eat_whitespace_eos(const char *s, const char *eos);
+const char *eat_whitespace_no_nl(const char *s);
+const char *eat_whitespace_eos_no_nl(const char *s, const char *eos);
+const char *find_whitespace(const char *s);
+const char *find_whitespace_eos(const char *s, const char *eos);
+const char *find_str_at_start_of_line(const char *haystack,
+ const char *needle);
+
+int string_is_C_identifier(const char *string);
+
+#endif /* !defined(TOR_UTIL_STRING_H) */
1
0
commit 1e07b4031e2613826cf7ff2838a2f0c8f03e81c2
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 08:41:57 2018 -0400
Move ARRAY_LENGTH to compiler_compat.h
---
src/common/util.h | 2 --
src/lib/cc/compat_compiler.h | 3 +++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/common/util.h b/src/common/util.h
index f2df84b19..8977b460b 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -451,6 +451,4 @@ STATIC int format_helper_exit_status(unsigned char child_state,
#endif /* defined(UTIL_PRIVATE) */
-#define ARRAY_LENGTH(x) ((sizeof(x)) / sizeof(x[0]))
-
#endif /* !defined(TOR_UTIL_H) */
diff --git a/src/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h
index 763c3d06d..67d945cfa 100644
--- a/src/lib/cc/compat_compiler.h
+++ b/src/lib/cc/compat_compiler.h
@@ -253,4 +253,7 @@
*/
#define STRUCT_VAR_P(st, off) ((void*) ( ((char*)(st)) + (off) ) )
+/** Macro: Yields the number of elements in array x. */
+#define ARRAY_LENGTH(x) ((sizeof(x)) / sizeof(x[0]))
+
#endif /* !defined(TOR_COMPAT_H) */
1
0
commit d1cada5a8a7e1631e25f5f413c66d5c9e5113e7a
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Jun 21 17:06:58 2018 -0400
Update permissible includes
---
src/lib/container/.may_include | 15 +++++++++++++++
src/lib/crypt_ops/.may_include | 2 ++
src/lib/tls/.may_include | 1 +
3 files changed, 18 insertions(+)
diff --git a/src/lib/container/.may_include b/src/lib/container/.may_include
new file mode 100644
index 000000000..2dfa85b20
--- /dev/null
+++ b/src/lib/container/.may_include
@@ -0,0 +1,15 @@
+orconfig.h
+lib/cc/*.h
+lib/container/*.h
+lib/ctime/*.h
+lib/defs/*.h
+lib/malloc/*.h
+lib/err/*.h
+lib/testsupport/testsupport.h
+
+ht.h
+siphash.h
+
+# XXX I'd like to remove this.
+common/util.h
+common/util_bug.h
diff --git a/src/lib/crypt_ops/.may_include b/src/lib/crypt_ops/.may_include
index 94275c1d9..438e5fcdc 100644
--- a/src/lib/crypt_ops/.may_include
+++ b/src/lib/crypt_ops/.may_include
@@ -1,8 +1,10 @@
orconfig.h
lib/cc/*.h
+lib/container/*.h
lib/crypt_ops/*.h
lib/ctime/*.h
lib/defs/*.h
+lib/malloc/*.h
lib/err/*.h
lib/testsupport/testsupport.h
diff --git a/src/lib/tls/.may_include b/src/lib/tls/.may_include
index 22792b6bf..8fdd62806 100644
--- a/src/lib/tls/.may_include
+++ b/src/lib/tls/.may_include
@@ -1,5 +1,6 @@
orconfig.h
lib/cc/*.h
+lib/container/*.h
lib/crypt_ops/*.h
lib/err/*.h
lib/testsupport/testsupport.h
1
0

[tor/master] Move smartlist_add_{v, }asprintf into smartlist.[ch]
by nickm@torproject.org 26 Jun '18
by nickm@torproject.org 26 Jun '18
26 Jun '18
commit 3883338c8121212b3f6f9c020d489d50bbcdd855
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 09:26:19 2018 -0400
Move smartlist_add_{v,}asprintf into smartlist.[ch]
Now that I know that "strings" nests below "container", I know this
is safe.
---
src/common/util.c | 24 ------------------------
src/common/util.h | 8 +-------
src/lib/container/smartlist.c | 25 +++++++++++++++++++++++++
src/lib/container/smartlist.h | 5 +++++
src/rust/build.rs | 1 +
5 files changed, 32 insertions(+), 31 deletions(-)
diff --git a/src/common/util.c b/src/common/util.c
index 597ff2c42..fc996f16c 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2595,30 +2595,6 @@ expand_filename(const char *filename)
#endif /* defined(_WIN32) */
}
-/** Append the string produced by tor_asprintf(<b>pattern</b>, <b>...</b>)
- * to <b>sl</b>. */
-void
-smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...)
-{
- va_list ap;
- va_start(ap, pattern);
- smartlist_add_vasprintf(sl, pattern, ap);
- va_end(ap);
-}
-
-/** va_list-based backend of smartlist_add_asprintf. */
-void
-smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern,
- va_list args)
-{
- char *str = NULL;
-
- tor_vasprintf(&str, pattern, args);
- tor_assert(str != NULL);
-
- smartlist_add(sl, str);
-}
-
/** Return a new list containing the filenames in the directory <b>dirname</b>.
* Return NULL on error or if <b>dirname</b> is not a directory.
*/
diff --git a/src/common/util.h b/src/common/util.h
index 5833fe567..de6ba8ece 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -126,13 +126,6 @@ const char *escaped(const char *string);
char *tor_escape_str_for_pt_args(const char *string,
const char *chars_to_escape);
-struct smartlist_t;
-void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...)
- CHECK_PRINTF(2, 3);
-void smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern,
- va_list args)
- CHECK_PRINTF(2, 0);
-
/* Time helpers */
long tv_udiff(const struct timeval *start, const struct timeval *end);
long tv_mdiff(const struct timeval *start, const struct timeval *end);
@@ -250,6 +243,7 @@ typedef struct sized_chunk_t {
const char *bytes;
size_t len;
} sized_chunk_t;
+struct smartlist_t;
int write_chunks_to_file(const char *fname, const struct smartlist_t *chunks,
int bin, int no_tempfile);
int append_bytes_to_file(const char *fname, const char *str, size_t len,
diff --git a/src/lib/container/smartlist.c b/src/lib/container/smartlist.c
index 3a0a2d106..57b88415a 100644
--- a/src/lib/container/smartlist.c
+++ b/src/lib/container/smartlist.c
@@ -18,6 +18,7 @@
#include "lib/defs/digest_sizes.h"
#include "lib/ctime/di_ops.h"
#include "lib/string/util_string.h"
+#include "lib/string/printf.h"
#include <stdlib.h>
#include <string.h>
@@ -124,6 +125,30 @@ smartlist_add_strdup(struct smartlist_t *sl, const char *string)
smartlist_add(sl, copy);
}
+/** Append the string produced by tor_asprintf(<b>pattern</b>, <b>...</b>)
+ * to <b>sl</b>. */
+void
+smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...)
+{
+ va_list ap;
+ va_start(ap, pattern);
+ smartlist_add_vasprintf(sl, pattern, ap);
+ va_end(ap);
+}
+
+/** va_list-based backend of smartlist_add_asprintf. */
+void
+smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern,
+ va_list args)
+{
+ char *str = NULL;
+
+ tor_vasprintf(&str, pattern, args);
+ tor_assert(str != NULL);
+
+ smartlist_add(sl, str);
+}
+
/** Remove all elements E from sl such that E==element. Preserve
* the order of any elements before E, but elements after E can be
* rearranged.
diff --git a/src/lib/container/smartlist.h b/src/lib/container/smartlist.h
index 7b80a9fed..53a4948cf 100644
--- a/src/lib/container/smartlist.h
+++ b/src/lib/container/smartlist.h
@@ -37,6 +37,11 @@ void smartlist_clear(smartlist_t *sl);
void smartlist_add(smartlist_t *sl, void *element);
void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2);
void smartlist_add_strdup(struct smartlist_t *sl, const char *string);
+void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...)
+ CHECK_PRINTF(2, 3);
+void smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern,
+ va_list args)
+ CHECK_PRINTF(2, 0);
void smartlist_remove(smartlist_t *sl, const void *element);
void smartlist_remove_keeporder(smartlist_t *sl, const void *element);
void *smartlist_pop_last(smartlist_t *sl);
diff --git a/src/rust/build.rs b/src/rust/build.rs
index a4f38d3b4..5c80265e5 100644
--- a/src/rust/build.rs
+++ b/src/rust/build.rs
@@ -152,6 +152,7 @@ pub fn main() {
cfg.component("tor-crypt-ops-testing");
cfg.component("or-testing");
cfg.component("tor-container-testing");
+ cfg.component("tor-string-testing");
cfg.component("tor-malloc");
cfg.component("tor-err-testing");
cfg.component("or-event-testing");
1
0

26 Jun '18
commit 2cf033f238c111bef62552da16117568435d3a18
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 09:48:24 2018 -0400
Extract simple integer math into its own module
---
.gitignore | 2 +
Makefile.am | 2 +
src/common/util.c | 161 ---------------------------------------
src/common/util.h | 29 +------
src/include.am | 1 +
src/lib/container/.may_include | 2 +-
src/lib/container/bloomfilt.c | 2 +-
src/lib/crypt_ops/.may_include | 1 +
src/lib/crypt_ops/crypto_pwbox.c | 2 +-
src/lib/intmath/.may_include | 4 +
src/lib/intmath/addsub.c | 20 +++++
src/lib/intmath/addsub.h | 13 ++++
src/lib/intmath/bits.c | 88 +++++++++++++++++++++
src/lib/intmath/bits.h | 16 ++++
src/lib/intmath/cmp.h | 20 +++++
src/lib/intmath/include.am | 22 ++++++
src/lib/intmath/muldiv.c | 75 ++++++++++++++++++
src/lib/intmath/muldiv.h | 22 ++++++
src/rust/build.rs | 1 +
19 files changed, 294 insertions(+), 189 deletions(-)
diff --git a/.gitignore b/.gitignore
index d03e1136d..6a48ba275 100644
--- a/.gitignore
+++ b/.gitignore
@@ -173,6 +173,8 @@ uptime-*.json
/src/lib/libtor-ctime-testing.a
/src/lib/libtor-err.a
/src/lib/libtor-err-testing.a
+/src/lib/libtor-intmath.a
+/src/lib/libtor-intmath-testing.a
/src/lib/libtor-malloc.a
/src/lib/libtor-malloc-testing.a
/src/lib/libtor-string.a
diff --git a/Makefile.am b/Makefile.am
index 50d1408fe..172ab36f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,6 +45,7 @@ TOR_UTIL_LIBS = \
src/lib/libtor-malloc.a \
src/lib/libtor-wallclock.a \
src/lib/libtor-err.a \
+ src/lib/libtor-intmath.a \
src/lib/libtor-ctime.a
# Variants of the above for linking the testing variant of tor (for coverage
@@ -56,6 +57,7 @@ TOR_UTIL_TESTING_LIBS = \
src/lib/libtor-malloc-testing.a \
src/lib/libtor-wallclock-testing.a \
src/lib/libtor-err-testing.a \
+ src/lib/libtor-intmath.a \
src/lib/libtor-ctime-testing.a
# Internal crypto libraries used in Tor
diff --git a/src/common/util.c b/src/common/util.c
index fc996f16c..5efbb2bbf 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -166,105 +166,6 @@ tor_llround(double d)
#endif /* defined(HAVE_LLROUND) || ... */
}
-/** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */
-int
-tor_log2(uint64_t u64)
-{
- int r = 0;
- if (u64 >= (U64_LITERAL(1)<<32)) {
- u64 >>= 32;
- r = 32;
- }
- if (u64 >= (U64_LITERAL(1)<<16)) {
- u64 >>= 16;
- r += 16;
- }
- if (u64 >= (U64_LITERAL(1)<<8)) {
- u64 >>= 8;
- r += 8;
- }
- if (u64 >= (U64_LITERAL(1)<<4)) {
- u64 >>= 4;
- r += 4;
- }
- if (u64 >= (U64_LITERAL(1)<<2)) {
- u64 >>= 2;
- r += 2;
- }
- if (u64 >= (U64_LITERAL(1)<<1)) {
- // u64 >>= 1; // not using this any more.
- r += 1;
- }
- return r;
-}
-
-/** Return the power of 2 in range [1,UINT64_MAX] closest to <b>u64</b>. If
- * there are two powers of 2 equally close, round down. */
-uint64_t
-round_to_power_of_2(uint64_t u64)
-{
- int lg2;
- uint64_t low;
- uint64_t high;
- if (u64 == 0)
- return 1;
-
- lg2 = tor_log2(u64);
- low = U64_LITERAL(1) << lg2;
-
- if (lg2 == 63)
- return low;
-
- high = U64_LITERAL(1) << (lg2+1);
- if (high - u64 < u64 - low)
- return high;
- else
- return low;
-}
-
-/** Return the lowest x such that x is at least <b>number</b>, and x modulo
- * <b>divisor</b> == 0. If no such x can be expressed as an unsigned, return
- * UINT_MAX. Asserts if divisor is zero. */
-unsigned
-round_to_next_multiple_of(unsigned number, unsigned divisor)
-{
- tor_assert(divisor > 0);
- if (UINT_MAX - divisor + 1 < number)
- return UINT_MAX;
- number += divisor - 1;
- number -= number % divisor;
- return number;
-}
-
-/** Return the lowest x such that x is at least <b>number</b>, and x modulo
- * <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return
- * UINT32_MAX. Asserts if divisor is zero. */
-uint32_t
-round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
-{
- tor_assert(divisor > 0);
- if (UINT32_MAX - divisor + 1 < number)
- return UINT32_MAX;
-
- number += divisor - 1;
- number -= number % divisor;
- return number;
-}
-
-/** Return the lowest x such that x is at least <b>number</b>, and x modulo
- * <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return
- * UINT64_MAX. Asserts if divisor is zero. */
-uint64_t
-round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
-{
- tor_assert(divisor > 0);
- if (UINT64_MAX - divisor + 1 < number)
- return UINT64_MAX;
- number += divisor - 1;
- number -= number % divisor;
- return number;
-}
-
/** Transform a random value <b>p</b> from the uniform distribution in
* [0.0, 1.0[ into a Laplace distributed value with location parameter
* <b>mu</b> and scale parameter <b>b</b>. Truncate the final result
@@ -319,68 +220,6 @@ add_laplace_noise(int64_t signal_, double random_, double delta_f,
return signal_ + noise;
}
-/* Helper: safely add two uint32_t's, capping at UINT32_MAX rather
- * than overflow */
-uint32_t
-tor_add_u32_nowrap(uint32_t a, uint32_t b)
-{
- /* a+b > UINT32_MAX check, without overflow */
- if (PREDICT_UNLIKELY(a > UINT32_MAX - b)) {
- return UINT32_MAX;
- } else {
- return a+b;
- }
-}
-
-/* Helper: return greatest common divisor of a,b */
-static uint64_t
-gcd64(uint64_t a, uint64_t b)
-{
- while (b) {
- uint64_t t = b;
- b = a % b;
- a = t;
- }
- return a;
-}
-
-/* Given a fraction *<b>numer</b> / *<b>denom</b>, simplify it.
- * Requires that the denominator is greater than 0. */
-void
-simplify_fraction64(uint64_t *numer, uint64_t *denom)
-{
- tor_assert(denom);
- uint64_t gcd = gcd64(*numer, *denom);
- *numer /= gcd;
- *denom /= gcd;
-}
-
-/** Return the number of bits set in <b>v</b>. */
-int
-n_bits_set_u8(uint8_t v)
-{
- static const int nybble_table[] = {
- 0, /* 0000 */
- 1, /* 0001 */
- 1, /* 0010 */
- 2, /* 0011 */
- 1, /* 0100 */
- 2, /* 0101 */
- 2, /* 0110 */
- 3, /* 0111 */
- 1, /* 1000 */
- 2, /* 1001 */
- 2, /* 1010 */
- 3, /* 1011 */
- 2, /* 1100 */
- 3, /* 1101 */
- 3, /* 1110 */
- 4, /* 1111 */
- };
-
- return nybble_table[v & 15] + nybble_table[v>>4];
-}
-
/* =====
* String manipulation
* ===== */
diff --git a/src/common/util.h b/src/common/util.h
index de6ba8ece..8f6ec34dc 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -27,6 +27,10 @@
#include "lib/wallclock/approx_time.h"
#include "lib/string/util_string.h"
#include "lib/string/scanf.h"
+#include "lib/intmath/bits.h"
+#include "lib/intmath/addsub.h"
+#include "lib/intmath/muldiv.h"
+#include "lib/intmath/cmp.h"
#include "common/util_bug.h"
#ifndef O_BINARY
@@ -66,35 +70,10 @@ void tor_log_mallinfo(int severity);
double tor_mathlog(double d) ATTR_CONST;
long tor_lround(double d) ATTR_CONST;
int64_t tor_llround(double d) ATTR_CONST;
-int tor_log2(uint64_t u64) ATTR_CONST;
-uint64_t round_to_power_of_2(uint64_t u64);
-unsigned round_to_next_multiple_of(unsigned number, unsigned divisor);
-uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor);
-uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor);
int64_t sample_laplace_distribution(double mu, double b, double p);
int64_t add_laplace_noise(int64_t signal, double random, double delta_f,
double epsilon);
-int n_bits_set_u8(uint8_t v);
int64_t clamp_double_to_int64(double number);
-void simplify_fraction64(uint64_t *numer, uint64_t *denom);
-
-uint32_t tor_add_u32_nowrap(uint32_t a, uint32_t b);
-
-/* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b>
- * and positive <b>b</b>. Works on integer types only. Not defined if a+(b-1)
- * can overflow. */
-#define CEIL_DIV(a,b) (((a)+((b)-1))/(b))
-
-/* Return <b>v</b> if it's between <b>min</b> and <b>max</b>. Otherwise
- * return <b>min</b> if <b>v</b> is smaller than <b>min</b>, or <b>max</b> if
- * <b>b</b> is larger than <b>max</b>.
- *
- * Requires that <b>min</b> is no more than <b>max</b>. May evaluate any of
- * its arguments more than once! */
-#define CLAMP(min,v,max) \
- ( ((v) < (min)) ? (min) : \
- ((v) > (max)) ? (max) : \
- (v) )
/* String manipulation */
diff --git a/src/include.am b/src/include.am
index 5676a2359..d69a2fd01 100644
--- a/src/include.am
+++ b/src/include.am
@@ -7,6 +7,7 @@ include src/lib/container/include.am
include src/lib/crypt_ops/include.am
include src/lib/defs/include.am
include src/lib/include.libdonna.am
+include src/lib/intmath/include.am
include src/lib/malloc/include.am
include src/lib/string/include.am
include src/lib/testsupport/include.am
diff --git a/src/lib/container/.may_include b/src/lib/container/.may_include
index eaa020bf5..42458b295 100644
--- a/src/lib/container/.may_include
+++ b/src/lib/container/.may_include
@@ -7,10 +7,10 @@ lib/malloc/*.h
lib/err/*.h
lib/string/*.h
lib/testsupport/testsupport.h
+lib/intmath/*.h
ht.h
siphash.h
# XXX I'd like to remove this.
-common/util.h
common/util_bug.h
diff --git a/src/lib/container/bloomfilt.c b/src/lib/container/bloomfilt.c
index 4847408ee..cbb4d13e5 100644
--- a/src/lib/container/bloomfilt.c
+++ b/src/lib/container/bloomfilt.c
@@ -14,7 +14,7 @@
#include <stdlib.h>
#include "lib/malloc/util_malloc.h"
#include "lib/container/bloomfilt.h"
-#include "common/util.h" // For tor_log2
+#include "lib/intmath/bits.h"
/** Return a newly allocated digestset_t, optimized to hold a total of
* <b>max_elements</b> digests with a reasonably low false positive weight. */
diff --git a/src/lib/crypt_ops/.may_include b/src/lib/crypt_ops/.may_include
index 0a9a0dda2..1b9289b2f 100644
--- a/src/lib/crypt_ops/.may_include
+++ b/src/lib/crypt_ops/.may_include
@@ -6,6 +6,7 @@ lib/ctime/*.h
lib/defs/*.h
lib/malloc/*.h
lib/err/*.h
+lib/intmath/*.h
lib/string/*.h
lib/testsupport/testsupport.h
diff --git a/src/lib/crypt_ops/crypto_pwbox.c b/src/lib/crypt_ops/crypto_pwbox.c
index 9a315d42d..6944f8ab5 100644
--- a/src/lib/crypt_ops/crypto_pwbox.c
+++ b/src/lib/crypt_ops/crypto_pwbox.c
@@ -15,6 +15,7 @@
#include "lib/crypt_ops/crypto_s2k.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/ctime/di_ops.h"
+#include "lib/intmath/muldiv.h"
#include "common/util.h"
#include "trunnel/pwbox.h"
@@ -212,4 +213,3 @@ crypto_unpwbox(uint8_t **out, size_t *outlen_out,
memwipe(keys, 0, sizeof(keys));
return rv;
}
-
diff --git a/src/lib/intmath/.may_include b/src/lib/intmath/.may_include
new file mode 100644
index 000000000..d96c11222
--- /dev/null
+++ b/src/lib/intmath/.may_include
@@ -0,0 +1,4 @@
+orconfig.h
+lib/cc/*.h
+lib/err/*.h
+lib/intmath/*.h
diff --git a/src/lib/intmath/addsub.c b/src/lib/intmath/addsub.c
new file mode 100644
index 000000000..816c5a2bd
--- /dev/null
+++ b/src/lib/intmath/addsub.c
@@ -0,0 +1,20 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/intmath/addsub.h"
+#include "lib/cc/compat_compiler.h"
+
+/* Helper: safely add two uint32_t's, capping at UINT32_MAX rather
+ * than overflow */
+uint32_t
+tor_add_u32_nowrap(uint32_t a, uint32_t b)
+{
+ /* a+b > UINT32_MAX check, without overflow */
+ if (PREDICT_UNLIKELY(a > UINT32_MAX - b)) {
+ return UINT32_MAX;
+ } else {
+ return a+b;
+ }
+}
diff --git a/src/lib/intmath/addsub.h b/src/lib/intmath/addsub.h
new file mode 100644
index 000000000..5277adfa4
--- /dev/null
+++ b/src/lib/intmath/addsub.h
@@ -0,0 +1,13 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_INTMATH_ADDSUB_H
+#define TOR_INTMATH_ADDSUB_H
+
+#include "lib/cc/torint.h"
+
+uint32_t tor_add_u32_nowrap(uint32_t a, uint32_t b);
+
+#endif /* !defined(TOR_INTMATH_MULDIV_H) */
diff --git a/src/lib/intmath/bits.c b/src/lib/intmath/bits.c
new file mode 100644
index 000000000..85d901f71
--- /dev/null
+++ b/src/lib/intmath/bits.c
@@ -0,0 +1,88 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/intmath/bits.h"
+
+/** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */
+int
+tor_log2(uint64_t u64)
+{
+ int r = 0;
+ if (u64 >= (U64_LITERAL(1)<<32)) {
+ u64 >>= 32;
+ r = 32;
+ }
+ if (u64 >= (U64_LITERAL(1)<<16)) {
+ u64 >>= 16;
+ r += 16;
+ }
+ if (u64 >= (U64_LITERAL(1)<<8)) {
+ u64 >>= 8;
+ r += 8;
+ }
+ if (u64 >= (U64_LITERAL(1)<<4)) {
+ u64 >>= 4;
+ r += 4;
+ }
+ if (u64 >= (U64_LITERAL(1)<<2)) {
+ u64 >>= 2;
+ r += 2;
+ }
+ if (u64 >= (U64_LITERAL(1)<<1)) {
+ // u64 >>= 1; // not using this any more.
+ r += 1;
+ }
+ return r;
+}
+
+/** Return the power of 2 in range [1,UINT64_MAX] closest to <b>u64</b>. If
+ * there are two powers of 2 equally close, round down. */
+uint64_t
+round_to_power_of_2(uint64_t u64)
+{
+ int lg2;
+ uint64_t low;
+ uint64_t high;
+ if (u64 == 0)
+ return 1;
+
+ lg2 = tor_log2(u64);
+ low = U64_LITERAL(1) << lg2;
+
+ if (lg2 == 63)
+ return low;
+
+ high = U64_LITERAL(1) << (lg2+1);
+ if (high - u64 < u64 - low)
+ return high;
+ else
+ return low;
+}
+
+/** Return the number of bits set in <b>v</b>. */
+int
+n_bits_set_u8(uint8_t v)
+{
+ static const int nybble_table[] = {
+ 0, /* 0000 */
+ 1, /* 0001 */
+ 1, /* 0010 */
+ 2, /* 0011 */
+ 1, /* 0100 */
+ 2, /* 0101 */
+ 2, /* 0110 */
+ 3, /* 0111 */
+ 1, /* 1000 */
+ 2, /* 1001 */
+ 2, /* 1010 */
+ 3, /* 1011 */
+ 2, /* 1100 */
+ 3, /* 1101 */
+ 3, /* 1110 */
+ 4, /* 1111 */
+ };
+
+ return nybble_table[v & 15] + nybble_table[v>>4];
+}
diff --git a/src/lib/intmath/bits.h b/src/lib/intmath/bits.h
new file mode 100644
index 000000000..70f855089
--- /dev/null
+++ b/src/lib/intmath/bits.h
@@ -0,0 +1,16 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_INTMATH_BITS_H
+#define TOR_INTMATH_BITS_H
+
+#include "lib/cc/torint.h"
+#include "lib/cc/compat_compiler.h"
+
+int tor_log2(uint64_t u64) ATTR_CONST;
+uint64_t round_to_power_of_2(uint64_t u64);
+int n_bits_set_u8(uint8_t v);
+
+#endif /* !defined(TOR_INTMATH_BITS_H) */
diff --git a/src/lib/intmath/cmp.h b/src/lib/intmath/cmp.h
new file mode 100644
index 000000000..90ea3ca07
--- /dev/null
+++ b/src/lib/intmath/cmp.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_INTMATH_CMP_H
+#define TOR_INTMATH_CMP_H
+
+/* Return <b>v</b> if it's between <b>min</b> and <b>max</b>. Otherwise
+ * return <b>min</b> if <b>v</b> is smaller than <b>min</b>, or <b>max</b> if
+ * <b>b</b> is larger than <b>max</b>.
+ *
+ * Requires that <b>min</b> is no more than <b>max</b>. May evaluate any of
+ * its arguments more than once! */
+#define CLAMP(min,v,max) \
+ ( ((v) < (min)) ? (min) : \
+ ((v) > (max)) ? (max) : \
+ (v) )
+
+#endif /* !defined(TOR_INTMATH_CMP_H) */
diff --git a/src/lib/intmath/include.am b/src/lib/intmath/include.am
new file mode 100644
index 000000000..40459d106
--- /dev/null
+++ b/src/lib/intmath/include.am
@@ -0,0 +1,22 @@
+
+noinst_LIBRARIES += src/lib/libtor-intmath.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-intmath-testing.a
+endif
+
+src_lib_libtor_intmath_a_SOURCES = \
+ src/lib/intmath/addsub.c \
+ src/lib/intmath/bits.c \
+ src/lib/intmath/muldiv.c
+
+src_lib_libtor_intmath_testing_a_SOURCES = \
+ $(src_lib_libtor_intmath_a_SOURCES)
+src_lib_libtor_intmath_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_intmath_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS += \
+ src/lib/intmath/addsub.h \
+ src/lib/intmath/cmp.h \
+ src/lib/intmath/bits.h \
+ src/lib/intmath/muldiv.h
diff --git a/src/lib/intmath/muldiv.c b/src/lib/intmath/muldiv.c
new file mode 100644
index 000000000..3e627b237
--- /dev/null
+++ b/src/lib/intmath/muldiv.c
@@ -0,0 +1,75 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/intmath/muldiv.h"
+#include "lib/err/torerr.h"
+
+#include <stdlib.h>
+
+/** Return the lowest x such that x is at least <b>number</b>, and x modulo
+ * <b>divisor</b> == 0. If no such x can be expressed as an unsigned, return
+ * UINT_MAX. Asserts if divisor is zero. */
+unsigned
+round_to_next_multiple_of(unsigned number, unsigned divisor)
+{
+ raw_assert(divisor > 0);
+ if (UINT_MAX - divisor + 1 < number)
+ return UINT_MAX;
+ number += divisor - 1;
+ number -= number % divisor;
+ return number;
+}
+
+/** Return the lowest x such that x is at least <b>number</b>, and x modulo
+ * <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return
+ * UINT32_MAX. Asserts if divisor is zero. */
+uint32_t
+round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
+{
+ raw_assert(divisor > 0);
+ if (UINT32_MAX - divisor + 1 < number)
+ return UINT32_MAX;
+
+ number += divisor - 1;
+ number -= number % divisor;
+ return number;
+}
+
+/** Return the lowest x such that x is at least <b>number</b>, and x modulo
+ * <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return
+ * UINT64_MAX. Asserts if divisor is zero. */
+uint64_t
+round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
+{
+ raw_assert(divisor > 0);
+ if (UINT64_MAX - divisor + 1 < number)
+ return UINT64_MAX;
+ number += divisor - 1;
+ number -= number % divisor;
+ return number;
+}
+
+/* Helper: return greatest common divisor of a,b */
+static uint64_t
+gcd64(uint64_t a, uint64_t b)
+{
+ while (b) {
+ uint64_t t = b;
+ b = a % b;
+ a = t;
+ }
+ return a;
+}
+
+/* Given a fraction *<b>numer</b> / *<b>denom</b>, simplify it.
+ * Requires that the denominator is greater than 0. */
+void
+simplify_fraction64(uint64_t *numer, uint64_t *denom)
+{
+ raw_assert(denom);
+ uint64_t gcd = gcd64(*numer, *denom);
+ *numer /= gcd;
+ *denom /= gcd;
+}
diff --git a/src/lib/intmath/muldiv.h b/src/lib/intmath/muldiv.h
new file mode 100644
index 000000000..de76d9eb6
--- /dev/null
+++ b/src/lib/intmath/muldiv.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_INTMATH_MULDIV_H
+#define TOR_INTMATH_MULDIV_H
+
+#include "lib/cc/torint.h"
+
+unsigned round_to_next_multiple_of(unsigned number, unsigned divisor);
+uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor);
+uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor);
+
+void simplify_fraction64(uint64_t *numer, uint64_t *denom);
+
+/* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b>
+ * and positive <b>b</b>. Works on integer types only. Not defined if a+(b-1)
+ * can overflow. */
+#define CEIL_DIV(a,b) (((a)+((b)-1))/(b))
+
+#endif /* !defined(TOR_INTMATH_MULDIV_H) */
diff --git a/src/rust/build.rs b/src/rust/build.rs
index 5c80265e5..03506fe84 100644
--- a/src/rust/build.rs
+++ b/src/rust/build.rs
@@ -156,6 +156,7 @@ pub fn main() {
cfg.component("tor-malloc");
cfg.component("tor-err-testing");
cfg.component("or-event-testing");
+ cfg.component("tor-intmath-testing");
cfg.component("tor-ctime-testing");
cfg.component("curve25519_donna");
cfg.component("keccak-tiny");
1
0

26 Jun '18
commit b2d4e786b7ed2563461513e36c7e75bea1f70be8
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 10:50:12 2018 -0400
Remove the util_bug.h include from smartlist.h.
This change makes a whole bunch of things in torlog.c break, since
apparently I did not find all the fd dependencies.
---
src/common/util.h | 1 +
src/lib/compress/.may_include | 1 +
src/lib/container/smartlist.c | 3 +++
src/lib/container/smartlist.h | 18 ++++++++++--------
src/lib/crypt_ops/.may_include | 1 +
src/lib/ctime/.may_include | 5 ++---
src/lib/ctime/di_ops.c | 17 ++++++++++-------
src/lib/log/.may_include | 10 ++++++++++
src/lib/log/ratelim.c | 1 +
src/lib/log/ratelim.h | 2 ++
src/lib/log/torlog.c | 4 +++-
src/lib/tls/.may_include | 1 +
src/lib/trace/.may_include | 4 +---
13 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/src/common/util.h b/src/common/util.h
index 9936c421d..3f6476d75 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -31,6 +31,7 @@
#include "lib/intmath/addsub.h"
#include "lib/intmath/muldiv.h"
#include "lib/intmath/cmp.h"
+#include "lib/log/ratelim.h"
#include "common/util_bug.h"
#ifndef O_BINARY
diff --git a/src/lib/compress/.may_include b/src/lib/compress/.may_include
index 70528a7df..3f69dd133 100644
--- a/src/lib/compress/.may_include
+++ b/src/lib/compress/.may_include
@@ -1,6 +1,7 @@
orconfig.h
lib/cc/*.h
lib/compress/*.h
+lib/log/*.h
# XXX I'd like to remove this.
common/*.h
diff --git a/src/lib/container/smartlist.c b/src/lib/container/smartlist.c
index 57b88415a..9d405085b 100644
--- a/src/lib/container/smartlist.c
+++ b/src/lib/container/smartlist.c
@@ -17,9 +17,12 @@
#include "lib/malloc/util_malloc.h"
#include "lib/defs/digest_sizes.h"
#include "lib/ctime/di_ops.h"
+#include "lib/string/compat_ctype.h"
#include "lib/string/util_string.h"
#include "lib/string/printf.h"
+#include "common/util_bug.h"
+
#include <stdlib.h>
#include <string.h>
diff --git a/src/lib/container/smartlist.h b/src/lib/container/smartlist.h
index 53a4948cf..dd455390e 100644
--- a/src/lib/container/smartlist.h
+++ b/src/lib/container/smartlist.h
@@ -7,8 +7,10 @@
#define TOR_SMARTLIST_H
#include <stddef.h>
+#include <stdarg.h>
+
#include "lib/cc/compat_compiler.h"
-#include "common/util_bug.h"
+#include "lib/cc/torint.h"
#include "lib/testsupport/testsupport.h"
/** A resizeable list of pointers, with associated helpful functionality.
@@ -66,22 +68,22 @@ void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2);
*/
static inline int smartlist_len(const smartlist_t *sl);
static inline int smartlist_len(const smartlist_t *sl) {
- tor_assert(sl);
+ raw_assert(sl);
return (sl)->num_used;
}
/** Return the <b>idx</b>th element of sl.
*/
static inline void *smartlist_get(const smartlist_t *sl, int idx);
static inline void *smartlist_get(const smartlist_t *sl, int idx) {
- tor_assert(sl);
- tor_assert(idx>=0);
- tor_assert(sl->num_used > idx);
+ raw_assert(sl);
+ raw_assert(idx>=0);
+ raw_assert(sl->num_used > idx);
return sl->list[idx];
}
static inline void smartlist_set(smartlist_t *sl, int idx, void *val) {
- tor_assert(sl);
- tor_assert(idx>=0);
- tor_assert(sl->num_used > idx);
+ raw_assert(sl);
+ raw_assert(idx>=0);
+ raw_assert(sl->num_used > idx);
sl->list[idx] = val;
}
#else /* !(defined(DEBUG_SMARTLIST)) */
diff --git a/src/lib/crypt_ops/.may_include b/src/lib/crypt_ops/.may_include
index 1b9289b2f..8031bb9bc 100644
--- a/src/lib/crypt_ops/.may_include
+++ b/src/lib/crypt_ops/.may_include
@@ -9,6 +9,7 @@ lib/err/*.h
lib/intmath/*.h
lib/string/*.h
lib/testsupport/testsupport.h
+lib/log/*.h
trunnel/pwbox.h
diff --git a/src/lib/ctime/.may_include b/src/lib/ctime/.may_include
index 72d854c37..e74669bce 100644
--- a/src/lib/ctime/.may_include
+++ b/src/lib/ctime/.may_include
@@ -1,6 +1,5 @@
orconfig.h
lib/cc/*.h
lib/ctime/*.h
-
-# XXXX I'd like to remove this
-common/util.h
+lib/err/*.h
+lib/malloc/*.h
diff --git a/src/lib/ctime/di_ops.c b/src/lib/ctime/di_ops.c
index 407131c44..287ff6080 100644
--- a/src/lib/ctime/di_ops.c
+++ b/src/lib/ctime/di_ops.c
@@ -8,7 +8,10 @@
#include "orconfig.h"
#include "lib/ctime/di_ops.h"
-#include "common/util.h"
+#include "lib/err/torerr.h"
+#include "lib/malloc/util_malloc.h"
+
+#include <string.h>
/**
* Timing-safe version of memcmp. As memcmp, compare the <b>sz</b> bytes at
@@ -170,8 +173,8 @@ dimap_add_entry(di_digest256_map_t **map,
di_digest256_map_t *new_ent;
{
void *old_val = dimap_search(*map, key, NULL);
- tor_assert(! old_val);
- tor_assert(val);
+ raw_assert(! old_val);
+ raw_assert(val);
}
new_ent = tor_malloc_zero(sizeof(di_digest256_map_t));
new_ent->next = *map;
@@ -263,10 +266,10 @@ select_array_member_cumulative_timei(const uint64_t *entries, int n_entries,
rand_val = INT64_MAX;
}
}
- tor_assert(total_so_far == total);
- tor_assert(n_chosen == 1);
- tor_assert(i_chosen >= 0);
- tor_assert(i_chosen < n_entries);
+ raw_assert(total_so_far == total);
+ raw_assert(n_chosen == 1);
+ raw_assert(i_chosen >= 0);
+ raw_assert(i_chosen < n_entries);
return i_chosen;
}
diff --git a/src/lib/log/.may_include b/src/lib/log/.may_include
index 380680640..4f6244c2d 100644
--- a/src/lib/log/.may_include
+++ b/src/lib/log/.may_include
@@ -1,3 +1,13 @@
+orconfig.h
lib/cc/*.h
+lib/container/smartlist.h
+lib/err/*.h
+lib/intmath/*.h
+lib/log/*.h
lib/malloc/*.h
+lib/string/*.h
+lib/testsupport/*.h
+lib/wallclock/*.h
+
+micro-revision.i
\ No newline at end of file
diff --git a/src/lib/log/ratelim.c b/src/lib/log/ratelim.c
index 2d276055b..677c49911 100644
--- a/src/lib/log/ratelim.c
+++ b/src/lib/log/ratelim.c
@@ -5,6 +5,7 @@
#include "lib/log/ratelim.h"
#include "lib/malloc/util_malloc.h"
+#include "lib/string/printf.h"
/** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return the number
* of calls to rate_limit_is_ready (including this one!) since the last time
diff --git a/src/lib/log/ratelim.h b/src/lib/log/ratelim.h
index efaeb9bf6..4ee6c5fed 100644
--- a/src/lib/log/ratelim.h
+++ b/src/lib/log/ratelim.h
@@ -6,6 +6,8 @@
#ifndef TOR_RATELIM_H
#define TOR_RATELIM_H
+#include <time.h>
+
/* Rate-limiter */
/** A ratelim_t remembers how often an event is occurring, and how often
diff --git a/src/lib/log/torlog.c b/src/lib/log/torlog.c
index e77b775c2..aec469c53 100644
--- a/src/lib/log/torlog.c
+++ b/src/lib/log/torlog.c
@@ -11,7 +11,7 @@
#include "orconfig.h"
#include <stdarg.h>
-// #include <stdio.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TIME_H
@@ -32,6 +32,8 @@
#define LOG_PRIVATE
#include "lib/log/torlog.h"
+#include "lib/log/ratelim.h"
+#include "lib/lock/compat_mutex.h"
#include "lib/container/smartlist.h"
#include "lib/err/torerr.h"
#include "lib/intmath/bits.h"
diff --git a/src/lib/tls/.may_include b/src/lib/tls/.may_include
index 8fdd62806..a2d84165f 100644
--- a/src/lib/tls/.may_include
+++ b/src/lib/tls/.may_include
@@ -5,6 +5,7 @@ lib/crypt_ops/*.h
lib/err/*.h
lib/testsupport/testsupport.h
lib/tls/*.h
+lib/log/*.h
ciphers.inc
diff --git a/src/lib/trace/.may_include b/src/lib/trace/.may_include
index 694c8405e..45cd13676 100644
--- a/src/lib/trace/.may_include
+++ b/src/lib/trace/.may_include
@@ -1,5 +1,3 @@
orconfig.h
+lib/log/*.h
lib/trace/*.h
-
-# XXXX
-common/torlog.h
1
0
commit 97b15a1d7c51764888d2172711e3f3a71fb01916
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 10:30:45 2018 -0400
Extract the locking and logging code
The locking code gets its own module, since it's more fundamental
than the higher-level locking code.
Extracting the logging code was the whole point here. :)
---
.gitignore | 2 +
Makefile.am | 4 ++
src/common/compat_pthreads.c | 80 +---------------------------
src/common/compat_threads.c | 28 ----------
src/common/compat_threads.h | 42 +--------------
src/common/compat_winthreads.c | 27 ----------
src/common/include.am | 2 -
src/common/util.c | 51 ------------------
src/common/util.h | 37 -------------
src/include.am | 2 +
src/lib/lock/.may_include | 5 ++
src/lib/lock/compat_mutex.c | 34 ++++++++++++
src/lib/lock/compat_mutex.h | 60 +++++++++++++++++++++
src/lib/lock/compat_mutex_pthreads.c | 97 ++++++++++++++++++++++++++++++++++
src/lib/lock/compat_mutex_winthreads.c | 39 ++++++++++++++
src/lib/lock/include.am | 24 +++++++++
src/lib/log/.may_include | 3 ++
src/lib/log/include.am | 19 +++++++
src/lib/log/ratelim.c | 54 +++++++++++++++++++
src/lib/log/ratelim.h | 46 ++++++++++++++++
src/{common/log.c => lib/log/torlog.c} | 24 +++++++--
src/{common => lib/log}/torlog.h | 0
src/rust/build.rs | 1 +
23 files changed, 413 insertions(+), 268 deletions(-)
diff --git a/.gitignore b/.gitignore
index 6a48ba275..f141fee17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -175,6 +175,8 @@ uptime-*.json
/src/lib/libtor-err-testing.a
/src/lib/libtor-intmath.a
/src/lib/libtor-intmath-testing.a
+/src/lib/libtor-lock.a
+/src/lib/libtor-lock-testing.a
/src/lib/libtor-malloc.a
/src/lib/libtor-malloc-testing.a
/src/lib/libtor-string.a
diff --git a/Makefile.am b/Makefile.am
index 172ab36f6..b6200c6a2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -40,6 +40,8 @@ endif
# "Common" libraries used to link tor's utility code.
TOR_UTIL_LIBS = \
src/common/libor.a \
+ src/lib/libtor-log.a \
+ src/lib/libtor-lock.a \
src/lib/libtor-container.a \
src/lib/libtor-string.a \
src/lib/libtor-malloc.a \
@@ -52,6 +54,8 @@ TOR_UTIL_LIBS = \
# and tests)
TOR_UTIL_TESTING_LIBS = \
src/common/libor-testing.a \
+ src/lib/libtor-log-testing.a \
+ src/lib/libtor-lock-testing.a \
src/lib/libtor-container-testing.a \
src/lib/libtor-string-testing.a \
src/lib/libtor-malloc-testing.a \
diff --git a/src/common/compat_pthreads.c b/src/common/compat_pthreads.c
index c2f8609db..c2bde962f 100644
--- a/src/common/compat_pthreads.c
+++ b/src/common/compat_pthreads.c
@@ -91,83 +91,6 @@ spawn_exit(void)
pthread_exit(NULL);
}
-/** A mutex attribute that we're going to use to tell pthreads that we want
- * "recursive" mutexes (i.e., once we can re-lock if we're already holding
- * them.) */
-static pthread_mutexattr_t attr_recursive;
-
-/** Initialize <b>mutex</b> so it can be locked. Every mutex must be set
- * up with tor_mutex_init() or tor_mutex_new(); not both. */
-void
-tor_mutex_init(tor_mutex_t *mutex)
-{
- if (PREDICT_UNLIKELY(!threads_initialized))
- tor_threads_init(); // LCOV_EXCL_LINE
- const int err = pthread_mutex_init(&mutex->mutex, &attr_recursive);
- if (PREDICT_UNLIKELY(err)) {
- // LCOV_EXCL_START
- raw_assert_unreached_msg("Error creating a mutex.");
- // LCOV_EXCL_STOP
- }
-}
-
-/** As tor_mutex_init, but initialize a mutex suitable that may be
- * non-recursive, if the OS supports that. */
-void
-tor_mutex_init_nonrecursive(tor_mutex_t *mutex)
-{
- int err;
- if (!threads_initialized)
- tor_threads_init(); // LCOV_EXCL_LINE
- err = pthread_mutex_init(&mutex->mutex, NULL);
- if (PREDICT_UNLIKELY(err)) {
- // LCOV_EXCL_START
- raw_assert_unreached_msg("Error creating a mutex.");
- // LCOV_EXCL_STOP
- }
-}
-
-/** Wait until <b>m</b> is free, then acquire it. */
-void
-tor_mutex_acquire(tor_mutex_t *m)
-{
- int err;
- raw_assert(m);
- err = pthread_mutex_lock(&m->mutex);
- if (PREDICT_UNLIKELY(err)) {
- // LCOV_EXCL_START
- raw_assert_unreached_msg("Error locking a mutex.");
- // LCOV_EXCL_STOP
- }
-}
-/** Release the lock <b>m</b> so another thread can have it. */
-void
-tor_mutex_release(tor_mutex_t *m)
-{
- int err;
- raw_assert(m);
- err = pthread_mutex_unlock(&m->mutex);
- if (PREDICT_UNLIKELY(err)) {
- // LCOV_EXCL_START
- raw_assert_unreached_msg("Error unlocking a mutex.");
- // LCOV_EXCL_STOP
- }
-}
-/** Clean up the mutex <b>m</b> so that it no longer uses any system
- * resources. Does not free <b>m</b>. This function must only be called on
- * mutexes from tor_mutex_init(). */
-void
-tor_mutex_uninit(tor_mutex_t *m)
-{
- int err;
- raw_assert(m);
- err = pthread_mutex_destroy(&m->mutex);
- if (PREDICT_UNLIKELY(err)) {
- // LCOV_EXCL_START
- raw_assert_unreached_msg("Error destroying a mutex.");
- // LCOV_EXCL_STOP
- }
-}
/** Return an integer representing this thread. */
unsigned long
tor_get_thread_id(void)
@@ -328,8 +251,7 @@ void
tor_threads_init(void)
{
if (!threads_initialized) {
- pthread_mutexattr_init(&attr_recursive);
- pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE);
+ tor_locking_init();
const int ret1 = pthread_attr_init(&attr_detached);
tor_assert(ret1 == 0);
#ifndef PTHREAD_CREATE_DETACHED
diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c
index 250ac48c0..89214ab1d 100644
--- a/src/common/compat_threads.c
+++ b/src/common/compat_threads.c
@@ -29,33 +29,6 @@
#include <unistd.h>
#endif
-/** Return a newly allocated, ready-for-use mutex. */
-tor_mutex_t *
-tor_mutex_new(void)
-{
- tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
- tor_mutex_init(m);
- return m;
-}
-/** Return a newly allocated, ready-for-use mutex. This one might be
- * non-recursive, if that's faster. */
-tor_mutex_t *
-tor_mutex_new_nonrecursive(void)
-{
- tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
- tor_mutex_init_nonrecursive(m);
- return m;
-}
-/** Release all storage and system resources held by <b>m</b>. */
-void
-tor_mutex_free_(tor_mutex_t *m)
-{
- if (!m)
- return;
- tor_mutex_uninit(m);
- tor_free(m);
-}
-
/** Allocate and return a new condition variable. */
tor_cond_t *
tor_cond_new(void)
@@ -404,4 +377,3 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
return oldval;
}
#endif /* !defined(HAVE_STDATOMIC_H) */
-
diff --git a/src/common/compat_threads.h b/src/common/compat_threads.h
index 19e0a4f11..d1fdfc96c 100644
--- a/src/common/compat_threads.h
+++ b/src/common/compat_threads.h
@@ -9,54 +9,15 @@
#include "orconfig.h"
#include "lib/cc/torint.h"
#include "lib/testsupport/testsupport.h"
-
-#if defined(HAVE_PTHREAD_H) && !defined(_WIN32)
-#include <pthread.h>
-#endif
+#include "lib/lock/compat_mutex.h"
#ifdef HAVE_STDATOMIC_H
#include <stdatomic.h>
#endif
-#if defined(_WIN32)
-#define USE_WIN32_THREADS
-#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
-#define USE_PTHREADS
-#else
-#error "No threading system was found"
-#endif /* defined(_WIN32) || ... */
-
int spawn_func(void (*func)(void *), void *data);
void spawn_exit(void) ATTR_NORETURN;
-/* Because we use threads instead of processes on most platforms (Windows,
- * Linux, etc), we need locking for them. On platforms with poor thread
- * support or broken gethostbyname_r, these functions are no-ops. */
-
-/** A generic lock structure for multithreaded builds. */
-typedef struct tor_mutex_t {
-#if defined(USE_WIN32_THREADS)
- /** Windows-only: on windows, we implement locks with CRITICAL_SECTIONS. */
- CRITICAL_SECTION mutex;
-#elif defined(USE_PTHREADS)
- /** Pthreads-only: with pthreads, we implement locks with
- * pthread_mutex_t. */
- pthread_mutex_t mutex;
-#else
- /** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
- int _unused;
-#endif /* defined(USE_WIN32_THREADS) || ... */
-} tor_mutex_t;
-
-tor_mutex_t *tor_mutex_new(void);
-tor_mutex_t *tor_mutex_new_nonrecursive(void);
-void tor_mutex_init(tor_mutex_t *m);
-void tor_mutex_init_nonrecursive(tor_mutex_t *m);
-void tor_mutex_acquire(tor_mutex_t *m);
-void tor_mutex_release(tor_mutex_t *m);
-void tor_mutex_free_(tor_mutex_t *m);
-#define tor_mutex_free(m) FREE_AND_NULL(tor_mutex_t, tor_mutex_free_, (m))
-void tor_mutex_uninit(tor_mutex_t *m);
unsigned long tor_get_thread_id(void);
void tor_threads_init(void);
@@ -220,4 +181,3 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
#endif /* defined(HAVE_STDATOMIC_H) */
#endif /* !defined(TOR_COMPAT_THREADS_H) */
-
diff --git a/src/common/compat_winthreads.c b/src/common/compat_winthreads.c
index 807c7b4ae..28981980b 100644
--- a/src/common/compat_winthreads.c
+++ b/src/common/compat_winthreads.c
@@ -54,33 +54,6 @@ spawn_exit(void)
// LCOV_EXCL_STOP
}
-void
-tor_mutex_init(tor_mutex_t *m)
-{
- InitializeCriticalSection(&m->mutex);
-}
-void
-tor_mutex_init_nonrecursive(tor_mutex_t *m)
-{
- InitializeCriticalSection(&m->mutex);
-}
-
-void
-tor_mutex_uninit(tor_mutex_t *m)
-{
- DeleteCriticalSection(&m->mutex);
-}
-void
-tor_mutex_acquire(tor_mutex_t *m)
-{
- raw_assert(m);
- EnterCriticalSection(&m->mutex);
-}
-void
-tor_mutex_release(tor_mutex_t *m)
-{
- LeaveCriticalSection(&m->mutex);
-}
unsigned long
tor_get_thread_id(void)
{
diff --git a/src/common/include.am b/src/common/include.am
index 422397886..d4404fb1b 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -38,7 +38,6 @@ LIBOR_A_SRC = \
src/common/compat_threads.c \
src/common/compat_time.c \
src/common/confline.c \
- src/common/log.c \
src/common/memarea.c \
src/common/util.c \
src/common/util_bug.c \
@@ -94,7 +93,6 @@ COMMONHEADERS = \
src/common/storagedir.h \
src/common/timers.h \
src/common/token_bucket.h \
- src/common/torlog.h \
src/common/util.h \
src/common/util_bug.h \
src/common/util_format.h \
diff --git a/src/common/util.c b/src/common/util.c
index 5efbb2bbf..2948e264d 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1310,57 +1310,6 @@ format_time_interval(char *out, size_t out_len, long interval)
}
/* =====
- * Rate limiting
- * ===== */
-
-/** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return the number
- * of calls to rate_limit_is_ready (including this one!) since the last time
- * rate_limit_is_ready returned nonzero. Otherwise return 0.
- * If the call number hits <b>RATELIM_TOOMANY</b> limit, drop a warning
- * about this event and stop counting. */
-static int
-rate_limit_is_ready(ratelim_t *lim, time_t now)
-{
- if (lim->rate + lim->last_allowed <= now) {
- int res = lim->n_calls_since_last_time + 1;
- lim->last_allowed = now;
- lim->n_calls_since_last_time = 0;
- return res;
- } else {
- if (lim->n_calls_since_last_time <= RATELIM_TOOMANY) {
- ++lim->n_calls_since_last_time;
- }
-
- return 0;
- }
-}
-
-/** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return a newly
- * allocated string indicating how many messages were suppressed, suitable to
- * append to a log message. Otherwise return NULL. */
-char *
-rate_limit_log(ratelim_t *lim, time_t now)
-{
- int n;
- if ((n = rate_limit_is_ready(lim, now))) {
- if (n == 1) {
- return tor_strdup("");
- } else {
- char *cp=NULL;
- const char *opt_over = (n >= RATELIM_TOOMANY) ? "over " : "";
- /* 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,
- " [%s%d similar message(s) suppressed in last %d seconds]",
- opt_over, n-1, lim->rate);
- return cp;
- }
- } else {
- return NULL;
- }
-}
-
-/* =====
* File helpers
* ===== */
diff --git a/src/common/util.h b/src/common/util.h
index 8f6ec34dc..9936c421d 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -126,43 +126,6 @@ int parse_iso_time_nospace(const char *cp, time_t *t);
int parse_http_time(const char *buf, struct tm *tm);
int format_time_interval(char *out, size_t out_len, long interval);
-/* Rate-limiter */
-
-/** A ratelim_t remembers how often an event is occurring, and how often
- * it's allowed to occur. Typical usage is something like:
- *
- <pre>
- if (possibly_very_frequent_event()) {
- const int INTERVAL = 300;
- static ratelim_t warning_limit = RATELIM_INIT(INTERVAL);
- char *m;
- if ((m = rate_limit_log(&warning_limit, approx_time()))) {
- log_warn(LD_GENERAL, "The event occurred!%s", m);
- tor_free(m);
- }
- }
- </pre>
-
- As a convenience wrapper for logging, you can replace the above with:
- <pre>
- if (possibly_very_frequent_event()) {
- static ratelim_t warning_limit = RATELIM_INIT(300);
- log_fn_ratelim(&warning_limit, LOG_WARN, LD_GENERAL,
- "The event occurred!");
- }
- </pre>
- */
-typedef struct ratelim_t {
- int rate;
- time_t last_allowed;
- int n_calls_since_last_time;
-} ratelim_t;
-
-#define RATELIM_INIT(r) { (r), 0, 0 }
-#define RATELIM_TOOMANY (16*1000*1000)
-
-char *rate_limit_log(ratelim_t *lim, time_t now);
-
/* File helpers */
ssize_t write_all(tor_socket_t fd, const char *buf, size_t count,int isSocket);
ssize_t read_all(tor_socket_t fd, char *buf, size_t count, int isSocket);
diff --git a/src/include.am b/src/include.am
index d69a2fd01..7eb6c069a 100644
--- a/src/include.am
+++ b/src/include.am
@@ -8,6 +8,8 @@ include src/lib/crypt_ops/include.am
include src/lib/defs/include.am
include src/lib/include.libdonna.am
include src/lib/intmath/include.am
+include src/lib/lock/include.am
+include src/lib/log/include.am
include src/lib/malloc/include.am
include src/lib/string/include.am
include src/lib/testsupport/include.am
diff --git a/src/lib/lock/.may_include b/src/lib/lock/.may_include
new file mode 100644
index 000000000..9522e3af4
--- /dev/null
+++ b/src/lib/lock/.may_include
@@ -0,0 +1,5 @@
+orconfig.h
+lib/cc/*.h
+lib/err/*.h
+lib/lock/*.h
+lib/malloc/*.h
diff --git a/src/lib/lock/compat_mutex.c b/src/lib/lock/compat_mutex.c
new file mode 100644
index 000000000..e0f6224a8
--- /dev/null
+++ b/src/lib/lock/compat_mutex.c
@@ -0,0 +1,34 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/lock/compat_mutex.h"
+#include "lib/malloc/util_malloc.h"
+
+/** Return a newly allocated, ready-for-use mutex. */
+tor_mutex_t *
+tor_mutex_new(void)
+{
+ tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
+ tor_mutex_init(m);
+ return m;
+}
+/** Return a newly allocated, ready-for-use mutex. This one might be
+ * non-recursive, if that's faster. */
+tor_mutex_t *
+tor_mutex_new_nonrecursive(void)
+{
+ tor_mutex_t *m = tor_malloc_zero(sizeof(tor_mutex_t));
+ tor_mutex_init_nonrecursive(m);
+ return m;
+}
+/** Release all storage and system resources held by <b>m</b>. */
+void
+tor_mutex_free_(tor_mutex_t *m)
+{
+ if (!m)
+ return;
+ tor_mutex_uninit(m);
+ tor_free(m);
+}
diff --git a/src/lib/lock/compat_mutex.h b/src/lib/lock/compat_mutex.h
new file mode 100644
index 000000000..92978086a
--- /dev/null
+++ b/src/lib/lock/compat_mutex.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_COMPAT_MUTEX_H
+#define TOR_COMPAT_MUTEX_H
+
+#include "orconfig.h"
+#include "lib/cc/torint.h"
+#include "lib/malloc/util_malloc.h"
+
+#if defined(HAVE_PTHREAD_H) && !defined(_WIN32)
+#include <pthread.h>
+#endif
+
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+#if defined(_WIN32)
+#define USE_WIN32_THREADS
+#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
+#define USE_PTHREADS
+#else
+#error "No threading system was found"
+#endif /* defined(_WIN32) || ... */
+
+/* Because we use threads instead of processes on most platforms (Windows,
+ * Linux, etc), we need locking for them. On platforms with poor thread
+ * support or broken gethostbyname_r, these functions are no-ops. */
+
+/** A generic lock structure for multithreaded builds. */
+typedef struct tor_mutex_t {
+#if defined(USE_WIN32_THREADS)
+ /** Windows-only: on windows, we implement locks with CRITICAL_SECTIONS. */
+ CRITICAL_SECTION mutex;
+#elif defined(USE_PTHREADS)
+ /** Pthreads-only: with pthreads, we implement locks with
+ * pthread_mutex_t. */
+ pthread_mutex_t mutex;
+#else
+ /** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
+ int _unused;
+#endif /* defined(USE_WIN32_MUTEX) || ... */
+} tor_mutex_t;
+
+tor_mutex_t *tor_mutex_new(void);
+tor_mutex_t *tor_mutex_new_nonrecursive(void);
+void tor_mutex_init(tor_mutex_t *m);
+void tor_mutex_init_nonrecursive(tor_mutex_t *m);
+void tor_mutex_acquire(tor_mutex_t *m);
+void tor_mutex_release(tor_mutex_t *m);
+void tor_mutex_free_(tor_mutex_t *m);
+#define tor_mutex_free(m) FREE_AND_NULL(tor_mutex_t, tor_mutex_free_, (m))
+void tor_mutex_uninit(tor_mutex_t *m);
+
+void tor_locking_init(void);
+
+#endif /* !defined(TOR_COMPAT_MUTEX_H) */
diff --git a/src/lib/lock/compat_mutex_pthreads.c b/src/lib/lock/compat_mutex_pthreads.c
new file mode 100644
index 000000000..390da4fb8
--- /dev/null
+++ b/src/lib/lock/compat_mutex_pthreads.c
@@ -0,0 +1,97 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/lock/compat_mutex.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/err/torerr.h"
+
+/** A mutex attribute that we're going to use to tell pthreads that we want
+ * "recursive" mutexes (i.e., once we can re-lock if we're already holding
+ * them.) */
+static pthread_mutexattr_t attr_recursive;
+static int attr_initialized = 0;
+
+void
+tor_locking_init(void)
+{
+ if (!attr_initialized) {
+ pthread_mutexattr_init(&attr_recursive);
+ pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE);
+ attr_initialized = 1;
+ }
+}
+
+/** Initialize <b>mutex</b> so it can be locked. Every mutex must be set
+ * up with tor_mutex_init() or tor_mutex_new(); not both. */
+void
+tor_mutex_init(tor_mutex_t *mutex)
+{
+ if (PREDICT_UNLIKELY(!attr_initialized))
+ tor_locking_init(); // LCOV_EXCL_LINE
+ const int err = pthread_mutex_init(&mutex->mutex, &attr_recursive);
+ if (PREDICT_UNLIKELY(err)) {
+ // LCOV_EXCL_START
+ raw_assert_unreached_msg("Error creating a mutex.");
+ // LCOV_EXCL_STOP
+ }
+}
+
+/** As tor_mutex_init, but initialize a mutex suitable that may be
+ * non-recursive, if the OS supports that. */
+void
+tor_mutex_init_nonrecursive(tor_mutex_t *mutex)
+{
+ int err;
+ if (!attr_initialized)
+ tor_locking_init(); // LCOV_EXCL_LINE
+ err = pthread_mutex_init(&mutex->mutex, NULL);
+ if (PREDICT_UNLIKELY(err)) {
+ // LCOV_EXCL_START
+ raw_assert_unreached_msg("Error creating a mutex.");
+ // LCOV_EXCL_STOP
+ }
+}
+
+/** Wait until <b>m</b> is free, then acquire it. */
+void
+tor_mutex_acquire(tor_mutex_t *m)
+{
+ int err;
+ raw_assert(m);
+ err = pthread_mutex_lock(&m->mutex);
+ if (PREDICT_UNLIKELY(err)) {
+ // LCOV_EXCL_START
+ raw_assert_unreached_msg("Error locking a mutex.");
+ // LCOV_EXCL_STOP
+ }
+}
+/** Release the lock <b>m</b> so another thread can have it. */
+void
+tor_mutex_release(tor_mutex_t *m)
+{
+ int err;
+ raw_assert(m);
+ err = pthread_mutex_unlock(&m->mutex);
+ if (PREDICT_UNLIKELY(err)) {
+ // LCOV_EXCL_START
+ raw_assert_unreached_msg("Error unlocking a mutex.");
+ // LCOV_EXCL_STOP
+ }
+}
+/** Clean up the mutex <b>m</b> so that it no longer uses any system
+ * resources. Does not free <b>m</b>. This function must only be called on
+ * mutexes from tor_mutex_init(). */
+void
+tor_mutex_uninit(tor_mutex_t *m)
+{
+ int err;
+ raw_assert(m);
+ err = pthread_mutex_destroy(&m->mutex);
+ if (PREDICT_UNLIKELY(err)) {
+ // LCOV_EXCL_START
+ raw_assert_unreached_msg("Error destroying a mutex.");
+ // LCOV_EXCL_STOP
+ }
+}
diff --git a/src/lib/lock/compat_mutex_winthreads.c b/src/lib/lock/compat_mutex_winthreads.c
new file mode 100644
index 000000000..c92eb6291
--- /dev/null
+++ b/src/lib/lock/compat_mutex_winthreads.c
@@ -0,0 +1,39 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/lock/compat_mutex.h"
+
+void
+tor_locking_init(void)
+{
+}
+
+void
+tor_mutex_init(tor_mutex_t *m)
+{
+ InitializeCriticalSection(&m->mutex);
+}
+void
+tor_mutex_init_nonrecursive(tor_mutex_t *m)
+{
+ InitializeCriticalSection(&m->mutex);
+}
+
+void
+tor_mutex_uninit(tor_mutex_t *m)
+{
+ DeleteCriticalSection(&m->mutex);
+}
+void
+tor_mutex_acquire(tor_mutex_t *m)
+{
+ raw_assert(m);
+ EnterCriticalSection(&m->mutex);
+}
+void
+tor_mutex_release(tor_mutex_t *m)
+{
+ LeaveCriticalSection(&m->mutex);
+}
diff --git a/src/lib/lock/include.am b/src/lib/lock/include.am
new file mode 100644
index 000000000..4e6f44434
--- /dev/null
+++ b/src/lib/lock/include.am
@@ -0,0 +1,24 @@
+
+noinst_LIBRARIES += src/lib/libtor-lock.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-lock-testing.a
+endif
+
+src_lib_libtor_lock_a_SOURCES = \
+ src/lib/lock/compat_mutex.c
+
+if THREADS_PTHREADS
+src_lib_libtor_lock_a_SOURCES += src/lib/lock/compat_mutex_pthreads.c
+endif
+if THREADS_WIN32
+src_lib_libtor_lock_a_SOURCES += src/lib/lock/compat_mutex_winthreads.c
+endif
+
+src_lib_libtor_lock_testing_a_SOURCES = \
+ $(src_lib_libtor_lock_a_SOURCES)
+src_lib_libtor_lock_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_lock_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS += \
+ src/lib/lock/compat_mutex.h
diff --git a/src/lib/log/.may_include b/src/lib/log/.may_include
new file mode 100644
index 000000000..380680640
--- /dev/null
+++ b/src/lib/log/.may_include
@@ -0,0 +1,3 @@
+
+lib/cc/*.h
+lib/malloc/*.h
diff --git a/src/lib/log/include.am b/src/lib/log/include.am
new file mode 100644
index 000000000..f9f327e2d
--- /dev/null
+++ b/src/lib/log/include.am
@@ -0,0 +1,19 @@
+
+noinst_LIBRARIES += src/lib/libtor-log.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-log-testing.a
+endif
+
+src_lib_libtor_log_a_SOURCES = \
+ src/lib/log/ratelim.c \
+ src/lib/log/torlog.c
+
+src_lib_libtor_log_testing_a_SOURCES = \
+ $(src_lib_libtor_log_a_SOURCES)
+src_lib_libtor_log_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_log_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS += \
+ src/lib/log/ratelim.h \
+ src/lib/log/torlog.h
diff --git a/src/lib/log/ratelim.c b/src/lib/log/ratelim.c
new file mode 100644
index 000000000..2d276055b
--- /dev/null
+++ b/src/lib/log/ratelim.c
@@ -0,0 +1,54 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/log/ratelim.h"
+#include "lib/malloc/util_malloc.h"
+
+/** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return the number
+ * of calls to rate_limit_is_ready (including this one!) since the last time
+ * rate_limit_is_ready returned nonzero. Otherwise return 0.
+ * If the call number hits <b>RATELIM_TOOMANY</b> limit, drop a warning
+ * about this event and stop counting. */
+static int
+rate_limit_is_ready(ratelim_t *lim, time_t now)
+{
+ if (lim->rate + lim->last_allowed <= now) {
+ int res = lim->n_calls_since_last_time + 1;
+ lim->last_allowed = now;
+ lim->n_calls_since_last_time = 0;
+ return res;
+ } else {
+ if (lim->n_calls_since_last_time <= RATELIM_TOOMANY) {
+ ++lim->n_calls_since_last_time;
+ }
+
+ return 0;
+ }
+}
+
+/** If the rate-limiter <b>lim</b> is ready at <b>now</b>, return a newly
+ * allocated string indicating how many messages were suppressed, suitable to
+ * append to a log message. Otherwise return NULL. */
+char *
+rate_limit_log(ratelim_t *lim, time_t now)
+{
+ int n;
+ if ((n = rate_limit_is_ready(lim, now))) {
+ if (n == 1) {
+ return tor_strdup("");
+ } else {
+ char *cp=NULL;
+ const char *opt_over = (n >= RATELIM_TOOMANY) ? "over " : "";
+ /* 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,
+ " [%s%d similar message(s) suppressed in last %d seconds]",
+ opt_over, n-1, lim->rate);
+ return cp;
+ }
+ } else {
+ return NULL;
+ }
+}
diff --git a/src/lib/log/ratelim.h b/src/lib/log/ratelim.h
new file mode 100644
index 000000000..efaeb9bf6
--- /dev/null
+++ b/src/lib/log/ratelim.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_RATELIM_H
+#define TOR_RATELIM_H
+
+/* Rate-limiter */
+
+/** A ratelim_t remembers how often an event is occurring, and how often
+ * it's allowed to occur. Typical usage is something like:
+ *
+ <pre>
+ if (possibly_very_frequent_event()) {
+ const int INTERVAL = 300;
+ static ratelim_t warning_limit = RATELIM_INIT(INTERVAL);
+ char *m;
+ if ((m = rate_limit_log(&warning_limit, approx_time()))) {
+ log_warn(LD_GENERAL, "The event occurred!%s", m);
+ tor_free(m);
+ }
+ }
+ </pre>
+
+ As a convenience wrapper for logging, you can replace the above with:
+ <pre>
+ if (possibly_very_frequent_event()) {
+ static ratelim_t warning_limit = RATELIM_INIT(300);
+ log_fn_ratelim(&warning_limit, LOG_WARN, LD_GENERAL,
+ "The event occurred!");
+ }
+ </pre>
+ */
+typedef struct ratelim_t {
+ int rate;
+ time_t last_allowed;
+ int n_calls_since_last_time;
+} ratelim_t;
+
+#define RATELIM_INIT(r) { (r), 0, 0 }
+#define RATELIM_TOOMANY (16*1000*1000)
+
+char *rate_limit_log(ratelim_t *lim, time_t now);
+
+#endif
diff --git a/src/common/log.c b/src/lib/log/torlog.c
similarity index 98%
rename from src/common/log.c
rename to src/lib/log/torlog.c
index bb4b1e121..e67442e68 100644
--- a/src/common/log.c
+++ b/src/lib/log/torlog.c
@@ -29,12 +29,14 @@
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#include "common/util.h"
+
#define LOG_PRIVATE
#include "common/torlog.h"
#include "lib/container/smartlist.h"
#include "lib/err/torerr.h"
+#include "lib/intmath/bits.h"
#include "lib/malloc/util_malloc.h"
+#include "lib/string/util_string.h"
#include "lib/wallclock/tor_gettimeofday.h"
#include "lib/wallclock/approx_time.h"
@@ -304,6 +306,22 @@ log_prefix_(char *buf, size_t buf_len, int severity)
return n+r;
}
+/** Minimal version of write_all, for use by logging. */
+static int
+write_all_to_fd(int fd, const char *buf, size_t count)
+{
+ size_t written = 0;
+ raw_assert(count < SSIZE_MAX);
+
+ while (written < count) {
+ ssize_t result = write(fd, buf+written, count-written);
+ if (result<0)
+ return -1;
+ written += result;
+ }
+ return 0;
+}
+
/** If lf refers to an actual file that we have just opened, and the file
* contains no data, log an "opening new logfile" message at the top.
*
@@ -337,7 +355,7 @@ log_tor_version(logfile_t *lf, int reset)
tor_snprintf(buf+n, sizeof(buf)-n,
"Tor %s opening %slog file.\n", VERSION, is_new?"new ":"");
}
- if (write_all(lf->fd, buf, strlen(buf), 0) < 0) /* error */
+ if (write_all_to_fd(lf->fd, buf, strlen(buf)) < 0) /* error */
return -1; /* failed */
return 0;
}
@@ -551,7 +569,7 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len,
lf->callback(severity, domain, msg_after_prefix);
}
} else {
- if (write_all(lf->fd, buf, msg_len, 0) < 0) { /* error */
+ if (write_all_to_fd(lf->fd, buf, msg_len) < 0) { /* error */
/* don't log the error! mark this log entry to be blown away, and
* continue. */
lf->seems_dead = 1;
diff --git a/src/common/torlog.h b/src/lib/log/torlog.h
similarity index 100%
rename from src/common/torlog.h
rename to src/lib/log/torlog.h
diff --git a/src/rust/build.rs b/src/rust/build.rs
index 03506fe84..8bb9eb295 100644
--- a/src/rust/build.rs
+++ b/src/rust/build.rs
@@ -151,6 +151,7 @@ pub fn main() {
// moving forward!
cfg.component("tor-crypt-ops-testing");
cfg.component("or-testing");
+ cfg.component("libtor-lock");
cfg.component("tor-container-testing");
cfg.component("tor-string-testing");
cfg.component("tor-malloc");
1
0

[tor/master] Automated fixup of include paths after torlog.h movement.
by nickm@torproject.org 26 Jun '18
by nickm@torproject.org 26 Jun '18
26 Jun '18
commit da4ae8a6b6bc45f301c1493bb55b09e2f1209ac2
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 10:32:10 2018 -0400
Automated fixup of include paths after torlog.h movement.
---
src/common/address.c | 2 +-
src/common/buffers.c | 2 +-
src/common/compat.c | 2 +-
src/common/compat_libevent.c | 2 +-
src/common/compat_pthreads.c | 2 +-
src/common/compat_threads.c | 2 +-
src/common/compat_time.c | 2 +-
src/common/compat_winthreads.c | 2 +-
src/common/confline.c | 2 +-
src/common/memarea.c | 2 +-
src/common/procmon.h | 2 +-
src/common/sandbox.c | 2 +-
src/common/storagedir.c | 2 +-
src/common/timers.c | 2 +-
src/common/util.c | 2 +-
src/common/util_bug.c | 2 +-
src/common/util_format.c | 2 +-
src/common/util_process.c | 2 +-
src/common/workqueue.c | 2 +-
src/lib/compress/compress.c | 2 +-
src/lib/compress/compress_lzma.c | 2 +-
src/lib/compress/compress_none.c | 2 +-
src/lib/compress/compress_zlib.c | 2 +-
src/lib/compress/compress_zstd.c | 2 +-
src/lib/crypt_ops/aes.c | 2 +-
src/lib/crypt_ops/crypto.c | 2 +-
src/lib/crypt_ops/crypto_curve25519.c | 2 +-
src/lib/crypt_ops/crypto_dh.c | 2 +-
src/lib/crypt_ops/crypto_digest.c | 2 +-
src/lib/crypt_ops/crypto_ed25519.c | 2 +-
src/lib/crypt_ops/crypto_format.c | 2 +-
src/lib/crypt_ops/crypto_rand.c | 2 +-
src/lib/crypt_ops/crypto_rsa.c | 2 +-
src/lib/crypt_ops/crypto_rsa.h | 2 +-
src/lib/crypt_ops/crypto_util.c | 2 +-
src/lib/log/torlog.c | 2 +-
src/lib/tls/buffers_tls.c | 2 +-
src/lib/tls/tortls.c | 2 +-
src/lib/trace/debug.h | 2 +-
src/or/keypin.c | 2 +-
src/or/onion_ntor.c | 2 +-
src/or/or.h | 2 +-
src/or/parsecommon.c | 2 +-
src/or/torcert.c | 2 +-
src/test/fuzz/fuzz_http.c | 2 +-
src/test/fuzz/fuzz_http_connect.c | 2 +-
src/test/log_test_helpers.c | 2 +-
src/test/test_bt_cl.c | 2 +-
src/test/test_logging.c | 2 +-
src/test/test_status.c | 2 +-
src/test/test_tortls.c | 2 +-
src/test/test_util_slow.c | 2 +-
src/tools/tor-gencert.c | 2 +-
src/tools/tor-resolve.c | 2 +-
54 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/src/common/address.c b/src/common/address.c
index f2cddd394..42052f85e 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -39,7 +39,7 @@
#include "common/util.h"
#include "common/util_format.h"
#include "common/address.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/container/smartlist.h"
#include "common/sandbox.h"
#include "siphash.h"
diff --git a/src/common/buffers.c b/src/common/buffers.c
index 41f98ddf7..4e5f56c73 100644
--- a/src/common/buffers.c
+++ b/src/common/buffers.c
@@ -26,7 +26,7 @@
#include "lib/compress/compress.h"
#include "common/util.h"
#include "lib/cc/torint.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
diff --git a/src/common/compat.c b/src/common/compat.c
index 8929f2f3d..b4175c15a 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -124,7 +124,7 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
#include <sys/file.h>
#endif
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "lib/container/smartlist.h"
#include "common/address.h"
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index e3216bfc4..a0b9bc535 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -14,7 +14,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include <event2/event.h>
#include <event2/thread.h>
diff --git a/src/common/compat_pthreads.c b/src/common/compat_pthreads.c
index c2bde962f..e345cfef0 100644
--- a/src/common/compat_pthreads.c
+++ b/src/common/compat_pthreads.c
@@ -16,7 +16,7 @@
#include <time.h>
#include "common/compat.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
/** Wraps a void (*)(void*) function and its argument so we can
diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c
index 89214ab1d..e66143b35 100644
--- a/src/common/compat_threads.c
+++ b/src/common/compat_threads.c
@@ -17,7 +17,7 @@
#include "common/compat_threads.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#ifdef HAVE_SYS_EVENTFD_H
#include <sys/eventfd.h>
diff --git a/src/common/compat_time.c b/src/common/compat_time.c
index d3cbd02c6..148f2f895 100644
--- a/src/common/compat_time.c
+++ b/src/common/compat_time.c
@@ -35,7 +35,7 @@
#endif
#include "lib/err/torerr.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#ifdef _WIN32
diff --git a/src/common/compat_winthreads.c b/src/common/compat_winthreads.c
index 28981980b..d082af31c 100644
--- a/src/common/compat_winthreads.c
+++ b/src/common/compat_winthreads.c
@@ -16,7 +16,7 @@
#include <windows.h>
#include <process.h>
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
/* This value is more or less total cargo-cult */
#define SPIN_COUNT 2000
diff --git a/src/common/confline.c b/src/common/confline.c
index 76f5ac04e..9e37bfbdb 100644
--- a/src/common/confline.c
+++ b/src/common/confline.c
@@ -6,7 +6,7 @@
#include "common/compat.h"
#include "common/confline.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "lib/container/smartlist.h"
diff --git a/src/common/memarea.c b/src/common/memarea.c
index ec10f0222..589277ba3 100644
--- a/src/common/memarea.c
+++ b/src/common/memarea.c
@@ -12,7 +12,7 @@
#include "common/memarea.h"
#include "common/util.h"
#include "common/compat.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#ifndef DISABLE_MEMORY_SENTINELS
diff --git a/src/common/procmon.h b/src/common/procmon.h
index 46b6435af..246ddd71d 100644
--- a/src/common/procmon.h
+++ b/src/common/procmon.h
@@ -12,7 +12,7 @@
#include "common/compat.h"
#include "common/compat_libevent.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
typedef struct tor_process_monitor_t tor_process_monitor_t;
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index 7e88ec9dd..b41b8f4ba 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -35,7 +35,7 @@
#include "common/sandbox.h"
#include "lib/container/map.h"
#include "lib/err/torerr.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/cc/torint.h"
#include "common/util.h"
#include "tor_queue.h"
diff --git a/src/common/storagedir.c b/src/common/storagedir.c
index 82a5e1b21..10b230127 100644
--- a/src/common/storagedir.c
+++ b/src/common/storagedir.c
@@ -7,7 +7,7 @@
#include "common/memarea.h"
#include "common/sandbox.h"
#include "common/storagedir.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#ifdef HAVE_SYS_TYPES_H
diff --git a/src/common/timers.c b/src/common/timers.c
index 2c39cf74b..72562f4cf 100644
--- a/src/common/timers.c
+++ b/src/common/timers.c
@@ -34,7 +34,7 @@
#include "common/compat.h"
#include "common/compat_libevent.h"
#include "common/timers.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
struct timeout_cb {
diff --git a/src/common/util.c b/src/common/util.c
index 2948e264d..986792ff2 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -15,7 +15,7 @@
#endif
#define UTIL_PRIVATE
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/cc/torint.h"
#include "lib/container/smartlist.h"
diff --git a/src/common/util_bug.c b/src/common/util_bug.c
index 7d6dc0750..0e6190caf 100644
--- a/src/common/util_bug.c
+++ b/src/common/util_bug.c
@@ -9,7 +9,7 @@
#include "orconfig.h"
#include "common/util_bug.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/err/backtrace.h"
#ifdef TOR_UNIT_TESTS
#include "lib/container/smartlist.h"
diff --git a/src/common/util_format.c b/src/common/util_format.c
index 8b299725a..04fd59d66 100644
--- a/src/common/util_format.c
+++ b/src/common/util_format.c
@@ -13,7 +13,7 @@
#include "orconfig.h"
#include <stddef.h>
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "common/util_format.h"
#include "lib/cc/torint.h"
diff --git a/src/common/util_process.c b/src/common/util_process.c
index 6eee659b2..321258b69 100644
--- a/src/common/util_process.c
+++ b/src/common/util_process.c
@@ -21,7 +21,7 @@
#include "common/compat.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util_process.h"
#include "ht.h"
diff --git a/src/common/workqueue.c b/src/common/workqueue.c
index be51e4f10..84945882d 100644
--- a/src/common/workqueue.c
+++ b/src/common/workqueue.c
@@ -31,7 +31,7 @@
#include "common/util.h"
#include "common/workqueue.h"
#include "tor_queue.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include <event2/event.h>
diff --git a/src/lib/compress/compress.c b/src/lib/compress/compress.c
index cb130b693..64f10b45c 100644
--- a/src/lib/compress/compress.c
+++ b/src/lib/compress/compress.c
@@ -20,7 +20,7 @@
#endif
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/compress/compress.h"
#include "lib/compress/compress_lzma.h"
#include "lib/compress/compress_none.h"
diff --git a/src/lib/compress/compress_lzma.c b/src/lib/compress/compress_lzma.c
index 921aaa1d7..e7f3680b2 100644
--- a/src/lib/compress/compress_lzma.c
+++ b/src/lib/compress/compress_lzma.c
@@ -14,7 +14,7 @@
#include "orconfig.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/compress/compress.h"
#include "lib/compress/compress_lzma.h"
diff --git a/src/lib/compress/compress_none.c b/src/lib/compress/compress_none.c
index 05a27e5cc..11f99d82e 100644
--- a/src/lib/compress/compress_none.c
+++ b/src/lib/compress/compress_none.c
@@ -17,7 +17,7 @@
#include "orconfig.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/compress/compress.h"
#include "lib/compress/compress_none.h"
diff --git a/src/lib/compress/compress_zlib.c b/src/lib/compress/compress_zlib.c
index 56dda8a2d..7cba1150e 100644
--- a/src/lib/compress/compress_zlib.c
+++ b/src/lib/compress/compress_zlib.c
@@ -14,7 +14,7 @@
#include "orconfig.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/compress/compress.h"
#include "lib/compress/compress_zlib.h"
diff --git a/src/lib/compress/compress_zstd.c b/src/lib/compress/compress_zstd.c
index 37204ab5e..f24c7a5ab 100644
--- a/src/lib/compress/compress_zstd.c
+++ b/src/lib/compress/compress_zstd.c
@@ -14,7 +14,7 @@
#include "orconfig.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/compress/compress.h"
#include "lib/compress/compress_zstd.h"
diff --git a/src/lib/crypt_ops/aes.c b/src/lib/crypt_ops/aes.c
index c421453fd..3a66e369c 100644
--- a/src/lib/crypt_ops/aes.c
+++ b/src/lib/crypt_ops/aes.c
@@ -38,7 +38,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#include "common/compat.h"
#include "lib/crypt_ops/aes.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/ctime/di_ops.h"
#ifdef ANDROID
diff --git a/src/lib/crypt_ops/crypto.c b/src/lib/crypt_ops/crypto.c
index 46026b6ac..fcd6945c8 100644
--- a/src/lib/crypt_ops/crypto.c
+++ b/src/lib/crypt_ops/crypto.c
@@ -62,7 +62,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#include <unistd.h>
#endif
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/cc/torint.h"
#include "lib/crypt_ops/aes.h"
#include "common/util.h"
diff --git a/src/lib/crypt_ops/crypto_curve25519.c b/src/lib/crypt_ops/crypto_curve25519.c
index 03225f1c1..276ff208a 100644
--- a/src/lib/crypt_ops/crypto_curve25519.c
+++ b/src/lib/crypt_ops/crypto_curve25519.c
@@ -26,7 +26,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "ed25519/donna/ed25519_donna_tor.h"
diff --git a/src/lib/crypt_ops/crypto_dh.c b/src/lib/crypt_ops/crypto_dh.c
index 2442dae55..daa984293 100644
--- a/src/lib/crypt_ops/crypto_dh.c
+++ b/src/lib/crypt_ops/crypto_dh.c
@@ -23,7 +23,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#include <openssl/bn.h>
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
/** A structure to hold the first half (x, g^x) of a Diffie-Hellman handshake
* while we're waiting for the second.*/
diff --git a/src/lib/crypt_ops/crypto_digest.c b/src/lib/crypt_ops/crypto_digest.c
index b1aede3a8..a50543593 100644
--- a/src/lib/crypt_ops/crypto_digest.c
+++ b/src/lib/crypt_ops/crypto_digest.c
@@ -14,7 +14,7 @@
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/crypt_ops/crypto_openssl_mgt.h"
#include "lib/crypt_ops/crypto_util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "keccak-tiny/keccak-tiny.h"
diff --git a/src/lib/crypt_ops/crypto_ed25519.c b/src/lib/crypt_ops/crypto_ed25519.c
index ca1030b0a..5655fbf50 100644
--- a/src/lib/crypt_ops/crypto_ed25519.c
+++ b/src/lib/crypt_ops/crypto_ed25519.c
@@ -27,7 +27,7 @@
#include "lib/crypt_ops/crypto_format.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "common/util_format.h"
diff --git a/src/lib/crypt_ops/crypto_format.c b/src/lib/crypt_ops/crypto_format.c
index e4237653f..888c0794e 100644
--- a/src/lib/crypt_ops/crypto_format.c
+++ b/src/lib/crypt_ops/crypto_format.c
@@ -23,7 +23,7 @@
#include "lib/string/util_string.h"
#include "common/util.h"
#include "common/util_format.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
/** Write the <b>datalen</b> bytes from <b>data</b> to the file named
* <b>fname</b> in the tagged-data format. This format contains a
diff --git a/src/lib/crypt_ops/crypto_rand.c b/src/lib/crypt_ops/crypto_rand.c
index 0d41a207e..bff32c7ec 100644
--- a/src/lib/crypt_ops/crypto_rand.c
+++ b/src/lib/crypt_ops/crypto_rand.c
@@ -27,7 +27,7 @@
#include "lib/crypt_ops/crypto_util.h"
#include "common/sandbox.h"
#include "lib/testsupport/testsupport.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "common/util_format.h"
diff --git a/src/lib/crypt_ops/crypto_rsa.c b/src/lib/crypt_ops/crypto_rsa.c
index a20d47132..3f2f8544f 100644
--- a/src/lib/crypt_ops/crypto_rsa.c
+++ b/src/lib/crypt_ops/crypto_rsa.c
@@ -33,7 +33,7 @@ DISABLE_GCC_WARNING(redundant-decls)
ENABLE_GCC_WARNING(redundant-decls)
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "common/util_format.h"
diff --git a/src/lib/crypt_ops/crypto_rsa.h b/src/lib/crypt_ops/crypto_rsa.h
index 3faec1237..75255c9cc 100644
--- a/src/lib/crypt_ops/crypto_rsa.h
+++ b/src/lib/crypt_ops/crypto_rsa.h
@@ -21,7 +21,7 @@
#include "lib/testsupport/testsupport.h"
#include "common/compat.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
/** Length of our public keys. */
#define PK_BYTES (1024/8)
diff --git a/src/lib/crypt_ops/crypto_util.c b/src/lib/crypt_ops/crypto_util.c
index 8ef0690c1..db88805a7 100644
--- a/src/lib/crypt_ops/crypto_util.c
+++ b/src/lib/crypt_ops/crypto_util.c
@@ -32,7 +32,7 @@ DISABLE_GCC_WARNING(redundant-decls)
ENABLE_GCC_WARNING(redundant-decls)
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
/**
* Destroy the <b>sz</b> bytes of data stored at <b>mem</b>, setting them to
diff --git a/src/lib/log/torlog.c b/src/lib/log/torlog.c
index e67442e68..e77b775c2 100644
--- a/src/lib/log/torlog.c
+++ b/src/lib/log/torlog.c
@@ -31,7 +31,7 @@
#endif
#define LOG_PRIVATE
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/container/smartlist.h"
#include "lib/err/torerr.h"
#include "lib/intmath/bits.h"
diff --git a/src/lib/tls/buffers_tls.c b/src/lib/tls/buffers_tls.c
index 55c3ac334..ac78b6501 100644
--- a/src/lib/tls/buffers_tls.c
+++ b/src/lib/tls/buffers_tls.c
@@ -12,7 +12,7 @@
#include "common/compat.h"
#include "common/util.h"
#include "lib/cc/torint.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/tls/tortls.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
diff --git a/src/lib/tls/tortls.c b/src/lib/tls/tortls.c
index eb8a91b42..6fa0611f1 100644
--- a/src/lib/tls/tortls.c
+++ b/src/lib/tls/tortls.c
@@ -54,7 +54,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#define TORTLS_PRIVATE
#include "lib/tls/tortls.h"
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/container/smartlist.h"
#include <string.h>
diff --git a/src/lib/trace/debug.h b/src/lib/trace/debug.h
index 0241f2ccf..9b5d9d05c 100644
--- a/src/lib/trace/debug.h
+++ b/src/lib/trace/debug.h
@@ -4,7 +4,7 @@
#ifndef TOR_TRACE_LOG_DEBUG_H
#define TOR_TRACE_LOG_DEBUG_H
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
/* Stringify pre-processor trick. */
#define XSTR(d) STR(d)
diff --git a/src/or/keypin.c b/src/or/keypin.c
index 1bdb471b3..312530fe4 100644
--- a/src/or/keypin.c
+++ b/src/or/keypin.c
@@ -19,7 +19,7 @@
#include "or/keypin.h"
#include "siphash.h"
#include "lib/cc/torint.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "common/util_format.h"
diff --git a/src/or/onion_ntor.c b/src/or/onion_ntor.c
index a6685eb99..3a60d1b7e 100644
--- a/src/or/onion_ntor.c
+++ b/src/or/onion_ntor.c
@@ -26,7 +26,7 @@
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/crypt_ops/crypto_util.h"
#include "or/onion_ntor.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
/** Free storage held in an ntor handshake state. */
diff --git a/src/or/or.h b/src/or/or.h
index 5c2a6d300..528159b4c 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -68,7 +68,7 @@
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_hkdf.h"
#include "lib/tls/tortls.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/container/smartlist.h"
#include "lib/container/map.h"
#include "lib/compress/compress.h"
diff --git a/src/or/parsecommon.c b/src/or/parsecommon.c
index 298d3658b..17a7c6a89 100644
--- a/src/or/parsecommon.c
+++ b/src/or/parsecommon.c
@@ -7,7 +7,7 @@
**/
#include "or/parsecommon.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util_format.h"
#include "lib/container/smartlist.h"
diff --git a/src/or/torcert.c b/src/or/torcert.c
index 23dfd3d43..e307dd1b5 100644
--- a/src/or/torcert.c
+++ b/src/or/torcert.c
@@ -30,7 +30,7 @@
#include "lib/crypt_ops/crypto_util.h"
#include "or/torcert.h"
#include "trunnel/ed25519_cert.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/util.h"
#include "common/compat.h"
#include "trunnel/link_handshake.h"
diff --git a/src/test/fuzz/fuzz_http.c b/src/test/fuzz/fuzz_http.c
index 564edbb55..c82c658d9 100644
--- a/src/test/fuzz/fuzz_http.c
+++ b/src/test/fuzz/fuzz_http.c
@@ -12,7 +12,7 @@
#include "or/config.h"
#include "or/connection.h"
#include "or/directory.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "or/dir_connection_st.h"
diff --git a/src/test/fuzz/fuzz_http_connect.c b/src/test/fuzz/fuzz_http_connect.c
index 1cde742f2..32bd26135 100644
--- a/src/test/fuzz/fuzz_http_connect.c
+++ b/src/test/fuzz/fuzz_http_connect.c
@@ -13,7 +13,7 @@
#include "or/connection.h"
#include "or/connection_edge.h"
#include "or/proto_socks.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "or/entry_connection_st.h"
#include "or/socks_request_st.h"
diff --git a/src/test/log_test_helpers.c b/src/test/log_test_helpers.c
index 03429b72c..e814555ba 100644
--- a/src/test/log_test_helpers.c
+++ b/src/test/log_test_helpers.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define LOG_PRIVATE
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "test/log_test_helpers.h"
/**
diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c
index 66dd931e5..c64ca8e2b 100644
--- a/src/test/test_bt_cl.c
+++ b/src/test/test_bt_cl.c
@@ -10,7 +10,7 @@
#include "or/or.h"
#include "common/util.h"
#include "lib/err/backtrace.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
/* -1: no crash.
* 0: crash with a segmentation fault.
diff --git a/src/test/test_logging.c b/src/test/test_logging.c
index d31c70437..c92dd620f 100644
--- a/src/test/test_logging.c
+++ b/src/test/test_logging.c
@@ -4,7 +4,7 @@
#include "orconfig.h"
#include "or/or.h"
#include "lib/err/torerr.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "test/test.h"
static void
diff --git a/src/test/test_status.c b/src/test/test_status.c
index 2f305224c..09b9662b4 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -12,7 +12,7 @@
#include <math.h>
#include "or/or.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "tor_queue.h"
#include "or/status.h"
#include "or/circuitlist.h"
diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c
index 80f95b6c0..f1b9b99f5 100644
--- a/src/test/test_tortls.c
+++ b/src/test/test_tortls.c
@@ -31,7 +31,7 @@ DISABLE_GCC_WARNING(redundant-decls)
ENABLE_GCC_WARNING(redundant-decls)
#include "or/or.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "or/config.h"
#include "lib/tls/tortls.h"
diff --git a/src/test/test_util_slow.c b/src/test/test_util_slow.c
index 9e4d7b0a1..9fbcd9d2b 100644
--- a/src/test/test_util_slow.c
+++ b/src/test/test_util_slow.c
@@ -8,7 +8,7 @@
#include "common/util.h"
#include "common/util_process.h"
#include "lib/crypt_ops/crypto.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "test/test.h"
#ifndef BUILDDIR
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index c2a2e0151..fc490ffeb 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -36,7 +36,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#endif
#include "common/util.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "lib/crypt_ops/crypto.h"
#include "lib/crypt_ops/crypto_digest.h"
#include "lib/crypt_ops/crypto_rand.h"
diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c
index 85ff14167..d80a7400f 100644
--- a/src/tools/tor-resolve.c
+++ b/src/tools/tor-resolve.c
@@ -7,7 +7,7 @@
#include "common/compat.h"
#include "common/util.h"
#include "common/address.h"
-#include "common/torlog.h"
+#include "lib/log/torlog.h"
#include "common/sandbox.h"
#include <stdio.h>
1
0

[tor/master] Extract core part of gmtime_r, localtime_r (without logging)
by nickm@torproject.org 26 Jun '18
by nickm@torproject.org 26 Jun '18
26 Jun '18
commit bfb39164ce49450fad11611a129dd875acebde54
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jun 22 11:07:10 2018 -0400
Extract core part of gmtime_r, localtime_r (without logging)
---
src/common/compat.c | 172 ++++----------------------------------
src/lib/log/torlog.c | 4 +-
src/lib/wallclock/include.am | 2 +
src/lib/wallclock/tm_cvt.c | 193 +++++++++++++++++++++++++++++++++++++++++++
src/lib/wallclock/tm_cvt.h | 17 ++++
5 files changed, 230 insertions(+), 158 deletions(-)
diff --git a/src/common/compat.c b/src/common/compat.c
index b4175c15a..351fa0563 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -127,6 +127,7 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
#include "lib/log/torlog.h"
#include "common/util.h"
#include "lib/container/smartlist.h"
+#include "lib/wallclock/tm_cvt.h"
#include "common/address.h"
#include "common/sandbox.h"
@@ -2648,183 +2649,40 @@ compute_num_cpus(void)
return num_cpus;
}
-#if !defined(_WIN32)
-/** Defined iff we need to add locks when defining fake versions of reentrant
- * versions of time-related functions. */
-#define TIME_FNS_NEED_LOCKS
-#endif
-
-/** Helper: Deal with confused or out-of-bounds values from localtime_r and
- * friends. (On some platforms, they can give out-of-bounds values or can
- * return NULL.) If <b>islocal</b>, this is a localtime result; otherwise
- * it's from gmtime. The function returns <b>r</b>, when given <b>timep</b>
- * as its input. If we need to store new results, store them in
- * <b>resultbuf</b>. */
-static struct tm *
-correct_tm(int islocal, const time_t *timep, struct tm *resultbuf,
- struct tm *r)
-{
- const char *outcome;
-
- if (PREDICT_LIKELY(r)) {
- /* We can't strftime dates after 9999 CE, and we want to avoid dates
- * before 1 CE (avoiding the year 0 issue and negative years). */
- if (r->tm_year > 8099) {
- r->tm_year = 8099;
- r->tm_mon = 11;
- r->tm_mday = 31;
- r->tm_yday = 364;
- r->tm_wday = 6;
- r->tm_hour = 23;
- r->tm_min = 59;
- r->tm_sec = 59;
- } else if (r->tm_year < (1-1900)) {
- r->tm_year = (1-1900);
- r->tm_mon = 0;
- r->tm_mday = 1;
- r->tm_yday = 0;
- r->tm_wday = 0;
- r->tm_hour = 0;
- r->tm_min = 0;
- r->tm_sec = 0;
- }
- return r;
- }
-
- /* If we get here, gmtime or localtime returned NULL. It might have done
- * this because of overrun or underrun, or it might have done it because of
- * some other weird issue. */
- if (timep) {
- if (*timep < 0) {
- r = resultbuf;
- r->tm_year = 70; /* 1970 CE */
- r->tm_mon = 0;
- r->tm_mday = 1;
- r->tm_yday = 0;
- r->tm_wday = 0;
- r->tm_hour = 0;
- r->tm_min = 0 ;
- r->tm_sec = 0;
- outcome = "Rounding up to 1970";
- goto done;
- } else if (*timep >= INT32_MAX) {
- /* Rounding down to INT32_MAX isn't so great, but keep in mind that we
- * only do it if gmtime/localtime tells us NULL. */
- r = resultbuf;
- r->tm_year = 137; /* 2037 CE */
- r->tm_mon = 11;
- r->tm_mday = 31;
- r->tm_yday = 364;
- r->tm_wday = 6;
- r->tm_hour = 23;
- r->tm_min = 59;
- r->tm_sec = 59;
- outcome = "Rounding down to 2037";
- goto done;
- }
- }
-
- /* If we get here, then gmtime/localtime failed without getting an extreme
- * value for *timep */
- /* LCOV_EXCL_START */
- tor_fragile_assert();
- r = resultbuf;
- memset(resultbuf, 0, sizeof(struct tm));
- outcome="can't recover";
- /* LCOV_EXCL_STOP */
- done:
- log_warn(LD_BUG, "%s("I64_FORMAT") failed with error %s: %s",
- islocal?"localtime":"gmtime",
- timep?I64_PRINTF_ARG(*timep):0,
- strerror(errno),
- outcome);
- return r;
-}
-/** @{ */
/** As localtime_r, but defined for platforms that don't have it:
*
* Convert *<b>timep</b> to a struct tm in local time, and store the value in
* *<b>result</b>. Return the result on success, or NULL on failure.
*/
-#ifdef HAVE_LOCALTIME_R
struct tm *
tor_localtime_r(const time_t *timep, struct tm *result)
{
- struct tm *r;
- r = localtime_r(timep, result);
- return correct_tm(1, timep, result, r);
-}
-#elif defined(TIME_FNS_NEED_LOCKS)
-struct tm *
-tor_localtime_r(const time_t *timep, struct tm *result)
-{
- struct tm *r;
- static tor_mutex_t *m=NULL;
- if (!m) { m=tor_mutex_new(); }
- tor_assert(result);
- tor_mutex_acquire(m);
- r = localtime(timep);
- if (r)
- memcpy(result, r, sizeof(struct tm));
- tor_mutex_release(m);
- return correct_tm(1, timep, result, r);
-}
-#else
-struct tm *
-tor_localtime_r(const time_t *timep, struct tm *result)
-{
- struct tm *r;
- tor_assert(result);
- r = localtime(timep);
- if (r)
- memcpy(result, r, sizeof(struct tm));
- return correct_tm(1, timep, result, r);
+ char *err = NULL;
+ struct tm *r = tor_localtime_r_msg(timep, result, &err);
+ if (err) {
+ log_warn(LD_BUG, "%s", err);
+ tor_free(err);
+ }
+ return r;
}
-#endif /* defined(HAVE_LOCALTIME_R) || ... */
-/** @} */
-/** @{ */
/** As gmtime_r, but defined for platforms that don't have it:
*
* Convert *<b>timep</b> to a struct tm in UTC, and store the value in
* *<b>result</b>. Return the result on success, or NULL on failure.
*/
-#ifdef HAVE_GMTIME_R
struct tm *
tor_gmtime_r(const time_t *timep, struct tm *result)
{
- struct tm *r;
- r = gmtime_r(timep, result);
- return correct_tm(0, timep, result, r);
-}
-#elif defined(TIME_FNS_NEED_LOCKS)
-struct tm *
-tor_gmtime_r(const time_t *timep, struct tm *result)
-{
- struct tm *r;
- static tor_mutex_t *m=NULL;
- if (!m) { m=tor_mutex_new(); }
- tor_assert(result);
- tor_mutex_acquire(m);
- r = gmtime(timep);
- if (r)
- memcpy(result, r, sizeof(struct tm));
- tor_mutex_release(m);
- return correct_tm(0, timep, result, r);
-}
-#else
-struct tm *
-tor_gmtime_r(const time_t *timep, struct tm *result)
-{
- struct tm *r;
- tor_assert(result);
- r = gmtime(timep);
- if (r)
- memcpy(result, r, sizeof(struct tm));
- return correct_tm(0, timep, result, r);
+ char *err = NULL;
+ struct tm *r = tor_gmtime_r_msg(timep, result, &err);
+ if (err) {
+ log_warn(LD_BUG, "%s", err);
+ tor_free(err);
+ }
+ return r;
}
-#endif /* defined(HAVE_GMTIME_R) || ... */
#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
#define HAVE_UNIX_MLOCKALL
diff --git a/src/lib/log/torlog.c b/src/lib/log/torlog.c
index aec469c53..fc2f898d8 100644
--- a/src/lib/log/torlog.c
+++ b/src/lib/log/torlog.c
@@ -41,6 +41,7 @@
#include "lib/string/util_string.h"
#include "lib/wallclock/tor_gettimeofday.h"
#include "lib/wallclock/approx_time.h"
+#include "lib/wallclock/tm_cvt.h"
#ifdef HAVE_ANDROID_LOG_H
#include <android/log.h>
@@ -298,7 +299,8 @@ log_prefix_(char *buf, size_t buf_len, int severity)
ms -= ((int)now.tv_usec / 1000) % log_time_granularity;
}
- n = strftime(buf, buf_len, "%b %d %H:%M:%S", tor_localtime_r(&t, &tm));
+ n = strftime(buf, buf_len, "%b %d %H:%M:%S",
+ tor_localtime_r_msg(&t, &tm, NULL));
r = tor_snprintf(buf+n, buf_len-n, ".%.3i [%s] ", ms,
sev_to_string(severity));
diff --git a/src/lib/wallclock/include.am b/src/lib/wallclock/include.am
index d414eb468..7b735e97e 100644
--- a/src/lib/wallclock/include.am
+++ b/src/lib/wallclock/include.am
@@ -7,6 +7,7 @@ endif
src_lib_libtor_wallclock_a_SOURCES = \
src/lib/wallclock/approx_time.c \
+ src/lib/wallclock/tm_cvt.c \
src/lib/wallclock/tor_gettimeofday.c
src_lib_libtor_wallclock_testing_a_SOURCES = \
@@ -16,4 +17,5 @@ src_lib_libtor_wallclock_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
noinst_HEADERS += \
src/lib/wallclock/approx_time.h \
+ src/lib/wallclock/tm_cvt.h \
src/lib/wallclock/tor_gettimeofday.h
diff --git a/src/lib/wallclock/tm_cvt.c b/src/lib/wallclock/tm_cvt.c
new file mode 100644
index 000000000..bb23d1bef
--- /dev/null
+++ b/src/lib/wallclock/tm_cvt.c
@@ -0,0 +1,193 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "lib/cc/torint.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/wallclock/tm_cvt.h"
+#include "lib/string/printf.h"
+
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+
+#if !defined(_WIN32)
+/** Defined iff we need to add locks when defining fake versions of reentrant
+ * versions of time-related functions. */
+#define TIME_FNS_NEED_LOCKS
+#endif
+
+/** Helper: Deal with confused or out-of-bounds values from localtime_r and
+ * friends. (On some platforms, they can give out-of-bounds values or can
+ * return NULL.) If <b>islocal</b>, this is a localtime result; otherwise
+ * it's from gmtime. The function returns <b>r</b>, when given <b>timep</b>
+ * as its input. If we need to store new results, store them in
+ * <b>resultbuf</b>. */
+static struct tm *
+correct_tm(int islocal, const time_t *timep, struct tm *resultbuf,
+ struct tm *r, char **err_out)
+{
+ const char *outcome;
+
+ if (PREDICT_LIKELY(r)) {
+ /* We can't strftime dates after 9999 CE, and we want to avoid dates
+ * before 1 CE (avoiding the year 0 issue and negative years). */
+ if (r->tm_year > 8099) {
+ r->tm_year = 8099;
+ r->tm_mon = 11;
+ r->tm_mday = 31;
+ r->tm_yday = 364;
+ r->tm_wday = 6;
+ r->tm_hour = 23;
+ r->tm_min = 59;
+ r->tm_sec = 59;
+ } else if (r->tm_year < (1-1900)) {
+ r->tm_year = (1-1900);
+ r->tm_mon = 0;
+ r->tm_mday = 1;
+ r->tm_yday = 0;
+ r->tm_wday = 0;
+ r->tm_hour = 0;
+ r->tm_min = 0;
+ r->tm_sec = 0;
+ }
+ return r;
+ }
+
+ /* If we get here, gmtime or localtime returned NULL. It might have done
+ * this because of overrun or underrun, or it might have done it because of
+ * some other weird issue. */
+ if (timep) {
+ if (*timep < 0) {
+ r = resultbuf;
+ r->tm_year = 70; /* 1970 CE */
+ r->tm_mon = 0;
+ r->tm_mday = 1;
+ r->tm_yday = 0;
+ r->tm_wday = 0;
+ r->tm_hour = 0;
+ r->tm_min = 0 ;
+ r->tm_sec = 0;
+ outcome = "Rounding up to 1970";
+ goto done;
+ } else if (*timep >= INT32_MAX) {
+ /* Rounding down to INT32_MAX isn't so great, but keep in mind that we
+ * only do it if gmtime/localtime tells us NULL. */
+ r = resultbuf;
+ r->tm_year = 137; /* 2037 CE */
+ r->tm_mon = 11;
+ r->tm_mday = 31;
+ r->tm_yday = 364;
+ r->tm_wday = 6;
+ r->tm_hour = 23;
+ r->tm_min = 59;
+ r->tm_sec = 59;
+ outcome = "Rounding down to 2037";
+ goto done;
+ }
+ }
+
+ /* If we get here, then gmtime/localtime failed without getting an extreme
+ * value for *timep */
+ /* LCOV_EXCL_START */
+ r = resultbuf;
+ memset(resultbuf, 0, sizeof(struct tm));
+ outcome="can't recover";
+ /* LCOV_EXCL_STOP */
+ done:
+ if (err_out) {
+ tor_asprintf(err_out, "%s("I64_FORMAT") failed with error %s: %s",
+ islocal?"localtime":"gmtime",
+ timep?I64_PRINTF_ARG(*timep):0,
+ strerror(errno),
+ outcome);
+ }
+ return r;
+}
+
+/** @{ */
+/** As localtime_r, but defined for platforms that don't have it:
+ *
+ * Convert *<b>timep</b> to a struct tm in local time, and store the value in
+ * *<b>result</b>. Return the result on success, or NULL on failure.
+ */
+#ifdef HAVE_LOCALTIME_R
+struct tm *
+tor_localtime_r_msg(const time_t *timep, struct tm *result, char **err_out)
+{
+ struct tm *r;
+ r = localtime_r(timep, result);
+ return correct_tm(1, timep, result, r, err_out);
+}
+#elif defined(TIME_FNS_NEED_LOCKS)
+struct tm *
+tor_localtime_r_msg(const time_t *timep, struct tm *result, char **err_out)
+{
+ struct tm *r;
+ static tor_mutex_t *m=NULL;
+ if (!m) { m=tor_mutex_new(); }
+ raw_assert(result);
+ tor_mutex_acquire(m);
+ r = localtime(timep);
+ if (r)
+ memcpy(result, r, sizeof(struct tm));
+ tor_mutex_release(m);
+ return correct_tm(1, timep, result, r, err_out);
+}
+#else
+struct tm *
+tor_localtime_r_msg(const time_t *timep, struct tm *result, char **err_out)
+{
+ struct tm *r;
+ raw_assert(result);
+ r = localtime(timep);
+ if (r)
+ memcpy(result, r, sizeof(struct tm));
+ return correct_tm(1, timep, result, rm, err_out);
+}
+#endif /* defined(HAVE_LOCALTIME_R) || ... */
+/** @} */
+
+/** @{ */
+/** As gmtime_r, but defined for platforms that don't have it:
+ *
+ * Convert *<b>timep</b> to a struct tm in UTC, and store the value in
+ * *<b>result</b>. Return the result on success, or NULL on failure.
+ */
+#ifdef HAVE_GMTIME_R
+struct tm *
+tor_gmtime_r_msg(const time_t *timep, struct tm *result, char **err_out)
+{
+ struct tm *r;
+ r = gmtime_r(timep, result);
+ return correct_tm(0, timep, result, r, err_out);
+}
+#elif defined(TIME_FNS_NEED_LOCKS)
+struct tm *
+tor_gmtime_r_msg(const time_t *timep, struct tm *result, char **err_out)
+{
+ struct tm *r;
+ static tor_mutex_t *m=NULL;
+ if (!m) { m=tor_mutex_new(); }
+ raw_assert(result);
+ tor_mutex_acquire(m);
+ r = gmtime(timep);
+ if (r)
+ memcpy(result, r, sizeof(struct tm));
+ tor_mutex_release(m);
+ return correct_tm(0, timep, result, r, err_out);
+}
+#else
+struct tm *
+tor_gmtime_r_msg(const time_t *timep, struct tm *result, char **err_out)
+{
+ struct tm *r;
+ raw_assert(result);
+ r = gmtime(timep);
+ if (r)
+ memcpy(result, r, sizeof(struct tm));
+ return correct_tm(0, timep, result, r, err_out);
+}
+#endif /* defined(HAVE_GMTIME_R) || ... */
diff --git a/src/lib/wallclock/tm_cvt.h b/src/lib/wallclock/tm_cvt.h
new file mode 100644
index 000000000..4d87acd4f
--- /dev/null
+++ b/src/lib/wallclock/tm_cvt.h
@@ -0,0 +1,17 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_WALLCLOCK_TM_CVT_H
+#define TOR_WALLCLOCK_TM_CVT_H
+
+#include <sys/types.h>
+
+struct tm;
+struct tm *tor_localtime_r_msg(const time_t *timep, struct tm *result,
+ char **err_out);
+struct tm *tor_gmtime_r_msg(const time_t *timep, struct tm *result,
+ char **err_out);
+
+#endif
1
0