ptp2: another round of memory leak fixes of PTPCanonEOSEvent

See f4313fdb74
This commit is contained in:
axxel
2024-10-13 13:10:39 +02:00
committed by Marcus Meissner
parent d8eb297571
commit 0f8b0d2416
3 changed files with 43 additions and 7 deletions

View File

@@ -4489,17 +4489,15 @@ camera_canon_eos_capture (Camera *camera, CameraCaptureType type, CameraFilePath
case PTP_EOSEvent_ObjectTransfer:
GP_LOG_D ("object transfer requested: handle 0x%x, name %s, size %lu",
event.u.object.Handle, event.u.object.Filename, event.u.object.ObjectSize);
oi = event.u.object;
move(oi, event.u.object);
break;
case PTP_EOSEvent_ObjectRemoved:
GP_LOG_D ("object removed: handle 0x%x", event.u.object.Handle);
ptp_free_objectinfo(&event.u.object);
ptp_remove_object_from_cache(params, event.u.object.Handle);
gp_filesystem_reset (camera->fs);
break;
case PTP_EOSEvent_ObjectAdded: {
GP_LOG_D ("object added: handle 0x%x, name %s", event.u.object.Handle, event.u.object.Filename);
ptp_free_objectinfo(&event.u.object);
/* just add it to the filesystem, and return in CameraPath */
/* We have some form of objectinfo in event.u.object already, but we let the
@@ -4510,13 +4508,14 @@ camera_canon_eos_capture (Camera *camera, CameraCaptureType type, CameraFilePath
if (event.u.object.ObjectFormat == PTP_OFC_Association)
continue;
gp_filesystem_append (camera->fs, path->folder, path->name, context);
oi = event.u.object;
move(oi, event.u.object);
break;
}
default:
GP_LOG_D ("unhandled eos event '%s'", ptp_get_eos_event_name(params, event.type));
break;
}
ptp_free_eos_event(&event);
/* for RAW+JPG mode capture, we just return the first image for now, and let wait_for_event get the rest. */
if (oi.Handle)
break;
@@ -6010,6 +6009,8 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context)
/* Discard all collected events before starting the next capture. */
GP_LOG_D("discarding %d EOS events", params->eos_events.len);
for_each (PTPCanonEOSEvent*, pevt, params->eos_events)
ptp_free_eos_event (pevt);
free_array (&params->eos_events);
if (params->eos_camerastatus == 1)
@@ -6080,6 +6081,7 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context)
ptp_free_devicepropdesc (&dpd);
}
}
ptp_free_eos_event(&event);
}
/* We found focus information, so half way pressing has finished! */
if (in_focus)
@@ -6151,6 +6153,7 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context)
}
break;
}
ptp_free_eos_event(&event);
}
} while (!eos_m_focus_done && waiting_for_timeout (&back_off_wait, focus_start, 2*1000)); /* wait 2 seconds for focus */
/* full release now (even if the press has failed) */
@@ -6639,7 +6642,7 @@ camera_wait_for_event (Camera *camera, int timeout,
case PTP_EOSEvent_ObjectTransfer:
GP_LOG_D ("object transfer requested: handle 0x%x, name %s, size %lu",
eos_event.u.object.Handle, eos_event.u.object.Filename, eos_event.u.object.ObjectSize);
ptp_free_objectinfo(&eos_event.u.object);
ptp_free_eos_event(&eos_event);
C_MEM (path = calloc(1, sizeof(CameraFilePath)));
strcpy (path->folder,"/");
@@ -6718,7 +6721,7 @@ camera_wait_for_event (Camera *camera, int timeout,
return GP_OK;
case PTP_EOSEvent_ObjectContentChanged: {
GP_LOG_D ("object content changed: handle 0x%x", eos_event.u.object.Handle);
ptp_free_objectinfo(&eos_event.u.object);
ptp_free_eos_event(&eos_event);
/* It might have gone away in the meantime */
PTPObject *ob;
if (PTP_RC_OK != ptp_object_want(params, eos_event.u.object.Handle, PTPOBJECT_OBJECTINFO_LOADED, &ob))
@@ -6741,7 +6744,7 @@ camera_wait_for_event (Camera *camera, int timeout,
case PTP_EOSEvent_ObjectAdded:
case PTP_EOSEvent_ObjectInfoChanged: {
GP_LOG_D ("object added: handle 0x%x, name %s", eos_event.u.object.Handle, eos_event.u.object.Filename);
ptp_free_objectinfo(&eos_event.u.object);
ptp_free_eos_event(&eos_event);
PTPObject *ob;
if ( (eos_event.type == PTP_EOSEvent_ObjectInfoChanged) &&
(PTP_RC_OK != ptp_object_find (params, eos_event.u.object.Handle, &ob))
@@ -6828,11 +6831,13 @@ camera_wait_for_event (Camera *camera, int timeout,
GP_LOG_D ("object removed: handle 0x%x", eos_event.u.object.Handle);
ptp_remove_object_from_cache(params, eos_event.u.object.Handle);
gp_filesystem_reset (camera->fs);
ptp_free_eos_event(&eos_event);
*eventtype = GP_EVENT_UNKNOWN;
*eventdata = aprintf("ObjectRemoved");
return GP_OK;
default:
GP_LOG_D ("Unhandled EOS event 0x%04x", eos_event.type);
ptp_free_eos_event(&eos_event);
break;
}
}

View File

@@ -2044,6 +2044,28 @@ ptp_free_objectpropdesc(PTPObjectPropDesc* opd)
}
}
void ptp_free_eos_event(PTPCanonEOSEvent *eos_event)
{
/* TODO: this function only exists because of the heap allocated Filename and Keyword members of
* of PTPObjectInfo. This function needs to be called on every ptp_get_one_eos_event() result.
* There are still tons of potential memory leaks in all sorts of error paths. The only sane solution
* to this is, to make the Filename property a statically sized string (and drop Keywords, which is
* unused anyway).
*/
switch (eos_event->type)
{
case PTP_EOSEvent_ObjectAdded:
case PTP_EOSEvent_ObjectContentChanged:
case PTP_EOSEvent_ObjectInfoChanged:
case PTP_EOSEvent_ObjectRemoved:
case PTP_EOSEvent_ObjectTransfer:
ptp_free_objectinfo(&eos_event->u.object);
break;
default:
break;
}
}
/**
* ptp_free_params:
@@ -2069,6 +2091,9 @@ ptp_free_params (PTPParams *params)
ptp_free_devicepropdesc (&params->canon_props[i]);
}
free (params->canon_props);
for_each (PTPCanonEOSEvent*, pevt, params->eos_events)
ptp_free_eos_event (pevt);
free_array (&params->eos_events);
for (i=0;i<params->dpd_cache_len;i++)

View File

@@ -74,6 +74,11 @@ static inline uint32_t _post_inc(uint32_t* o, int n)
#define ARRAYSIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
#define move(dst, src) do { \
dst = src; \
memset(&(src), 0, sizeof(src)); \
} while(0)
/* The follow set of macros implements a generic array or list of TYPE.
* This is basically a TYPE* pointer and a length integer. This structure
* together with the typical use-cases repeats regularly throughout the
@@ -4943,6 +4948,7 @@ void ptp_free_propvalue (uint16_t, PTPPropValue*);
void ptp_free_deviceinfo (PTPDeviceInfo *);
void ptp_free_objectinfo (PTPObjectInfo *oi);
void ptp_free_object (PTPObject *oi);
void ptp_free_eos_event (PTPCanonEOSEvent *);
const char *ptp_strerror (uint16_t ret, uint16_t vendor);
void ptp_debug (PTPParams *params, const char *format, ...)