summaryrefslogtreecommitdiff
path: root/src/or/routerparse.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-05-24 15:48:53 +0000
committerNick Mathewson <nickm@torproject.org>2007-05-24 15:48:53 +0000
commitfa64904306888059cefe50429ce6f1502f2a19c6 (patch)
tree214be15937a6e7dfc3c72c718a6e2f9095885407 /src/or/routerparse.c
parent5616baa52ac7443cad1039e9ce2585165e5b2159 (diff)
downloadtor-fa64904306888059cefe50429ce6f1502f2a19c6.tar.gz
tor-fa64904306888059cefe50429ce6f1502f2a19c6.zip
r12912@catbus: nickm | 2007-05-24 11:48:49 -0400
Backport minimal parts of r10192 (fix bugs found by Benedikt) and r10248 (handle lack of nul at end of mmap). svn:r10301
Diffstat (limited to 'src/or/routerparse.c')
-rw-r--r--src/or/routerparse.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index bd1562e43b..6c77eb688e 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -163,6 +163,8 @@ static void token_free(directory_token_t *tok);
static smartlist_t *find_all_exitpolicy(smartlist_t *s);
static directory_token_t *find_first_by_keyword(smartlist_t *s,
directory_keyword keyword);
+static directory_token_t *find_last_by_keyword(smartlist_t *s,
+ directory_keyword keyword);
static int tokenize_string(const char *start, const char *end,
smartlist_t *out, where_syntax where);
static directory_token_t *get_next_token(const char **s, where_syntax where);
@@ -641,7 +643,8 @@ check_directory_signature(const char *digest,
* Returns 0 on success and -1 on failure.
*/
int
-router_parse_list_from_string(const char **s, smartlist_t *dest,
+router_parse_list_from_string(const char **s, const char *eos,
+ smartlist_t *dest,
saved_location_t saved_location)
{
routerinfo_t *router;
@@ -652,19 +655,25 @@ router_parse_list_from_string(const char **s, smartlist_t *dest,
tor_assert(dest);
start = *s;
+ if (!eos)
+ eos = *s + strlen(*s);
+
while (1) {
- *s = eat_whitespace(*s);
+ *s = eat_whitespace_eos(*s, eos);
+ if (eos - *s < 32) /* not long enough to hold a descriptor. */
+ break;
+
/* Don't start parsing the rest of *s unless it contains a router. */
if (strcmpstart(*s, "router ")!=0)
break;
- if ((end = strstr(*s+1, "\nrouter "))) {
+ if ((end = tor_memstr(*s+1, eos-(*s+1), "\nrouter "))) {
cp = end;
end++;
- } else if ((end = strstr(*s+1, "\ndirectory-signature"))) {
+ } else if ((end = tor_memstr(*s+1, eos-(*s+1), "\ndirectory-signature"))) {
cp = end;
end++;
} else {
- cp = end = *s+strlen(*s);
+ cp = end = eos;
}
while (cp > *s && (!*cp || TOR_ISSPACE(*cp)))
@@ -938,7 +947,12 @@ router_parse_entry_from_string(const char *s, const char *end,
log_warn(LD_DIR, "Missing router signature");
goto err;
}
- if (strcmp(tok->object_type, "SIGNATURE") || tok->object_size != 128) {
+ if (tok != find_last_by_keyword(tokens, K_ROUTER_SIGNATURE)) {
+ log_warn(LD_DIR, "Multiple signatures on one router. That's not ok.");
+ goto err;
+ }
+ if (!tok->object_type ||
+ strcmp(tok->object_type, "SIGNATURE") || tok->object_size != 128) {
log_warn(LD_DIR, "Bad object type or length on router signature");
goto err;
}
@@ -1637,7 +1651,7 @@ get_next_token(const char **s, where_syntax where)
}
*s = eat_whitespace(*s);
if (strcmpstart(*s, "-----BEGIN ")) {
- goto done_tokenizing;
+ goto check_obj;
}
obstart = *s;
*s += 11; /* length of "-----BEGIN ". */
@@ -1673,6 +1687,7 @@ get_next_token(const char **s, where_syntax where)
}
*s += i+6;
}
+ check_obj:
switch (o_syn)
{
case NO_OBJ:
@@ -1735,6 +1750,17 @@ find_first_by_keyword(smartlist_t *s, directory_keyword keyword)
return NULL;
}
+/** Find the last token in <b>s</b> whose keyword is <b>keyword</b>; return
+ * NULL if no such keyword is found.
+ */
+static directory_token_t *
+find_last_by_keyword(smartlist_t *s, directory_keyword keyword)
+{
+ directory_token_t *last = NULL;
+ SMARTLIST_FOREACH(s, directory_token_t *, t, if (t->tp == keyword) last = t);
+ return last;
+}
+
/** Return a newly allocated smartlist of all accept or reject tokens in
* <b>s</b>.
*/