summaryrefslogtreecommitdiff
path: root/src/or/routerparse.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-02-15 07:47:28 -0500
committerNick Mathewson <nickm@torproject.org>2017-02-15 07:47:28 -0500
commit1ebdae61711ec03ce49af2f356756b5db9587412 (patch)
tree5b861d2cf06aae03e2d426584e19910f7912ea20 /src/or/routerparse.c
parent9b90d515a9fc52c2579d55406e78de8d2fb5fa19 (diff)
parented806843dc8e7942a2a0abfbb2ae374e11963feb (diff)
downloadtor-1ebdae61711ec03ce49af2f356756b5db9587412.tar.gz
tor-1ebdae61711ec03ce49af2f356756b5db9587412.zip
Merge branch 'maint-0.2.7' into maint-0.2.8
Diffstat (limited to 'src/or/routerparse.c')
-rw-r--r--src/or/routerparse.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 4db40c8435..b6a90431a7 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -4848,26 +4848,37 @@ tor_version_compare(tor_version_t *a, tor_version_t *b)
int i;
tor_assert(a);
tor_assert(b);
- if ((i = a->major - b->major))
- return i;
- else if ((i = a->minor - b->minor))
- return i;
- else if ((i = a->micro - b->micro))
- return i;
- else if ((i = a->status - b->status))
- return i;
- else if ((i = a->patchlevel - b->patchlevel))
- return i;
- else if ((i = strcmp(a->status_tag, b->status_tag)))
- return i;
- else if ((i = a->svn_revision - b->svn_revision))
- return i;
- else if ((i = a->git_tag_len - b->git_tag_len))
- return i;
- else if (a->git_tag_len)
- return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len);
+
+ /* We take this approach to comparison to ensure the same (bogus!) behavior
+ * on all inputs as we would have seen before bug #21278 was fixed. The
+ * only important difference here is that this method doesn't cause
+ * a signed integer underflow.
+ */
+#define CMP(field) do { \
+ unsigned aval = (unsigned) a->field; \
+ unsigned bval = (unsigned) b->field; \
+ int result = (int) (aval - bval); \
+ if (result < 0) \
+ return -1; \
+ else if (result > 0) \
+ return 1; \
+ } while (0)
+
+ CMP(major);
+ CMP(minor);
+ CMP(micro);
+ CMP(status);
+ CMP(patchlevel);
+ if ((i = strcmp(a->status_tag, b->status_tag)))
+ return i;
+ CMP(svn_revision);
+ CMP(git_tag_len);
+ if (a->git_tag_len)
+ return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len);
else
- return 0;
+ return 0;
+
+#undef CMP
}
/** Return true iff versions <b>a</b> and <b>b</b> belong to the same series.