|  | @@ -451,9 +451,10 @@ static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
 | 
	
		
			
				|  |  |  static addr_policy_t *router_parse_addr_policy(directory_token_t *tok);
 | 
	
		
			
				|  |  |  static addr_policy_t *router_parse_addr_policy_private(directory_token_t *tok);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int router_get_hash_impl(const char *s, char *digest,
 | 
	
		
			
				|  |  | +static int router_get_hash_impl(const char *s, size_t s_len, char *digest,
 | 
	
		
			
				|  |  |                                  const char *start_str, const char *end_str,
 | 
	
		
			
				|  |  |                                  char end_char);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void token_free(directory_token_t *tok);
 | 
	
		
			
				|  |  |  static smartlist_t *find_all_exitpolicy(smartlist_t *s);
 | 
	
		
			
				|  |  |  static directory_token_t *_find_by_keyword(smartlist_t *s,
 | 
	
	
		
			
				|  | @@ -504,7 +505,7 @@ static int tor_version_same_series(tor_version_t *a, tor_version_t *b);
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  |  router_get_dir_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  return router_get_hash_impl(s,digest,
 | 
	
		
			
				|  |  | +  return router_get_hash_impl(s, strlen(s), digest,
 | 
	
		
			
				|  |  |                                "signed-directory","\ndirectory-signature",'\n');
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -512,9 +513,9 @@ router_get_dir_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |   * <b>s</b>. Return 0 on success, -1 on failure.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  | -router_get_router_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  | +router_get_router_hash(const char *s, size_t s_len, char *digest)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  return router_get_hash_impl(s,digest,
 | 
	
		
			
				|  |  | +  return router_get_hash_impl(s, s_len, digest,
 | 
	
		
			
				|  |  |                                "router ","\nrouter-signature", '\n');
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -524,7 +525,7 @@ router_get_router_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  |  router_get_runningrouters_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  return router_get_hash_impl(s,digest,
 | 
	
		
			
				|  |  | +  return router_get_hash_impl(s, strlen(s), digest,
 | 
	
		
			
				|  |  |                                "network-status","\ndirectory-signature", '\n');
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -533,7 +534,7 @@ router_get_runningrouters_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  |  router_get_networkstatus_v2_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  return router_get_hash_impl(s,digest,
 | 
	
		
			
				|  |  | +  return router_get_hash_impl(s, strlen(s), digest,
 | 
	
		
			
				|  |  |                                "network-status-version","\ndirectory-signature",
 | 
	
		
			
				|  |  |                                '\n');
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -543,8 +544,9 @@ router_get_networkstatus_v2_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  |  router_get_networkstatus_v3_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  return router_get_hash_impl(s,digest,
 | 
	
		
			
				|  |  | -                              "network-status-version","\ndirectory-signature",
 | 
	
		
			
				|  |  | +  return router_get_hash_impl(s, strlen(s), digest,
 | 
	
		
			
				|  |  | +                              "network-status-version",
 | 
	
		
			
				|  |  | +                              "\ndirectory-signature",
 | 
	
		
			
				|  |  |                                ' ');
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -553,7 +555,8 @@ router_get_networkstatus_v3_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  int
 | 
	
		
			
				|  |  |  router_get_extrainfo_hash(const char *s, char *digest)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  return router_get_hash_impl(s,digest,"extra-info","\nrouter-signature",'\n');
 | 
	
		
			
				|  |  | +  return router_get_hash_impl(s, strlen(s), digest, "extra-info",
 | 
	
		
			
				|  |  | +                              "\nrouter-signature",'\n');
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /** Helper: used to generate signatures for routers, directories and
 | 
	
	
		
			
				|  | @@ -1118,6 +1121,8 @@ dump_distinct_digest_count(int severity)
 | 
	
		
			
				|  |  |   * s through end into the signed_descriptor_body of the resulting
 | 
	
		
			
				|  |  |   * routerinfo_t.
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  | + * If <b>end</b> is NULL, <b>s</b> must be properly NULL-terminated.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  |   * If <b>allow_annotations</b>, it's okay to encounter annotations in <b>s</b>
 | 
	
		
			
				|  |  |   * before the router; if it's false, reject the router if it's annotated.  If
 | 
	
		
			
				|  |  |   * <b>prepend_annotations</b> is set, it should contain some annotations:
 | 
	
	
		
			
				|  | @@ -1180,7 +1185,7 @@ router_parse_entry_from_string(const char *s, const char *end,
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (router_get_router_hash(s, digest) < 0) {
 | 
	
		
			
				|  |  | +  if (router_get_router_hash(s, end - s, digest) < 0) {
 | 
	
		
			
				|  |  |      log_warn(LD_DIR, "Couldn't compute router hash.");
 | 
	
		
			
				|  |  |      goto err;
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -1600,7 +1605,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
 | 
	
		
			
				|  |  |      log_warn(LD_DIR, "Error tokenizing key certificate");
 | 
	
		
			
				|  |  |      goto err;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  if (router_get_hash_impl(s, digest, "dir-key-certificate-version",
 | 
	
		
			
				|  |  | +  if (router_get_hash_impl(s, strlen(s), digest, "dir-key-certificate-version",
 | 
	
		
			
				|  |  |                             "\ndir-key-certification", '\n') < 0)
 | 
	
		
			
				|  |  |      goto err;
 | 
	
		
			
				|  |  |    tok = smartlist_get(tokens, 0);
 | 
	
	
		
			
				|  | @@ -2159,6 +2164,7 @@ networkstatus_v2_parse_from_string(const char *s)
 | 
	
		
			
				|  |  |    return ns;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /** Parse a v3 networkstatus vote, opinion, or consensus (depending on
 | 
	
		
			
				|  |  |   * ns_type), from <b>s</b>, and return the result.  Return NULL on failure. */
 | 
	
		
			
				|  |  |  networkstatus_t *
 | 
	
	
		
			
				|  | @@ -3295,12 +3301,12 @@ find_all_exitpolicy(smartlist_t *s)
 | 
	
		
			
				|  |  |   * If no such substring exists, return -1.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  | -router_get_hash_impl(const char *s, char *digest,
 | 
	
		
			
				|  |  | -                     const char *start_str,
 | 
	
		
			
				|  |  | -                     const char *end_str, char end_c)
 | 
	
		
			
				|  |  | +router_get_hash_impl(const char *s, size_t s_len, char *digest,
 | 
	
		
			
				|  |  | +                            const char *start_str,
 | 
	
		
			
				|  |  | +                            const char *end_str, char end_c)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  char *start, *end;
 | 
	
		
			
				|  |  | -  start = strstr(s, start_str);
 | 
	
		
			
				|  |  | +  const char *start, *end;
 | 
	
		
			
				|  |  | +  start = tor_memstr(s, s_len, start_str);
 | 
	
		
			
				|  |  |    if (!start) {
 | 
	
		
			
				|  |  |      log_warn(LD_DIR,"couldn't find start of hashed material \"%s\"",start_str);
 | 
	
		
			
				|  |  |      return -1;
 | 
	
	
		
			
				|  | @@ -3311,12 +3317,13 @@ router_get_hash_impl(const char *s, char *digest,
 | 
	
		
			
				|  |  |               start_str);
 | 
	
		
			
				|  |  |      return -1;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  end = strstr(start+strlen(start_str), end_str);
 | 
	
		
			
				|  |  | +  end = tor_memstr(start+strlen(start_str),
 | 
	
		
			
				|  |  | +                   s_len - (start-s) - strlen(start_str), end_str);
 | 
	
		
			
				|  |  |    if (!end) {
 | 
	
		
			
				|  |  |      log_warn(LD_DIR,"couldn't find end of hashed material \"%s\"",end_str);
 | 
	
		
			
				|  |  |      return -1;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  end = strchr(end+strlen(end_str), end_c);
 | 
	
		
			
				|  |  | +  end = memchr(end+strlen(end_str), end_c, s_len - (end-s) - strlen(end_str));
 | 
	
		
			
				|  |  |    if (!end) {
 | 
	
		
			
				|  |  |      log_warn(LD_DIR,"couldn't find EOL");
 | 
	
		
			
				|  |  |      return -1;
 | 
	
	
		
			
				|  | @@ -3564,7 +3571,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
 | 
	
		
			
				|  |  |      goto err;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    /* Compute descriptor hash for later validation. */
 | 
	
		
			
				|  |  | -  if (router_get_hash_impl(desc, desc_hash,
 | 
	
		
			
				|  |  | +  if (router_get_hash_impl(desc, strlen(desc), desc_hash,
 | 
	
		
			
				|  |  |                             "rendezvous-service-descriptor ",
 | 
	
		
			
				|  |  |                             "\nsignature", '\n') < 0) {
 | 
	
		
			
				|  |  |      log_warn(LD_REND, "Couldn't compute descriptor hash.");
 |