Commit f63e06d3 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Extract the part of tor_version_as_new_as that extracts platform

Also add a "strict" mode to reject negative inputs.
parent 4a2afd5b
Loading
Loading
Loading
Loading
+46 −14
Original line number Diff line number Diff line
@@ -5517,35 +5517,67 @@ microdescs_parse_from_string(const char *s, const char *eos,
 * the router is at least as new as the cutoff, else return 0.
 */
int
tor_version_as_new_as(const char *platform, const char *cutoff)
tor_version_parse_platform(const char *platform,
                           tor_version_t *router_version,
                           int strict)
{
  tor_version_t cutoff_version, router_version;
  char *s, *s2, *start;
  char tmp[128];
  char *s, *s2, *start;

  tor_assert(platform);

  if (tor_version_parse(cutoff, &cutoff_version)<0) {
    log_warn(LD_BUG,"cutoff version '%s' unparseable.",cutoff);
  if (strcmpstart(platform,"Tor ")) /* nonstandard Tor; say 0. */
    return 0;
  }
  if (strcmpstart(platform,"Tor ")) /* nonstandard Tor; be safe and say yes */
    return 1;

  start = (char *)eat_whitespace(platform+3);
  if (!*start) return 0;
  if (!*start) return -1;
  s = (char *)find_whitespace(start); /* also finds '\0', which is fine */
  s2 = (char*)eat_whitespace(s);
  if (!strcmpstart(s2, "(r") || !strcmpstart(s2, "(git-"))
    s = (char*)find_whitespace(s2);

  if ((size_t)(s-start+1) >= sizeof(tmp)) /* too big, no */
    return 0;
    return -1;
  strlcpy(tmp, start, s-start+1);

  if (tor_version_parse(tmp, &router_version)<0) {
  if (tor_version_parse(tmp, router_version)<0) {
    log_info(LD_DIR,"Router version '%s' unparseable.",tmp);
    return 1; /* be safe and say yes */
    return -1;
  }

  if (strict) {
    if (router_version->major < 0 ||
        router_version->minor < 0 ||
        router_version->minor < 0 ||
        router_version->patchlevel < 0 ||
        router_version->svn_revision < 0) {
      return -1;
    }
  }
  return 1;
}

/** Parse the Tor version of the platform string <b>platform</b>,
 * and compare it to the version in <b>cutoff</b>. Return 1 if
 * the router is at least as new as the cutoff, else return 0.
 */
int
tor_version_as_new_as(const char *platform, const char *cutoff)
{
  tor_version_t cutoff_version, router_version;
  int r;
  tor_assert(platform);

  if (tor_version_parse(cutoff, &cutoff_version)<0) {
    log_warn(LD_BUG,"cutoff version '%s' unparseable.",cutoff);
    return 0;
  }

  r = tor_version_parse_platform(platform, &router_version, 0);
  if (r == 0) {
    /* nonstandard Tor; be safe and say yes */
    return 1;
  } else if (r < 0) {
    /* unparseable version; be safe and say yes. */
    return 1;
  }

  /* Here's why we don't need to do any special handling for svn revisions:
+3 −0
Original line number Diff line number Diff line
@@ -45,6 +45,9 @@ MOCK_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string,
         (const char *s, int assume_action, int *malformed_list));
version_status_t tor_version_is_obsolete(const char *myversion,
                                         const char *versionlist);
int tor_version_parse_platform(const char *platform,
                               tor_version_t *version_out,
                               int strict);
int tor_version_as_new_as(const char *platform, const char *cutoff);
int tor_version_parse(const char *s, tor_version_t *out);
int tor_version_compare(tor_version_t *a, tor_version_t *b);