commit 7159edf9090e0a0e4c7d02e80b81bc00083884cc Author: Nick Mathewson nickm@torproject.org Date: Tue Jun 26 20:51:17 2018 -0400
Move the escape-for-log code into src/lib/log
It doesn't need anything higher-level, and everything that needs the logs potentially needs this. --- src/common/util.c | 122 --------------------------------------------- src/common/util.h | 5 +- src/lib/log/escape.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/log/escape.h | 18 +++++++ src/lib/log/include.am | 2 + 5 files changed, 153 insertions(+), 126 deletions(-)
diff --git a/src/common/util.c b/src/common/util.c index fa95f933c..dbde0aa5b 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -559,128 +559,6 @@ tor_parse_uint64(const char *s, int base, uint64_t min, CHECK_STRTOX_RESULT(); }
-/** Allocate and return a new string representing the contents of <b>s</b>, - * surrounded by quotes and using standard C escapes. - * - * Generally, we use this for logging values that come in over the network to - * keep them from tricking users, and for sending certain values to the - * controller. - * - * We trust values from the resolver, OS, configuration file, and command line - * to not be maliciously ill-formed. We validate incoming routerdescs and - * SOCKS requests and addresses from BEGIN cells as they're parsed; - * afterwards, we trust them as non-malicious. - */ -char * -esc_for_log(const char *s) -{ - const char *cp; - char *result, *outp; - size_t len = 3; - if (!s) { - return tor_strdup("(null)"); - } - - for (cp = s; *cp; ++cp) { - switch (*cp) { - case '\': - case '"': - case ''': - case '\r': - case '\n': - case '\t': - len += 2; - break; - default: - if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) - ++len; - else - len += 4; - break; - } - } - - tor_assert(len <= SSIZE_MAX); - - result = outp = tor_malloc(len); - *outp++ = '"'; - for (cp = s; *cp; ++cp) { - /* This assertion should always succeed, since we will write at least - * one char here, and two chars for closing quote and nul later */ - tor_assert((outp-result) < (ssize_t)len-2); - switch (*cp) { - case '\': - case '"': - case ''': - *outp++ = '\'; - *outp++ = *cp; - break; - case '\n': - *outp++ = '\'; - *outp++ = 'n'; - break; - case '\t': - *outp++ = '\'; - *outp++ = 't'; - break; - case '\r': - *outp++ = '\'; - *outp++ = 'r'; - break; - default: - if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) { - *outp++ = *cp; - } else { - tor_assert((outp-result) < (ssize_t)len-4); - tor_snprintf(outp, 5, "\%03o", (int)(uint8_t) *cp); - outp += 4; - } - break; - } - } - - tor_assert((outp-result) <= (ssize_t)len-2); - *outp++ = '"'; - *outp++ = 0; - - return result; -} - -/** Similar to esc_for_log. Allocate and return a new string representing - * the first n characters in <b>chars</b>, surround by quotes and using - * standard C escapes. If a NUL character is encountered in <b>chars</b>, - * the resulting string will be terminated there. - */ -char * -esc_for_log_len(const char *chars, size_t n) -{ - char *string = tor_strndup(chars, n); - char *string_escaped = esc_for_log(string); - tor_free(string); - return string_escaped; -} - -/** Allocate and return a new string representing the contents of <b>s</b>, - * surrounded by quotes and using standard C escapes. - * - * THIS FUNCTION IS NOT REENTRANT. Don't call it from outside the main - * thread. Also, each call invalidates the last-returned value, so don't - * try log_warn(LD_GENERAL, "%s %s", escaped(a), escaped(b)); - */ -const char * -escaped(const char *s) -{ - static char *escaped_val_ = NULL; - tor_free(escaped_val_); - - if (s) - escaped_val_ = esc_for_log(s); - else - escaped_val_ = NULL; - - return escaped_val_; -} - /** 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 d1b4e8fe9..d2c27064e 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -33,6 +33,7 @@ #include "lib/intmath/cmp.h" #include "lib/log/ratelim.h" #include "lib/log/util_bug.h" +#include "lib/log/escape.h"
#ifndef O_BINARY #define O_BINARY 0 @@ -99,10 +100,6 @@ int tor_mem_is_zero(const char *mem, size_t len); int tor_digest_is_zero(const char *digest); int tor_digest256_is_zero(const char *digest);
-char *esc_for_log(const char *string) ATTR_MALLOC; -char *esc_for_log_len(const char *chars, size_t n) ATTR_MALLOC; -const char *escaped(const char *string); - char *tor_escape_str_for_pt_args(const char *string, const char *chars_to_escape);
diff --git a/src/lib/log/escape.c b/src/lib/log/escape.c new file mode 100644 index 000000000..756171030 --- /dev/null +++ b/src/lib/log/escape.c @@ -0,0 +1,132 @@ +/* Copyright (c) 2003, Roger Dingledine + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "lib/log/escape.h" +#include "lib/log/util_bug.h" +#include "lib/string/compat_ctype.h" +#include "lib/string/printf.h" +#include "lib/malloc/util_malloc.h" + +/** Allocate and return a new string representing the contents of <b>s</b>, + * surrounded by quotes and using standard C escapes. + * + * Generally, we use this for logging values that come in over the network to + * keep them from tricking users, and for sending certain values to the + * controller. + * + * We trust values from the resolver, OS, configuration file, and command line + * to not be maliciously ill-formed. We validate incoming routerdescs and + * SOCKS requests and addresses from BEGIN cells as they're parsed; + * afterwards, we trust them as non-malicious. + */ +char * +esc_for_log(const char *s) +{ + const char *cp; + char *result, *outp; + size_t len = 3; + if (!s) { + return tor_strdup("(null)"); + } + + for (cp = s; *cp; ++cp) { + switch (*cp) { + case '\': + case '"': + case ''': + case '\r': + case '\n': + case '\t': + len += 2; + break; + default: + if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) + ++len; + else + len += 4; + break; + } + } + + tor_assert(len <= SSIZE_MAX); + + result = outp = tor_malloc(len); + *outp++ = '"'; + for (cp = s; *cp; ++cp) { + /* This assertion should always succeed, since we will write at least + * one char here, and two chars for closing quote and nul later */ + tor_assert((outp-result) < (ssize_t)len-2); + switch (*cp) { + case '\': + case '"': + case ''': + *outp++ = '\'; + *outp++ = *cp; + break; + case '\n': + *outp++ = '\'; + *outp++ = 'n'; + break; + case '\t': + *outp++ = '\'; + *outp++ = 't'; + break; + case '\r': + *outp++ = '\'; + *outp++ = 'r'; + break; + default: + if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) { + *outp++ = *cp; + } else { + tor_assert((outp-result) < (ssize_t)len-4); + tor_snprintf(outp, 5, "\%03o", (int)(uint8_t) *cp); + outp += 4; + } + break; + } + } + + tor_assert((outp-result) <= (ssize_t)len-2); + *outp++ = '"'; + *outp++ = 0; + + return result; +} + +/** Similar to esc_for_log. Allocate and return a new string representing + * the first n characters in <b>chars</b>, surround by quotes and using + * standard C escapes. If a NUL character is encountered in <b>chars</b>, + * the resulting string will be terminated there. + */ +char * +esc_for_log_len(const char *chars, size_t n) +{ + char *string = tor_strndup(chars, n); + char *string_escaped = esc_for_log(string); + tor_free(string); + return string_escaped; +} + +/** Allocate and return a new string representing the contents of <b>s</b>, + * surrounded by quotes and using standard C escapes. + * + * THIS FUNCTION IS NOT REENTRANT. Don't call it from outside the main + * thread. Also, each call invalidates the last-returned value, so don't + * try log_warn(LD_GENERAL, "%s %s", escaped(a), escaped(b)); + */ +const char * +escaped(const char *s) +{ + static char *escaped_val_ = NULL; + tor_free(escaped_val_); + + if (s) + escaped_val_ = esc_for_log(s); + else + escaped_val_ = NULL; + + return escaped_val_; +} diff --git a/src/lib/log/escape.h b/src/lib/log/escape.h new file mode 100644 index 000000000..5d2e79d6c --- /dev/null +++ b/src/lib/log/escape.h @@ -0,0 +1,18 @@ +/* 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_ESCAPE_H +#define TOR_ESCAPE_H + +#include "orconfig.h" +#include "lib/cc/compat_compiler.h" +#include <stddef.h> + +char *esc_for_log(const char *string) ATTR_MALLOC; +char *esc_for_log_len(const char *chars, size_t n) ATTR_MALLOC; +const char *escaped(const char *string); + +#endif /* !defined(TOR_TORLOG_H) */ diff --git a/src/lib/log/include.am b/src/lib/log/include.am index bbe345de7..235c95fdf 100644 --- a/src/lib/log/include.am +++ b/src/lib/log/include.am @@ -6,6 +6,7 @@ noinst_LIBRARIES += src/lib/libtor-log-testing.a endif
src_lib_libtor_log_a_SOURCES = \ + src/lib/log/escape.c \ src/lib/log/ratelim.c \ src/lib/log/torlog.c \ src/lib/log/util_bug.c @@ -19,6 +20,7 @@ src/lib/log/torlog.$(OBJEXT) \ src/lib/log/src_lib_libtor_log_testing_a-torlog.$(OBJEXT): micro-revision.i
noinst_HEADERS += \ + src/lib/log/escape.h \ src/lib/log/ratelim.h \ src/lib/log/torlog.h \ src/lib/log/util_bug.h