diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2023-07-05 10:42:17 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2023-07-05 10:42:21 -0400 |
commit | 6b0ddba545ca578903fe856af6d820883121bb1e (patch) | |
tree | 7e8a485e89bc23075e084fe16c44e5e280c5855c /version_compare.c | |
parent | a70733d9a64320eac8038d733df67467cd97976c (diff) | |
download | version_compare-master.tar.gz |
* Pad first element of a version to avoid small versions being detected as greater than larger versions
* before: 1.0.3 > 2.0.0 == TRUE
* after: 1.0.3 > 2.0.0 == FALSE
Diffstat (limited to 'version_compare.c')
-rw-r--r-- | version_compare.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/version_compare.c b/version_compare.c index c6aaca7..7e63024 100644 --- a/version_compare.c +++ b/version_compare.c @@ -128,7 +128,7 @@ char *collapse_whitespace(char **s) { * @return -1 on error */ int version_sum(const char *str) { - int result; + int i, result, epoch; char *s, *ptr, *end; if (!str || isempty(str)) { @@ -136,6 +136,7 @@ int version_sum(const char *str) { } result = 0; + epoch = 0; s = strdup(str); if (!s) { return -1; @@ -146,17 +147,44 @@ int version_sum(const char *str) { // Parsing stops at the first non-alpha, non-'.' character // Digits are processed until the first invalid character // I'm torn whether this should be considered an error + i = 0; while (end != NULL) { - result += (int) strtoul(ptr, &end, 10); + int tmp_result = 0; + + tmp_result = (int) strtoul(ptr, &end, 10); + + // Circumvent a bug which allows a smaller version to be greater + // than a larger version + // Bug: + // 1.0.3 == 1 + 0 + 3 = 4 + // 2.0.0 == 2 + 0 + 0 = 2 + // Correction: + // ((1 * EPOCH_MOD) + 1).0.3 = 104 + // ((2 * EPOCH_MOD) + 2).0.0 = 202 + if (!i && tmp_result && *end != ':') { + result += tmp_result * EPOCH_MOD; + i++; + } + ptr = end; - if (*ptr == '.') + if (*ptr == '.' || *ptr == '-') { ptr++; + } + else if (!epoch && *ptr == ':') { + epoch = 1; + result += EPOCH_MOD; + ptr++; + } else if (isalpha(*ptr)) { result += *ptr - ('a' - 1); ptr++; } else end = NULL; + + if (tmp_result) { + result += tmp_result; + } } free(s); @@ -204,6 +232,12 @@ int version_parse_operator(char *str) { return result; } +int version_has_epoch(const char *str) { + char *result; + result = strchr(str, ':'); + return result ? 1 : 0; +} + /** * Compare version strings based on flag(s) * @param flags verison operators @@ -227,6 +261,14 @@ int version_compare(int flags, const char *aa, const char *bb) { if (result_b < 0) return -1; + + if ((version_has_epoch(aa) && !version_has_epoch(bb))) { + result_a -= EPOCH_MOD; + } + if (!version_has_epoch(aa) && version_has_epoch(bb)) { + result_b -= EPOCH_MOD; + } + result = 0; if (flags & GT && flags & EQ) result |= result_a >= result_b; |