Darwin: Fix #65 memory leak in submit_iso_transfer()
authorThomas Röfer <Thomas.Roefer@dfki.de>
Fri, 19 Nov 2010 21:03:11 +0000 (22:03 +0100)
committerPeter Stuge <peter@stuge.se>
Mon, 13 Jun 2011 20:01:43 +0000 (22:01 +0200)
This was also independently fixed by Hoi-Ho Chan, but Thomas caught
an additional problem with his fix.

This commit came via OpenKinect into libusb thanks to Kyle Machulis
and Hector Martin.

libusb/os/darwin_usb.c
libusb/os/darwin_usb.h

index 4bd13d4..9121dd1 100644 (file)
@@ -1182,10 +1182,18 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer) {
   /* are we reading or writing? */
   is_read = transfer->endpoint & LIBUSB_ENDPOINT_IN;
 
-  /* construct an array of IOUSBIsocFrames */
-  tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
-  if (!tpriv->isoc_framelist)
-    return LIBUSB_ERROR_NO_MEM;
+  /* construct an array of IOUSBIsocFrames, reuse the old one if possible */
+  if (tpriv->isoc_framelist && tpriv->num_iso_packets != transfer->num_iso_packets) {
+    free(tpriv->isoc_framelist);
+    tpriv->isoc_framelist = NULL;
+  }
+
+  if (!tpriv->isoc_framelist) {
+    tpriv->num_iso_packets = transfer->num_iso_packets;
+    tpriv->isoc_framelist = (IOUSBIsocFrame*) calloc (transfer->num_iso_packets, sizeof(IOUSBIsocFrame));
+    if (!tpriv->isoc_framelist)
+      return LIBUSB_ERROR_NO_MEM;
+  }
 
   /* copy the frame list from the libusb descriptor (the structures differ only is member order) */
   for (i = 0 ; i < transfer->num_iso_packets ; i++)
index a71d464..dc14ed6 100644 (file)
@@ -146,6 +146,7 @@ struct darwin_device_handle_priv {
 struct darwin_transfer_priv {
   /* Isoc */
   IOUSBIsocFrame *isoc_framelist;
+  size_t num_iso_packets;
 
   /* Control */
 #if !defined (LIBUSB_NO_TIMEOUT_DEVICE)