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

27 Jun '18
commit 235ddb15a0f9fc322002ba39e8900634316dc333
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 15:59:07 2018 -0400
Move util_format into a new libtor-encoding library
libtor-encoding is about various ways to transform data to and from
character sequences.
---
.gitignore | 2 ++
Makefile.am | 2 ++
src/common/include.am | 2 --
src/common/util.c | 2 +-
src/include.am | 1 +
src/lib/crypt_ops/.may_include | 1 +
src/lib/crypt_ops/crypto.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/encoding/.may_include | 8 ++++++++
src/{common/util_format.c => lib/encoding/binascii.c} | 11 +++++++----
src/{common/util_format.h => lib/encoding/binascii.h} | 6 ++++--
src/lib/encoding/include.am | 16 ++++++++++++++++
src/or/keypin.c | 2 +-
src/or/or.h | 2 +-
src/or/parsecommon.c | 2 +-
src/or/shared_random_client.c | 2 +-
src/rust/build.rs | 1 +
src/test/test_crypto_openssl.c | 2 +-
src/test/test_util_format.c | 2 +-
src/tools/tor-gencert.c | 2 +-
23 files changed, 55 insertions(+), 21 deletions(-)
diff --git a/.gitignore b/.gitignore
index 02e8bb77c..5198daf4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -171,6 +171,8 @@ uptime-*.json
/src/lib/libtor-crypt-ops-testing.a
/src/lib/libtor-ctime.a
/src/lib/libtor-ctime-testing.a
+/src/lib/libtor-encoding.a
+/src/lib/libtor-encoding-testing.a
/src/lib/libtor-err.a
/src/lib/libtor-err-testing.a
/src/lib/libtor-fdio.a
diff --git a/Makefile.am b/Makefile.am
index ef727e01f..c016310a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -41,6 +41,7 @@ endif
TOR_UTIL_LIBS = \
src/common/libor.a \
src/lib/libtor-fs.a \
+ src/lib/libtor-encoding.a \
src/lib/libtor-sandbox.a \
src/lib/libtor-container.a \
src/lib/libtor-net.a \
@@ -60,6 +61,7 @@ TOR_UTIL_LIBS = \
TOR_UTIL_TESTING_LIBS = \
src/common/libor-testing.a \
src/lib/libtor-fs-testing.a \
+ src/lib/libtor-encoding-testing.a \
src/lib/libtor-sandbox-testing.a \
src/lib/libtor-container-testing.a \
src/lib/libtor-net-testing.a \
diff --git a/src/common/include.am b/src/common/include.am
index c8be3658e..2360c7f77 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -39,7 +39,6 @@ LIBOR_A_SRC = \
src/common/confline.c \
src/common/memarea.c \
src/common/util.c \
- src/common/util_format.c \
src/common/util_process.c \
src/common/storagedir.c \
src/common/token_bucket.c \
@@ -88,7 +87,6 @@ COMMONHEADERS = \
src/common/timers.h \
src/common/token_bucket.h \
src/common/util.h \
- src/common/util_format.h \
src/common/util_process.h \
src/common/workqueue.h
diff --git a/src/common/util.c b/src/common/util.c
index 497f54972..92742a814 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -24,7 +24,7 @@
#include "lib/sandbox/sandbox.h"
#include "lib/err/backtrace.h"
#include "common/util_process.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#ifdef _WIN32
#include <io.h>
diff --git a/src/include.am b/src/include.am
index 62234d468..c83ec0d57 100644
--- a/src/include.am
+++ b/src/include.am
@@ -7,6 +7,7 @@ include src/lib/compress/include.am
include src/lib/container/include.am
include src/lib/crypt_ops/include.am
include src/lib/defs/include.am
+include src/lib/encoding/include.am
include src/lib/fdio/include.am
include src/lib/fs/include.am
include src/lib/include.libdonna.am
diff --git a/src/lib/crypt_ops/.may_include b/src/lib/crypt_ops/.may_include
index d05e86f72..dad6d5fc6 100644
--- a/src/lib/crypt_ops/.may_include
+++ b/src/lib/crypt_ops/.may_include
@@ -4,6 +4,7 @@ lib/container/*.h
lib/crypt_ops/*.h
lib/ctime/*.h
lib/defs/*.h
+lib/encoding/*.h
lib/malloc/*.h
lib/err/*.h
lib/intmath/*.h
diff --git a/src/lib/crypt_ops/crypto.c b/src/lib/crypt_ops/crypto.c
index 193580397..efd355928 100644
--- a/src/lib/crypt_ops/crypto.c
+++ b/src/lib/crypt_ops/crypto.c
@@ -67,7 +67,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#include "lib/crypt_ops/aes.h"
#include "common/util.h"
#include "common/compat.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.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 5655fbf50..b0e23e29c 100644
--- a/src/lib/crypt_ops/crypto_ed25519.c
+++ b/src/lib/crypt_ops/crypto_ed25519.c
@@ -29,7 +29,7 @@
#include "lib/crypt_ops/crypto_util.h"
#include "lib/log/torlog.h"
#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#include "ed25519/ref10/ed25519_ref10.h"
#include "ed25519/donna/ed25519_donna_tor.h"
diff --git a/src/lib/crypt_ops/crypto_format.c b/src/lib/crypt_ops/crypto_format.c
index 888c0794e..131aa449e 100644
--- a/src/lib/crypt_ops/crypto_format.c
+++ b/src/lib/crypt_ops/crypto_format.c
@@ -22,7 +22,7 @@
#include "lib/crypt_ops/crypto_util.h"
#include "lib/string/util_string.h"
#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#include "lib/log/torlog.h"
/** Write the <b>datalen</b> bytes from <b>data</b> to the file named
diff --git a/src/lib/crypt_ops/crypto_rand.c b/src/lib/crypt_ops/crypto_rand.c
index bf6a35ddb..247a50224 100644
--- a/src/lib/crypt_ops/crypto_rand.c
+++ b/src/lib/crypt_ops/crypto_rand.c
@@ -29,7 +29,7 @@
#include "lib/testsupport/testsupport.h"
#include "lib/log/torlog.h"
#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
DISABLE_GCC_WARNING(redundant-decls)
#include <openssl/rand.h>
diff --git a/src/lib/crypt_ops/crypto_rsa.c b/src/lib/crypt_ops/crypto_rsa.c
index 3f2f8544f..a62c0018f 100644
--- a/src/lib/crypt_ops/crypto_rsa.c
+++ b/src/lib/crypt_ops/crypto_rsa.c
@@ -35,7 +35,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#include "lib/log/torlog.h"
#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
/** Declaration for crypto_pk_t structure. */
struct crypto_pk_t
diff --git a/src/lib/encoding/.may_include b/src/lib/encoding/.may_include
new file mode 100644
index 000000000..299e0fc4f
--- /dev/null
+++ b/src/lib/encoding/.may_include
@@ -0,0 +1,8 @@
+orconfig.h
+lib/cc/*.h
+lib/encoding/*.h
+lib/intmath/*.h
+lib/log/*.h
+lib/malloc/*.h
+lib/string/*.h
+lib/testsupport/*.h
diff --git a/src/common/util_format.c b/src/lib/encoding/binascii.c
similarity index 98%
rename from src/common/util_format.c
rename to src/lib/encoding/binascii.c
index 04fd59d66..554b95016 100644
--- a/src/common/util_format.c
+++ b/src/lib/encoding/binascii.c
@@ -5,18 +5,21 @@
/* See LICENSE for licensing information */
/**
- * \file util_format.c
+ * \file binascii.c
*
* \brief Miscellaneous functions for encoding and decoding various things
* in base{16,32,64}.
*/
#include "orconfig.h"
-#include <stddef.h>
+
+#include "lib/encoding/binascii.h"
#include "lib/log/torlog.h"
-#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/log/util_bug.h"
#include "lib/cc/torint.h"
+#include "lib/string/compat_ctype.h"
+#include "lib/intmath/muldiv.h"
+#include "lib/malloc/util_malloc.h"
#include <stddef.h>
#include <string.h>
diff --git a/src/common/util_format.h b/src/lib/encoding/binascii.h
similarity index 95%
rename from src/common/util_format.h
rename to src/lib/encoding/binascii.h
index 713fd0d00..04310f4ed 100644
--- a/src/common/util_format.h
+++ b/src/lib/encoding/binascii.h
@@ -4,9 +4,11 @@
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#ifndef TOR_UTIL_FORMAT_H
-#define TOR_UTIL_FORMAT_H
+#ifndef TOR_BINASCII_H
+#define TOR_BINASCII_H
+#include "orconfig.h"
+#include <stddef.h>
#include "lib/testsupport/testsupport.h"
#include "lib/cc/torint.h"
diff --git a/src/lib/encoding/include.am b/src/lib/encoding/include.am
new file mode 100644
index 000000000..fcd9baf3d
--- /dev/null
+++ b/src/lib/encoding/include.am
@@ -0,0 +1,16 @@
+noinst_LIBRARIES += src/lib/libtor-encoding.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-encoding-testing.a
+endif
+
+src_lib_libtor_encoding_a_SOURCES = \
+ src/lib/encoding/binascii.c
+
+src_lib_libtor_encoding_testing_a_SOURCES = \
+ $(src_lib_libtor_encoding_a_SOURCES)
+src_lib_libtor_encoding_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_encoding_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS += \
+ src/lib/encoding/binascii.h
diff --git a/src/or/keypin.c b/src/or/keypin.c
index db267673f..8e1ef099a 100644
--- a/src/or/keypin.c
+++ b/src/or/keypin.c
@@ -22,7 +22,7 @@
#include "lib/log/torlog.h"
#include "lib/fdio/fdio.h"
#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
diff --git a/src/or/or.h b/src/or/or.h
index a71cb6b00..df0e60c26 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -81,7 +81,7 @@
#include "lib/crypt_ops/crypto_ed25519.h"
#include "tor_queue.h"
#include "common/token_bucket.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#include "or/hs_circuitmap.h"
// These, more than other includes, are for keeping the other struct
diff --git a/src/or/parsecommon.c b/src/or/parsecommon.c
index 17a7c6a89..3b6e15b0f 100644
--- a/src/or/parsecommon.c
+++ b/src/or/parsecommon.c
@@ -8,7 +8,7 @@
#include "or/parsecommon.h"
#include "lib/log/torlog.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#include "lib/container/smartlist.h"
#define MIN_ANNOTATION A_PURPOSE
diff --git a/src/or/shared_random_client.c b/src/or/shared_random_client.c
index f0b13a171..9a6c0f664 100644
--- a/src/or/shared_random_client.c
+++ b/src/or/shared_random_client.c
@@ -15,7 +15,7 @@
#include "or/voting_schedule.h"
#include "or/networkstatus.h"
#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#include "or/networkstatus_st.h"
diff --git a/src/rust/build.rs b/src/rust/build.rs
index 90f53bd23..36f847d2e 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-sandbox");
+ cfg.component("tor-encoding-testing");
cfg.component("tor-net");
cfg.component("tor-log");
cfg.component("tor-lock");
diff --git a/src/test/test_crypto_openssl.c b/src/test/test_crypto_openssl.c
index cc817ad70..a01de18a6 100644
--- a/src/test/test_crypto_openssl.c
+++ b/src/test/test_crypto_openssl.c
@@ -9,7 +9,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "common/util.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#include "common/compat.h"
#include "test/test.h"
diff --git a/src/test/test_util_format.c b/src/test/test_util_format.c
index 931a184e7..44a00b9b7 100644
--- a/src/test/test_util_format.c
+++ b/src/test/test_util_format.c
@@ -8,7 +8,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#define UTIL_FORMAT_PRIVATE
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#define NS_MODULE util_format
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index f65a0e250..2fda1cd8f 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -42,7 +42,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/net/address.h"
-#include "common/util_format.h"
+#include "lib/encoding/binascii.h"
#define IDENTITY_KEY_BITS 3072
#define SIGNING_KEY_BITS 2048
1
0

