[tor-commits] [tor/master] Extract field-parsing code for microdesc_parse.c

asn at torproject.org asn at torproject.org
Wed Sep 25 11:13:20 UTC 2019


commit ec368409fa7732a08e85c1bfb254469f02458266
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon Sep 9 15:41:24 2019 -0400

    Extract field-parsing code for microdesc_parse.c
    
    The code here parses the fields from the microdescriptor, including
    possible annotations, and stores them into a microdesc_t object.
    
    This commit is almost pure code movement; I recommend using
    --color-moved to review it.
---
 src/feature/dirparse/microdesc_parse.c | 143 +++++++++++++++++++--------------
 1 file changed, 83 insertions(+), 60 deletions(-)

diff --git a/src/feature/dirparse/microdesc_parse.c b/src/feature/dirparse/microdesc_parse.c
index 29bebbed3..5af4c60cb 100644
--- a/src/feature/dirparse/microdesc_parse.c
+++ b/src/feature/dirparse/microdesc_parse.c
@@ -162,62 +162,27 @@ microdesc_extract_body(microdesc_t *md,
   return no_onion_key ? -1 : 0;
 }
 
-/** Parse as many microdescriptors as are found from the string starting at
- * <b>s</b> and ending at <b>eos</b>.  If allow_annotations is set, read any
- * annotations we recognize and ignore ones we don't.
- *
- * If <b>saved_location</b> isn't SAVED_IN_CACHE, make a local copy of each
- * descriptor in the body field of each microdesc_t.
+/**
+ * Parse a microdescriptor which begins at <b>s</b> and ends at
+ * <b>start_of_next_microdesc.  Store its fields into <b>md</b>.  Use
+ * <b>where</b> for generating log information.  If <b>allow_annotations</b>
+ * is true, then one or more annotations may precede the microdescriptor body
+ * proper.  Use <b>area</b> for memory management, clearing it when done.
  *
- * Return all newly parsed microdescriptors in a newly allocated
- * smartlist_t. If <b>invalid_disgests_out</b> is provided, add a SHA256
- * microdesc digest to it for every microdesc that we found to be badly
- * formed. (This may cause duplicates) */
-smartlist_t *
-microdescs_parse_from_string(const char *s, const char *eos,
-                             int allow_annotations,
-                             saved_location_t where,
-                             smartlist_t *invalid_digests_out)
+ * On success, return 0; otherwise return -1.
+ **/
+static int
+microdesc_parse_fields(microdesc_t *md,
+                       memarea_t *area,
+                       const char *s, const char *start_of_next_microdesc,
+                       int allow_annotations,
+                       saved_location_t where)
 {
-  smartlist_t *tokens;
-  smartlist_t *result;
-  microdesc_t *md = NULL;
-  memarea_t *area;
-  const char *start = s;
-  const char *start_of_next_microdesc;
+  smartlist_t *tokens = smartlist_new();
+  int rv = -1;
   int flags = allow_annotations ? TS_ANNOTATIONS_OK : 0;
-
   directory_token_t *tok;
 
-  if (!eos)
-    eos = s + strlen(s);
-
-  s = eat_whitespace_eos(s, eos);
-  area = memarea_new();
-  result = smartlist_new();
-  tokens = smartlist_new();
-
-  while (s < eos) {
-    int okay = 0;
-
-    start_of_next_microdesc = find_start_of_next_microdesc(s, eos);
-    if (!start_of_next_microdesc)
-      start_of_next_microdesc = eos;
-
-    md = tor_malloc_zero(sizeof(microdesc_t));
-    uint8_t md_digest[DIGEST256_LEN];
-    {
-      int body_not_found = microdesc_extract_body(md, start, s,
-                                                  start_of_next_microdesc,
-                                                  where) < 0;
-
-      memcpy(md_digest, md->digest, DIGEST256_LEN);
-      if (body_not_found) {
-        log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Malformed or truncated descriptor");
-        goto next;
-      }
-    }
-
     if (tokenize_string(area, s, start_of_next_microdesc, tokens,
                         microdesc_token_table, flags)) {
       log_warn(LD_DIR, "Unparseable microdescriptor found in %s",
@@ -301,10 +266,74 @@ microdescs_parse_from_string(const char *s, const char *eos,
       md->policy_is_reject_star = 1;
     }
 
-    smartlist_add(result, md);
-    okay = 1;
+    rv = 0;
+ next: // todo: rename this label.
+
+    SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
+    memarea_clear(area);
+    smartlist_free(tokens);
+
+    return rv;
+}
+
+/** Parse as many microdescriptors as are found from the string starting at
+ * <b>s</b> and ending at <b>eos</b>.  If allow_annotations is set, read any
+ * annotations we recognize and ignore ones we don't.
+ *
+ * If <b>saved_location</b> isn't SAVED_IN_CACHE, make a local copy of each
+ * descriptor in the body field of each microdesc_t.
+ *
+ * Return all newly parsed microdescriptors in a newly allocated
+ * smartlist_t. If <b>invalid_disgests_out</b> is provided, add a SHA256
+ * microdesc digest to it for every microdesc that we found to be badly
+ * formed. (This may cause duplicates) */
+smartlist_t *
+microdescs_parse_from_string(const char *s, const char *eos,
+                             int allow_annotations,
+                             saved_location_t where,
+                             smartlist_t *invalid_digests_out)
+{
+  smartlist_t *result;
+  microdesc_t *md = NULL;
+  memarea_t *area;
+  const char *start = s;
+  const char *start_of_next_microdesc;
+
+  if (!eos)
+    eos = s + strlen(s);
+
+  s = eat_whitespace_eos(s, eos);
+  area = memarea_new();
+  result = smartlist_new();
+
+  while (s < eos) {
+    int okay = 0;
+
+    start_of_next_microdesc = find_start_of_next_microdesc(s, eos);
+    if (!start_of_next_microdesc)
+      start_of_next_microdesc = eos;
+
+    md = tor_malloc_zero(sizeof(microdesc_t));
+    uint8_t md_digest[DIGEST256_LEN];
+    {
+      int body_not_found = microdesc_extract_body(md, start, s,
+                                                  start_of_next_microdesc,
+                                                  where) < 0;
+
+      memcpy(md_digest, md->digest, DIGEST256_LEN);
+      if (body_not_found) {
+        log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Malformed or truncated descriptor");
+        goto next;
+      }
+    }
+
+    if (microdesc_parse_fields(md, area, s, start_of_next_microdesc,
+                               allow_annotations, where) == 0) {
+      smartlist_add(result, md);
+      md = NULL; // prevent free
+      okay = 1;
+    }
 
-    md = NULL;
   next:
     if (! okay && invalid_digests_out) {
       smartlist_add(invalid_digests_out,
@@ -312,16 +341,10 @@ microdescs_parse_from_string(const char *s, const char *eos,
     }
     microdesc_free(md);
     md = NULL;
-
-    SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
-    memarea_clear(area);
-    smartlist_clear(tokens);
     s = start_of_next_microdesc;
   }
 
-  SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
   memarea_drop_all(area);
-  smartlist_free(tokens);
 
   return result;
 }





More information about the tor-commits mailing list