mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
util: choose whether to require micro in version strings
To avoid regressions, we let callers specify whether to require a minor and micro version. Callers that were parsing uname() output benefit from defaulting to 0, whereas callers that were parsing version strings from other sources should not change in behavior. * src/util/util.c (virParseVersionString): Allow caller to choose whether to fail if minor or micro is missing. * src/util/util.h (virParseVersionString): Update signature. * src/esx/esx_driver.c (esxGetVersion): Update callers. * src/lxc/lxc_driver.c (lxcVersion): Likewise. * src/openvz/openvz_conf.c (openvzExtractVersionInfo): Likewise. * src/uml/uml_driver.c (umlGetVersion): Likewise. * src/vbox/vbox_MSCOMGlue.c (vboxLookupVersionInRegistry): Likewise. * src/vbox/vbox_tmpl.c (vboxExtractVersion): Likewise. * src/vmware/vmware_conf.c (vmwareExtractVersion): Likewise. * src/xenapi/xenapi_driver.c (xenapiGetVersion): Likewise. Reported by Matthias Bolte.
This commit is contained in:
parent
6ae3052c06
commit
8ce1afff88
@ -1202,7 +1202,7 @@ esxGetVersion(virConnectPtr conn, unsigned long *version)
|
|||||||
esxPrivate *priv = conn->privateData;
|
esxPrivate *priv = conn->privateData;
|
||||||
|
|
||||||
if (virParseVersionString(priv->primary->service->about->version,
|
if (virParseVersionString(priv->primary->service->about->version,
|
||||||
version) < 0) {
|
version, false) < 0) {
|
||||||
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Could not parse version number from '%s'"),
|
_("Could not parse version number from '%s'"),
|
||||||
priv->primary->service->about->version);
|
priv->primary->service->about->version);
|
||||||
|
@ -2249,7 +2249,7 @@ static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *versio
|
|||||||
|
|
||||||
uname(&ver);
|
uname(&ver);
|
||||||
|
|
||||||
if (virParseVersionString(ver.release, version) < 0) {
|
if (virParseVersionString(ver.release, version, true) < 0) {
|
||||||
lxcError(VIR_ERR_INTERNAL_ERROR, _("Unknown release: %s"), ver.release);
|
lxcError(VIR_ERR_INTERNAL_ERROR, _("Unknown release: %s"), ver.release);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ openvzExtractVersionInfo(const char *cmdstr, int *retversion)
|
|||||||
if ((tmp = STRSKIP(tmp, "vzctl version ")) == NULL)
|
if ((tmp = STRSKIP(tmp, "vzctl version ")) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virParseVersionString(tmp, &version) < 0)
|
if (virParseVersionString(tmp, &version, false) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (retversion)
|
if (retversion)
|
||||||
|
@ -1227,7 +1227,7 @@ static int umlGetVersion(virConnectPtr conn, unsigned long *version) {
|
|||||||
if (driver->umlVersion == 0) {
|
if (driver->umlVersion == 0) {
|
||||||
uname(&ut);
|
uname(&ut);
|
||||||
|
|
||||||
if (virParseVersionString(ut.release, &driver->umlVersion) < 0) {
|
if (virParseVersionString(ut.release, &driver->umlVersion, true) < 0) {
|
||||||
umlReportError(VIR_ERR_INTERNAL_ERROR,
|
umlReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("cannot parse version %s"), ut.release);
|
_("cannot parse version %s"), ut.release);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -1585,6 +1585,8 @@ virParseNumber(const char **str)
|
|||||||
* virParseVersionString:
|
* virParseVersionString:
|
||||||
* @str: const char pointer to the version string
|
* @str: const char pointer to the version string
|
||||||
* @version: unsigned long pointer to output the version number
|
* @version: unsigned long pointer to output the version number
|
||||||
|
* @allowMissing: true to treat 3 like 3.0.0, false to error out on
|
||||||
|
* missing minor or micro
|
||||||
*
|
*
|
||||||
* Parse an unsigned version number from a version string. Expecting
|
* Parse an unsigned version number from a version string. Expecting
|
||||||
* 'major.minor.micro' format, ignoring an optional suffix.
|
* 'major.minor.micro' format, ignoring an optional suffix.
|
||||||
@ -1596,7 +1598,8 @@ virParseNumber(const char **str)
|
|||||||
* Returns the 0 for success, -1 for error.
|
* Returns the 0 for success, -1 for error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virParseVersionString(const char *str, unsigned long *version)
|
virParseVersionString(const char *str, unsigned long *version,
|
||||||
|
bool allowMissing)
|
||||||
{
|
{
|
||||||
unsigned int major, minor = 0, micro = 0;
|
unsigned int major, minor = 0, micro = 0;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
@ -1604,12 +1607,21 @@ virParseVersionString(const char *str, unsigned long *version)
|
|||||||
if (virStrToLong_ui(str, &tmp, 10, &major) < 0)
|
if (virStrToLong_ui(str, &tmp, 10, &major) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (!allowMissing && *tmp != '.')
|
||||||
|
return -1;
|
||||||
|
|
||||||
if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0)
|
if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (!allowMissing && *tmp != '.')
|
||||||
|
return -1;
|
||||||
|
|
||||||
if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0)
|
if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (major > UINT_MAX / 1000000 || minor > 999 || micro > 999)
|
||||||
|
return -1;
|
||||||
|
|
||||||
*version = 1000000 * major + 1000 * minor + micro;
|
*version = 1000000 * major + 1000 * minor + micro;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -168,7 +168,8 @@ int virMacAddrCompare (const char *mac1, const char *mac2);
|
|||||||
|
|
||||||
void virSkipSpaces(const char **str);
|
void virSkipSpaces(const char **str);
|
||||||
int virParseNumber(const char **str);
|
int virParseNumber(const char **str);
|
||||||
int virParseVersionString(const char *str, unsigned long *version);
|
int virParseVersionString(const char *str, unsigned long *version,
|
||||||
|
bool allowMissing);
|
||||||
int virAsprintf(char **strp, const char *fmt, ...)
|
int virAsprintf(char **strp, const char *fmt, ...)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3);
|
||||||
int virVasprintf(char **strp, const char *fmt, va_list list)
|
int virVasprintf(char **strp, const char *fmt, va_list list)
|
||||||
|
@ -430,7 +430,7 @@ vboxLookupVersionInRegistry(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virParseVersionString(value, &vboxVersion) < 0) {
|
if (virParseVersionString(value, &vboxVersion, false) < 0) {
|
||||||
VIR_ERROR(_("Could not parse version number from '%s'"), value);
|
VIR_ERROR(_("Could not parse version number from '%s'"), value);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -929,7 +929,7 @@ static int vboxExtractVersion(vboxGlobalData *data) {
|
|||||||
|
|
||||||
VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion);
|
VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion);
|
||||||
|
|
||||||
if (virParseVersionString(vboxVersion, &data->version) >= 0)
|
if (virParseVersionString(vboxVersion, &data->version, false) >= 0)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
VBOX_UTF8_FREE(vboxVersion);
|
VBOX_UTF8_FREE(vboxVersion);
|
||||||
|
@ -248,7 +248,7 @@ vmwareExtractVersion(struct vmware_driver *driver)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virParseVersionString(tmp, &version) < 0) {
|
if (virParseVersionString(tmp, &version, false) < 0) {
|
||||||
vmwareError(VIR_ERR_INTERNAL_ERROR, "%s",
|
vmwareError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("version parsing error"));
|
_("version parsing error"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -302,7 +302,7 @@ xenapiGetVersion (virConnectPtr conn, unsigned long *hvVer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (version) {
|
if (version) {
|
||||||
if (virParseVersionString(version, hvVer) < 0)
|
if (virParseVersionString(version, hvVer, false) < 0)
|
||||||
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR,
|
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Couldn't parse version info"));
|
_("Couldn't parse version info"));
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user