Browse Source

Separate is-recognized-option from get-option-value, since NULL is ambiguous and returning "" misrepresents.

svn:r2731
Nick Mathewson 21 years ago
parent
commit
48a0b6c476
3 changed files with 24 additions and 5 deletions
  1. 18 2
      src/or/config.c
  2. 5 3
      src/or/control.c
  3. 1 0
      src/or/or.h

+ 18 - 2
src/or/config.c

@@ -255,7 +255,7 @@ options_act(void) {
   if (options->command != CMD_RUN_TOR)
     return 0;
 
-  if (set_max_file_descriptors(get_options()->MaxConn) < 0)
+  if (set_max_file_descriptors(options->MaxConn) < 0)
     return -1;
 
   /* Configure the log(s) */
@@ -542,6 +542,14 @@ config_reset_line(or_options_t *options, const char *key)
   option_reset(options, var);
 }
 
+/** Return true iff key is a valid configuration option. */
+int
+config_option_is_recognized(const char *key)
+{
+  config_var_t *var = config_find_option(key);
+  return (var != NULL);
+}
+
 /** Return a canonicalized list of the options assigned for key.
  */
 struct config_line_t *
@@ -551,6 +559,7 @@ config_get_assigned_option(or_options_t *options, const char *key)
   const void *value;
   char buf[32];
   struct config_line_t *result;
+  tor_assert(options && key);
 
   var = config_find_option(key);
   if (!var) {
@@ -583,7 +592,13 @@ config_get_assigned_option(or_options_t *options, const char *key)
   switch(var->type)
     {
     case CONFIG_TYPE_STRING:
-      result->value = tor_strdup(*(char**)value ? *(char**)value : "");
+      if (*(char**)value) {
+        result->value = tor_strdup(*(char**)value);
+      } else {
+        tor_free(result->key);
+        tor_free(result);
+        return NULL;
+      }
       break;
     case CONFIG_TYPE_UINT:
       /* XXX This means every or_options_t uint or bool element
@@ -633,6 +648,7 @@ static int
 config_assign(or_options_t *options, struct config_line_t *list, int reset)
 {
   struct config_line_t *p;
+  tor_assert(options);
 
   /* pass 1: normalize keys */
   for (p = list; p; p = p->next) {

+ 5 - 3
src/or/control.c

@@ -146,7 +146,7 @@ send_control_message(connection_t *conn, uint16_t type, uint16_t len,
 {
   char buf[4];
   tor_assert(conn);
-  tor_assert(len || !body);
+  tor_assert(len || !body || !strlen(body));
   tor_assert(type <= _CONTROL_CMD_MAX_RECOGNIZED);
   set_uint32(buf, htons(len));
   set_uint32(buf+2, htons(type));
@@ -249,11 +249,13 @@ handle_control_getconf(connection_t *conn, uint16_t body_len, const char *body)
   answers = smartlist_create();
   SMARTLIST_FOREACH(questions, const char *, q,
   {
-    struct config_line_t *answer = config_get_assigned_option(options,q);
-    if (!answer) {
+    int recognized = config_option_is_recognized(q);
+    if (!recognized) {
       send_control_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, body);
       goto done;
     } else {
+      struct config_line_t *answer = config_get_assigned_option(options,q);
+
       while (answer) {
         struct config_line_t *next;
         size_t alen = strlen(answer->key)+strlen(answer->value)+2;

+ 1 - 0
src/or/or.h

@@ -1106,6 +1106,7 @@ void config_parse_exit_policy(struct config_line_t *cfg,
                               struct exit_policy_t **dest);
 void exit_policy_free(struct exit_policy_t *p);
 const char *get_data_directory(void);
+int config_option_is_recognized(const char *key);
 struct config_line_t *config_get_assigned_option(or_options_t *options,
                                                  const char *key);
 struct config_line_t *config_line_prepend(struct config_line_t *front,