27 Jun '18
commit e165c9c304800718daa589469349282110e00909
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 15:36:42 2018 -0400
Move various mem* functions to lib/string
---
src/common/compat.c | 46 ------------------
src/common/compat.h | 10 ----
src/common/util.c | 55 ----------------------
src/common/util.h | 4 --
src/lib/string/.may_include | 1 +
src/lib/string/util_string.c | 108 +++++++++++++++++++++++++++++++++++++++++++
src/lib/string/util_string.h | 8 ++++
7 files changed, 117 insertions(+), 115 deletions(-)
diff --git a/src/common/compat.c b/src/common/compat.c
index 367ea26c2..cdc53175d 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -131,52 +131,6 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
#include "lib/net/address.h"
#include "lib/sandbox/sandbox.h"
-/** 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.
- *
- * This function is <em>not</em> timing-safe.
- *
- * Requires that <b>nlen</b> be greater than zero.
- */
-const void *
-tor_memmem(const void *_haystack, size_t hlen,
- const void *_needle, size_t nlen)
-{
-#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
- tor_assert(nlen);
- return memmem(_haystack, hlen, _needle, nlen);
-#else
- /* This isn't as fast as the GLIBC implementation, but it doesn't need to
- * be. */
- const char *p, *last_possible_start;
- const char *haystack = (const char*)_haystack;
- const char *needle = (const char*)_needle;
- char first;
- tor_assert(nlen);
-
- if (nlen > hlen)
- return NULL;
-
- p = haystack;
- /* Last position at which the needle could start. */
- last_possible_start = haystack + hlen - nlen;
- first = *(const char*)needle;
- while ((p = memchr(p, first, last_possible_start + 1 - p))) {
- if (fast_memeq(p, needle, nlen))
- return p;
- if (++p > last_possible_start) {
- /* This comparison shouldn't be necessary, since if p was previously
- * equal to last_possible_start, the next memchr call would be
- * "memchr(p, first, 0)", which will return NULL. But it clarifies the
- * logic. */
- return NULL;
- }
- }
- return NULL;
-#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
-}
-
/** Represents a lockfile on which we hold the lock. */
struct tor_lockfile_t {
/** Name of the file */
diff --git a/src/common/compat.h b/src/common/compat.h
index 766f62557..399badb6a 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -63,16 +63,6 @@
#include <stdio.h>
#include <errno.h>
-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,
- const char *needle) ATTR_NONNULL((1,3));
-static inline const void *
-tor_memstr(const void *haystack, size_t hlen, const char *needle)
-{
- return tor_memmem(haystack, hlen, needle, strlen(needle));
-}
-
/* ===== Time compatibility */
struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
diff --git a/src/common/util.c b/src/common/util.c
index 09d3b2679..64efbc81e 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -240,54 +240,6 @@ hex_str(const char *from, size_t fromlen)
return buf;
}
-/** 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.
- *
- * [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
- * less than strlen(prefix).]
- */
-int
-fast_memcmpstart(const void *mem, size_t memlen,
- const char *prefix)
-{
- size_t plen = strlen(prefix);
- if (memlen < plen)
- return -1;
- return fast_memcmp(mem, prefix, plen);
-}
-
-/** Return true iff the 'len' bytes at 'mem' are all zero. */
-int
-tor_mem_is_zero(const char *mem, size_t len)
-{
- static const char ZERO[] = {
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- };
- while (len >= sizeof(ZERO)) {
- /* It's safe to use fast_memcmp here, since the very worst thing an
- * attacker could learn is how many initial bytes of a secret were zero */
- if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
- return 0;
- len -= sizeof(ZERO);
- mem += sizeof(ZERO);
- }
- /* Deal with leftover bytes. */
- if (len)
- return fast_memeq(mem, ZERO, len);
-
- return 1;
-}
-
-/** Return true iff the DIGEST_LEN bytes in digest are all zero. */
-int
-tor_digest_is_zero(const char *digest)
-{
- static const uint8_t ZERO_DIGEST[] = {
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
- };
- return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
-}
-
/** Return true if <b>string</b> is a valid 'key=[value]' string.
* "value" is optional, to indicate the empty string. Log at logging
* <b>severity</b> if something ugly happens. */
@@ -436,13 +388,6 @@ string_is_valid_nonrfc_hostname(const char *string)
return result;
}
-/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
-int
-tor_digest256_is_zero(const char *digest)
-{
- return tor_mem_is_zero(digest, DIGEST256_LEN);
-}
-
/** Return a newly allocated string equal to <b>string</b>, except that every
* character in <b>chars_to_escape</b> is preceded by a backslash. */
char *
diff --git a/src/common/util.h b/src/common/util.h
index 2b16fc457..f16a1fa98 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -78,10 +78,6 @@ int string_is_valid_nonrfc_hostname(const char *string);
int string_is_valid_ipv4_address(const char *string);
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 *tor_escape_str_for_pt_args(const char *string,
const char *chars_to_escape);
diff --git a/src/lib/string/.may_include b/src/lib/string/.may_include
index c5d771861..ec5c76983 100644
--- a/src/lib/string/.may_include
+++ b/src/lib/string/.may_include
@@ -1,5 +1,6 @@
orconfig.h
lib/cc/*.h
+lib/defs/*.h
lib/err/*.h
lib/malloc/*.h
lib/ctime/*.h
diff --git a/src/lib/string/util_string.c b/src/lib/string/util_string.c
index aba37fcc0..e8ed3d4f5 100644
--- a/src/lib/string/util_string.c
+++ b/src/lib/string/util_string.c
@@ -7,10 +7,102 @@
#include "lib/string/compat_ctype.h"
#include "lib/err/torerr.h"
#include "lib/ctime/di_ops.h"
+#include "lib/defs/digest_sizes.h"
#include <string.h>
#include <stdlib.h>
+/** 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.
+ *
+ * This function is <em>not</em> timing-safe.
+ *
+ * Requires that <b>nlen</b> be greater than zero.
+ */
+const void *
+tor_memmem(const void *_haystack, size_t hlen,
+ const void *_needle, size_t nlen)
+{
+#if defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2)
+ raw_assert(nlen);
+ return memmem(_haystack, hlen, _needle, nlen);
+#else
+ /* This isn't as fast as the GLIBC implementation, but it doesn't need to
+ * be. */
+ const char *p, *last_possible_start;
+ const char *haystack = (const char*)_haystack;
+ const char *needle = (const char*)_needle;
+ char first;
+ raw_assert(nlen);
+
+ if (nlen > hlen)
+ return NULL;
+
+ p = haystack;
+ /* Last position at which the needle could start. */
+ last_possible_start = haystack + hlen - nlen;
+ first = *(const char*)needle;
+ while ((p = memchr(p, first, last_possible_start + 1 - p))) {
+ if (fast_memeq(p, needle, nlen))
+ return p;
+ if (++p > last_possible_start) {
+ /* This comparison shouldn't be necessary, since if p was previously
+ * equal to last_possible_start, the next memchr call would be
+ * "memchr(p, first, 0)", which will return NULL. But it clarifies the
+ * logic. */
+ return NULL;
+ }
+ }
+ return NULL;
+#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
+}
+
+const void *
+tor_memstr(const void *haystack, size_t hlen, const char *needle)
+{
+ return tor_memmem(haystack, hlen, needle, strlen(needle));
+}
+
+/** Return true iff the 'len' bytes at 'mem' are all zero. */
+int
+tor_mem_is_zero(const char *mem, size_t len)
+{
+ static const char ZERO[] = {
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+ };
+ while (len >= sizeof(ZERO)) {
+ /* It's safe to use fast_memcmp here, since the very worst thing an
+ * attacker could learn is how many initial bytes of a secret were zero */
+ if (fast_memcmp(mem, ZERO, sizeof(ZERO)))
+ return 0;
+ len -= sizeof(ZERO);
+ mem += sizeof(ZERO);
+ }
+ /* Deal with leftover bytes. */
+ if (len)
+ return fast_memeq(mem, ZERO, len);
+
+ return 1;
+}
+
+/** Return true iff the DIGEST_LEN bytes in digest are all zero. */
+int
+tor_digest_is_zero(const char *digest)
+{
+ static const uint8_t ZERO_DIGEST[] = {
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
+ };
+ return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
+}
+
+/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
+int
+tor_digest256_is_zero(const char *digest)
+{
+ return tor_mem_is_zero(digest, DIGEST256_LEN);
+}
+
/** Remove from the string <b>s</b> every character which appears in
* <b>strip</b>. */
void
@@ -140,6 +232,22 @@ strcasecmpstart(const char *s1, const char *s2)
return strncasecmp(s1, s2, n);
}
+/** 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.
+ *
+ * [As fast_memcmp(mem, prefix, strlen(prefix)) but returns -1 if memlen is
+ * less than strlen(prefix).]
+ */
+int
+fast_memcmpstart(const void *mem, size_t memlen,
+ const char *prefix)
+{
+ size_t plen = strlen(prefix);
+ if (memlen < plen)
+ return -1;
+ return fast_memcmp(mem, prefix, plen);
+}
+
/** Compares the last strlen(s2) characters of s1 with s2. Returns as for
* strcmp.
*/
diff --git a/src/lib/string/util_string.h b/src/lib/string/util_string.h
index f194c3637..bdc2e77ce 100644
--- a/src/lib/string/util_string.h
+++ b/src/lib/string/util_string.h
@@ -11,6 +11,14 @@
#include <stddef.h>
+const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
+ size_t nlen) ATTR_NONNULL((1,3));
+const void *tor_memstr(const void *haystack, size_t hlen,
+ const char *needle) ATTR_NONNULL((1,3));
+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);
+
/** Allowable characters in a hexadecimal string. */
#define HEX_CHARACTERS "0123456789ABCDEFabcdef"
void tor_strlower(char *s) ATTR_NONNULL((1));
1
0

