Переглянути джерело

Merge remote-tracking branch 'public/bug13661_025'

Nick Mathewson 9 роки тому
батько
коміт
ae9efa863e
3 змінених файлів з 78 додано та 26 видалено
  1. 6 0
      changes/bug13661
  2. 36 26
      src/or/routerparse.c
  3. 36 0
      src/test/test_dir.c

+ 6 - 0
changes/bug13661

@@ -0,0 +1,6 @@
+  o Minor bugfixes:
+
+    - Support two-number and three-number version numbers correctly, in
+      case we change the Tor versioning system in the future.  Fixes bug
+      13661; bugfix on 0.0.8pre1.
+

+ 36 - 26
src/or/routerparse.c

@@ -4250,40 +4250,50 @@ tor_version_parse(const char *s, tor_version_t *out)
   char *eos=NULL;
   const char *cp=NULL;
   /* Format is:
-   *   "Tor " ? NUM dot NUM dot NUM [ ( pre | rc | dot ) NUM [ - tag ] ]
+   *   "Tor " ? NUM dot NUM [ dot NUM [ ( pre | rc | dot ) NUM ] ] [ - tag ]
    */
   tor_assert(s);
   tor_assert(out);
 
   memset(out, 0, sizeof(tor_version_t));
-
+  out->status = VER_RELEASE;
   if (!strcasecmpstart(s, "Tor "))
     s += 4;
 
-  /* Get major. */
-  out->major = (int)strtol(s,&eos,10);
-  if (!eos || eos==s || *eos != '.') return -1;
-  cp = eos+1;
-
-  /* Get minor */
-  out->minor = (int) strtol(cp,&eos,10);
-  if (!eos || eos==cp || *eos != '.') return -1;
-  cp = eos+1;
-
-  /* Get micro */
-  out->micro = (int) strtol(cp,&eos,10);
-  if (!eos || eos==cp) return -1;
-  if (!*eos) {
-    out->status = VER_RELEASE;
-    out->patchlevel = 0;
+  cp = s;
+
+#define NUMBER(m)                               \
+  do {                                          \
+    out->m = (int)strtol(cp, &eos, 10);         \
+    if (!eos || eos == cp)                      \
+      return -1;                                \
+    cp = eos;                                   \
+  } while (0)
+
+#define DOT()                                   \
+  do {                                          \
+    if (*cp != '.')                             \
+      return -1;                                \
+    ++cp;                                       \
+  } while (0)
+
+  NUMBER(major);
+  DOT();
+  NUMBER(minor);
+  if (*cp == 0)
     return 0;
-  }
-  cp = eos;
+  else if (*cp == '-')
+    goto status_tag;
+  DOT();
+  NUMBER(micro);
 
   /* Get status */
-  if (*cp == '.') {
-    out->status = VER_RELEASE;
+  if (*cp == 0) {
+    return 0;
+  } else if (*cp == '.') {
     ++cp;
+  } else if (*cp == '-') {
+    goto status_tag;
   } else if (0==strncmp(cp, "pre", 3)) {
     out->status = VER_PRE;
     cp += 3;
@@ -4294,11 +4304,9 @@ tor_version_parse(const char *s, tor_version_t *out)
     return -1;
   }
 
-  /* Get patchlevel */
-  out->patchlevel = (int) strtol(cp,&eos,10);
-  if (!eos || eos==cp) return -1;
-  cp = eos;
+  NUMBER(patchlevel);
 
+ status_tag:
   /* Get status tag. */
   if (*cp == '-' || *cp == '.')
     ++cp;
@@ -4334,6 +4342,8 @@ tor_version_parse(const char *s, tor_version_t *out)
   }
 
   return 0;
+#undef NUMBER
+#undef DOT
 }
 
 /** Compare two tor versions; Return <0 if a < b; 0 if a ==b, >0 if a >

+ 36 - 0
src/test/test_dir.c

@@ -845,6 +845,42 @@ test_dir_versions(void *arg)
   tt_int_op(VER_RELEASE,OP_EQ, ver1.status);
   tt_str_op("",OP_EQ, ver1.status_tag);
 
+  test_eq(0, tor_version_parse("10.1", &ver1));
+  test_eq(10, ver1.major);
+  test_eq(1, ver1.minor);
+  test_eq(0, ver1.micro);
+  test_eq(0, ver1.patchlevel);
+  test_eq(VER_RELEASE, ver1.status);
+  test_streq("", ver1.status_tag);
+  test_eq(0, tor_version_parse("5.99.999", &ver1));
+  test_eq(5, ver1.major);
+  test_eq(99, ver1.minor);
+  test_eq(999, ver1.micro);
+  test_eq(0, ver1.patchlevel);
+  test_eq(VER_RELEASE, ver1.status);
+  test_streq("", ver1.status_tag);
+  test_eq(0, tor_version_parse("10.1-alpha", &ver1));
+  test_eq(10, ver1.major);
+  test_eq(1, ver1.minor);
+  test_eq(0, ver1.micro);
+  test_eq(0, ver1.patchlevel);
+  test_eq(VER_RELEASE, ver1.status);
+  test_streq("alpha", ver1.status_tag);
+  test_eq(0, tor_version_parse("2.1.700-alpha", &ver1));
+  test_eq(2, ver1.major);
+  test_eq(1, ver1.minor);
+  test_eq(700, ver1.micro);
+  test_eq(0, ver1.patchlevel);
+  test_eq(VER_RELEASE, ver1.status);
+  test_streq("alpha", ver1.status_tag);
+  test_eq(0, tor_version_parse("1.6.8-alpha-dev", &ver1));
+  test_eq(1, ver1.major);
+  test_eq(6, ver1.minor);
+  test_eq(8, ver1.micro);
+  test_eq(0, ver1.patchlevel);
+  test_eq(VER_RELEASE, ver1.status);
+  test_streq("alpha-dev", ver1.status_tag);
+
 #define tt_versionstatus_op(vs1, op, vs2)                               \
   tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t,       \
                       (val1_ op val2_),"%d",TT_EXIT_TEST_FUNCTION)