summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFTDI Dev <jenkins@ftdichip.com>2016-03-02 16:29:27 +0000
committerChris Dickens <christopher.a.dickens@gmail.com>2016-05-29 19:56:17 -0700
commitadb6e39b68699b5d849836f9aaff7640b0f16173 (patch)
tree47db3eab0eff3fe3c48f8c633d204f9456e898bb
parentad6f23480ecfbe10a34a78afde58fdac32d3e457 (diff)
downloadlibusb-adb6e39b68699b5d849836f9aaff7640b0f16173.tar.gz
Clean failure in discovered_devs_append.
Closes #161 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/core.c40
-rw-r--r--libusb/version_nano.h2
2 files changed, 25 insertions, 17 deletions
diff --git a/libusb/core.c b/libusb/core.c
index d57edad..54c1010 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -627,6 +627,16 @@ static struct discovered_devs *discovered_devs_alloc(void)
return ret;
}
+static void discovered_devs_free(struct discovered_devs *discdevs)
+{
+ size_t i;
+
+ for (i = 0; i < discdevs->len; i++)
+ libusb_unref_device(discdevs->devices[i]);
+
+ free(discdevs);
+}
+
/* append a device to the discovered devices collection. may realloc itself,
* returning new discdevs. returns NULL on realloc failure. */
struct discovered_devs *discovered_devs_append(
@@ -634,6 +644,7 @@ struct discovered_devs *discovered_devs_append(
{
size_t len = discdevs->len;
size_t capacity;
+ struct discovered_devs *new_discdevs;
/* if there is space, just append the device */
if (len < discdevs->capacity) {
@@ -645,25 +656,21 @@ struct discovered_devs *discovered_devs_append(
/* exceeded capacity, need to grow */
usbi_dbg("need to increase capacity");
capacity = discdevs->capacity + DISCOVERED_DEVICES_SIZE_STEP;
- discdevs = usbi_reallocf(discdevs,
+ /* can't use usbi_reallocf here because in failure cases it would
+ * free the existing discdevs without unreferencing its devices. */
+ new_discdevs = realloc(discdevs,
sizeof(*discdevs) + (sizeof(void *) * capacity));
- if (discdevs) {
- discdevs->capacity = capacity;
- discdevs->devices[len] = libusb_ref_device(dev);
- discdevs->len++;
+ if (!new_discdevs) {
+ discovered_devs_free(discdevs);
+ return NULL;
}
- return discdevs;
-}
-
-static void discovered_devs_free(struct discovered_devs *discdevs)
-{
- size_t i;
-
- for (i = 0; i < discdevs->len; i++)
- libusb_unref_device(discdevs->devices[i]);
+ discdevs = new_discdevs;
+ discdevs->capacity = capacity;
+ discdevs->devices[len] = libusb_ref_device(dev);
+ discdevs->len++;
- free(discdevs);
+ return discdevs;
}
/* Allocate a new device with a specific session ID. The returned device has
@@ -854,7 +861,8 @@ ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx,
*list = ret;
out:
- discovered_devs_free(discdevs);
+ if (discdevs)
+ discovered_devs_free(discdevs);
return len;
}
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 17cd90c..9e02ae0 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11112
+#define LIBUSB_NANO 11113