[tor/master] Move several address-string-testing functions to address.c
by nickm@torproject.org 27 Jun '18
by nickm@torproject.org 27 Jun '18
27 Jun '18
commit 3cff3e825a1478fc3350bbca16f091b8f635f921
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 15:45:53 2018 -0400
Move several address-string-testing functions to address.c
---
src/common/util.c | 115 --------------------------------------------------
src/common/util.h | 4 --
src/lib/net/address.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/lib/net/address.h | 5 +++
4 files changed, 120 insertions(+), 119 deletions(-)
diff --git a/src/common/util.c b/src/common/util.c
index 64efbc81e..497f54972 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -273,121 +273,6 @@ string_is_key_value(int severity, const char *string)
return 1;
}
-/** Return true if <b>string</b> represents a valid IPv4 adddress in
- * 'a.b.c.d' form.
- */
-int
-string_is_valid_ipv4_address(const char *string)
-{
- struct in_addr addr;
-
- return (tor_inet_pton(AF_INET,string,&addr) == 1);
-}
-
-/** Return true if <b>string</b> represents a valid IPv6 address in
- * a form that inet_pton() can parse.
- */
-int
-string_is_valid_ipv6_address(const char *string)
-{
- struct in6_addr addr;
-
- return (tor_inet_pton(AF_INET6,string,&addr) == 1);
-}
-
-/** Return true iff <b>string</b> is a valid destination address,
- * i.e. either a DNS hostname or IPv4/IPv6 address string.
- */
-int
-string_is_valid_dest(const char *string)
-{
- char *tmp = NULL;
- int retval;
- size_t len;
-
- if (string == NULL)
- return 0;
-
- len = strlen(string);
-
- if (len == 0)
- return 0;
-
- if (string[0] == '[' && string[len - 1] == ']')
- string = tmp = tor_strndup(string + 1, len - 2);
-
- retval = string_is_valid_ipv4_address(string) ||
- string_is_valid_ipv6_address(string) ||
- string_is_valid_nonrfc_hostname(string);
-
- tor_free(tmp);
-
- return retval;
-}
-
-/** Return true iff <b>string</b> matches a pattern of DNS names
- * that we allow Tor clients to connect to.
- *
- * Note: This allows certain technically invalid characters ('_') to cope
- * with misconfigured zones that have been encountered in the wild.
- */
-int
-string_is_valid_nonrfc_hostname(const char *string)
-{
- int result = 1;
- int has_trailing_dot;
- char *last_label;
- smartlist_t *components;
-
- if (!string || strlen(string) == 0)
- return 0;
-
- if (string_is_valid_ipv4_address(string))
- return 0;
-
- components = smartlist_new();
-
- smartlist_split_string(components,string,".",0,0);
-
- if (BUG(smartlist_len(components) == 0))
- return 0; // LCOV_EXCL_LINE should be impossible given the earlier checks.
-
- /* Allow a single terminating '.' used rarely to indicate domains
- * are FQDNs rather than relative. */
- last_label = (char *)smartlist_get(components,
- smartlist_len(components) - 1);
- has_trailing_dot = (last_label[0] == '\0');
- if (has_trailing_dot) {
- smartlist_pop_last(components);
- tor_free(last_label);
- last_label = NULL;
- }
-
- SMARTLIST_FOREACH_BEGIN(components, char *, c) {
- if ((c[0] == '-') || (*c == '_')) {
- result = 0;
- break;
- }
-
- do {
- result = (TOR_ISALNUM(*c) || (*c == '-') || (*c == '_'));
- c++;
- } while (result && *c);
-
- if (result == 0) {
- break;
- }
- } SMARTLIST_FOREACH_END(c);
-
- SMARTLIST_FOREACH_BEGIN(components, char *, c) {
- tor_free(c);
- } SMARTLIST_FOREACH_END(c);
-
- smartlist_free(components);
-
- return result;
-}
-
/** Return a newly allocated string equal to <b>string</b>, except that every
* character in <b>chars_to_escape</b> is preceded by a backslash. */
char *
diff --git a/src/common/util.h b/src/common/util.h
index f16a1fa98..fa7886d0f 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -73,10 +73,6 @@ int64_t clamp_double_to_int64(double number);
const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
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);
-int string_is_valid_ipv4_address(const char *string);
-int string_is_valid_ipv6_address(const char *string);
char *tor_escape_str_for_pt_args(const char *string,
const char *chars_to_escape);
diff --git a/src/lib/net/address.c b/src/lib/net/address.c
index 69abb98a1..10e38871e 100644
--- a/src/lib/net/address.c
+++ b/src/lib/net/address.c
@@ -2139,3 +2139,118 @@ tor_addr_port_eq(const tor_addr_port_t *a,
{
return tor_addr_eq(&a->addr, &b->addr) && a->port == b->port;
}
+
+/** Return true if <b>string</b> represents a valid IPv4 adddress in
+ * 'a.b.c.d' form.
+ */
+int
+string_is_valid_ipv4_address(const char *string)
+{
+ struct in_addr addr;
+
+ return (tor_inet_pton(AF_INET,string,&addr) == 1);
+}
+
+/** Return true if <b>string</b> represents a valid IPv6 address in
+ * a form that inet_pton() can parse.
+ */
+int
+string_is_valid_ipv6_address(const char *string)
+{
+ struct in6_addr addr;
+
+ return (tor_inet_pton(AF_INET6,string,&addr) == 1);
+}
+
+/** Return true iff <b>string</b> is a valid destination address,
+ * i.e. either a DNS hostname or IPv4/IPv6 address string.
+ */
+int
+string_is_valid_dest(const char *string)
+{
+ char *tmp = NULL;
+ int retval;
+ size_t len;
+
+ if (string == NULL)
+ return 0;
+
+ len = strlen(string);
+
+ if (len == 0)
+ return 0;
+
+ if (string[0] == '[' && string[len - 1] == ']')
+ string = tmp = tor_strndup(string + 1, len - 2);
+
+ retval = string_is_valid_ipv4_address(string) ||
+ string_is_valid_ipv6_address(string) ||
+ string_is_valid_nonrfc_hostname(string);
+
+ tor_free(tmp);
+
+ return retval;
+}
+
+/** Return true iff <b>string</b> matches a pattern of DNS names
+ * that we allow Tor clients to connect to.
+ *
+ * Note: This allows certain technically invalid characters ('_') to cope
+ * with misconfigured zones that have been encountered in the wild.
+ */
+int
+string_is_valid_nonrfc_hostname(const char *string)
+{
+ int result = 1;
+ int has_trailing_dot;
+ char *last_label;
+ smartlist_t *components;
+
+ if (!string || strlen(string) == 0)
+ return 0;
+
+ if (string_is_valid_ipv4_address(string))
+ return 0;
+
+ components = smartlist_new();
+
+ smartlist_split_string(components,string,".",0,0);
+
+ if (BUG(smartlist_len(components) == 0))
+ return 0; // LCOV_EXCL_LINE should be impossible given the earlier checks.
+
+ /* Allow a single terminating '.' used rarely to indicate domains
+ * are FQDNs rather than relative. */
+ last_label = (char *)smartlist_get(components,
+ smartlist_len(components) - 1);
+ has_trailing_dot = (last_label[0] == '\0');
+ if (has_trailing_dot) {
+ smartlist_pop_last(components);
+ tor_free(last_label);
+ last_label = NULL;
+ }
+
+ SMARTLIST_FOREACH_BEGIN(components, char *, c) {
+ if ((c[0] == '-') || (*c == '_')) {
+ result = 0;
+ break;
+ }
+
+ do {
+ result = (TOR_ISALNUM(*c) || (*c == '-') || (*c == '_'));
+ c++;
+ } while (result && *c);
+
+ if (result == 0) {
+ break;
+ }
+ } SMARTLIST_FOREACH_END(c);
+
+ SMARTLIST_FOREACH_BEGIN(components, char *, c) {
+ tor_free(c);
+ } SMARTLIST_FOREACH_END(c);
+
+ smartlist_free(components);
+
+ return result;
+}
diff --git a/src/lib/net/address.h b/src/lib/net/address.h
index 78b798755..f8ea573c3 100644
--- a/src/lib/net/address.h
+++ b/src/lib/net/address.h
@@ -357,6 +357,11 @@ tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port);
int tor_addr_port_eq(const tor_addr_port_t *a,
const tor_addr_port_t *b);
+int string_is_valid_dest(const char *string);
+int string_is_valid_nonrfc_hostname(const char *string);
+int string_is_valid_ipv4_address(const char *string);
+int string_is_valid_ipv6_address(const char *string);
+
#ifdef ADDRESS_PRIVATE
MOCK_DECL(struct smartlist_t *,get_interface_addresses_raw,(int severity,
sa_family_t family));
1
0
commit 9e592d1decf1b16128a716220de68322b51d6315
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 15:28:55 2018 -0400
Move tor_strtok_r to libtor-string
---
src/common/compat.c | 50 ---------------------------------------
src/common/compat.h | 7 ------
src/lib/string/compat_string.c | 53 ++++++++++++++++++++++++++++++++++++++++++
src/lib/string/compat_string.h | 7 ++++++
4 files changed, 60 insertions(+), 57 deletions(-)
diff --git a/src/common/compat.c b/src/common/compat.c
index 033ffa6ae..367ea26c2 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -177,56 +177,6 @@ tor_memmem(const void *_haystack, size_t hlen,
#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
}
-/** Helper for tor_strtok_r_impl: Advances cp past all characters in
- * <b>sep</b>, and returns its new value. */
-static char *
-strtok_helper(char *cp, const char *sep)
-{
- if (sep[1]) {
- while (*cp && strchr(sep, *cp))
- ++cp;
- } else {
- while (*cp && *cp == *sep)
- ++cp;
- }
- return cp;
-}
-
-/** Implementation of strtok_r for platforms whose coders haven't figured out
- * how to write one. Hey, retrograde libc developers! You can use this code
- * here for free! */
-char *
-tor_strtok_r_impl(char *str, const char *sep, char **lasts)
-{
- char *cp, *start;
- tor_assert(*sep);
- if (str) {
- str = strtok_helper(str, sep);
- if (!*str)
- return NULL;
- start = cp = *lasts = str;
- } else if (!*lasts || !**lasts) {
- return NULL;
- } else {
- start = cp = *lasts;
- }
-
- if (sep[1]) {
- while (*cp && !strchr(sep, *cp))
- ++cp;
- } else {
- cp = strchr(cp, *sep);
- }
-
- if (!cp || !*cp) {
- *lasts = NULL;
- } else {
- *cp++ = '\0';
- *lasts = strtok_helper(cp, sep);
- }
- return start;
-}
-
/** Represents a lockfile on which we hold the lock. */
struct tor_lockfile_t {
/** Name of the file */
diff --git a/src/common/compat.h b/src/common/compat.h
index 2282e07be..766f62557 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -73,13 +73,6 @@ tor_memstr(const void *haystack, size_t hlen, const char *needle)
return tor_memmem(haystack, hlen, needle, strlen(needle));
}
-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)
-#else
-#define tor_strtok_r(str, sep, lasts) tor_strtok_r_impl(str, sep, lasts)
-#endif
-
/* ===== Time compatibility */
struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
diff --git a/src/lib/string/compat_string.c b/src/lib/string/compat_string.c
index 6df1bc4a1..3f8a4d515 100644
--- a/src/lib/string/compat_string.c
+++ b/src/lib/string/compat_string.c
@@ -4,6 +4,7 @@
/* See LICENSE for licensing information */
#include "lib/string/compat_string.h"
+#include "lib/err/torerr.h"
/* Inline the strl functions if the platform doesn't have them. */
#ifndef HAVE_STRLCPY
@@ -12,3 +13,55 @@
#ifndef HAVE_STRLCAT
#include "strlcat.c"
#endif
+
+#include <stdlib.h>
+
+/** Helper for tor_strtok_r_impl: Advances cp past all characters in
+ * <b>sep</b>, and returns its new value. */
+static char *
+strtok_helper(char *cp, const char *sep)
+{
+ if (sep[1]) {
+ while (*cp && strchr(sep, *cp))
+ ++cp;
+ } else {
+ while (*cp && *cp == *sep)
+ ++cp;
+ }
+ return cp;
+}
+
+/** Implementation of strtok_r for platforms whose coders haven't figured out
+ * how to write one. Hey, retrograde libc developers! You can use this code
+ * here for free! */
+char *
+tor_strtok_r_impl(char *str, const char *sep, char **lasts)
+{
+ char *cp, *start;
+ raw_assert(*sep);
+ if (str) {
+ str = strtok_helper(str, sep);
+ if (!*str)
+ return NULL;
+ start = cp = *lasts = str;
+ } else if (!*lasts || !**lasts) {
+ return NULL;
+ } else {
+ start = cp = *lasts;
+ }
+
+ if (sep[1]) {
+ while (*cp && !strchr(sep, *cp))
+ ++cp;
+ } else {
+ cp = strchr(cp, *sep);
+ }
+
+ if (!cp || !*cp) {
+ *lasts = NULL;
+ } else {
+ *cp++ = '\0';
+ *lasts = strtok_helper(cp, sep);
+ }
+ return start;
+}
diff --git a/src/lib/string/compat_string.h b/src/lib/string/compat_string.h
index 212d08b7a..24cd0f8b1 100644
--- a/src/lib/string/compat_string.h
+++ b/src/lib/string/compat_string.h
@@ -36,4 +36,11 @@ size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
#endif
+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)
+#else
+#define tor_strtok_r(str, sep, lasts) tor_strtok_r_impl(str, sep, lasts)
+#endif
+
#endif
1
0
commit 0a9d8dcf2b0de62402efacc0fa4bc9a29109a6c0
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 16:21:55 2018 -0400
Move hex_str to binascii.c
---
src/common/util.c | 15 ---------------
src/common/util.h | 2 --
src/lib/encoding/binascii.c | 15 +++++++++++++++
src/lib/encoding/binascii.h | 2 ++
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/common/util.c b/src/common/util.c
index 574b017ba..28efa4a04 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -225,21 +225,6 @@ add_laplace_noise(int64_t signal_, double random_, double delta_f,
* String manipulation
* ===== */
-/** 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
- * hex_str will trash old results.
- */
-const char *
-hex_str(const char *from, size_t fromlen)
-{
- static char buf[65];
- if (fromlen>(sizeof(buf)-1)/2)
- fromlen = (sizeof(buf)-1)/2;
- base16_encode(buf,sizeof(buf),from,fromlen);
- return buf;
-}
-
/** Return true if <b>string</b> is a valid 'key=[value]' string.
* "value" is optional, to indicate the empty string. Log at logging
* <b>severity</b> if something ugly happens. */
diff --git a/src/common/util.h b/src/common/util.h
index f9018ff88..7547b8708 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -71,8 +71,6 @@ int64_t clamp_double_to_int64(double number);
/* String manipulation */
-const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
-
int string_is_key_value(int severity, const char *string);
char *tor_escape_str_for_pt_args(const char *string,
diff --git a/src/lib/encoding/binascii.c b/src/lib/encoding/binascii.c
index 554b95016..df9bb4a81 100644
--- a/src/lib/encoding/binascii.c
+++ b/src/lib/encoding/binascii.c
@@ -25,6 +25,21 @@
#include <string.h>
#include <stdlib.h>
+/** 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
+ * hex_str will trash old results.
+ */
+const char *
+hex_str(const char *from, size_t fromlen)
+{
+ static char buf[65];
+ if (fromlen>(sizeof(buf)-1)/2)
+ fromlen = (sizeof(buf)-1)/2;
+ base16_encode(buf,sizeof(buf),from,fromlen);
+ return buf;
+}
+
/* Return the base32 encoded size in bytes using the source length srclen.
*
* (WATCH OUT: This API counts the terminating NUL byte, but
diff --git a/src/lib/encoding/binascii.h b/src/lib/encoding/binascii.h
index 04310f4ed..67f9eb0e8 100644
--- a/src/lib/encoding/binascii.h
+++ b/src/lib/encoding/binascii.h
@@ -12,6 +12,8 @@
#include "lib/testsupport/testsupport.h"
#include "lib/cc/torint.h"
+const char *hex_str(const char *from, size_t fromlen);
+
/** @{ */
/** These macros don't check for overflow. Use them only for constant inputs
* (like array declarations). The *_LEN macros are the raw encoding lengths
1
0

27 Jun '18
commit 696f6f15697260255146d634e1529202cc4c2b77
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 16:43:01 2018 -0400
Split confline into confline and conffile.
The "conffile" module knows about includes and filesystem access,
whereas confline doesn't. This will make it possible to put these
functions into libraries without introducing a cycle.
---
src/common/conffile.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++
src/common/conffile.h | 17 +++++
src/common/confline.c | 168 +++----------------------------------------------
src/common/confline.h | 20 ++++--
src/common/include.am | 2 +
src/or/config.c | 1 +
src/test/test_config.c | 3 +-
7 files changed, 209 insertions(+), 166 deletions(-)
diff --git a/src/common/conffile.c b/src/common/conffile.c
new file mode 100644
index 000000000..bfb78c35c
--- /dev/null
+++ b/src/common/conffile.c
@@ -0,0 +1,164 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-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 "common/compat.h"
+#include "common/confline.h"
+#include "common/conffile.h"
+#include "lib/log/torlog.h"
+#include "common/util.h"
+#include "lib/container/smartlist.h"
+
+static smartlist_t *config_get_file_list(const char *path,
+ smartlist_t *opened_files);
+static int config_get_included_config(const char *path, int recursion_level,
+ int extended, config_line_t **config,
+ config_line_t **config_last,
+ smartlist_t *opened_lst);
+static int config_process_include(const char *path, int recursion_level,
+ int extended, config_line_t **list,
+ config_line_t **list_last,
+ smartlist_t *opened_lst);
+
+/** Helper: parse the config string and strdup into key/value
+ * strings. Set *result to the list, or NULL if parsing the string
+ * failed. Set *has_include to 1 if <b>result</b> has values from
+ * %included files. <b>opened_lst</b> will have a list of opened files if
+ * provided. Return 0 on success, -1 on failure. Warn and ignore any
+ * misformatted lines.
+ *
+ * If <b>extended</b> is set, then treat keys beginning with / and with + as
+ * indicating "clear" and "append" respectively. */
+int
+config_get_lines_include(const char *string, config_line_t **result,
+ int extended, int *has_include,
+ smartlist_t *opened_lst)
+{
+ return config_get_lines_aux(string, result, extended, 1, has_include,
+ opened_lst, 1, NULL, config_process_include);
+}
+
+/** Adds a list of configuration files present on <b>path</b> to
+ * <b>file_list</b>. <b>path</b> can be a file or a directory. If it is a file,
+ * only that file will be added to <b>file_list</b>. If it is a directory,
+ * all paths for files on that directory root (no recursion) except for files
+ * whose name starts with a dot will be added to <b>file_list</b>.
+ * <b>opened_files</b> will have a list of files opened by this function
+ * if provided. Return 0 on success, -1 on failure. Ignores empty files.
+ */
+static smartlist_t *
+config_get_file_list(const char *path, smartlist_t *opened_files)
+{
+ smartlist_t *file_list = smartlist_new();
+
+ if (opened_files) {
+ smartlist_add_strdup(opened_files, path);
+ }
+
+ file_status_t file_type = file_status(path);
+ if (file_type == FN_FILE) {
+ smartlist_add_strdup(file_list, path);
+ return file_list;
+ } else if (file_type == FN_DIR) {
+ smartlist_t *all_files = tor_listdir(path);
+ if (!all_files) {
+ smartlist_free(file_list);
+ return NULL;
+ }
+ smartlist_sort_strings(all_files);
+ SMARTLIST_FOREACH_BEGIN(all_files, char *, f) {
+ if (f[0] == '.') {
+ tor_free(f);
+ continue;
+ }
+
+ char *fullname;
+ tor_asprintf(&fullname, "%s"PATH_SEPARATOR"%s", path, f);
+ tor_free(f);
+
+ if (opened_files) {
+ smartlist_add_strdup(opened_files, fullname);
+ }
+
+ if (file_status(fullname) != FN_FILE) {
+ tor_free(fullname);
+ continue;
+ }
+ smartlist_add(file_list, fullname);
+ } SMARTLIST_FOREACH_END(f);
+ smartlist_free(all_files);
+ return file_list;
+ } else if (file_type == FN_EMPTY) {
+ return file_list;
+ } else {
+ smartlist_free(file_list);
+ return NULL;
+ }
+}
+
+/** Creates a list of config lines present on included <b>path</b>.
+ * Set <b>config</b> to the list and <b>config_last</b> to the last element of
+ * <b>config</b>. <b>opened_lst</b> will have a list of opened files if
+ * provided. Return 0 on success, -1 on failure. */
+static int
+config_get_included_config(const char *path, int recursion_level, int extended,
+ config_line_t **config, config_line_t **config_last,
+ smartlist_t *opened_lst)
+{
+ char *included_conf = read_file_to_str(path, 0, NULL);
+ if (!included_conf) {
+ return -1;
+ }
+
+ if (config_get_lines_aux(included_conf, config, extended, 1, NULL,
+ opened_lst, recursion_level+1, config_last,
+ config_process_include) < 0) {
+ tor_free(included_conf);
+ return -1;
+ }
+
+ tor_free(included_conf);
+ return 0;
+}
+
+/** Process an %include <b>path</b> in a config file. Set <b>list</b> to the
+ * list of configuration settings obtained and <b>list_last</b> to the last
+ * element of the same list. <b>opened_lst</b> will have a list of opened
+ * files if provided. Return 0 on success, -1 on failure. */
+static int
+config_process_include(const char *path, int recursion_level, int extended,
+ config_line_t **list, config_line_t **list_last,
+ smartlist_t *opened_lst)
+{
+ config_line_t *ret_list = NULL;
+ config_line_t **next = &ret_list;
+
+ smartlist_t *config_files = config_get_file_list(path, opened_lst);
+ if (!config_files) {
+ return -1;
+ }
+
+ int rv = -1;
+ SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
+ config_line_t *included_config = NULL;
+ if (config_get_included_config(config_file, recursion_level, extended,
+ &included_config, list_last,
+ opened_lst) < 0) {
+ goto done;
+ }
+
+ *next = included_config;
+ if (*list_last)
+ next = &(*list_last)->next;
+
+ } SMARTLIST_FOREACH_END(config_file);
+ *list = ret_list;
+ rv = 0;
+
+ done:
+ SMARTLIST_FOREACH(config_files, char *, f, tor_free(f));
+ smartlist_free(config_files);
+ return rv;
+}
diff --git a/src/common/conffile.h b/src/common/conffile.h
new file mode 100644
index 000000000..bd8250b00
--- /dev/null
+++ b/src/common/conffile.h
@@ -0,0 +1,17 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-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_CONFFILE_H
+#define TOR_CONFFILE_H
+
+struct smartlist_t;
+struct config_line_t;
+
+int config_get_lines_include(const char *string, struct config_line_t **result,
+ int extended, int *has_include,
+ struct smartlist_t *opened_lst);
+
+#endif /* !defined(TOR_CONFLINE_H) */
diff --git a/src/common/confline.c b/src/common/confline.c
index 9e37bfbdb..80e5994ce 100644
--- a/src/common/confline.c
+++ b/src/common/confline.c
@@ -10,21 +10,6 @@
#include "common/util.h"
#include "lib/container/smartlist.h"
-static int config_get_lines_aux(const char *string, config_line_t **result,
- int extended, int allow_include,
- int *has_include, smartlist_t *opened_lst,
- int recursion_level, config_line_t **last);
-static smartlist_t *config_get_file_list(const char *path,
- smartlist_t *opened_files);
-static int config_get_included_config(const char *path, int recursion_level,
- int extended, config_line_t **config,
- config_line_t **config_last,
- smartlist_t *opened_lst);
-static int config_process_include(const char *path, int recursion_level,
- int extended, config_line_t **list,
- config_line_t **list_last,
- smartlist_t *opened_lst);
-
/** Helper: allocate a new configuration option mapping 'key' to 'val',
* append it to *<b>lst</b>. */
void
@@ -86,11 +71,12 @@ config_line_find(const config_line_t *lines,
* <b>opened_lst</b> will have a list of opened files if provided.
* Returns the a pointer to the last element of the <b>result</b> in
* <b>last</b>. */
-static int
+int
config_get_lines_aux(const char *string, config_line_t **result, int extended,
int allow_include, int *has_include,
smartlist_t *opened_lst, int recursion_level,
- config_line_t **last)
+ config_line_t **last,
+ include_handler_fn handle_include)
{
config_line_t *list = NULL, **next, *list_last = NULL;
char *k, *v;
@@ -133,13 +119,13 @@ config_get_lines_aux(const char *string, config_line_t **result, int extended,
}
}
- if (allow_include && !strcmp(k, "%include")) {
+ if (allow_include && !strcmp(k, "%include") && handle_include) {
tor_free(k);
include_used = 1;
config_line_t *include_list;
- if (config_process_include(v, recursion_level, extended, &include_list,
- &list_last, opened_lst) < 0) {
+ if (handle_include(v, recursion_level, extended, &include_list,
+ &list_last, opened_lst) < 0) {
log_warn(LD_CONFIG, "Error reading included configuration "
"file or directory: \"%s\".", v);
config_free_lines(list);
@@ -178,152 +164,12 @@ config_get_lines_aux(const char *string, config_line_t **result, int extended,
return 0;
}
-/** Helper: parse the config string and strdup into key/value
- * strings. Set *result to the list, or NULL if parsing the string
- * failed. Set *has_include to 1 if <b>result</b> has values from
- * %included files. <b>opened_lst</b> will have a list of opened files if
- * provided. Return 0 on success, -1 on failure. Warn and ignore any
- * misformatted lines.
- *
- * If <b>extended</b> is set, then treat keys beginning with / and with + as
- * indicating "clear" and "append" respectively. */
-int
-config_get_lines_include(const char *string, config_line_t **result,
- int extended, int *has_include,
- smartlist_t *opened_lst)
-{
- return config_get_lines_aux(string, result, extended, 1, has_include,
- opened_lst, 1, NULL);
-}
-
/** Same as config_get_lines_include but does not allow %include */
int
config_get_lines(const char *string, config_line_t **result, int extended)
{
return config_get_lines_aux(string, result, extended, 0, NULL, NULL, 1,
- NULL);
-}
-
-/** Adds a list of configuration files present on <b>path</b> to
- * <b>file_list</b>. <b>path</b> can be a file or a directory. If it is a file,
- * only that file will be added to <b>file_list</b>. If it is a directory,
- * all paths for files on that directory root (no recursion) except for files
- * whose name starts with a dot will be added to <b>file_list</b>.
- * <b>opened_files</b> will have a list of files opened by this function
- * if provided. Return 0 on success, -1 on failure. Ignores empty files.
- */
-static smartlist_t *
-config_get_file_list(const char *path, smartlist_t *opened_files)
-{
- smartlist_t *file_list = smartlist_new();
-
- if (opened_files) {
- smartlist_add_strdup(opened_files, path);
- }
-
- file_status_t file_type = file_status(path);
- if (file_type == FN_FILE) {
- smartlist_add_strdup(file_list, path);
- return file_list;
- } else if (file_type == FN_DIR) {
- smartlist_t *all_files = tor_listdir(path);
- if (!all_files) {
- smartlist_free(file_list);
- return NULL;
- }
- smartlist_sort_strings(all_files);
- SMARTLIST_FOREACH_BEGIN(all_files, char *, f) {
- if (f[0] == '.') {
- tor_free(f);
- continue;
- }
-
- char *fullname;
- tor_asprintf(&fullname, "%s"PATH_SEPARATOR"%s", path, f);
- tor_free(f);
-
- if (opened_files) {
- smartlist_add_strdup(opened_files, fullname);
- }
-
- if (file_status(fullname) != FN_FILE) {
- tor_free(fullname);
- continue;
- }
- smartlist_add(file_list, fullname);
- } SMARTLIST_FOREACH_END(f);
- smartlist_free(all_files);
- return file_list;
- } else if (file_type == FN_EMPTY) {
- return file_list;
- } else {
- smartlist_free(file_list);
- return NULL;
- }
-}
-
-/** Creates a list of config lines present on included <b>path</b>.
- * Set <b>config</b> to the list and <b>config_last</b> to the last element of
- * <b>config</b>. <b>opened_lst</b> will have a list of opened files if
- * provided. Return 0 on success, -1 on failure. */
-static int
-config_get_included_config(const char *path, int recursion_level, int extended,
- config_line_t **config, config_line_t **config_last,
- smartlist_t *opened_lst)
-{
- char *included_conf = read_file_to_str(path, 0, NULL);
- if (!included_conf) {
- return -1;
- }
-
- if (config_get_lines_aux(included_conf, config, extended, 1, NULL,
- opened_lst, recursion_level+1, config_last) < 0) {
- tor_free(included_conf);
- return -1;
- }
-
- tor_free(included_conf);
- return 0;
-}
-
-/** Process an %include <b>path</b> in a config file. Set <b>list</b> to the
- * list of configuration settings obtained and <b>list_last</b> to the last
- * element of the same list. <b>opened_lst</b> will have a list of opened
- * files if provided. Return 0 on success, -1 on failure. */
-static int
-config_process_include(const char *path, int recursion_level, int extended,
- config_line_t **list, config_line_t **list_last,
- smartlist_t *opened_lst)
-{
- config_line_t *ret_list = NULL;
- config_line_t **next = &ret_list;
-
- smartlist_t *config_files = config_get_file_list(path, opened_lst);
- if (!config_files) {
- return -1;
- }
-
- int rv = -1;
- SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
- config_line_t *included_config = NULL;
- if (config_get_included_config(config_file, recursion_level, extended,
- &included_config, list_last,
- opened_lst) < 0) {
- goto done;
- }
-
- *next = included_config;
- if (*list_last)
- next = &(*list_last)->next;
-
- } SMARTLIST_FOREACH_END(config_file);
- *list = ret_list;
- rv = 0;
-
- done:
- SMARTLIST_FOREACH(config_files, char *, f, tor_free(f));
- smartlist_free(config_files);
- return rv;
+ NULL, NULL);
}
/**
diff --git a/src/common/confline.h b/src/common/confline.h
index d1f6fdb7e..f03faed5e 100644
--- a/src/common/confline.h
+++ b/src/common/confline.h
@@ -44,10 +44,6 @@ const config_line_t *config_line_find(const config_line_t *lines,
const char *key);
int config_lines_eq(config_line_t *a, config_line_t *b);
int config_count_key(const config_line_t *a, const char *key);
-int config_get_lines(const char *string, config_line_t **result, int extended);
-int config_get_lines_include(const char *string, config_line_t **result,
- int extended, int *has_include,
- struct smartlist_t *opened_lst);
void config_free_lines_(config_line_t *front);
#define config_free_lines(front) \
do { \
@@ -57,4 +53,20 @@ void config_free_lines_(config_line_t *front);
const char *parse_config_line_from_str_verbose(const char *line,
char **key_out, char **value_out,
const char **err_out);
+
+int config_get_lines(const char *string, struct config_line_t **result,
+ int extended);
+
+typedef int (*include_handler_fn)(const char *, int, int,
+ struct config_line_t **,
+ struct config_line_t **,
+ struct smartlist_t *);
+
+int config_get_lines_aux(const char *string, struct config_line_t **result,
+ int extended,
+ int allow_include, int *has_include,
+ struct smartlist_t *opened_lst, int recursion_level,
+ config_line_t **last,
+ include_handler_fn handle_include);
+
#endif /* !defined(TOR_CONFLINE_H) */
diff --git a/src/common/include.am b/src/common/include.am
index 2360c7f77..4fd3284ab 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -37,6 +37,7 @@ LIBOR_A_SRC = \
src/common/compat_threads.c \
src/common/compat_time.c \
src/common/confline.c \
+ src/common/conffile.c \
src/common/memarea.c \
src/common/util.c \
src/common/util_process.c \
@@ -79,6 +80,7 @@ COMMONHEADERS = \
src/common/compat_libevent.h \
src/common/compat_threads.h \
src/common/compat_time.h \
+ src/common/conffile.h \
src/common/confline.h \
src/common/handles.h \
src/common/memarea.h \
diff --git a/src/or/config.c b/src/or/config.c
index 98f3ff77b..b0141b9c0 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -111,6 +111,7 @@
#include <shlobj.h>
#endif
+#include "common/conffile.h"
#include "common/procmon.h"
#include "or/dirauth/dirvote.h"
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 5abc97fc3..dcdaa2ed5 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -48,6 +48,8 @@
#include "or/port_cfg_st.h"
#include "or/routerinfo_st.h"
+#include "common/conffile.h"
+
static void
test_config_addressmap(void *arg)
{
@@ -5731,4 +5733,3 @@ struct testcase_t config_tests[] = {
CONFIG_TEST(compute_max_mem_in_queues, 0),
END_OF_TESTCASES
};
-
1
0

27 Jun '18
commit 194a34cdc28c6b309dd9a32f5446409810b1d32b
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 16:17:46 2018 -0400
Extract time encoding functions into lib/encoding
---
src/common/compat.c | 34 ---
src/common/compat.h | 3 -
src/common/util.c | 442 -------------------------------------
src/common/util.h | 17 +-
src/lib/encoding/.may_include | 1 +
src/lib/encoding/include.am | 6 +-
src/lib/encoding/time_fmt.c | 493 ++++++++++++++++++++++++++++++++++++++++++
src/lib/encoding/time_fmt.h | 38 ++++
8 files changed, 537 insertions(+), 497 deletions(-)
diff --git a/src/common/compat.c b/src/common/compat.c
index cdc53175d..48e706456 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -965,40 +965,6 @@ compute_num_cpus(void)
return num_cpus;
}
-/** 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.
- */
-struct tm *
-tor_localtime_r(const time_t *timep, struct tm *result)
-{
- 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;
-}
-
-/** 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.
- */
-struct tm *
-tor_gmtime_r(const time_t *timep, struct tm *result)
-{
- 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;
-}
-
#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
#define HAVE_UNIX_MLOCKALL
#endif
diff --git a/src/common/compat.h b/src/common/compat.h
index 399badb6a..95447d3b8 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -65,9 +65,6 @@
/* ===== Time compatibility */
-struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
-struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
-
#ifndef timeradd
/** Replacement for timeradd on platforms that do not have it: sets tvout to
* the sum of tv1 and tv2. */
diff --git a/src/common/util.c b/src/common/util.c
index 92742a814..574b017ba 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -460,448 +460,6 @@ tv_to_msec(const struct timeval *tv)
return conv;
}
-/** Yield true iff <b>y</b> is a leap-year. */
-#define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400)))
-/** Helper: Return the number of leap-days between Jan 1, y1 and Jan 1, y2. */
-static int
-n_leapdays(int year1, int year2)
-{
- --year1;
- --year2;
- return (year2/4 - year1/4) - (year2/100 - year1/100)
- + (year2/400 - year1/400);
-}
-/** Number of days per month in non-leap year; used by tor_timegm and
- * parse_rfc1123_time. */
-static const int days_per_month[] =
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-/** Compute a time_t given a struct tm. The result is given in UTC, and
- * does not account for leap seconds. Return 0 on success, -1 on failure.
- */
-int
-tor_timegm(const struct tm *tm, time_t *time_out)
-{
- /* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
- * It's way more brute-force than fiddling with tzset().
- *
- * We use int64_t rather than time_t to avoid overflow on multiplication on
- * platforms with 32-bit time_t. Since year is clipped to INT32_MAX, and
- * since 365 * 24 * 60 * 60 is approximately 31 million, it's not possible
- * for INT32_MAX years to overflow int64_t when converted to seconds. */
- int64_t year, days, hours, minutes, seconds;
- int i, invalid_year, dpm;
-
- /* Initialize time_out to 0 for now, to avoid bad usage in case this function
- fails and the caller ignores the return value. */
- tor_assert(time_out);
- *time_out = 0;
-
- /* avoid int overflow on addition */
- if (tm->tm_year < INT32_MAX-1900) {
- year = tm->tm_year + 1900;
- } else {
- /* clamp year */
- year = INT32_MAX;
- }
- invalid_year = (year < 1970 || tm->tm_year >= INT32_MAX-1900);
-
- if (tm->tm_mon >= 0 && tm->tm_mon <= 11) {
- dpm = days_per_month[tm->tm_mon];
- if (tm->tm_mon == 1 && !invalid_year && IS_LEAPYEAR(tm->tm_year)) {
- dpm = 29;
- }
- } else {
- /* invalid month - default to 0 days per month */
- dpm = 0;
- }
-
- if (invalid_year ||
- tm->tm_mon < 0 || tm->tm_mon > 11 ||
- tm->tm_mday < 1 || tm->tm_mday > dpm ||
- tm->tm_hour < 0 || tm->tm_hour > 23 ||
- tm->tm_min < 0 || tm->tm_min > 59 ||
- tm->tm_sec < 0 || tm->tm_sec > 60) {
- log_warn(LD_BUG, "Out-of-range argument to tor_timegm");
- return -1;
- }
- days = 365 * (year-1970) + n_leapdays(1970,(int)year);
- for (i = 0; i < tm->tm_mon; ++i)
- days += days_per_month[i];
- if (tm->tm_mon > 1 && IS_LEAPYEAR(year))
- ++days;
- days += tm->tm_mday - 1;
- hours = days*24 + tm->tm_hour;
-
- minutes = hours*60 + tm->tm_min;
- seconds = minutes*60 + tm->tm_sec;
- /* Check that "seconds" will fit in a time_t. On platforms where time_t is
- * 32-bit, this check will fail for dates in and after 2038.
- *
- * We already know that "seconds" can't be negative because "year" >= 1970 */
-#if SIZEOF_TIME_T < 8
- if (seconds < TIME_MIN || seconds > TIME_MAX) {
- log_warn(LD_BUG, "Result does not fit in tor_timegm");
- return -1;
- }
-#endif /* SIZEOF_TIME_T < 8 */
- *time_out = (time_t)seconds;
- return 0;
-}
-
-/* strftime is locale-specific, so we need to replace those parts */
-
-/** A c-locale array of 3-letter names of weekdays, starting with Sun. */
-static const char *WEEKDAY_NAMES[] =
- { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-/** A c-locale array of 3-letter names of months, starting with Jan. */
-static const char *MONTH_NAMES[] =
- { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-/** Set <b>buf</b> to the RFC1123 encoding of the UTC value of <b>t</b>.
- * The buffer must be at least RFC1123_TIME_LEN+1 bytes long.
- *
- * (RFC1123 format is "Fri, 29 Sep 2006 15:54:20 GMT". Note the "GMT"
- * rather than "UTC".)
- */
-void
-format_rfc1123_time(char *buf, time_t t)
-{
- struct tm tm;
-
- tor_gmtime_r(&t, &tm);
-
- strftime(buf, RFC1123_TIME_LEN+1, "___, %d ___ %Y %H:%M:%S GMT", &tm);
- tor_assert(tm.tm_wday >= 0);
- tor_assert(tm.tm_wday <= 6);
- memcpy(buf, WEEKDAY_NAMES[tm.tm_wday], 3);
- tor_assert(tm.tm_mon >= 0);
- tor_assert(tm.tm_mon <= 11);
- memcpy(buf+8, MONTH_NAMES[tm.tm_mon], 3);
-}
-
-/** Parse the (a subset of) the RFC1123 encoding of some time (in UTC) from
- * <b>buf</b>, and store the result in *<b>t</b>.
- *
- * Note that we only accept the subset generated by format_rfc1123_time above,
- * not the full range of formats suggested by RFC 1123.
- *
- * Return 0 on success, -1 on failure.
-*/
-int
-parse_rfc1123_time(const char *buf, time_t *t)
-{
- struct tm tm;
- char month[4];
- char weekday[4];
- int i, m, invalid_year;
- unsigned tm_mday, tm_year, tm_hour, tm_min, tm_sec;
- unsigned dpm;
-
- if (strlen(buf) != RFC1123_TIME_LEN)
- return -1;
- memset(&tm, 0, sizeof(tm));
- if (tor_sscanf(buf, "%3s, %2u %3s %u %2u:%2u:%2u GMT", weekday,
- &tm_mday, month, &tm_year, &tm_hour,
- &tm_min, &tm_sec) < 7) {
- char *esc = esc_for_log(buf);
- log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
- tor_free(esc);
- return -1;
- }
-
- m = -1;
- for (i = 0; i < 12; ++i) {
- if (!strcmp(month, MONTH_NAMES[i])) {
- m = i;
- break;
- }
- }
- if (m<0) {
- char *esc = esc_for_log(buf);
- log_warn(LD_GENERAL, "Got invalid RFC1123 time %s: No such month", esc);
- tor_free(esc);
- return -1;
- }
- tm.tm_mon = m;
-
- invalid_year = (tm_year >= INT32_MAX || tm_year < 1970);
- tor_assert(m >= 0 && m <= 11);
- dpm = days_per_month[m];
- if (m == 1 && !invalid_year && IS_LEAPYEAR(tm_year)) {
- dpm = 29;
- }
-
- if (invalid_year || tm_mday < 1 || tm_mday > dpm ||
- tm_hour > 23 || tm_min > 59 || tm_sec > 60) {
- char *esc = esc_for_log(buf);
- log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
- tor_free(esc);
- return -1;
- }
- tm.tm_mday = (int)tm_mday;
- tm.tm_year = (int)tm_year;
- tm.tm_hour = (int)tm_hour;
- tm.tm_min = (int)tm_min;
- tm.tm_sec = (int)tm_sec;
-
- if (tm.tm_year < 1970) {
- /* LCOV_EXCL_START
- * XXXX I think this is dead code; we already checked for
- * invalid_year above. */
- tor_assert_nonfatal_unreached();
- char *esc = esc_for_log(buf);
- log_warn(LD_GENERAL,
- "Got invalid RFC1123 time %s. (Before 1970)", esc);
- tor_free(esc);
- return -1;
- /* LCOV_EXCL_STOP */
- }
- tm.tm_year -= 1900;
-
- return tor_timegm(&tm, t);
-}
-
-/** Set <b>buf</b> to the ISO8601 encoding of the local value of <b>t</b>.
- * The buffer must be at least ISO_TIME_LEN+1 bytes long.
- *
- * (ISO8601 format is 2006-10-29 10:57:20)
- */
-void
-format_local_iso_time(char *buf, time_t t)
-{
- struct tm tm;
- strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_localtime_r(&t, &tm));
-}
-
-/** Set <b>buf</b> to the ISO8601 encoding of the GMT value of <b>t</b>.
- * The buffer must be at least ISO_TIME_LEN+1 bytes long.
- */
-void
-format_iso_time(char *buf, time_t t)
-{
- struct tm tm;
- strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_gmtime_r(&t, &tm));
-}
-
-/** As format_local_iso_time, but use the yyyy-mm-ddThh:mm:ss format to avoid
- * embedding an internal space. */
-void
-format_local_iso_time_nospace(char *buf, time_t t)
-{
- format_local_iso_time(buf, t);
- buf[10] = 'T';
-}
-
-/** As format_iso_time, but use the yyyy-mm-ddThh:mm:ss format to avoid
- * embedding an internal space. */
-void
-format_iso_time_nospace(char *buf, time_t t)
-{
- format_iso_time(buf, t);
- buf[10] = 'T';
-}
-
-/** As format_iso_time_nospace, but include microseconds in decimal
- * fixed-point format. Requires that buf be at least ISO_TIME_USEC_LEN+1
- * bytes long. */
-void
-format_iso_time_nospace_usec(char *buf, const struct timeval *tv)
-{
- tor_assert(tv);
- format_iso_time_nospace(buf, (time_t)tv->tv_sec);
- tor_snprintf(buf+ISO_TIME_LEN, 8, ".%06d", (int)tv->tv_usec);
-}
-
-/** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>,
- * parse it and store its value in *<b>t</b>. Return 0 on success, -1 on
- * failure. Ignore extraneous stuff in <b>cp</b> after the end of the time
- * string, unless <b>strict</b> is set. If <b>nospace</b> is set,
- * expect the YYYY-MM-DDTHH:MM:SS format. */
-int
-parse_iso_time_(const char *cp, time_t *t, int strict, int nospace)
-{
- struct tm st_tm;
- unsigned int year=0, month=0, day=0, hour=0, minute=0, second=0;
- int n_fields;
- char extra_char, separator_char;
- n_fields = tor_sscanf(cp, "%u-%2u-%2u%c%2u:%2u:%2u%c",
- &year, &month, &day,
- &separator_char,
- &hour, &minute, &second, &extra_char);
- if (strict ? (n_fields != 7) : (n_fields < 7)) {
- char *esc = esc_for_log(cp);
- log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
- tor_free(esc);
- return -1;
- }
- if (separator_char != (nospace ? 'T' : ' ')) {
- char *esc = esc_for_log(cp);
- log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
- tor_free(esc);
- return -1;
- }
- if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
- hour > 23 || minute > 59 || second > 60 || year >= INT32_MAX) {
- char *esc = esc_for_log(cp);
- log_warn(LD_GENERAL, "ISO time %s was nonsensical", esc);
- tor_free(esc);
- return -1;
- }
- st_tm.tm_year = (int)year-1900;
- st_tm.tm_mon = month-1;
- st_tm.tm_mday = day;
- st_tm.tm_hour = hour;
- st_tm.tm_min = minute;
- st_tm.tm_sec = second;
- st_tm.tm_wday = 0; /* Should be ignored. */
-
- if (st_tm.tm_year < 70) {
- /* LCOV_EXCL_START
- * XXXX I think this is dead code; we already checked for
- * year < 1970 above. */
- tor_assert_nonfatal_unreached();
- char *esc = esc_for_log(cp);
- log_warn(LD_GENERAL, "Got invalid ISO time %s. (Before 1970)", esc);
- tor_free(esc);
- return -1;
- /* LCOV_EXCL_STOP */
- }
- return tor_timegm(&st_tm, t);
-}
-
-/** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>,
- * parse it and store its value in *<b>t</b>. Return 0 on success, -1 on
- * failure. Reject the string if any characters are present after the time.
- */
-int
-parse_iso_time(const char *cp, time_t *t)
-{
- return parse_iso_time_(cp, t, 1, 0);
-}
-
-/**
- * As parse_iso_time, but parses a time encoded by format_iso_time_nospace().
- */
-int
-parse_iso_time_nospace(const char *cp, time_t *t)
-{
- return parse_iso_time_(cp, t, 1, 1);
-}
-
-/** Given a <b>date</b> in one of the three formats allowed by HTTP (ugh),
- * parse it into <b>tm</b>. Return 0 on success, negative on failure. */
-int
-parse_http_time(const char *date, struct tm *tm)
-{
- const char *cp;
- char month[4];
- char wkday[4];
- int i;
- unsigned tm_mday, tm_year, tm_hour, tm_min, tm_sec;
-
- tor_assert(tm);
- memset(tm, 0, sizeof(*tm));
-
- /* First, try RFC1123 or RFC850 format: skip the weekday. */
- if ((cp = strchr(date, ','))) {
- ++cp;
- if (*cp != ' ')
- return -1;
- ++cp;
- if (tor_sscanf(cp, "%2u %3s %4u %2u:%2u:%2u GMT",
- &tm_mday, month, &tm_year,
- &tm_hour, &tm_min, &tm_sec) == 6) {
- /* rfc1123-date */
- tm_year -= 1900;
- } else if (tor_sscanf(cp, "%2u-%3s-%2u %2u:%2u:%2u GMT",
- &tm_mday, month, &tm_year,
- &tm_hour, &tm_min, &tm_sec) == 6) {
- /* rfc850-date */
- } else {
- return -1;
- }
- } else {
- /* No comma; possibly asctime() format. */
- if (tor_sscanf(date, "%3s %3s %2u %2u:%2u:%2u %4u",
- wkday, month, &tm_mday,
- &tm_hour, &tm_min, &tm_sec, &tm_year) == 7) {
- tm_year -= 1900;
- } else {
- return -1;
- }
- }
- tm->tm_mday = (int)tm_mday;
- tm->tm_year = (int)tm_year;
- tm->tm_hour = (int)tm_hour;
- tm->tm_min = (int)tm_min;
- tm->tm_sec = (int)tm_sec;
- tm->tm_wday = 0; /* Leave this unset. */
-
- month[3] = '\0';
- /* Okay, now decode the month. */
- /* set tm->tm_mon to dummy value so the check below fails. */
- tm->tm_mon = -1;
- for (i = 0; i < 12; ++i) {
- if (!strcasecmp(MONTH_NAMES[i], month)) {
- tm->tm_mon = i;
- }
- }
-
- if (tm->tm_year < 0 ||
- tm->tm_mon < 0 || tm->tm_mon > 11 ||
- tm->tm_mday < 1 || tm->tm_mday > 31 ||
- tm->tm_hour < 0 || tm->tm_hour > 23 ||
- tm->tm_min < 0 || tm->tm_min > 59 ||
- tm->tm_sec < 0 || tm->tm_sec > 60)
- return -1; /* Out of range, or bad month. */
-
- return 0;
-}
-
-/** Given an <b>interval</b> in seconds, try to write it to the
- * <b>out_len</b>-byte buffer in <b>out</b> in a human-readable form.
- * Returns a non-negative integer on success, -1 on failure.
- */
-int
-format_time_interval(char *out, size_t out_len, long interval)
-{
- /* We only report seconds if there's no hours. */
- long sec = 0, min = 0, hour = 0, day = 0;
-
- /* -LONG_MIN is LONG_MAX + 1, which causes signed overflow */
- if (interval < -LONG_MAX)
- interval = LONG_MAX;
- else if (interval < 0)
- interval = -interval;
-
- if (interval >= 86400) {
- day = interval / 86400;
- interval %= 86400;
- }
- if (interval >= 3600) {
- hour = interval / 3600;
- interval %= 3600;
- }
- if (interval >= 60) {
- min = interval / 60;
- interval %= 60;
- }
- sec = interval;
-
- if (day) {
- return tor_snprintf(out, out_len, "%ld days, %ld hours, %ld minutes",
- day, hour, min);
- } else if (hour) {
- return tor_snprintf(out, out_len, "%ld hours, %ld minutes", hour, min);
- } else if (min) {
- return tor_snprintf(out, out_len, "%ld minutes, %ld seconds", min, sec);
- } else {
- return tor_snprintf(out, out_len, "%ld seconds", sec);
- }
-}
-
/* =====
* File helpers
* ===== */
diff --git a/src/common/util.h b/src/common/util.h
index fa7886d0f..f9018ff88 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -38,6 +38,7 @@
#include "lib/fs/dir.h"
#include "lib/fs/files.h"
#include "lib/fs/path.h"
+#include "lib/encoding/time_fmt.h"
void tor_log_mallinfo(int severity);
@@ -81,22 +82,6 @@ char *tor_escape_str_for_pt_args(const char *string,
long tv_udiff(const struct timeval *start, const struct timeval *end);
long tv_mdiff(const struct timeval *start, const struct timeval *end);
int64_t tv_to_msec(const struct timeval *tv);
-int tor_timegm(const struct tm *tm, time_t *time_out);
-#define RFC1123_TIME_LEN 29
-void format_rfc1123_time(char *buf, time_t t);
-int parse_rfc1123_time(const char *buf, time_t *t);
-#define ISO_TIME_LEN 19
-#define ISO_TIME_USEC_LEN (ISO_TIME_LEN+7)
-void format_local_iso_time(char *buf, time_t t);
-void format_iso_time(char *buf, time_t t);
-void format_local_iso_time_nospace(char *buf, time_t t);
-void format_iso_time_nospace(char *buf, time_t t);
-void format_iso_time_nospace_usec(char *buf, const struct timeval *tv);
-int parse_iso_time_(const char *cp, time_t *t, int strict, int nospace);
-int parse_iso_time(const char *buf, time_t *t);
-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);
/* File helpers */
diff --git a/src/lib/encoding/.may_include b/src/lib/encoding/.may_include
index 299e0fc4f..92231b513 100644
--- a/src/lib/encoding/.may_include
+++ b/src/lib/encoding/.may_include
@@ -6,3 +6,4 @@ lib/log/*.h
lib/malloc/*.h
lib/string/*.h
lib/testsupport/*.h
+lib/wallclock/*.h
diff --git a/src/lib/encoding/include.am b/src/lib/encoding/include.am
index fcd9baf3d..345fe14e1 100644
--- a/src/lib/encoding/include.am
+++ b/src/lib/encoding/include.am
@@ -5,7 +5,8 @@ noinst_LIBRARIES += src/lib/libtor-encoding-testing.a
endif
src_lib_libtor_encoding_a_SOURCES = \
- src/lib/encoding/binascii.c
+ src/lib/encoding/binascii.c \
+ src/lib/encoding/time_fmt.c
src_lib_libtor_encoding_testing_a_SOURCES = \
$(src_lib_libtor_encoding_a_SOURCES)
@@ -13,4 +14,5 @@ src_lib_libtor_encoding_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
src_lib_libtor_encoding_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
noinst_HEADERS += \
- src/lib/encoding/binascii.h
+ src/lib/encoding/binascii.h \
+ src/lib/encoding/time_fmt.h
diff --git a/src/lib/encoding/time_fmt.c b/src/lib/encoding/time_fmt.c
new file mode 100644
index 000000000..ef60f17e3
--- /dev/null
+++ b/src/lib/encoding/time_fmt.c
@@ -0,0 +1,493 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-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/encoding/time_fmt.h"
+#include "lib/log/torlog.h"
+#include "lib/log/escape.h"
+#include "lib/log/util_bug.h"
+#include "lib/malloc/util_malloc.h"
+#include "lib/string/printf.h"
+#include "lib/string/scanf.h"
+#include "lib/wallclock/tm_cvt.h"
+
+#include <string.h>
+#include <time.h>
+
+/** 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.
+ */
+struct tm *
+tor_localtime_r(const time_t *timep, struct tm *result)
+{
+ 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;
+}
+
+/** 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.
+ */
+struct tm *
+tor_gmtime_r(const time_t *timep, struct tm *result)
+{
+ 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;
+}
+
+/** Yield true iff <b>y</b> is a leap-year. */
+#define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400)))
+/** Helper: Return the number of leap-days between Jan 1, y1 and Jan 1, y2. */
+static int
+n_leapdays(int year1, int year2)
+{
+ --year1;
+ --year2;
+ return (year2/4 - year1/4) - (year2/100 - year1/100)
+ + (year2/400 - year1/400);
+}
+/** Number of days per month in non-leap year; used by tor_timegm and
+ * parse_rfc1123_time. */
+static const int days_per_month[] =
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+/** Compute a time_t given a struct tm. The result is given in UTC, and
+ * does not account for leap seconds. Return 0 on success, -1 on failure.
+ */
+int
+tor_timegm(const struct tm *tm, time_t *time_out)
+{
+ /* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
+ * It's way more brute-force than fiddling with tzset().
+ *
+ * We use int64_t rather than time_t to avoid overflow on multiplication on
+ * platforms with 32-bit time_t. Since year is clipped to INT32_MAX, and
+ * since 365 * 24 * 60 * 60 is approximately 31 million, it's not possible
+ * for INT32_MAX years to overflow int64_t when converted to seconds. */
+ int64_t year, days, hours, minutes, seconds;
+ int i, invalid_year, dpm;
+
+ /* Initialize time_out to 0 for now, to avoid bad usage in case this function
+ fails and the caller ignores the return value. */
+ tor_assert(time_out);
+ *time_out = 0;
+
+ /* avoid int overflow on addition */
+ if (tm->tm_year < INT32_MAX-1900) {
+ year = tm->tm_year + 1900;
+ } else {
+ /* clamp year */
+ year = INT32_MAX;
+ }
+ invalid_year = (year < 1970 || tm->tm_year >= INT32_MAX-1900);
+
+ if (tm->tm_mon >= 0 && tm->tm_mon <= 11) {
+ dpm = days_per_month[tm->tm_mon];
+ if (tm->tm_mon == 1 && !invalid_year && IS_LEAPYEAR(tm->tm_year)) {
+ dpm = 29;
+ }
+ } else {
+ /* invalid month - default to 0 days per month */
+ dpm = 0;
+ }
+
+ if (invalid_year ||
+ tm->tm_mon < 0 || tm->tm_mon > 11 ||
+ tm->tm_mday < 1 || tm->tm_mday > dpm ||
+ tm->tm_hour < 0 || tm->tm_hour > 23 ||
+ tm->tm_min < 0 || tm->tm_min > 59 ||
+ tm->tm_sec < 0 || tm->tm_sec > 60) {
+ log_warn(LD_BUG, "Out-of-range argument to tor_timegm");
+ return -1;
+ }
+ days = 365 * (year-1970) + n_leapdays(1970,(int)year);
+ for (i = 0; i < tm->tm_mon; ++i)
+ days += days_per_month[i];
+ if (tm->tm_mon > 1 && IS_LEAPYEAR(year))
+ ++days;
+ days += tm->tm_mday - 1;
+ hours = days*24 + tm->tm_hour;
+
+ minutes = hours*60 + tm->tm_min;
+ seconds = minutes*60 + tm->tm_sec;
+ /* Check that "seconds" will fit in a time_t. On platforms where time_t is
+ * 32-bit, this check will fail for dates in and after 2038.
+ *
+ * We already know that "seconds" can't be negative because "year" >= 1970 */
+#if SIZEOF_TIME_T < 8
+ if (seconds < TIME_MIN || seconds > TIME_MAX) {
+ log_warn(LD_BUG, "Result does not fit in tor_timegm");
+ return -1;
+ }
+#endif /* SIZEOF_TIME_T < 8 */
+ *time_out = (time_t)seconds;
+ return 0;
+}
+
+/* strftime is locale-specific, so we need to replace those parts */
+
+/** A c-locale array of 3-letter names of weekdays, starting with Sun. */
+static const char *WEEKDAY_NAMES[] =
+ { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+/** A c-locale array of 3-letter names of months, starting with Jan. */
+static const char *MONTH_NAMES[] =
+ { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+/** Set <b>buf</b> to the RFC1123 encoding of the UTC value of <b>t</b>.
+ * The buffer must be at least RFC1123_TIME_LEN+1 bytes long.
+ *
+ * (RFC1123 format is "Fri, 29 Sep 2006 15:54:20 GMT". Note the "GMT"
+ * rather than "UTC".)
+ */
+void
+format_rfc1123_time(char *buf, time_t t)
+{
+ struct tm tm;
+
+ tor_gmtime_r(&t, &tm);
+
+ strftime(buf, RFC1123_TIME_LEN+1, "___, %d ___ %Y %H:%M:%S GMT", &tm);
+ tor_assert(tm.tm_wday >= 0);
+ tor_assert(tm.tm_wday <= 6);
+ memcpy(buf, WEEKDAY_NAMES[tm.tm_wday], 3);
+ tor_assert(tm.tm_mon >= 0);
+ tor_assert(tm.tm_mon <= 11);
+ memcpy(buf+8, MONTH_NAMES[tm.tm_mon], 3);
+}
+
+/** Parse the (a subset of) the RFC1123 encoding of some time (in UTC) from
+ * <b>buf</b>, and store the result in *<b>t</b>.
+ *
+ * Note that we only accept the subset generated by format_rfc1123_time above,
+ * not the full range of formats suggested by RFC 1123.
+ *
+ * Return 0 on success, -1 on failure.
+*/
+int
+parse_rfc1123_time(const char *buf, time_t *t)
+{
+ struct tm tm;
+ char month[4];
+ char weekday[4];
+ int i, m, invalid_year;
+ unsigned tm_mday, tm_year, tm_hour, tm_min, tm_sec;
+ unsigned dpm;
+
+ if (strlen(buf) != RFC1123_TIME_LEN)
+ return -1;
+ memset(&tm, 0, sizeof(tm));
+ if (tor_sscanf(buf, "%3s, %2u %3s %u %2u:%2u:%2u GMT", weekday,
+ &tm_mday, month, &tm_year, &tm_hour,
+ &tm_min, &tm_sec) < 7) {
+ char *esc = esc_for_log(buf);
+ log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
+ tor_free(esc);
+ return -1;
+ }
+
+ m = -1;
+ for (i = 0; i < 12; ++i) {
+ if (!strcmp(month, MONTH_NAMES[i])) {
+ m = i;
+ break;
+ }
+ }
+ if (m<0) {
+ char *esc = esc_for_log(buf);
+ log_warn(LD_GENERAL, "Got invalid RFC1123 time %s: No such month", esc);
+ tor_free(esc);
+ return -1;
+ }
+ tm.tm_mon = m;
+
+ invalid_year = (tm_year >= INT32_MAX || tm_year < 1970);
+ tor_assert(m >= 0 && m <= 11);
+ dpm = days_per_month[m];
+ if (m == 1 && !invalid_year && IS_LEAPYEAR(tm_year)) {
+ dpm = 29;
+ }
+
+ if (invalid_year || tm_mday < 1 || tm_mday > dpm ||
+ tm_hour > 23 || tm_min > 59 || tm_sec > 60) {
+ char *esc = esc_for_log(buf);
+ log_warn(LD_GENERAL, "Got invalid RFC1123 time %s", esc);
+ tor_free(esc);
+ return -1;
+ }
+ tm.tm_mday = (int)tm_mday;
+ tm.tm_year = (int)tm_year;
+ tm.tm_hour = (int)tm_hour;
+ tm.tm_min = (int)tm_min;
+ tm.tm_sec = (int)tm_sec;
+
+ if (tm.tm_year < 1970) {
+ /* LCOV_EXCL_START
+ * XXXX I think this is dead code; we already checked for
+ * invalid_year above. */
+ tor_assert_nonfatal_unreached();
+ char *esc = esc_for_log(buf);
+ log_warn(LD_GENERAL,
+ "Got invalid RFC1123 time %s. (Before 1970)", esc);
+ tor_free(esc);
+ return -1;
+ /* LCOV_EXCL_STOP */
+ }
+ tm.tm_year -= 1900;
+
+ return tor_timegm(&tm, t);
+}
+
+/** Set <b>buf</b> to the ISO8601 encoding of the local value of <b>t</b>.
+ * The buffer must be at least ISO_TIME_LEN+1 bytes long.
+ *
+ * (ISO8601 format is 2006-10-29 10:57:20)
+ */
+void
+format_local_iso_time(char *buf, time_t t)
+{
+ struct tm tm;
+ strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_localtime_r(&t, &tm));
+}
+
+/** Set <b>buf</b> to the ISO8601 encoding of the GMT value of <b>t</b>.
+ * The buffer must be at least ISO_TIME_LEN+1 bytes long.
+ */
+void
+format_iso_time(char *buf, time_t t)
+{
+ struct tm tm;
+ strftime(buf, ISO_TIME_LEN+1, "%Y-%m-%d %H:%M:%S", tor_gmtime_r(&t, &tm));
+}
+
+/** As format_local_iso_time, but use the yyyy-mm-ddThh:mm:ss format to avoid
+ * embedding an internal space. */
+void
+format_local_iso_time_nospace(char *buf, time_t t)
+{
+ format_local_iso_time(buf, t);
+ buf[10] = 'T';
+}
+
+/** As format_iso_time, but use the yyyy-mm-ddThh:mm:ss format to avoid
+ * embedding an internal space. */
+void
+format_iso_time_nospace(char *buf, time_t t)
+{
+ format_iso_time(buf, t);
+ buf[10] = 'T';
+}
+
+/** As format_iso_time_nospace, but include microseconds in decimal
+ * fixed-point format. Requires that buf be at least ISO_TIME_USEC_LEN+1
+ * bytes long. */
+void
+format_iso_time_nospace_usec(char *buf, const struct timeval *tv)
+{
+ tor_assert(tv);
+ format_iso_time_nospace(buf, (time_t)tv->tv_sec);
+ tor_snprintf(buf+ISO_TIME_LEN, 8, ".%06d", (int)tv->tv_usec);
+}
+
+/** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>,
+ * parse it and store its value in *<b>t</b>. Return 0 on success, -1 on
+ * failure. Ignore extraneous stuff in <b>cp</b> after the end of the time
+ * string, unless <b>strict</b> is set. If <b>nospace</b> is set,
+ * expect the YYYY-MM-DDTHH:MM:SS format. */
+int
+parse_iso_time_(const char *cp, time_t *t, int strict, int nospace)
+{
+ struct tm st_tm;
+ unsigned int year=0, month=0, day=0, hour=0, minute=0, second=0;
+ int n_fields;
+ char extra_char, separator_char;
+ n_fields = tor_sscanf(cp, "%u-%2u-%2u%c%2u:%2u:%2u%c",
+ &year, &month, &day,
+ &separator_char,
+ &hour, &minute, &second, &extra_char);
+ if (strict ? (n_fields != 7) : (n_fields < 7)) {
+ char *esc = esc_for_log(cp);
+ log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
+ tor_free(esc);
+ return -1;
+ }
+ if (separator_char != (nospace ? 'T' : ' ')) {
+ char *esc = esc_for_log(cp);
+ log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
+ tor_free(esc);
+ return -1;
+ }
+ if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
+ hour > 23 || minute > 59 || second > 60 || year >= INT32_MAX) {
+ char *esc = esc_for_log(cp);
+ log_warn(LD_GENERAL, "ISO time %s was nonsensical", esc);
+ tor_free(esc);
+ return -1;
+ }
+ st_tm.tm_year = (int)year-1900;
+ st_tm.tm_mon = month-1;
+ st_tm.tm_mday = day;
+ st_tm.tm_hour = hour;
+ st_tm.tm_min = minute;
+ st_tm.tm_sec = second;
+ st_tm.tm_wday = 0; /* Should be ignored. */
+
+ if (st_tm.tm_year < 70) {
+ /* LCOV_EXCL_START
+ * XXXX I think this is dead code; we already checked for
+ * year < 1970 above. */
+ tor_assert_nonfatal_unreached();
+ char *esc = esc_for_log(cp);
+ log_warn(LD_GENERAL, "Got invalid ISO time %s. (Before 1970)", esc);
+ tor_free(esc);
+ return -1;
+ /* LCOV_EXCL_STOP */
+ }
+ return tor_timegm(&st_tm, t);
+}
+
+/** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>,
+ * parse it and store its value in *<b>t</b>. Return 0 on success, -1 on
+ * failure. Reject the string if any characters are present after the time.
+ */
+int
+parse_iso_time(const char *cp, time_t *t)
+{
+ return parse_iso_time_(cp, t, 1, 0);
+}
+
+/**
+ * As parse_iso_time, but parses a time encoded by format_iso_time_nospace().
+ */
+int
+parse_iso_time_nospace(const char *cp, time_t *t)
+{
+ return parse_iso_time_(cp, t, 1, 1);
+}
+
+/** Given a <b>date</b> in one of the three formats allowed by HTTP (ugh),
+ * parse it into <b>tm</b>. Return 0 on success, negative on failure. */
+int
+parse_http_time(const char *date, struct tm *tm)
+{
+ const char *cp;
+ char month[4];
+ char wkday[4];
+ int i;
+ unsigned tm_mday, tm_year, tm_hour, tm_min, tm_sec;
+
+ tor_assert(tm);
+ memset(tm, 0, sizeof(*tm));
+
+ /* First, try RFC1123 or RFC850 format: skip the weekday. */
+ if ((cp = strchr(date, ','))) {
+ ++cp;
+ if (*cp != ' ')
+ return -1;
+ ++cp;
+ if (tor_sscanf(cp, "%2u %3s %4u %2u:%2u:%2u GMT",
+ &tm_mday, month, &tm_year,
+ &tm_hour, &tm_min, &tm_sec) == 6) {
+ /* rfc1123-date */
+ tm_year -= 1900;
+ } else if (tor_sscanf(cp, "%2u-%3s-%2u %2u:%2u:%2u GMT",
+ &tm_mday, month, &tm_year,
+ &tm_hour, &tm_min, &tm_sec) == 6) {
+ /* rfc850-date */
+ } else {
+ return -1;
+ }
+ } else {
+ /* No comma; possibly asctime() format. */
+ if (tor_sscanf(date, "%3s %3s %2u %2u:%2u:%2u %4u",
+ wkday, month, &tm_mday,
+ &tm_hour, &tm_min, &tm_sec, &tm_year) == 7) {
+ tm_year -= 1900;
+ } else {
+ return -1;
+ }
+ }
+ tm->tm_mday = (int)tm_mday;
+ tm->tm_year = (int)tm_year;
+ tm->tm_hour = (int)tm_hour;
+ tm->tm_min = (int)tm_min;
+ tm->tm_sec = (int)tm_sec;
+ tm->tm_wday = 0; /* Leave this unset. */
+
+ month[3] = '\0';
+ /* Okay, now decode the month. */
+ /* set tm->tm_mon to dummy value so the check below fails. */
+ tm->tm_mon = -1;
+ for (i = 0; i < 12; ++i) {
+ if (!strcasecmp(MONTH_NAMES[i], month)) {
+ tm->tm_mon = i;
+ }
+ }
+
+ if (tm->tm_year < 0 ||
+ tm->tm_mon < 0 || tm->tm_mon > 11 ||
+ tm->tm_mday < 1 || tm->tm_mday > 31 ||
+ tm->tm_hour < 0 || tm->tm_hour > 23 ||
+ tm->tm_min < 0 || tm->tm_min > 59 ||
+ tm->tm_sec < 0 || tm->tm_sec > 60)
+ return -1; /* Out of range, or bad month. */
+
+ return 0;
+}
+
+/** Given an <b>interval</b> in seconds, try to write it to the
+ * <b>out_len</b>-byte buffer in <b>out</b> in a human-readable form.
+ * Returns a non-negative integer on success, -1 on failure.
+ */
+int
+format_time_interval(char *out, size_t out_len, long interval)
+{
+ /* We only report seconds if there's no hours. */
+ long sec = 0, min = 0, hour = 0, day = 0;
+
+ /* -LONG_MIN is LONG_MAX + 1, which causes signed overflow */
+ if (interval < -LONG_MAX)
+ interval = LONG_MAX;
+ else if (interval < 0)
+ interval = -interval;
+
+ if (interval >= 86400) {
+ day = interval / 86400;
+ interval %= 86400;
+ }
+ if (interval >= 3600) {
+ hour = interval / 3600;
+ interval %= 3600;
+ }
+ if (interval >= 60) {
+ min = interval / 60;
+ interval %= 60;
+ }
+ sec = interval;
+
+ if (day) {
+ return tor_snprintf(out, out_len, "%ld days, %ld hours, %ld minutes",
+ day, hour, min);
+ } else if (hour) {
+ return tor_snprintf(out, out_len, "%ld hours, %ld minutes", hour, min);
+ } else if (min) {
+ return tor_snprintf(out, out_len, "%ld minutes, %ld seconds", min, sec);
+ } else {
+ return tor_snprintf(out, out_len, "%ld seconds", sec);
+ }
+}
diff --git a/src/lib/encoding/time_fmt.h b/src/lib/encoding/time_fmt.h
new file mode 100644
index 000000000..41508ce5e
--- /dev/null
+++ b/src/lib/encoding/time_fmt.h
@@ -0,0 +1,38 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-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_TIME_FMT_H
+#define TOR_TIME_FMT_H
+
+#include "orconfig.h"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+struct tm;
+struct timeval;
+
+struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
+struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
+int tor_timegm(const struct tm *tm, time_t *time_out);
+
+#define RFC1123_TIME_LEN 29
+void format_rfc1123_time(char *buf, time_t t);
+int parse_rfc1123_time(const char *buf, time_t *t);
+#define ISO_TIME_LEN 19
+#define ISO_TIME_USEC_LEN (ISO_TIME_LEN+7)
+void format_local_iso_time(char *buf, time_t t);
+void format_iso_time(char *buf, time_t t);
+void format_local_iso_time_nospace(char *buf, time_t t);
+void format_iso_time_nospace(char *buf, time_t t);
+void format_iso_time_nospace_usec(char *buf, const struct timeval *tv);
+int parse_iso_time_(const char *cp, time_t *t, int strict, int nospace);
+int parse_iso_time(const char *buf, time_t *t);
+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);
+
+#endif
1
0

