In the original code, errors of Get{Vendor,Product}Id,
VBOX_UTF16_TO_UTF8, strtol were ignored.
In order to handle the errors, the patch introduces
vboxGetVendorProductIds utility function because adding error
codes in the loop is difficult.
Reported-by: Laine Stump <laine(a)laine.org>
Signed-off-by: Ryota Ozaki <ozaki.ryota(a)gmail.com>
---
src/vbox/vbox_tmpl.c | 74 ++++++++++++++++++++++++++++++++++++----------------
1 file changed, 51 insertions(+), 23 deletions(-)
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 9336514..27c21bd 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -2208,6 +2208,51 @@ vboxDomainGetMaxVcpus(virDomainPtr dom)
VIR_DOMAIN_VCPU_MAXIMUM));
}
+static int vboxGetVendorProductIds(vboxGlobalData *data,
+ IUSBDeviceFilter *deviceFilter,
+ unsigned *vendorId,
+ unsigned *productId)
+{
+ PRUnichar *idUtf16 = NULL;
+ char *idUtf8 = NULL;
+ char *endptr = NULL;
+ unsigned vId = 0;
+ unsigned pId = 0;
+ int result = -1;
+
+ if (deviceFilter->vtbl->GetVendorId(deviceFilter, &idUtf16) != 0)
+ goto out;
+
+ if (VBOX_UTF16_TO_UTF8(idUtf16, &idUtf8) < 0)
+ goto release_utf16;
+
+ if (virStrToLong_ui(idUtf8, &endptr, 16, &vId) < 0)
+ goto release_utf8;
+
+ VBOX_UTF8_FREE(idUtf8);
+ VBOX_UTF16_FREE(idUtf16);
+
+ if (deviceFilter->vtbl->GetProductId(deviceFilter, &idUtf16) != 0)
+ goto out;
+
+ if (VBOX_UTF16_TO_UTF8(idUtf16, &idUtf8) < 0)
+ goto release_utf16;
+
+ if (virStrToLong_ui(idUtf8, &endptr, 16, &pId) < 0)
+ goto release_utf8;
+
+ *vendorId = vId;
+ *productId = pId;
+ result = 0;
+
+release_utf8:
+ VBOX_UTF8_FREE(idUtf8);
+release_utf16:
+ VBOX_UTF16_FREE(idUtf16);
+out:
+ return result;
+}
+
static void vboxHostDeviceGetXMLDesc(vboxGlobalData *data, virDomainDefPtr def, IMachine
*machine)
{
#if VBOX_API_VERSION < 4003
@@ -2278,13 +2323,7 @@ static void vboxHostDeviceGetXMLDesc(vboxGlobalData *data,
virDomainDefPtr def,
for (i = 0; i < deviceFilters.count; i++) {
PRBool active = PR_FALSE;
IUSBDeviceFilter *deviceFilter = deviceFilters.items[i];
- PRUnichar *vendorIdUtf16 = NULL;
- char *vendorIdUtf8 = NULL;
- unsigned vendorId = 0;
- PRUnichar *productIdUtf16 = NULL;
- char *productIdUtf8 = NULL;
- unsigned productId = 0;
- char *endptr = NULL;
+ int res = 0;
deviceFilter->vtbl->GetActive(deviceFilter, &active);
if (!active)
@@ -2295,23 +2334,12 @@ static void vboxHostDeviceGetXMLDesc(vboxGlobalData *data,
virDomainDefPtr def,
def->hostdevs[USBFilterCount]->source.subsys.type =
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
- deviceFilter->vtbl->GetVendorId(deviceFilter, &vendorIdUtf16);
- deviceFilter->vtbl->GetProductId(deviceFilter, &productIdUtf16);
+ res = vboxGetVendorProductIds(data, deviceFilter,
+
&def->hostdevs[USBFilterCount]->source.subsys.u.usb.vendor,
+
&def->hostdevs[USBFilterCount]->source.subsys.u.usb.product);
- VBOX_UTF16_TO_UTF8(vendorIdUtf16, &vendorIdUtf8);
- VBOX_UTF16_TO_UTF8(productIdUtf16, &productIdUtf8);
-
- vendorId = strtol(vendorIdUtf8, &endptr, 16);
- productId = strtol(productIdUtf8, &endptr, 16);
-
- def->hostdevs[USBFilterCount]->source.subsys.u.usb.vendor = vendorId;
- def->hostdevs[USBFilterCount]->source.subsys.u.usb.product = productId;
-
- VBOX_UTF16_FREE(vendorIdUtf16);
- VBOX_UTF8_FREE(vendorIdUtf8);
-
- VBOX_UTF16_FREE(productIdUtf16);
- VBOX_UTF8_FREE(productIdUtf8);
+ if (res < 0)
+ goto release_hostdevs;
USBFilterCount++;
}
--
1.8.4