Commit 9265190b authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Merge branch 'bug1384'

parents 73a4c069 a9d055c5
Loading
Loading
Loading
Loading

changes/bug1384

0 → 100644
+5 −0
Original line number Diff line number Diff line
  o Minor features:
    - Warn when the same option is provided more then once in a torrc file,
      on the command line, or in a single SETCONF statement, and option
      is one that only accepts a single value. Closes bug 1384.
+2 −1
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@ OPTIONS
Other options can be specified either on the command-line (--option
    value), or in the configuration file (option value or option "value").
    Options are case-insensitive. C-style escaped characters are allowed inside
    quoted values.
    quoted values.   Options on the command line take precedence over
    options found in the configuration file.

**BandwidthRate** __N__ **bytes**|**KB**|**MB**|**GB**::
    A token bucket limits the average incoming bandwidth usage on this node to
+31 −2
Original line number Diff line number Diff line
@@ -1562,6 +1562,16 @@ config_find_option(config_format_t *fmt, const char *key)
  return NULL;
}

/** Return the number of option entries in <b>fmt</b>. */
static int
config_count_options(config_format_t *fmt)
{
  int i;
  for (i=0; fmt->vars[i].name; ++i)
    ;
  return i;
}

/*
 * Functions to assign config options.
 */
@@ -1706,7 +1716,7 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
static int
config_assign_line(config_format_t *fmt, or_options_t *options,
                   config_line_t *c, int use_defaults,
                   int clear_first, char **msg)
                   int clear_first, bitarray_t *options_seen, char **msg)
{
  config_var_t *var;

@@ -1726,6 +1736,7 @@ config_assign_line(config_format_t *fmt, or_options_t *options,
      return -1;
    }
  }

  /* Put keyword into canonical case. */
  if (strcmp(var->name, c->key)) {
    tor_free(c->key);
@@ -1748,6 +1759,18 @@ config_assign_line(config_format_t *fmt, or_options_t *options,
    return 0;
  }

  if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
                       var->type != CONFIG_TYPE_LINELIST_S)) {
    /* We're tracking which options we've seen, and this option is not
     * supposed to occur more than once. */
    int var_index = (int)(var - fmt->vars);
    if (bitarray_is_set(options_seen, var_index)) {
      log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
               "value will be ignored.", var->name);
    }
    bitarray_set(options_seen, var_index);
  }

  if (config_assign_value(fmt, options, c, msg) < 0)
    return -2;
  return 0;
@@ -2016,6 +2039,8 @@ config_assign(config_format_t *fmt, void *options, config_line_t *list,
              int use_defaults, int clear_first, char **msg)
{
  config_line_t *p;
  bitarray_t *options_seen;
  const int n_options = config_count_options(fmt);

  CHECK(fmt, options);

@@ -2035,14 +2060,18 @@ config_assign(config_format_t *fmt, void *options, config_line_t *list,
      config_reset_line(fmt, options, p->key, use_defaults);
  }

  options_seen = bitarray_init_zero(n_options);
  /* pass 3: assign. */
  while (list) {
    int r;
    if ((r=config_assign_line(fmt, options, list, use_defaults,
                              clear_first, msg)))
                              clear_first, options_seen, msg))) {
      bitarray_free(options_seen);
      return r;
    }
    list = list->next;
  }
  bitarray_free(options_seen);
  return 0;
}