[tor/master] Move confline.c to lib/encoding: it is about encoding key-value pairs
by nickm@torproject.org 27 Jun '18
by nickm@torproject.org 27 Jun '18
27 Jun '18
commit b9b44bf000735135e1913fd9c22cd6c1547dbdb3
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Jun 27 16:52:39 2018 -0400
Move confline.c to lib/encoding: it is about encoding key-value pairs
Also, move "unescape_string()" to encoding too, since it's about
encoding data as C strings.
---
src/common/include.am | 2 -
src/common/util.c | 119 ----------------------------
src/common/util.h | 3 +-
src/{common => lib/encoding}/confline.c | 15 ++--
src/{common => lib/encoding}/confline.h | 0
src/lib/encoding/cstring.c | 132 ++++++++++++++++++++++++++++++++
src/lib/encoding/cstring.h | 13 ++++
src/lib/encoding/include.am | 4 +
8 files changed, 160 insertions(+), 128 deletions(-)
diff --git a/src/common/include.am b/src/common/include.am
index 4fd3284ab..14e7dcb9f 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -36,7 +36,6 @@ LIBOR_A_SRC = \
src/common/compat.c \
src/common/compat_threads.c \
src/common/compat_time.c \
- src/common/confline.c \
src/common/conffile.c \
src/common/memarea.c \
src/common/util.c \
@@ -81,7 +80,6 @@ COMMONHEADERS = \
src/common/compat_threads.h \
src/common/compat_time.h \
src/common/conffile.h \
- src/common/confline.h \
src/common/handles.h \
src/common/memarea.h \
src/common/procmon.h \
diff --git a/src/common/util.c b/src/common/util.c
index 28efa4a04..f641c1081 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -453,125 +453,6 @@ tv_to_msec(const struct timeval *tv)
* Filesystem operations.
*/
-#define TOR_ISODIGIT(c) ('0' <= (c) && (c) <= '7')
-
-/** Given a c-style double-quoted escaped string in <b>s</b>, extract and
- * decode its contents into a newly allocated string. On success, assign this
- * string to *<b>result</b>, assign its length to <b>size_out</b> (if
- * provided), and return a pointer to the position in <b>s</b> immediately
- * after the string. On failure, return NULL.
- */
-const char *
-unescape_string(const char *s, char **result, size_t *size_out)
-{
- const char *cp;
- char *out;
- if (s[0] != '\"')
- return NULL;
- cp = s+1;
- while (1) {
- switch (*cp) {
- case '\0':
- case '\n':
- return NULL;
- case '\"':
- goto end_of_loop;
- case '\\':
- if (cp[1] == 'x' || cp[1] == 'X') {
- if (!(TOR_ISXDIGIT(cp[2]) && TOR_ISXDIGIT(cp[3])))
- return NULL;
- cp += 4;
- } else if (TOR_ISODIGIT(cp[1])) {
- cp += 2;
- if (TOR_ISODIGIT(*cp)) ++cp;
- if (TOR_ISODIGIT(*cp)) ++cp;
- } else if (cp[1] == 'n' || cp[1] == 'r' || cp[1] == 't' || cp[1] == '"'
- || cp[1] == '\\' || cp[1] == '\'') {
- cp += 2;
- } else {
- return NULL;
- }
- break;
- default:
- ++cp;
- break;
- }
- }
- end_of_loop:
- out = *result = tor_malloc(cp-s + 1);
- cp = s+1;
- while (1) {
- switch (*cp)
- {
- case '\"':
- *out = '\0';
- if (size_out) *size_out = out - *result;
- return cp+1;
-
- /* LCOV_EXCL_START -- we caught this in parse_config_from_line. */
- case '\0':
- tor_fragile_assert();
- tor_free(*result);
- return NULL;
- /* LCOV_EXCL_STOP */
- case '\\':
- switch (cp[1])
- {
- case 'n': *out++ = '\n'; cp += 2; break;
- case 'r': *out++ = '\r'; cp += 2; break;
- case 't': *out++ = '\t'; cp += 2; break;
- case 'x': case 'X':
- {
- int x1, x2;
-
- x1 = hex_decode_digit(cp[2]);
- x2 = hex_decode_digit(cp[3]);
- if (x1 == -1 || x2 == -1) {
- /* LCOV_EXCL_START */
- /* we caught this above in the initial loop. */
- tor_assert_nonfatal_unreached();
- tor_free(*result);
- return NULL;
- /* LCOV_EXCL_STOP */
- }
-
- *out++ = ((x1<<4) + x2);
- cp += 4;
- }
- break;
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7':
- {
- int n = cp[1]-'0';
- cp += 2;
- if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; }
- if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; }
- if (n > 255) { tor_free(*result); return NULL; }
- *out++ = (char)n;
- }
- break;
- case '\'':
- case '\"':
- case '\\':
- case '\?':
- *out++ = cp[1];
- cp += 2;
- break;
-
- /* LCOV_EXCL_START */
- default:
- /* we caught this above in the initial loop. */
- tor_assert_nonfatal_unreached();
- tor_free(*result); return NULL;
- /* LCOV_EXCL_STOP */
- }
- break;
- default:
- *out++ = *cp++;
- }
- }
-}
-
/* =====
* Process helpers
* ===== */
diff --git a/src/common/util.h b/src/common/util.h
index 7547b8708..549bbf9aa 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -39,6 +39,7 @@
#include "lib/fs/files.h"
#include "lib/fs/path.h"
#include "lib/encoding/time_fmt.h"
+#include "lib/encoding/cstring.h"
void tor_log_mallinfo(int severity);
@@ -102,8 +103,6 @@ const char *stream_status_to_string(enum stream_status stream_status);
enum stream_status get_string_from_pipe(int fd, char *buf, size_t count);
-const char *unescape_string(const char *s, char **result, size_t *size_out);
-
/* Process helpers */
void start_daemon(void);
void finish_daemon(const char *desired_cwd);
diff --git a/src/common/confline.c b/src/lib/encoding/confline.c
similarity index 96%
rename from src/common/confline.c
rename to src/lib/encoding/confline.c
index 80e5994ce..7f535b321 100644
--- a/src/common/confline.c
+++ b/src/lib/encoding/confline.c
@@ -4,11 +4,16 @@
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "common/compat.h"
-#include "common/confline.h"
+#include "lib/encoding/confline.h"
+#include "lib/encoding/cstring.h"
#include "lib/log/torlog.h"
-#include "common/util.h"
-#include "lib/container/smartlist.h"
+#include "lib/log/util_bug.h"
+#include "lib/malloc/util_malloc.h"
+#include "lib/string/compat_ctype.h"
+#include "lib/string/compat_string.h"
+#include "lib/string/util_string.h"
+
+#include <string.h>
/** Helper: allocate a new configuration option mapping 'key' to 'val',
* append it to *<b>lst</b>. */
@@ -74,7 +79,7 @@ config_line_find(const config_line_t *lines,
int
config_get_lines_aux(const char *string, config_line_t **result, int extended,
int allow_include, int *has_include,
- smartlist_t *opened_lst, int recursion_level,
+ struct smartlist_t *opened_lst, int recursion_level,
config_line_t **last,
include_handler_fn handle_include)
{
diff --git a/src/common/confline.h b/src/lib/encoding/confline.h
similarity index 100%
rename from src/common/confline.h
rename to src/lib/encoding/confline.h
diff --git a/src/lib/encoding/cstring.c b/src/lib/encoding/cstring.c
new file mode 100644
index 000000000..86c17f0d2
--- /dev/null
+++ b/src/lib/encoding/cstring.c
@@ -0,0 +1,132 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-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/encoding/cstring.h"
+#include "lib/log/torlog.h"
+#include "lib/log/util_bug.h"
+#include "lib/malloc/util_malloc.h"
+#include "lib/string/compat_ctype.h"
+
+#include <string.h>
+
+#define TOR_ISODIGIT(c) ('0' <= (c) && (c) <= '7')
+
+/** Given a c-style double-quoted escaped string in <b>s</b>, extract and
+ * decode its contents into a newly allocated string. On success, assign this
+ * string to *<b>result</b>, assign its length to <b>size_out</b> (if
+ * provided), and return a pointer to the position in <b>s</b> immediately
+ * after the string. On failure, return NULL.
+ */
+const char *
+unescape_string(const char *s, char **result, size_t *size_out)
+{
+ const char *cp;
+ char *out;
+ if (s[0] != '\"')
+ return NULL;
+ cp = s+1;
+ while (1) {
+ switch (*cp) {
+ case '\0':
+ case '\n':
+ return NULL;
+ case '\"':
+ goto end_of_loop;
+ case '\\':
+ if (cp[1] == 'x' || cp[1] == 'X') {
+ if (!(TOR_ISXDIGIT(cp[2]) && TOR_ISXDIGIT(cp[3])))
+ return NULL;
+ cp += 4;
+ } else if (TOR_ISODIGIT(cp[1])) {
+ cp += 2;
+ if (TOR_ISODIGIT(*cp)) ++cp;
+ if (TOR_ISODIGIT(*cp)) ++cp;
+ } else if (cp[1] == 'n' || cp[1] == 'r' || cp[1] == 't' || cp[1] == '"'
+ || cp[1] == '\\' || cp[1] == '\'') {
+ cp += 2;
+ } else {
+ return NULL;
+ }
+ break;
+ default:
+ ++cp;
+ break;
+ }
+ }
+ end_of_loop:
+ out = *result = tor_malloc(cp-s + 1);
+ cp = s+1;
+ while (1) {
+ switch (*cp)
+ {
+ case '\"':
+ *out = '\0';
+ if (size_out) *size_out = out - *result;
+ return cp+1;
+
+ /* LCOV_EXCL_START -- we caught this in parse_config_from_line. */
+ case '\0':
+ tor_fragile_assert();
+ tor_free(*result);
+ return NULL;
+ /* LCOV_EXCL_STOP */
+ case '\\':
+ switch (cp[1])
+ {
+ case 'n': *out++ = '\n'; cp += 2; break;
+ case 'r': *out++ = '\r'; cp += 2; break;
+ case 't': *out++ = '\t'; cp += 2; break;
+ case 'x': case 'X':
+ {
+ int x1, x2;
+
+ x1 = hex_decode_digit(cp[2]);
+ x2 = hex_decode_digit(cp[3]);
+ if (x1 == -1 || x2 == -1) {
+ /* LCOV_EXCL_START */
+ /* we caught this above in the initial loop. */
+ tor_assert_nonfatal_unreached();
+ tor_free(*result);
+ return NULL;
+ /* LCOV_EXCL_STOP */
+ }
+
+ *out++ = ((x1<<4) + x2);
+ cp += 4;
+ }
+ break;
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7':
+ {
+ int n = cp[1]-'0';
+ cp += 2;
+ if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; }
+ if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; }
+ if (n > 255) { tor_free(*result); return NULL; }
+ *out++ = (char)n;
+ }
+ break;
+ case '\'':
+ case '\"':
+ case '\\':
+ case '\?':
+ *out++ = cp[1];
+ cp += 2;
+ break;
+
+ /* LCOV_EXCL_START */
+ default:
+ /* we caught this above in the initial loop. */
+ tor_assert_nonfatal_unreached();
+ tor_free(*result); return NULL;
+ /* LCOV_EXCL_STOP */
+ }
+ break;
+ default:
+ *out++ = *cp++;
+ }
+ }
+}
diff --git a/src/lib/encoding/cstring.h b/src/lib/encoding/cstring.h
new file mode 100644
index 000000000..3dff5e7f7
--- /dev/null
+++ b/src/lib/encoding/cstring.h
@@ -0,0 +1,13 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-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_CSTRING_H
+#define TOR_CSTRING_H
+
+#include <stddef.h>
+const char *unescape_string(const char *s, char **result, size_t *size_out);
+
+#endif /* !defined(TOR_CSTRING_H) */
diff --git a/src/lib/encoding/include.am b/src/lib/encoding/include.am
index 345fe14e1..93f515dd4 100644
--- a/src/lib/encoding/include.am
+++ b/src/lib/encoding/include.am
@@ -6,6 +6,8 @@ endif
src_lib_libtor_encoding_a_SOURCES = \
src/lib/encoding/binascii.c \
+ src/lib/encoding/confline.c \
+ src/lib/encoding/cstring.c \
src/lib/encoding/time_fmt.c
src_lib_libtor_encoding_testing_a_SOURCES = \
@@ -15,4 +17,6 @@ src_lib_libtor_encoding_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
noinst_HEADERS += \
src/lib/encoding/binascii.h \
+ src/lib/encoding/confline.h \
+ src/lib/encoding/cstring.h \
src/lib/encoding/time_fmt.h
1
0

