diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-02-15 07:50:45 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-02-15 07:50:45 -0500 |
commit | 2afdf8de2f8a71e6a7de24546a03e505f4258aff (patch) | |
tree | 847b55532a59d25f56470b6361817f2931cf36f7 /src | |
parent | 92f8b56e27450f3646ea1b2a5751fce9e77beb86 (diff) | |
parent | 194e31057fbf07d6bdf4b62d26e1a9db334e5f1c (diff) | |
download | tor-2afdf8de2f8a71e6a7de24546a03e505f4258aff.tar.gz tor-2afdf8de2f8a71e6a7de24546a03e505f4258aff.zip |
Merge branch 'maint-0.2.4' into release-0.2.4
Diffstat (limited to 'src')
-rw-r--r-- | src/or/routerparse.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 71373ce63e..1243035f90 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -4545,26 +4545,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. |