Tor  0.4.7.0-alpha-dev
escape.c
Go to the documentation of this file.
1 /* Copyright (c) 2003, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file escape.c
8  * \brief Escape untrusted strings before sending them to the log.
9  **/
10 
11 #include "lib/log/escape.h"
12 #include "lib/log/util_bug.h"
14 #include "lib/string/printf.h"
15 #include "lib/malloc/malloc.h"
16 
17 /** Allocate and return a new string representing the contents of <b>s</b>,
18  * surrounded by quotes and using standard C escapes.
19  *
20  * Generally, we use this for logging values that come in over the network to
21  * keep them from tricking users, and for sending certain values to the
22  * controller.
23  *
24  * We trust values from the resolver, OS, configuration file, and command line
25  * to not be maliciously ill-formed. We validate incoming routerdescs and
26  * SOCKS requests and addresses from BEGIN cells as they're parsed;
27  * afterwards, we trust them as non-malicious.
28  */
29 char *
30 esc_for_log(const char *s)
31 {
32  const char *cp;
33  char *result, *outp;
34  size_t len = 3;
35  if (!s) {
36  return tor_strdup("(null)");
37  }
38 
39  for (cp = s; *cp; ++cp) {
40  switch (*cp) {
41  case '\\':
42  case '\"':
43  case '\'':
44  case '\r':
45  case '\n':
46  case '\t':
47  len += 2;
48  break;
49  default:
50  if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127)
51  ++len;
52  else
53  len += 4;
54  break;
55  }
56  }
57 
58  tor_assert(len <= SSIZE_MAX);
59 
60  result = outp = tor_malloc(len);
61  *outp++ = '\"';
62  for (cp = s; *cp; ++cp) {
63  /* This assertion should always succeed, since we will write at least
64  * one char here, and two chars for closing quote and nul later */
65  tor_assert((outp-result) < (ssize_t)len-2);
66  switch (*cp) {
67  case '\\':
68  case '\"':
69  case '\'':
70  *outp++ = '\\';
71  *outp++ = *cp;
72  break;
73  case '\n':
74  *outp++ = '\\';
75  *outp++ = 'n';
76  break;
77  case '\t':
78  *outp++ = '\\';
79  *outp++ = 't';
80  break;
81  case '\r':
82  *outp++ = '\\';
83  *outp++ = 'r';
84  break;
85  default:
86  if (TOR_ISPRINT(*cp) && ((uint8_t)*cp)<127) {
87  *outp++ = *cp;
88  } else {
89  tor_assert((outp-result) < (ssize_t)len-4);
90  tor_snprintf(outp, 5, "\\%03o", (int)(uint8_t) *cp);
91  outp += 4;
92  }
93  break;
94  }
95  }
96 
97  tor_assert((outp-result) <= (ssize_t)len-2);
98  *outp++ = '\"';
99  *outp++ = 0;
100 
101  return result;
102 }
103 
104 /** Similar to esc_for_log. Allocate and return a new string representing
105  * the first n characters in <b>chars</b>, surround by quotes and using
106  * standard C escapes. If a NUL character is encountered in <b>chars</b>,
107  * the resulting string will be terminated there.
108  */
109 char *
110 esc_for_log_len(const char *chars, size_t n)
111 {
112  char *string = tor_strndup(chars, n);
113  char *string_escaped = esc_for_log(string);
114  tor_free(string);
115  return string_escaped;
116 }
117 
118 /** Allocate and return a new string representing the contents of <b>s</b>,
119  * surrounded by quotes and using standard C escapes.
120  *
121  * THIS FUNCTION IS NOT REENTRANT. Don't call it from outside the main
122  * thread. Also, each call invalidates the last-returned value, so don't
123  * try log_warn(LD_GENERAL, "%s %s", escaped(a), escaped(b));
124  */
125 const char *
126 escaped(const char *s)
127 {
128  static char *escaped_val_ = NULL;
129  tor_free(escaped_val_);
130 
131  if (s)
132  escaped_val_ = esc_for_log(s);
133  else
134  escaped_val_ = NULL;
135 
136  return escaped_val_;
137 }
Locale-independent character-type inspection (header)
const char * escaped(const char *s)
Definition: escape.c:126
char * esc_for_log(const char *s)
Definition: escape.c:30
char * esc_for_log_len(const char *chars, size_t n)
Definition: escape.c:110
Header for escape.c.
Headers for util_malloc.c.
#define tor_free(p)
Definition: malloc.h:52
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
Header for printf.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102