[torbutton/master] Bug 26500: Reposition circuit display relay icon for RTL locales
by gk@torproject.org 27 Jun '18
by gk@torproject.org 27 Jun '18
27 Jun '18
commit b61ed65010816c8ceb4361dbd02a278347dca91b
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Mon Jun 25 11:37:47 2018 -0700
Bug 26500: Reposition circuit display relay icon for RTL locales
It seems -moz-locale-dir(rtl) works in XUL; dir(rtl) does not.
---
src/chrome/skin/tor-circuit-display.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/chrome/skin/tor-circuit-display.css b/src/chrome/skin/tor-circuit-display.css
index c9e682a..ed17f91 100644
--- a/src/chrome/skin/tor-circuit-display.css
+++ b/src/chrome/skin/tor-circuit-display.css
@@ -21,7 +21,7 @@ and lines drawn between them to represent Tor network inter-relay connections.
width: 100%;
}
-#circuit-display-content:dir(rtl) {
+#circuit-display-content:-moz-locale-dir(rtl) {
background-position: calc(100% - 1em) 1em;
}
1
0

[tor-browser-build/master] Add newline at the end of projects/release/update_responses_config.yml
by boklm@torproject.org 27 Jun '18
by boklm@torproject.org 27 Jun '18
27 Jun '18
commit 7a338d60a3106b70d411a6ebd1095bf3bc6862f4
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Wed Jun 27 22:11:42 2018 +0200
Add newline at the end of projects/release/update_responses_config.yml
---
projects/release/update_responses_config.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/release/update_responses_config.yml b/projects/release/update_responses_config.yml
index 0c49fe1..92c2203 100644
--- a/projects/release/update_responses_config.yml
+++ b/projects/release/update_responses_config.yml
@@ -46,4 +46,4 @@ versions:
win32:
minSupportedOSVersion: 6.1
win64:
- minSupportedOSVersion: 6.1
\ No newline at end of file
+ minSupportedOSVersion: 6.1
1
0