tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

qstring.c (2416B)


      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 }