aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-01-06 15:16:28 -0500
committerNick Mathewson <nickm@torproject.org>2015-01-06 15:16:28 -0500
commitae9efa863e3cfcdf38a5b4e36570df9effe68dfd (patch)
treed905b823a986b1948aa57680387912ff410c6589
parent90b9e23bec4687962a999c2575909b9230bd425a (diff)
parentfc62721b06e3ac231b570741e21dba03b5cadaca (diff)
downloadtor-ae9efa863e3cfcdf38a5b4e36570df9effe68dfd.tar.gz
tor-ae9efa863e3cfcdf38a5b4e36570df9effe68dfd.zip
Merge remote-tracking branch 'public/bug13661_025'
-rw-r--r--changes/bug136616
-rw-r--r--src/or/routerparse.c62
-rw-r--r--src/test/test_dir.c36
3 files changed, 78 insertions, 26 deletions
diff --git a/changes/bug13661 b/changes/bug13661
new file mode 100644
index 0000000000..7f0cb5e706
--- /dev/null
+++ b/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.
+
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 840350dab2..39063a97b3 100644
--- a/src/or/routerparse.c
+++ b/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 >
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 69933896dd..9da44ed546 100644
--- a/src/test/test_dir.c
+++ b/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)