vercmp exhibited some odd behavior here, declaring versions such as '23.3a' and '23.3.a' as equivalent. Add an extra check before we return equality that the versions have the same length. Adds a pair of test cases to the vercmp test suite as well. Reported-by: Eric Belanger <eric@archlinux.org> Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- lib/libalpm/version.c | 13 ++++++++++++- test/util/vercmptest.sh | 4 ++++ 2 files changed, 16 insertions(+), 1 deletions(-) diff --git a/lib/libalpm/version.c b/lib/libalpm/version.c index 9f3a9b7..bab9f92 100644 --- a/lib/libalpm/version.c +++ b/lib/libalpm/version.c @@ -88,6 +88,7 @@ static int rpmvercmp(const char *a, const char *b) char *str1, *str2; char *ptr1, *ptr2; char *one, *two; + size_t one_len, two_len; int rc; int isnum; int ret = 0; @@ -101,6 +102,9 @@ static int rpmvercmp(const char *a, const char *b) one = str1; two = str2; + one_len = strlen(one); + two_len = strlen(two); + /* loop through each version segment of str1 and str2 and compare them */ while(*one && *two) { while(*one && !isalnum((int)*one)) one++; @@ -187,9 +191,16 @@ static int rpmvercmp(const char *a, const char *b) /* this catches the case where all numeric and alpha segments have */ /* compared identically but the segment separating characters were */ - /* different */ + /* different. versions must also be the same length to be equivalent, */ + /* otherwise, the shorter version is declared newer. */ if ((!*one) && (!*two)) { + int diff = two_len - one_len; ret = 0; + if(diff > 0) { + ret = 1; + } else if (diff < 0) { + ret = -1; + } goto cleanup; } diff --git a/test/util/vercmptest.sh b/test/util/vercmptest.sh index 54ede04..ff498ba 100755 --- a/test/util/vercmptest.sh +++ b/test/util/vercmptest.sh @@ -137,6 +137,10 @@ runtest 1:1.0 1.0 1 runtest 1:1.0 1.1 1 runtest 1:1.1 1.1 1 +# same alnum content, different length +runtest 1a 1.a 1 +runtest 23.3.a 23.3a -1 + #END TESTS echo -- 1.7.6