mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
common: Improve compare_string_versions.
* common/stringhelp.c: Include limits.h. (compare_version_strings): Change semantics to behave like strcmp. Include the patch lebel in the comparison. Allow checking a single version string. * common/t-stringhelp.c (test_compare_version_strings): Adjust test vectors and a few new vectors. * g10/call-agent.c (warn_version_mismatch): Adjust to new sematics. * g10/call-dirmngr.c (warn_version_mismatch): Ditto. * sm/call-agent.c (warn_version_mismatch): Ditto. * sm/call-dirmngr.c (warn_version_mismatch): Ditto. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
60ad1a7f37
commit
488b183811
@ -49,6 +49,7 @@
|
|||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "common-defs.h"
|
#include "common-defs.h"
|
||||||
@ -1356,9 +1357,9 @@ parse_version_number (const char *s, int *number)
|
|||||||
|
|
||||||
/* This function breaks up the complete string-representation of the
|
/* This function breaks up the complete string-representation of the
|
||||||
version number S, which is of the following struture: <major
|
version number S, which is of the following struture: <major
|
||||||
number>.<minor number>.<micro number><patch level>. The major,
|
number>.<minor number>[.<micro number>]<patch level>. The major,
|
||||||
minor and micro number components will be stored in *MAJOR, *MINOR
|
minor, and micro number components will be stored in *MAJOR, *MINOR
|
||||||
and *MICRO.
|
and *MICRO. If MICRO is not given 0 is used instead.
|
||||||
|
|
||||||
On success, the last component, the patch level, will be returned;
|
On success, the last component, the patch level, will be returned;
|
||||||
in failure, NULL will be returned. */
|
in failure, NULL will be returned. */
|
||||||
@ -1385,32 +1386,50 @@ parse_version_string (const char *s, int *major, int *minor, int *micro)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check that the version string MY_VERSION is greater or equal than
|
/* Compare the version string MY_VERSION to the version string
|
||||||
REQ_VERSION. Returns true if the condition is satisfied or false
|
* REQ_VERSION. Returns -1, 0, or 1 if MY_VERSION is found,
|
||||||
if not. This works with 3 part and two part version strings; for a
|
* respectively, to be less than, to match, or be greater than
|
||||||
two part version string the micor part is assumed to be 0. */
|
* REQ_VERSION. This function works for three and two part version
|
||||||
|
* strings; for a two part version string the micro part is assumed to
|
||||||
|
* be 0. Patch levels are compared as strings. If a version number
|
||||||
|
* is invalid INT_MIN is returned. If REQ_VERSION is given as NULL
|
||||||
|
* the function returns 0 if MY_VERSION is parsable version string. */
|
||||||
int
|
int
|
||||||
compare_version_strings (const char *my_version, const char *req_version)
|
compare_version_strings (const char *my_version, const char *req_version)
|
||||||
{
|
{
|
||||||
int my_major, my_minor, my_micro;
|
int my_major, my_minor, my_micro;
|
||||||
int rq_major, rq_minor, rq_micro;
|
int rq_major, rq_minor, rq_micro;
|
||||||
|
const char *my_patch, *rq_patch;
|
||||||
|
int result;
|
||||||
|
|
||||||
if (!my_version || !req_version)
|
if (!my_version)
|
||||||
return 0;
|
return INT_MIN;
|
||||||
|
|
||||||
if (!parse_version_string (my_version, &my_major, &my_minor, &my_micro))
|
my_patch = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
|
||||||
return 0;
|
if (!my_patch)
|
||||||
if (!parse_version_string(req_version, &rq_major, &rq_minor, &rq_micro))
|
return INT_MIN;
|
||||||
return 0;
|
if (!req_version)
|
||||||
|
return 0; /* MY_VERSION can be parsed. */
|
||||||
|
rq_patch = parse_version_string (req_version, &rq_major, &rq_minor,&rq_micro);
|
||||||
|
if (!rq_patch)
|
||||||
|
return INT_MIN;
|
||||||
|
|
||||||
if (my_major > rq_major
|
if (my_major == rq_major)
|
||||||
|| (my_major == rq_major && my_minor > rq_minor)
|
|
||||||
|| (my_major == rq_major && my_minor == rq_minor
|
|
||||||
&& my_micro >= rq_micro))
|
|
||||||
{
|
{
|
||||||
return 1;
|
if (my_minor == rq_minor)
|
||||||
|
{
|
||||||
|
if (my_micro == rq_micro)
|
||||||
|
result = strcmp (my_patch, rq_patch);
|
||||||
|
else
|
||||||
|
result = my_micro - rq_micro;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = my_minor - rq_minor;
|
||||||
}
|
}
|
||||||
return 0;
|
else
|
||||||
|
result = my_major - rq_major;
|
||||||
|
|
||||||
|
return !result? 0 : result < 0 ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "t-support.h"
|
#include "t-support.h"
|
||||||
#include "stringhelp.h"
|
#include "stringhelp.h"
|
||||||
@ -903,45 +904,63 @@ static void
|
|||||||
test_compare_version_strings (void)
|
test_compare_version_strings (void)
|
||||||
{
|
{
|
||||||
struct { const char *a; const char *b; int okay; } tests[] = {
|
struct { const char *a; const char *b; int okay; } tests[] = {
|
||||||
{ "1.0.0", "1.0.0", 1 },
|
{ "1.0.0", "1.0.0", 0 },
|
||||||
{ "1.0.0-", "1.0.0", 1 },
|
{ "1.0.0-", "1.0.0", 1 },
|
||||||
{ "1.0.0-1", "1.0.0", 1 },
|
{ "1.0.0-1", "1.0.0", 1 },
|
||||||
{ "1.0.0.1", "1.0.0", 1 },
|
{ "1.0.0.1", "1.0.0", 1 },
|
||||||
{ "1.0.0", "1.0.1", 0 },
|
{ "1.0.0", "1.0.1", -1 },
|
||||||
{ "1.0.0-", "1.0.1", 0 },
|
{ "1.0.0-", "1.0.1", -1 },
|
||||||
{ "1.0.0-1", "1.0.1", 0 },
|
{ "1.0.0-1", "1.0.1", -1 },
|
||||||
{ "1.0.0.1", "1.0.1", 0 },
|
{ "1.0.0.1", "1.0.1", -1 },
|
||||||
{ "1.0.0", "1.1.0", 0 },
|
{ "1.0.0", "1.1.0", -1 },
|
||||||
{ "1.0.0-", "1.1.0", 0 },
|
{ "1.0.0-", "1.1.0", -1 },
|
||||||
{ "1.0.0-1", "1.1.0", 0 },
|
{ "1.0.0-1", "1.1.0", -1 },
|
||||||
{ "1.0.0.1", "1.1.0", 0 },
|
{ "1.0.0.1", "1.1.0", -1 },
|
||||||
|
|
||||||
{ "1.0.0", "1.0.0-", 1 },
|
{ "1.0.0", "1.0.0-", -1 },
|
||||||
{ "1.0.0", "1.0.0-1", 1 },
|
{ "1.0.0", "1.0.0-1", -1 },
|
||||||
{ "1.0.0", "1.0.0.1", 1 },
|
{ "1.0.0", "1.0.0.1", -1 },
|
||||||
{ "1.1.0", "1.0.0", 1 },
|
{ "1.1.0", "1.0.0", 1 },
|
||||||
{ "1.1.1", "1.1.0", 1 },
|
{ "1.1.1", "1.1.0", 1 },
|
||||||
{ "1.1.2", "1.1.2", 1 },
|
{ "1.1.2", "1.1.2", 0 },
|
||||||
{ "1.1.2", "1.0.2", 1 },
|
{ "1.1.2", "1.0.2", 1 },
|
||||||
{ "1.1.2", "0.0.2", 1 },
|
{ "1.1.2", "0.0.2", 1 },
|
||||||
{ "1.1.2", "1.1.3", 0 },
|
{ "1.1.2", "1.1.3", -1 },
|
||||||
|
|
||||||
{ "0.99.1", "0.9.9", 1 },
|
{ "0.99.1", "0.9.9", 1 },
|
||||||
{ "0.9.1", "0.91.0", 0 },
|
{ "0.9.1", "0.91.0", -1 },
|
||||||
|
|
||||||
{ "1.5.3", "1.5", 1 },
|
{ "1.5.3", "1.5", 1 },
|
||||||
{ "1.5.0", "1.5", 1 },
|
{ "1.5.0", "1.5", 0 },
|
||||||
{ "1.4.99", "1.5", 0 },
|
{ "1.4.99", "1.5", -1 },
|
||||||
{ "1.5", "1.4.99", 1 },
|
{ "1.5", "1.4.99", 1 },
|
||||||
{ "1.5", "1.5.0", 1 },
|
{ "1.5", "1.5.0", 0 },
|
||||||
{ "1.5", "1.5.1", 0 },
|
{ "1.5", "1.5.1", -1 },
|
||||||
|
|
||||||
{ "1.5.3-x17", "1.5-23", 1 },
|
{ "1.5.3-x17", "1.5-23", 1 },
|
||||||
|
|
||||||
{ "1.5.3a", "1.5.3", 1 },
|
{ "1.5.3a", "1.5.3", 1 },
|
||||||
{ "1.5.3a", "1.5.3b", 1 },
|
{ "1.5.3a", "1.5.3b", -1 },
|
||||||
|
|
||||||
{ NULL, NULL, 0 }
|
{ "3.1.4-ab", "3.1.4-ab", 0 },
|
||||||
|
{ "3.1.4-ab", "3.1.4-ac", -1 },
|
||||||
|
{ "3.1.4-ac", "3.1.4-ab", 1 },
|
||||||
|
{ "3.1.4-ab", "3.1.4-abb", -1 },
|
||||||
|
{ "3.1.4-abb", "3.1.4-ab", 1 },
|
||||||
|
|
||||||
|
{ "", "", INT_MIN },
|
||||||
|
{ NULL, "", INT_MIN },
|
||||||
|
{ "1.2.3", "", INT_MIN },
|
||||||
|
{ "1.2.3", "2", INT_MIN },
|
||||||
|
|
||||||
|
/* Test cases for validity of A. */
|
||||||
|
{ "", NULL, INT_MIN },
|
||||||
|
{ "1", NULL, INT_MIN },
|
||||||
|
{ "1.", NULL, 0 },
|
||||||
|
{ "1.0", NULL, 0 },
|
||||||
|
{ "1.0.", NULL, 0 },
|
||||||
|
{ "a1.2", NULL, INT_MIN },
|
||||||
|
{ NULL, NULL, INT_MIN }
|
||||||
};
|
};
|
||||||
int idx;
|
int idx;
|
||||||
int res;
|
int res;
|
||||||
|
@ -195,7 +195,7 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
|
|||||||
if (err)
|
if (err)
|
||||||
log_error (_("error getting version from '%s': %s\n"),
|
log_error (_("error getting version from '%s': %s\n"),
|
||||||
servername, gpg_strerror (err));
|
servername, gpg_strerror (err));
|
||||||
else if (!compare_version_strings (serverversion, myversion))
|
else if (compare_version_strings (serverversion, myversion) < 0)
|
||||||
{
|
{
|
||||||
char *warn;
|
char *warn;
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername)
|
|||||||
if (err)
|
if (err)
|
||||||
log_error (_("error getting version from '%s': %s\n"),
|
log_error (_("error getting version from '%s': %s\n"),
|
||||||
servername, gpg_strerror (err));
|
servername, gpg_strerror (err));
|
||||||
else if (!compare_version_strings (serverversion, myversion))
|
else if (compare_version_strings (serverversion, myversion) < 0)
|
||||||
{
|
{
|
||||||
char *warn;
|
char *warn;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx,
|
|||||||
if (err)
|
if (err)
|
||||||
log_error (_("error getting version from '%s': %s\n"),
|
log_error (_("error getting version from '%s': %s\n"),
|
||||||
servername, gpg_strerror (err));
|
servername, gpg_strerror (err));
|
||||||
else if (!compare_version_strings (serverversion, myversion))
|
else if (compare_version_strings (serverversion, myversion) < 0)
|
||||||
{
|
{
|
||||||
char *warn;
|
char *warn;
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx,
|
|||||||
if (err)
|
if (err)
|
||||||
log_error (_("error getting version from '%s': %s\n"),
|
log_error (_("error getting version from '%s': %s\n"),
|
||||||
servername, gpg_strerror (err));
|
servername, gpg_strerror (err));
|
||||||
else if (!compare_version_strings (serverversion, myversion))
|
else if (compare_version_strings (serverversion, myversion) < 0)
|
||||||
{
|
{
|
||||||
char *warn;
|
char *warn;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user