Tor  0.4.7.0-alpha-dev
qstring.c
Go to the documentation of this file.
1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2  * Copyright (c) 2007-2021, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
4 
5 /**
6  * \file qstring.c
7  * \brief Implement QuotedString parsing.
8  *
9  * Note that this is only used for controller authentication; do not
10  * create new users for this. Instead, prefer the cstring.c functions.
11  **/
12 
13 #include "orconfig.h"
14 #include "lib/encoding/qstring.h"
15 #include "lib/malloc/malloc.h"
16 #include "lib/log/util_bug.h"
17 
18 /** If the first <b>in_len_max</b> characters in <b>start</b> contain a
19  * QuotedString, return the length of that
20  * string (as encoded, including quotes). Otherwise return -1. */
21 static inline int
22 get_qstring_length(const char *start, size_t in_len_max,
23  int *chars_out)
24 {
25  const char *cp, *end;
26  int chars = 0;
27 
28  if (*start != '\"')
29  return -1;
30 
31  cp = start+1;
32  end = start+in_len_max;
33 
34  /* Calculate length. */
35  while (1) {
36  if (cp >= end) {
37  return -1; /* Too long. */
38  } else if (*cp == '\\') {
39  if (++cp == end)
40  return -1; /* Can't escape EOS. */
41  ++cp;
42  ++chars;
43  } else if (*cp == '\"') {
44  break;
45  } else {
46  ++cp;
47  ++chars;
48  }
49  }
50  if (chars_out)
51  *chars_out = chars;
52  return (int)(cp - start+1);
53 }
54 
55 /** Given a pointer to a string starting at <b>start</b> containing
56  * <b>in_len_max</b> characters, decode a string beginning with one double
57  * quote, containing any number of non-quote characters or characters escaped
58  * with a backslash, and ending with a final double quote. Place the resulting
59  * string (unquoted, unescaped) into a newly allocated string in *<b>out</b>;
60  * store its length in <b>out_len</b>. On success, return a pointer to the
61  * character immediately following the escaped string. On failure, return
62  * NULL. */
63 const char *
64 decode_qstring(const char *start, size_t in_len_max,
65  char **out, size_t *out_len)
66 {
67  const char *cp, *end;
68  char *outp;
69  int len, n_chars = 0;
70 
71  len = get_qstring_length(start, in_len_max, &n_chars);
72  if (len<0)
73  return NULL;
74 
75  end = start+len-1; /* Index of last quote. */
76  tor_assert(*end == '\"');
77  outp = *out = tor_malloc(len+1);
78  *out_len = n_chars;
79 
80  cp = start+1;
81  while (cp < end) {
82  if (*cp == '\\')
83  ++cp;
84  *outp++ = *cp++;
85  }
86  *outp = '\0';
87  tor_assert((outp - *out) == (int)*out_len);
88 
89  return end+1;
90 }
Headers for util_malloc.c.
const char * decode_qstring(const char *start, size_t in_len_max, char **out, size_t *out_len)
Definition: qstring.c:64
static int get_qstring_length(const char *start, size_t in_len_max, int *chars_out)
Definition: qstring.c:22
Header for qstring.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102