From 0a68e763e1ba86befd07018843b97898b0b5b86c Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 20 Sep 2024 09:36:16 +0200 Subject: [PATCH 1/2] improve API of ptp_unpack_string and ptp_unpack_uint[16|32]_array Those functions get passed an offset value into the data buffer. This offset value needed to be updated on the calling side after the call with internal knowledge of what exactly the unpack function itself was doing. Now the offset becomes an in/out parameter and in updated internally. This substantially reduces the complexity of the calling code. Furthermore, the return value is now an error indicator and the array length gets set via a pointer. This further fixes a few places where there was a bug in the bounds checking or no bounds checking at all. --- camlibs/ptp2/ptp-pack.c | 415 ++++++++++++++-------------------------- camlibs/ptp2/ptp.c | 91 ++++----- 2 files changed, 183 insertions(+), 323 deletions(-) diff --git a/camlibs/ptp2/ptp-pack.c b/camlibs/ptp2/ptp-pack.c index 2803eacc4..65189b36d 100644 --- a/camlibs/ptp2/ptp-pack.c +++ b/camlibs/ptp2/ptp-pack.c @@ -142,62 +142,52 @@ dtoh64ap (PTPParams *params, const unsigned char *a) * len - in ptp string characters currently */ static inline int -ptp_unpack_string(PTPParams *params, const unsigned char* data, uint32_t offset, uint32_t total, uint8_t *len, char **retstr) +ptp_unpack_string(PTPParams *params, const unsigned char* data, uint32_t *offset, uint32_t size, char **result) { - uint8_t length; - uint16_t string[PTP_MAXSTRLEN+1]; + uint8_t ucs2len; /* length of the string in UCS-2 chars, including terminating \0 */ + uint16_t ucs2src[PTP_MAXSTRLEN+1]; /* allow for UTF-8: max of 3 bytes per UCS-2 char, plus final null */ - char loclstr[PTP_MAXSTRLEN*3+1]; - size_t nconv, srclen, destlen; - char *src, *dest; + char utf8dest[PTP_MAXSTRLEN*3+1] = { 0 }; - *len = 0; - *retstr = NULL; + if (!data || !offset || !result) + return 0; + + *result = NULL; - if (offset + 1 > total) + if (*offset + 1 > size) return 0; - length = dtoh8a(&data[offset]); /* PTP_MAXSTRLEN == 255, 8 bit len */ - if (length == 0) { /* nothing to do? */ - *len = 0; - *retstr = strdup(""); /* return an empty string, not NULL */ + ucs2len = dtoh8a(data + *offset); /* PTP_MAXSTRLEN == 255, 8 bit len */ + *offset += 1; + if (ucs2len == 0) { /* nothing to do? */ + *result = strdup(""); /* return an empty string, not NULL */ return 1; } - if (offset + 1 + length*sizeof(string[0]) > total) + if (*offset + ucs2len * sizeof(ucs2src[0]) > size) return 0; - *len = length; - /* copy to string[] to ensure correct alignment for iconv(3) */ - memcpy(string, &data[offset+1], length * sizeof(string[0])); - string[length] = 0x0000U; /* be paranoid! add a terminator. */ - loclstr[0] = '\0'; + memcpy(ucs2src, data + *offset, ucs2len * sizeof(ucs2src[0])); + ucs2src[ucs2len] = 0; /* be paranoid! add a terminator. */ /* convert from camera UCS-2 to our locale */ - src = (char *)string; - srclen = length * sizeof(string[0]); - dest = loclstr; - destlen = sizeof(loclstr)-1; - nconv = (size_t)-1; + size_t nconv = (size_t)-1; #if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) + char* src = (char *)ucs2src; + size_t srclen = ucs2len * sizeof(ucs2src[0]); + char* dest = utf8dest; + size_t destlen = sizeof(utf8dest)-1; if (params->cd_ucs2_to_locale != (iconv_t)-1) nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, &dest, &destlen); #endif if (nconv == (size_t) -1) { /* do it the hard way */ - int i; /* try the old way, in case iconv is broken */ - for (i=0;i127) - loclstr[i] = '?'; - else - loclstr[i] = dtoh16a(&data[offset+1+2*i]); - } - dest = loclstr+length; + for (int i=0;i<=ucs2len;i++) + utf8dest[i] = ucs2src[i] > 127 ? '?' : (char)ucs2src[i]; } - *dest = '\0'; - loclstr[sizeof(loclstr)-1] = '\0'; /* be safe? */ - *retstr = strdup(loclstr); + *result = strdup(utf8dest); + *offset += 2 * ucs2len; return 1; } @@ -286,38 +276,39 @@ ptp_get_packed_stringcopy(PTPParams *params, const char *string, uint32_t *packe return (retcopy); } -static inline uint32_t -ptp_unpack_uint32_t_array(PTPParams *params, const unsigned char* data, unsigned int offset, unsigned int datalen, uint32_t **array) +static inline int +ptp_unpack_uint32_t_array(PTPParams *params, const uint8_t* data, uint32_t *offset, uint32_t datalen, + uint32_t **array, uint32_t* arraylen) { - uint32_t n, i=0; - - if (!data) + if (!array || !arraylen) return 0; - if (offset >= datalen) - return 0; + *array = NULL; + *arraylen = 0; - if (offset + sizeof(uint32_t) > datalen) + if (!data || *offset + sizeof(uint32_t) > datalen) return 0; - *array = NULL; - n=dtoh32a(&data[offset]); - if (n >= UINT_MAX/sizeof(uint32_t)) - return 0; - if (!n) - return 0; + uint32_t n = dtoh32a(data + *offset); + *offset += sizeof(uint32_t); + if (n == 0) + return 1; - if (offset + sizeof(uint32_t)*(n+1) > datalen) { - ptp_debug (params ,"array runs over datalen bufferend (%ld vs %d)", offset + sizeof(uint32_t)*(n+1) , datalen); + if (*offset + n * sizeof(uint32_t) > datalen) { + ptp_debug (params ,"array runs over datalen buffer end (%ld vs %u)", *offset + n * sizeof(uint32_t) , datalen); return 0; } - *array = calloc (n,sizeof(uint32_t)); + *array = calloc (n, sizeof(uint32_t)); if (!*array) return 0; - for (i=0;i datalen) return 0; - n=dtoh32a(&data[offset]); - if (n >= (UINT_MAX - offset - sizeof(uint32_t))/sizeof(uint16_t)) - return 0; - if (!n) - return 0; - if (offset + sizeof(uint32_t) > datalen) - return 0; - if (offset + sizeof(uint32_t)+sizeof(uint16_t)*n > datalen) { - ptp_debug (params ,"array runs over datalen bufferend (%ld vs %d)", offset + sizeof(uint32_t)+n*sizeof(uint16_t) , datalen); + uint32_t n = dtoh32a(data + *offset); + *offset += sizeof(uint32_t); + if (n == 0) + return 1; + + if (*offset + n * sizeof(uint16_t) > datalen) { + ptp_debug (params ,"array runs over datalen buffer end (%ld vs %u)", *offset + n * sizeof(uint16_t) , datalen); return 0; } - *array = calloc (n,sizeof(uint16_t)); + + *array = calloc (n, sizeof(uint16_t)); if (!*array) return 0; - for (i=0;iStandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); - di->VendorExtensionID = - dtoh32a(&data[PTP_di_VendorExtensionID]); - di->VendorExtensionVersion = - dtoh16a(&data[PTP_di_VendorExtensionVersion]); - if (!ptp_unpack_string(params, data, - PTP_di_VendorExtensionDesc, - datalen, - &len, - &di->VendorExtensionDesc) - ) + di->StandardVersion = dtoh16a(data + PTP_di_StandardVersion); + di->VendorExtensionID = dtoh32a(data + PTP_di_VendorExtensionID); + di->VendorExtensionVersion = dtoh16a(data + PTP_di_VendorExtensionVersion); + offset = PTP_di_VendorExtensionDesc; + if (!ptp_unpack_string(params, data, &offset, datalen, &di->VendorExtensionDesc)) return 0; - totallen=len*2+1; - if (datalen <= totallen + PTP_di_FunctionalMode + sizeof(uint16_t)) { - ptp_debug (params, "datalen %d <= totallen + PTP_di_FunctionalMode + sizeof(uint16_t) %ld", - datalen, totallen + PTP_di_FunctionalMode + sizeof(uint16_t)); - return 0; - } - di->FunctionalMode = - dtoh16a(&data[PTP_di_FunctionalMode+totallen]); - di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &di->OperationsSupported); - totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 1", datalen, totallen+PTP_di_OperationsSupported); + if (datalen <= offset + sizeof(uint16_t)) { + ptp_debug (params, "FunctionalMode outside buffer bounds (%ld > %u)", offset + sizeof(uint16_t), datalen); return 0; } - di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &di->EventsSupported); - totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 2", datalen, totallen+PTP_di_OperationsSupported); + di->FunctionalMode = dtoh16a(data + offset); + offset += 2; + if (!ptp_unpack_uint16_t_array(params, data, &offset, datalen, &di->OperationsSupported, &di->OperationsSupported_len)) { + ptp_debug (params, "failed to unpack OperationsSupported array"); return 0; } - di->DevicePropertiesSupported_len = - ptp_unpack_uint16_t_array(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &di->DevicePropertiesSupported); - totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 3", datalen, totallen+PTP_di_OperationsSupported); + if (!ptp_unpack_uint16_t_array(params, data, &offset, datalen, &di->EventsSupported, &di->EventsSupported_len)) { + ptp_debug (params, "failed to unpack EventsSupported array"); return 0; } - di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &di->CaptureFormats); - totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 4", datalen, totallen+PTP_di_OperationsSupported); + if (!ptp_unpack_uint16_t_array(params, data, &offset, datalen, &di->DevicePropertiesSupported, &di->DevicePropertiesSupported_len)) { + ptp_debug (params, "failed to unpack DevicePropertiesSupported array"); return 0; } - di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &di->ImageFormats); - totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 5", datalen, totallen+PTP_di_OperationsSupported); + if (!ptp_unpack_uint16_t_array(params, data, &offset, datalen, &di->CaptureFormats, &di->CaptureFormats_len)) { + ptp_debug (params, "failed to unpack CaptureFormats array"); return 0; } - if (!ptp_unpack_string(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &len, - &di->Manufacturer) - ) + if (!ptp_unpack_uint16_t_array(params, data, &offset, datalen, &di->ImageFormats, &di->ImageFormats_len)) { + ptp_debug (params, "failed to unpack ImageFormats array"); return 0; - totallen+=len*2+1; - /* be more relaxed ... as these are optional its ok if they are not here */ - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 6", datalen, totallen+PTP_di_OperationsSupported); - return 1; } - if (!ptp_unpack_string(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &len, - &di->Model) - ) - return 1; - totallen+=len*2+1; - /* be more relaxed ... as these are optional its ok if they are not here */ - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 7", datalen, totallen+PTP_di_OperationsSupported); - return 1; - } - if (!ptp_unpack_string(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &len, - &di->DeviceVersion) - ) - return 1; - totallen+=len*2+1; + /* be more relaxed ... as these are optional its ok if they are not here */ - if (datalen <= totallen+PTP_di_OperationsSupported) { - ptp_debug (params, "datalen %d <= totallen+PTP_di_OperationsSupported %d 8", datalen, totallen+PTP_di_OperationsSupported); - return 1; - } - if (!ptp_unpack_string(params, data, - PTP_di_OperationsSupported+totallen, - datalen, - &len, - &di->SerialNumber) - ) - return 1; + if (!ptp_unpack_string(params, data, &offset, datalen, &di->Manufacturer)) + ptp_debug (params, "failed to unpack Manufacturer string"); + + if (!ptp_unpack_string(params, data, &offset, datalen, &di->Model)) + ptp_debug (params, "failed to unpack Model string"); + + if (!ptp_unpack_string(params, data, &offset, datalen, &di->DeviceVersion)) + ptp_debug (params, "failed to unpack DeviceVersion string"); + + if (!ptp_unpack_string(params, data, &offset, datalen, &di->SerialNumber)) + ptp_debug (params, "failed to unpack SerialNumber string"); + return 1; } @@ -517,29 +445,15 @@ ptp_free_DI (PTPDeviceInfo *di) { static inline int ptp_unpack_EOS_DI (PTPParams *params, const unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen) { - unsigned int totallen = 4; + uint32_t offset = 4; memset (di,0, sizeof(*di)); - if (datalen < 8) return 0; - - /* uint32_t struct len - ignore */ - di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data, - totallen, datalen, &di->EventsSupported); - if (!di->EventsSupported) return 0; - totallen += di->EventsSupported_len*sizeof(uint32_t)+4; - if (totallen >= datalen) return 0; - - di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data, - totallen, datalen, &di->DevicePropertiesSupported); - if (!di->DevicePropertiesSupported) return 0; - totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4; - if (totallen >= datalen) return 0; - - di->unk_len = ptp_unpack_uint32_t_array(params, data, - totallen, datalen, &di->unk); - if (!di->unk) return 0; - totallen += di->unk_len*sizeof(uint32_t)+4; - return 1; + + ptp_unpack_uint32_t_array(params, data, &offset, datalen, &di->EventsSupported, &di->EventsSupported_len); + ptp_unpack_uint32_t_array(params, data, &offset, datalen, &di->DevicePropertiesSupported, &di->DevicePropertiesSupported_len); + ptp_unpack_uint32_t_array(params, data, &offset, datalen, &di->unk, &di->unk_len); + + return offset >= 16; } static inline void @@ -552,33 +466,20 @@ ptp_free_EOS_DI (PTPCanonEOSDeviceInfo *di) /* ObjectHandles array pack/unpack */ -#define PTP_oh 0 - static inline void ptp_unpack_OH (PTPParams *params, const unsigned char* data, PTPObjectHandles *oh, unsigned int len) { - if (len) { - oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, len, &oh->Handler); - } else { - oh->n = 0; - oh->Handler = NULL; - } + uint32_t offset = 0; + ptp_unpack_uint32_t_array(params, data, &offset, len, &oh->Handler, &oh->n); } /* StoreIDs array pack/unpack */ -#define PTP_sids 0 - static inline void ptp_unpack_SIDs (PTPParams *params, const unsigned char* data, PTPStorageIDs *sids, unsigned int len) { - sids->n = 0; - sids->Storage = NULL; - - if (!data || !len) - return; - - sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, len, &sids->Storage); + uint32_t offset = 0; + ptp_unpack_uint32_t_array(params, data, &offset, len, &sids->Storage, &sids->n); } /* StorageInfo pack/unpack */ @@ -594,8 +495,6 @@ ptp_unpack_SIDs (PTPParams *params, const unsigned char* data, PTPStorageIDs *si static inline int ptp_unpack_SI (PTPParams *params, const unsigned char* data, PTPStorageInfo *si, unsigned int len) { - uint8_t storagedescriptionlen; - if (!data || len < 26) return 0; si->StorageType=dtoh16a(&data[PTP_si_StorageType]); si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); @@ -604,21 +503,14 @@ ptp_unpack_SI (PTPParams *params, const unsigned char* data, PTPStorageInfo *si, si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); - /* FIXME: check more lengths here */ - if (!ptp_unpack_string(params, data, - PTP_si_StorageDescription, - len, - &storagedescriptionlen, - &si->StorageDescription) - ) - return 0; + uint32_t offset = PTP_si_StorageDescription; - if (!ptp_unpack_string(params, data, - PTP_si_StorageDescription+storagedescriptionlen*2+1, - len, - &storagedescriptionlen, - &si->VolumeLabel)) { - ptp_debug(params, "could not unpack storage description"); + if (!ptp_unpack_string(params, data, &offset, len, &si->StorageDescription)) { + ptp_debug(params, "could not unpack StorageDescription"); + return 0; + } + if (!ptp_unpack_string(params, data, &offset, len, &si->VolumeLabel)) { + ptp_debug(params, "could not unpack VolumeLabel"); return 0; } return 1; @@ -758,8 +650,6 @@ ptp_unpack_PTPTIME (const char *str) { static inline void ptp_unpack_OI (PTPParams *params, const unsigned char* data, PTPObjectInfo *oi, unsigned int len) { - uint8_t filenamelen; - uint8_t capturedatelen; char *capture_date; if (!data || len < PTP_oi_SequenceNumber) @@ -792,19 +682,15 @@ ptp_unpack_OI (PTPParams *params, const unsigned char* data, PTPObjectInfo *oi, oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); - ptp_unpack_string(params, data, PTP_oi_filenamelen, len, &filenamelen, &oi->Filename); - ptp_unpack_string(params, data, PTP_oi_filenamelen+filenamelen*2+1, len, &capturedatelen, &capture_date); - /* subset of ISO 8601, without '.s' tenths of second and - * time zone - */ + uint32_t offset = PTP_oi_filenamelen; + ptp_unpack_string(params, data, &offset, len, &oi->Filename); + ptp_unpack_string(params, data, &offset, len, &capture_date); + /* subset of ISO 8601, without '.s' tenths of second and time zone */ oi->CaptureDate = ptp_unpack_PTPTIME(capture_date); free(capture_date); /* now the modification date ... */ - ptp_unpack_string(params, data, - PTP_oi_filenamelen+filenamelen*2 - +capturedatelen*2+2, len, &capturedatelen, &capture_date - ); + ptp_unpack_string(params, data, &offset, len, &capture_date); oi->ModificationDate = ptp_unpack_PTPTIME(capture_date); free(capture_date); } @@ -907,15 +793,9 @@ ptp_unpack_DPV ( /* XXX: other int types are unimplemented */ /* XXX: other int arrays are unimplemented also */ case PTP_DTC_STR: { - uint8_t len; /* XXX: max size */ - - if (*offset >= total+1) - return 0; - - if (!ptp_unpack_string(params,data,*offset,total,&len,&value->str)) + if (!ptp_unpack_string(params, data, offset, total, &value->str)) return 0; - *offset += len*2+1; break; } default: @@ -1225,7 +1105,6 @@ static inline int ptp_unpack_OPD (PTPParams *params, const unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) { unsigned int offset=0, ret; - uint8_t len; memset (opd, 0, sizeof(*opd)); @@ -1288,14 +1167,10 @@ ptp_unpack_OPD (PTPParams *params, const unsigned char* data, PTPObjectPropDesc } break; case PTP_OPFF_DateTime: - if (!ptp_unpack_string(params, data, offset, opdlen, &len, &opd->FORM.DateTime.String)) - opd->FORM.DateTime.String = NULL; - offset += 2*len+1; /* offset not used afterwards anymore */ + ptp_unpack_string(params, data, &offset, opdlen, &opd->FORM.DateTime.String); break; case PTP_OPFF_RegularExpression: - if (!ptp_unpack_string(params, data, offset, opdlen, &len, &opd->FORM.RegularExpression.String)) - opd->FORM.RegularExpression.String = NULL; - offset += 2*len+1; /* offset not used afterwards anymore */ + ptp_unpack_string(params, data, &offset, opdlen, &opd->FORM.RegularExpression.String); break; case PTP_OPFF_FixedLengthArray: if (offset + sizeof(uint16_t) > opdlen) goto outofmemory; @@ -2527,7 +2402,6 @@ ptp_unpack_CANON_changes (PTPParams *params, const unsigned char* data, unsigned break; case PTP_DTC_STR: { #if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */ - uint8_t len = 0; dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); #else @@ -3156,45 +3030,42 @@ ptp_unpack_ptp11_manifest ( PTPObjectFilesystemInfo **oifs ) { uint64_t numberoifs, i; - unsigned int curoffset; + unsigned int offset; PTPObjectFilesystemInfo *xoifs; if (!data || datalen < 8) return 0; numberoifs = dtoh64ap(params,data); - curoffset = 8; + offset = 8; xoifs = calloc(numberoifs, sizeof(PTPObjectFilesystemInfo)); if (!xoifs) return 0; for (i = 0; i < numberoifs; i++) { - uint8_t len,dlen; char *modify_date; PTPObjectFilesystemInfo *oif = xoifs+i; - if (curoffset + 34 + 2 > datalen) + if (offset + 34 + 2 > datalen) goto tooshort; - oif->ObjectHandle = dtoh32ap(params,data+curoffset); - oif->StorageID = dtoh32ap(params,data+curoffset+4); - oif->ObjectFormat = dtoh16ap(params,data+curoffset+8); - oif->ProtectionStatus = dtoh16ap(params,data+curoffset+10); - oif->ObjectCompressedSize64 = dtoh64ap(params,data+curoffset+12); - oif->ParentObject = dtoh32ap(params,data+curoffset+20); - oif->AssociationType = dtoh16ap(params,data+curoffset+24); - oif->AssociationDesc = dtoh32ap(params,data+curoffset+26); - oif->SequenceNumber = dtoh32ap(params,data+curoffset+30); - if (!ptp_unpack_string(params, data, curoffset+34, datalen, &len, &oif->Filename)) - goto tooshort; - if (curoffset+34+len*2+1 > datalen) + oif->ObjectHandle = dtoh32a(data+offset); + oif->StorageID = dtoh32a(data+offset+4); + oif->ObjectFormat = dtoh16a(data+offset+8); + oif->ProtectionStatus = dtoh16a(data+offset+10); + oif->ObjectCompressedSize64 = dtoh64a(data+offset+12); + oif->ParentObject = dtoh32a(data+offset+20); + oif->AssociationType = dtoh16a(data+offset+24); + oif->AssociationDesc = dtoh32a(data+offset+26); + oif->SequenceNumber = dtoh32a(data+offset+30); + offset += 34; + if (!ptp_unpack_string(params, data, &offset, datalen, &oif->Filename)) goto tooshort; - if (!ptp_unpack_string(params, data, curoffset+len*2+1+34, datalen, &dlen, &modify_date)) + if (!ptp_unpack_string(params, data, &offset, datalen, &modify_date)) goto tooshort; oif->ModificationDate = ptp_unpack_PTPTIME(modify_date); free(modify_date); - curoffset += 34+len*2+dlen*2+2; } *numoifs = numberoifs; *oifs = xoifs; diff --git a/camlibs/ptp2/ptp.c b/camlibs/ptp2/ptp.c index 4b1a56905..6fd67865b 100644 --- a/camlibs/ptp2/ptp.c +++ b/camlibs/ptp2/ptp.c @@ -2165,7 +2165,7 @@ ptp_getstorageinfo (PTPParams* params, uint32_t storageid, PTP_CNT_INIT(ptp, PTP_OC_GetStorageInfo, storageid); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); memset(storageinfo, 0, sizeof(*storageinfo)); - ret = ptp_unpack_SI(params, data, storageinfo, size) ? PTP_RC_OK : PTP_RC_GeneralError; + ret = ptp_unpack_SI(params, data, storageinfo, size) ? PTP_RC_OK : PTP_ERROR_IO; free(data); return ret; } @@ -2828,7 +2828,7 @@ ptp_getdevicepropvalue (PTPParams* params, uint32_t propcode, PTP_CNT_INIT(ptp, PTP_OC_GetDevicePropValue, propcode); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); - ret = ptp_unpack_DPV(params, data, &offset, size, value, datatype) ? PTP_RC_OK : PTP_RC_GeneralError; + ret = ptp_unpack_DPV(params, data, &offset, size, value, datatype) ? PTP_RC_OK : PTP_ERROR_IO; if (ret != PTP_RC_OK) ptp_debug (params, "ptp_getdevicepropvalue: unpacking DPV failed"); free(data); @@ -3178,22 +3178,21 @@ ptp_canon_gettreesize (PTPParams* params, PTPCanon_directtransfer_entry **entries, unsigned int *cnt) { PTPContainer ptp; - unsigned char *data = NULL, *cur; - unsigned int size, i; + unsigned char *data = NULL; + unsigned int size = 0, i, offset = 0; PTP_CNT_INIT(ptp, PTP_OC_CANON_GetTreeSize); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); *cnt = dtoh32a(data); + offset += 4; *entries = calloc((*cnt), sizeof(PTPCanon_directtransfer_entry)); if (!*entries) goto error; - cur = data+4; for (i=0;i<*cnt;i++) { - unsigned char len; - (*entries)[i].oid = dtoh32a(cur); - if (!ptp_unpack_string(params, cur, 4, size-(cur-data-4), &len, &(*entries)[i].str)) + (*entries)[i].oid = dtoh32a(data + offset); + offset += 4; + if (!ptp_unpack_string(params, data, &offset, size, &(*entries)[i].str)) break; - cur += 4+(cur[4]*2+1); } free (data); return PTP_RC_OK; @@ -4290,14 +4289,15 @@ uint16_t ptp_canon_getchanges (PTPParams* params, uint16_t** props, uint32_t* propnum) { PTPContainer ptp; + uint16_t ret; unsigned char *data = NULL; - unsigned int size; + unsigned int size = 0, offset = 0; PTP_CNT_INIT(ptp, PTP_OC_CANON_GetChanges); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); - *propnum=ptp_unpack_uint16_t_array(params,data,0,size,props); + ret = ptp_unpack_uint16_t_array(params, data, &offset, size, props, propnum) ? PTP_RC_OK : PTP_ERROR_IO; free(data); - return PTP_RC_OK; + return ret; } /** @@ -4489,7 +4489,7 @@ ptp_sony_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int { PTPContainer ptp; unsigned char *xdata = NULL; - unsigned int xsize, psize1 = 0, psize2 = 0, i; + unsigned int xsize, psize1 = 0, psize2 = 0, i, offset; uint16_t *props1 = NULL,*props2 = NULL; *props = NULL; @@ -4505,24 +4505,24 @@ ptp_sony_get_vendorpropcodes (PTPParams* params, uint16_t **props, unsigned int return PTP_RC_OK; } ptp_debug (params, "camera version is %d", dtoh16a(xdata)); + offset = 2; - psize1 = ptp_unpack_uint16_t_array (params, xdata+2, 0, xsize, &props1); + ptp_unpack_uint16_t_array (params, xdata, &offset, xsize, &props1, &psize1); ptp_debug (params, "device properties:"); for (i=0;iwifi_profiles[profn].device_type = data[pos++]; params->wifi_profiles[profn].icon_type = data[pos++]; - if (!ptp_unpack_string(params, data, pos, size, &len, &buffer)) + if (!ptp_unpack_string(params, data, &pos, size, &buffer)) goto error; strncpy(params->wifi_profiles[profn].creation_date, buffer, sizeof(params->wifi_profiles[profn].creation_date)); free (buffer); - pos += (len*2+1); if (pos+1 >= size) goto error; /* FIXME: check if it is really last usage date */ - if (!ptp_unpack_string(params, data, pos, size, &len, &buffer)) + if (!ptp_unpack_string(params, data, &pos, size, &buffer)) goto error; strncpy(params->wifi_profiles[profn].lastusage_date, buffer, sizeof(params->wifi_profiles[profn].lastusage_date)); free (buffer); - pos += (len*2+1); if (pos+5 >= size) goto error; @@ -5380,12 +5374,12 @@ ptp_mtp_getobjectpropssupported (PTPParams* params, uint16_t ofc, ) { PTPContainer ptp; unsigned char *data = NULL; - unsigned int xsize = 0; + unsigned int xsize = 0, offset = 0; PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectPropsSupported, ofc); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &xsize)); if (!data) return PTP_RC_GeneralError; - *propnum=ptp_unpack_uint16_t_array (params, data, 0, xsize, props); + ptp_unpack_uint16_t_array (params, data, &offset, xsize, props, propnum); free(data); return PTP_RC_OK; } @@ -5482,21 +5476,16 @@ uint16_t ptp_mtp_getobjectreferences (PTPParams* params, uint32_t handle, uint32_t** ohArray, uint32_t* arraylen) { PTPContainer ptp; + uint16_t ret; unsigned char *data = NULL; unsigned int size; + uint32_t offset = 0; PTP_CNT_INIT(ptp, PTP_OC_MTP_GetObjectReferences, handle); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data , &size)); - /* Sandisk Sansa skips the DATA phase, but returns OK as response. - * this will gives us a NULL here. Handle it. -Marcus */ - if ((data == NULL) || (size == 0)) { - *arraylen = 0; - *ohArray = NULL; - } else { - *arraylen = ptp_unpack_uint32_t_array(params, data , 0, size, ohArray); - } + ret = ptp_unpack_uint32_t_array(params, data , &offset, size, ohArray, arraylen) ? PTP_RC_OK : PTP_ERROR_IO; free(data); - return PTP_RC_OK; + return ret; } uint16_t From 77d63219e8fe9127bf693c02df7f0f5c98ecec30 Mon Sep 17 00:00:00 2001 From: axxel Date: Fri, 20 Sep 2024 16:59:23 +0200 Subject: [PATCH 2/2] introduce helper macros for automatic offset increment after dtoh The idea is to remove 'manual' offset adjustments: ``` unsigned offset = 0; unsigned val = dtoh32o(data, offset); // offset is now 4 ``` Also contains some code beautification near the use of dtoh style macros. --- camlibs/ptp2/ptp-pack.c | 376 ++++++++++++++++++---------------------- camlibs/ptp2/ptp.c | 50 +++--- 2 files changed, 190 insertions(+), 236 deletions(-) diff --git a/camlibs/ptp2/ptp-pack.c b/camlibs/ptp2/ptp-pack.c index 65189b36d..a11ad9b6e 100644 --- a/camlibs/ptp2/ptp-pack.c +++ b/camlibs/ptp2/ptp-pack.c @@ -132,6 +132,18 @@ dtoh64ap (PTPParams *params, const unsigned char *a) #define dtoh32(x) dtoh32p(params,x) #define dtoh64(x) dtoh64p(params,x) +static inline uint32_t _post_inc(uint32_t* o, int n) +{ + uint32_t res = *o; + *o += n; + return res; +} + +#define dtoh8o(a, o) dtoh8a ((a) + _post_inc(&o, sizeof(uint8_t))) +#define dtoh16o(a, o) dtoh16a((a) + _post_inc(&o, sizeof(uint16_t))) +#define dtoh32o(a, o) dtoh32a((a) + _post_inc(&o, sizeof(uint32_t))) +#define dtoh64o(a, o) dtoh64a((a) + _post_inc(&o, sizeof(uint64_t))) + /* * PTP strings ... if the size field is: @@ -157,8 +169,7 @@ ptp_unpack_string(PTPParams *params, const unsigned char* data, uint32_t *offset if (*offset + 1 > size) return 0; - ucs2len = dtoh8a(data + *offset); /* PTP_MAXSTRLEN == 255, 8 bit len */ - *offset += 1; + ucs2len = dtoh8o(data, *offset); /* PTP_MAXSTRLEN == 255, 8 bit len */ if (ucs2len == 0) { /* nothing to do? */ *result = strdup(""); /* return an empty string, not NULL */ return 1; @@ -289,8 +300,7 @@ ptp_unpack_uint32_t_array(PTPParams *params, const uint8_t* data, uint32_t *offs if (!data || *offset + sizeof(uint32_t) > datalen) return 0; - uint32_t n = dtoh32a(data + *offset); - *offset += sizeof(uint32_t); + uint32_t n = dtoh32o(data, *offset); if (n == 0) return 1; @@ -304,8 +314,7 @@ ptp_unpack_uint32_t_array(PTPParams *params, const uint8_t* data, uint32_t *offs return 0; for (unsigned i=0;i datalen) return 0; - uint32_t n = dtoh32a(data + *offset); - *offset += sizeof(uint32_t); + uint32_t n = dtoh32o(data, *offset); if (n == 0) return 1; @@ -353,8 +361,7 @@ ptp_unpack_uint16_t_array(PTPParams *params, const uint8_t* data, uint32_t *offs return 0; for (unsigned i=0;iStandardVersion = dtoh16a(data + PTP_di_StandardVersion); - di->VendorExtensionID = dtoh32a(data + PTP_di_VendorExtensionID); + di->StandardVersion = dtoh16a(data + PTP_di_StandardVersion); + di->VendorExtensionID = dtoh32a(data + PTP_di_VendorExtensionID); di->VendorExtensionVersion = dtoh16a(data + PTP_di_VendorExtensionVersion); offset = PTP_di_VendorExtensionDesc; + if (!ptp_unpack_string(params, data, &offset, datalen, &di->VendorExtensionDesc)) return 0; if (datalen <= offset + sizeof(uint16_t)) { ptp_debug (params, "FunctionalMode outside buffer bounds (%ld > %u)", offset + sizeof(uint16_t), datalen); return 0; } - di->FunctionalMode = dtoh16a(data + offset); - offset += 2; + di->FunctionalMode = dtoh16o(data, offset); if (!ptp_unpack_uint16_t_array(params, data, &offset, datalen, &di->OperationsSupported, &di->OperationsSupported_len)) { ptp_debug (params, "failed to unpack OperationsSupported array"); return 0; @@ -496,12 +503,12 @@ static inline int ptp_unpack_SI (PTPParams *params, const unsigned char* data, PTPStorageInfo *si, unsigned int len) { if (!data || len < 26) return 0; - si->StorageType=dtoh16a(&data[PTP_si_StorageType]); - si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); - si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); - si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); - si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); - si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); + si->StorageType = dtoh16a(data + PTP_si_StorageType); + si->FilesystemType = dtoh16a(data + PTP_si_FilesystemType); + si->AccessCapability = dtoh16a(data + PTP_si_AccessCapability); + si->MaxCapability = dtoh64a(data + PTP_si_MaxCapability); + si->FreeSpaceInBytes = dtoh64a(data + PTP_si_FreeSpaceInBytes); + si->FreeSpaceInImages = dtoh32a(data + PTP_si_FreeSpaceInImages); uint32_t offset = PTP_si_StorageDescription; @@ -657,11 +664,11 @@ ptp_unpack_OI (PTPParams *params, const unsigned char* data, PTPObjectInfo *oi, oi->Filename = oi->Keywords = NULL; - /* FIXME: also handle length with all the strings at the end */ - oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); - oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); - oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); - oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); + /* FIXME: also handle leng th with all the strings at the end */ + oi->StorageID = dtoh32a(data + PTP_oi_StorageID); + oi->ObjectFormat = dtoh16a(data + PTP_oi_ObjectFormat); + oi->ProtectionStatus = dtoh16a(data + PTP_oi_ProtectionStatus); + oi->ObjectCompressedSize = dtoh32a(data + PTP_oi_ObjectCompressedSize); /* Stupid Samsung Galaxy developers emit a 64bit objectcompressedsize */ if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) { @@ -670,17 +677,17 @@ ptp_unpack_OI (PTPParams *params, const unsigned char* data, PTPObjectInfo *oi, data += 4; len -= 4; } - oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); - oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); - oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); - oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); - oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); - oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); - oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); - oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); - oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); - oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); - oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); + oi->ThumbFormat = dtoh16a(data + PTP_oi_ThumbFormat); + oi->ThumbCompressedSize = dtoh32a(data + PTP_oi_ThumbCompressedSize); + oi->ThumbPixWidth = dtoh32a(data + PTP_oi_ThumbPixWidth); + oi->ThumbPixHeight = dtoh32a(data + PTP_oi_ThumbPixHeight); + oi->ImagePixWidth = dtoh32a(data + PTP_oi_ImagePixWidth); + oi->ImagePixHeight = dtoh32a(data + PTP_oi_ImagePixHeight); + oi->ImageBitDepth = dtoh32a(data + PTP_oi_ImageBitDepth); + oi->ParentObject = dtoh32a(data + PTP_oi_ParentObject); + oi->AssociationType = dtoh16a(data + PTP_oi_AssociationType); + oi->AssociationDesc = dtoh32a(data + PTP_oi_AssociationDesc); + oi->SequenceNumber = dtoh32a(data + PTP_oi_SequenceNumber); uint32_t offset = PTP_oi_filenamelen; ptp_unpack_string(params, data, &offset, len, &oi->Filename); @@ -699,7 +706,7 @@ ptp_unpack_OI (PTPParams *params, const unsigned char* data, PTPObjectInfo *oi, #define CTVAL(target,func) { \ if (total - *offset < sizeof(target)) \ return 0; \ - target = func(&data[*offset]); \ + target = func(data + *offset); \ *offset += sizeof(target); \ } @@ -707,7 +714,7 @@ ptp_unpack_OI (PTPParams *params, const unsigned char* data, PTPObjectInfo *oi, unsigned int n,j; \ if (total - *offset < sizeof(uint32_t)) \ return 0; \ - n = dtoh32a (&data[*offset]); \ + n = dtoh32a (data + *offset); \ *offset += sizeof(uint32_t); \ \ if (n >= UINT_MAX/sizeof(val->a.v[0])) \ @@ -811,28 +818,25 @@ ptp_unpack_DPV ( #define PTP_dpd_FactoryDefaultValue 5 static inline int -ptp_unpack_DPD (PTPParams *params, const unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen, unsigned int *newoffset) +ptp_unpack_DPD (PTPParams *params, const unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen, uint32_t *offset) { - unsigned int offset = 0, ret; - - *newoffset = 0; + int ret; memset (dpd, 0, sizeof(*dpd)); if (dpdlen <= 5) return 0; - dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); - dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); - dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); + dpd->DevicePropertyCode = dtoh16a(data + PTP_dpd_DevicePropertyCode); + dpd->DataType = dtoh16a(data + PTP_dpd_DataType); + dpd->GetSet = dtoh8a (data + PTP_dpd_GetSet); dpd->FormFlag=PTP_DPFF_None; - offset = PTP_dpd_FactoryDefaultValue; - ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); + *offset = PTP_dpd_FactoryDefaultValue; + ret = ptp_unpack_DPV (params, data, offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); if (!ret) goto outofmemory; - if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) { - *newoffset = offset; + if ((dpd->DataType == PTP_DTC_STR) && (*offset == dpdlen)) return 1; - } - ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); + + ret = ptp_unpack_DPV (params, data, offset, dpdlen, &dpd->CurrentValue, dpd->DataType); if (!ret) goto outofmemory; /* if offset==0 then Data Type format is not supported by this @@ -840,37 +844,33 @@ ptp_unpack_DPD (PTPParams *params, const unsigned char* data, PTPDevicePropDesc values). In both cases Form Flag should be set to 0x00 and FORM is not present. */ - if (offset + sizeof(uint8_t) > dpdlen) { - *newoffset = offset; + if (*offset + sizeof(uint8_t) > dpdlen) return 1; - } - dpd->FormFlag=dtoh8a(&data[offset]); - offset+=sizeof(uint8_t); + dpd->FormFlag = dtoh8o(data, *offset); switch (dpd->FormFlag) { case PTP_DPFF_Range: - ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); + ret = ptp_unpack_DPV (params, data, offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); if (!ret) goto outofmemory; - ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); + ret = ptp_unpack_DPV (params, data, offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); if (!ret) goto outofmemory; - ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); + ret = ptp_unpack_DPV (params, data, offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); if (!ret) goto outofmemory; break; case PTP_DPFF_Enumeration: { int i; #define N dpd->FORM.Enum.NumberOfValues - if (offset + sizeof(uint16_t) > dpdlen) goto outofmemory; + if (*offset + sizeof(uint16_t) > dpdlen) goto outofmemory; - N = dtoh16a(&data[offset]); - offset+=sizeof(uint16_t); + N = dtoh16o(data, *offset); dpd->FORM.Enum.SupportedValue = calloc(N,sizeof(dpd->FORM.Enum.SupportedValue[0])); if (!dpd->FORM.Enum.SupportedValue) goto outofmemory; for (i=0;iFORM.Enum.SupportedValue[i], dpd->DataType); + ret = ptp_unpack_DPV (params, data, offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); /* Slightly different handling here. The HP PhotoSmart 120 * specifies an enumeration with N in wrong endian @@ -887,7 +887,6 @@ ptp_unpack_DPD (PTPParams *params, const unsigned char* data, PTPDevicePropDesc } } #undef N - *newoffset = offset; return 1; outofmemory: ptp_free_devicepropdesc(dpd); @@ -906,21 +905,19 @@ static inline int ptp_unpack_Sony_DPD (PTPParams *params, const unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen, unsigned int *poffset) { unsigned int ret; - unsigned int isenabled, getset; + unsigned int isenabled; if (!data || dpdlen < PTP_dpd_Sony_FactoryDefaultValue) return 0; memset (dpd, 0, sizeof(*dpd)); - dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_Sony_DevicePropertyCode]); - dpd->DataType=dtoh16a(&data[PTP_dpd_Sony_DataType]); - - getset = dtoh8a(&data[PTP_dpd_Sony_GetSet]); - isenabled = dtoh8a(&data[PTP_dpd_Sony_IsEnabled]); + dpd->DevicePropertyCode = dtoh16a(data + PTP_dpd_Sony_DevicePropertyCode); + dpd->DataType = dtoh16a(data + PTP_dpd_Sony_DataType); + dpd->GetSet = dtoh8a (data + PTP_dpd_Sony_GetSet); + isenabled = dtoh8a (data + PTP_dpd_Sony_IsEnabled); - ptp_debug (params, "prop 0x%04x, datatype 0x%04x, isEnabled %d getset %d", dpd->DevicePropertyCode, dpd->DataType, isenabled, getset); + ptp_debug (params, "prop 0x%04x, datatype 0x%04x, isEnabled %d getset %d", dpd->DevicePropertyCode, dpd->DataType, isenabled, dpd->GetSet); - dpd->GetSet = getset; switch (isenabled) { case 0: /* grayed out */ dpd->GetSet = 0; /* just to be safe */ @@ -950,9 +947,8 @@ ptp_unpack_Sony_DPD (PTPParams *params, const unsigned char* data, PTPDeviceProp if (*poffset==PTP_dpd_Sony_FactoryDefaultValue) return 1; - dpd->FormFlag=dtoh8a(&data[*poffset]); + dpd->FormFlag = dtoh8o(data, *poffset); ptp_debug (params, "formflag 0x%04x", dpd->FormFlag); - *poffset+=sizeof(uint8_t); switch (dpd->FormFlag) { case PTP_DPFF_Range: @@ -966,8 +962,7 @@ ptp_unpack_Sony_DPD (PTPParams *params, const unsigned char* data, PTPDeviceProp case PTP_DPFF_Enumeration: { int i; #define N dpd->FORM.Enum.NumberOfValues - N = dtoh16a(&data[*poffset]); - *poffset+=sizeof(uint16_t); + N = dtoh16o(data, *poffset); dpd->FORM.Enum.SupportedValue = calloc(N,sizeof(dpd->FORM.Enum.SupportedValue[0])); if (!dpd->FORM.Enum.SupportedValue) goto outofmemory; @@ -990,15 +985,14 @@ ptp_unpack_Sony_DPD (PTPParams *params, const unsigned char* data, PTPDeviceProp } } if (dpdlen >= *poffset + 2) { - uint16_t val = dtoh16a(&data[*poffset]); + uint16_t val = dtoh16a(data + *poffset); /* check if we have a secondary list of items, this is for newer Sonys (2024) */ if (val < 0x200) { /* actually would be 0x5XXX or 0xDxxx */ if (dpd->FormFlag == PTP_DPFF_Enumeration) { int i; - N = dtoh16a(&data[*poffset]); - *poffset+=sizeof(uint16_t); + N = dtoh16o(data, *poffset); dpd->FORM.Enum.SupportedValue = calloc(N,sizeof(dpd->FORM.Enum.SupportedValue[0])); if (!dpd->FORM.Enum.SupportedValue) goto outofmemory; @@ -1111,21 +1105,19 @@ ptp_unpack_OPD (PTPParams *params, const unsigned char* data, PTPObjectPropDesc if (opdlen < 5) return 0; - opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); - opd->DataType=dtoh16a(&data[PTP_opd_DataType]); - opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); + opd->ObjectPropertyCode = dtoh16a(data + PTP_opd_ObjectPropertyCode); + opd->DataType = dtoh16a(data + PTP_opd_DataType); + opd->GetSet = dtoh8a (data + PTP_opd_GetSet); offset = PTP_opd_FactoryDefaultValue; ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); if (!ret) goto outofmemory; if (offset + sizeof(uint32_t) > opdlen) goto outofmemory; - opd->GroupCode=dtoh32a(&data[offset]); - offset+=sizeof(uint32_t); + opd->GroupCode = dtoh32o(data, offset); if (offset + sizeof(uint8_t) > opdlen) goto outofmemory; - opd->FormFlag=dtoh8a(&data[offset]); - offset+=sizeof(uint8_t); + opd->FormFlag = dtoh8o(data, offset); switch (opd->FormFlag) { case PTP_OPFF_Range: @@ -1141,8 +1133,7 @@ ptp_unpack_OPD (PTPParams *params, const unsigned char* data, PTPObjectPropDesc #define N opd->FORM.Enum.NumberOfValues if (offset + sizeof(uint16_t) > opdlen) goto outofmemory; - N = dtoh16a(&data[offset]); - offset+=sizeof(uint16_t); + N = dtoh16o(data, offset); opd->FORM.Enum.SupportedValue = calloc(N,sizeof(opd->FORM.Enum.SupportedValue[0])); if (!opd->FORM.Enum.SupportedValue) @@ -1174,13 +1165,11 @@ ptp_unpack_OPD (PTPParams *params, const unsigned char* data, PTPObjectPropDesc break; case PTP_OPFF_FixedLengthArray: if (offset + sizeof(uint16_t) > opdlen) goto outofmemory; - opd->FORM.FixedLengthArray.NumberOfValues = dtoh16a(&data[offset]); - offset += sizeof(uint16_t); /* offset not used afterwards anymore */ + opd->FORM.FixedLengthArray.NumberOfValues = dtoh16o(data, offset); break; case PTP_OPFF_ByteArray: if (offset + sizeof(uint16_t) > opdlen) goto outofmemory; - opd->FORM.ByteArray.NumberOfValues = dtoh16a(&data[offset]); - offset += sizeof(uint16_t); /* offset not used afterwards anymore */ + opd->FORM.ByteArray.NumberOfValues = dtoh16o(data, offset); break; case PTP_OPFF_LongString: break; @@ -1384,7 +1373,7 @@ ptp_unpack_OPL (PTPParams *params, const unsigned char* data, MTPProperties **pp return 0; } - prop_count = dtoh32a(data); + prop_count = dtoh32o(data, offset); *pprops = NULL; if (prop_count == 0) return 0; @@ -1395,12 +1384,10 @@ ptp_unpack_OPL (PTPParams *params, const unsigned char* data, MTPProperties **pp } ptp_debug (params ,"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count); - data += sizeof(uint32_t); - len -= sizeof(uint32_t); props = calloc(prop_count , sizeof(MTPProperties)); if (!props) return 0; for (i = 0; i < prop_count; i++) { - if (len <= (sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t))) { + if (len <= offset + 4 + 2 + 2) { ptp_debug (params ,"short MTP Object Property List at property %d (of %d)", i, prop_count); ptp_debug (params ,"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL"); ptp_debug (params ,"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST"); @@ -1410,27 +1397,16 @@ ptp_unpack_OPL (PTPParams *params, const unsigned char* data, MTPProperties **pp } - props[i].ObjectHandle = dtoh32a(data); - data += sizeof(uint32_t); - len -= sizeof(uint32_t); - - props[i].property = dtoh16a(data); - data += sizeof(uint16_t); - len -= sizeof(uint16_t); - - props[i].datatype = dtoh16a(data); - data += sizeof(uint16_t); - len -= sizeof(uint16_t); + props[i].ObjectHandle = dtoh32o(data, offset); + props[i].property = dtoh16o(data, offset); + props[i].datatype = dtoh16o(data, offset); - offset = 0; if (!ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype)) { ptp_debug (params ,"unpacking DPV of property %d encountered insufficient buffer. attack?", i); qsort (props, i, sizeof(MTPProperties),_compare_func); *pprops = props; return i; } - data += offset; - len -= offset; } qsort (props, prop_count, sizeof(MTPProperties),_compare_func); *pprops = props; @@ -1460,31 +1436,31 @@ ptp_unpack_EC (PTPParams *params, const unsigned char* data, PTPContainer *ec, u return; memset(ec,0,sizeof(*ec)); - length=dtoh32a(&data[PTP_ec_Length]); + length = dtoh32a(data + PTP_ec_Length); if (length > len) { ptp_debug (params, "length %d in container, but data only %d bytes?!", length, len); return; } - type = dtoh16a(&data[PTP_ec_Type]); + type = dtoh16a(data + PTP_ec_Type); - ec->Code=dtoh16a(&data[PTP_ec_Code]); - ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]); + ec->Code = dtoh16a(data + PTP_ec_Code); + ec->Transaction_ID = dtoh32a(data + PTP_ec_TransId); if (type!=PTP_USB_CONTAINER_EVENT) { ptp_debug (params, "Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID); return; } if (length>=(PTP_ec_Param1+4)) { - ec->Param1=dtoh32a(&data[PTP_ec_Param1]); - ec->Nparam=1; + ec->Param1 = dtoh32a(data + PTP_ec_Param1); + ec->Nparam = 1; } if (length>=(PTP_ec_Param2+4)) { - ec->Param2=dtoh32a(&data[PTP_ec_Param2]); - ec->Nparam=2; + ec->Param2 = dtoh32a(data + PTP_ec_Param2); + ec->Nparam = 2; } if (length>=(PTP_ec_Param3+4)) { - ec->Param3=dtoh32a(&data[PTP_ec_Param3]); - ec->Nparam=3; + ec->Param3 = dtoh32a(data + PTP_ec_Param3); + ec->Nparam = 3; } } @@ -1502,16 +1478,14 @@ ptp_unpack_EC (PTPParams *params, const unsigned char* data, PTPContainer *ec, u static inline void ptp_unpack_Canon_FE (PTPParams *params, const unsigned char* data, PTPCANONFolderEntry *fe) { - int i; if (data==NULL) return; - fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); - fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); - fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); - fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); - fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); - for (i=0; iFilename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); + fe->ObjectHandle = dtoh32a(data + PTP_cfe_ObjectHandle); + fe->ObjectFormatCode = dtoh16a(data + PTP_cfe_ObjectFormatCode); + fe->Flags = dtoh8a (data + PTP_cfe_Flags); + fe->ObjectSize = dtoh32a(data + PTP_cfe_ObjectSize); + fe->Time = (time_t)dtoh32a(data + PTP_cfe_Time); + strncpy(fe->Filename, (char*)data + PTP_cfe_Filename, PTP_CANON_FilenameBufferLen); } /* @@ -1577,17 +1551,15 @@ ObjectInfo for 'IMG_0199.JPG': static inline void ptp_unpack_Canon_EOS_FE (PTPParams *params, const unsigned char* data, unsigned int size, PTPCANONFolderEntry *fe) { - int i; - if (size < PTP_cefe_Time + 4) return; - fe->ObjectHandle=dtoh32a(&data[PTP_cefe_ObjectHandle]); - fe->ObjectFormatCode=dtoh16a(&data[PTP_cefe_ObjectFormatCode]); - fe->Flags=dtoh8a(&data[PTP_cefe_Flags]); - fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cefe_ObjectSize]); - fe->Time=(time_t)dtoh32a(&data[PTP_cefe_Time]); - for (i=0; iFilename[i]=(char)data[PTP_cefe_Filename+i]; + fe->ObjectHandle = dtoh32a(data + PTP_cefe_ObjectHandle); + fe->ObjectFormatCode = dtoh16a(data + PTP_cefe_ObjectFormatCode); + fe->Flags = dtoh8a (data + PTP_cefe_Flags); + fe->ObjectSize = dtoh32a(data + PTP_cefe_ObjectSize); + fe->Time = (time_t)dtoh32a(data + PTP_cefe_Time); + + strncpy(fe->Filename, (char*)data + PTP_cefe_Filename, PTP_CANON_FilenameBufferLen); fe->Filename[PTP_CANON_FilenameBufferLen-1] = 0; } @@ -2795,7 +2767,7 @@ ptp_unpack_Nikon_EC (PTPParams *params, const unsigned char* data, unsigned int static inline int ptp_unpack_Nikon_EC_EX (PTPParams *params, const unsigned char* data, unsigned int len, PTPContainer **ec, unsigned int *cnt) { - unsigned int i, offset; + unsigned int i, offset = 0; *ec = NULL; if (!data || len < PTP_nikon_ec_ex_Code) @@ -2809,39 +2781,31 @@ ptp_unpack_Nikon_EC_EX (PTPParams *params, const unsigned char* data, unsigned i return 1; *ec = calloc((*cnt), sizeof(PTPContainer)); - offset = PTP_nikon_ec_ex_Code+sizeof(uint16_t); + offset = 4; for (i=0;i<*cnt;i++) { - memset(&(*ec)[i],0,sizeof(PTPContainer)); - if (len - offset < 4) { - free (*ec); - *ec = NULL; - *cnt = 0; - return 0; - } - (*ec)[i].Code = dtoh16a(&data[offset]); - (*ec)[i].Nparam = dtoh16a(&data[offset+2]); + if (len < offset + 4) + goto error; + + (*ec)[i].Code = dtoh16o(data, offset); + (*ec)[i].Nparam = dtoh16o(data, offset); ptp_debug (params, "nikon eventex %d: code 0x%04x, params %d", i, (*ec)[i].Code, (*ec)[i].Nparam); - if ( ((*ec)[i].Nparam > 5) || - (len < ((*ec)[i].Nparam*sizeof(uint32_t)) + 4 + offset) - ) { - free (*ec); - *ec = NULL; - *cnt = 0; - return 0; - } - switch ((*ec)[i].Nparam) { - case 5: (*ec)[i].Param5 = dtoh32a(&data[offset+4+sizeof(uint32_t)*4]);/* fallthrough */ - case 4: (*ec)[i].Param4 = dtoh32a(&data[offset+4+sizeof(uint32_t)*3]);/* fallthrough */ - case 3: (*ec)[i].Param3 = dtoh32a(&data[offset+4+sizeof(uint32_t)*2]);/* fallthrough */ - case 2: (*ec)[i].Param2 = dtoh32a(&data[offset+4+sizeof(uint32_t)*1]);/* fallthrough */ - case 1: (*ec)[i].Param1 = dtoh32a(&data[offset+4]); - /* fallthrough */ - case 0: break; - } - offset += (*ec)[i].Nparam*sizeof(uint32_t) + 4; + if (((*ec)[i].Nparam > 5) || (len < offset + ((*ec)[i].Nparam*sizeof(uint32_t)))) + goto error; + + if ((*ec)[i].Nparam >= 1) (*ec)[i].Param1 = dtoh32o(data, offset); + if ((*ec)[i].Nparam >= 2) (*ec)[i].Param2 = dtoh32o(data, offset); + if ((*ec)[i].Nparam >= 3) (*ec)[i].Param3 = dtoh32o(data, offset); + if ((*ec)[i].Nparam >= 4) (*ec)[i].Param4 = dtoh32o(data, offset); + if ((*ec)[i].Nparam == 5) (*ec)[i].Param5 = dtoh32o(data, offset); } return 1; + +error: + free (*ec); + *ec = NULL; + *cnt = 0; + return 0; } static inline uint32_t @@ -3030,13 +2994,12 @@ ptp_unpack_ptp11_manifest ( PTPObjectFilesystemInfo **oifs ) { uint64_t numberoifs, i; - unsigned int offset; + unsigned int offset = 0; PTPObjectFilesystemInfo *xoifs; if (!data || datalen < 8) return 0; - numberoifs = dtoh64ap(params,data); - offset = 8; + numberoifs = dtoh64o(data, offset); xoifs = calloc(numberoifs, sizeof(PTPObjectFilesystemInfo)); if (!xoifs) return 0; @@ -3048,16 +3011,16 @@ ptp_unpack_ptp11_manifest ( if (offset + 34 + 2 > datalen) goto tooshort; - oif->ObjectHandle = dtoh32a(data+offset); - oif->StorageID = dtoh32a(data+offset+4); - oif->ObjectFormat = dtoh16a(data+offset+8); - oif->ProtectionStatus = dtoh16a(data+offset+10); - oif->ObjectCompressedSize64 = dtoh64a(data+offset+12); - oif->ParentObject = dtoh32a(data+offset+20); - oif->AssociationType = dtoh16a(data+offset+24); - oif->AssociationDesc = dtoh32a(data+offset+26); - oif->SequenceNumber = dtoh32a(data+offset+30); - offset += 34; + oif->ObjectHandle = dtoh32o(data, offset); + oif->StorageID = dtoh32o(data, offset); + oif->ObjectFormat = dtoh16o(data, offset); + oif->ProtectionStatus = dtoh16o(data, offset); + oif->ObjectCompressedSize64 = dtoh64o(data, offset); + oif->ParentObject = dtoh32o(data, offset); + oif->AssociationType = dtoh16o(data, offset); + oif->AssociationDesc = dtoh32o(data, offset); + oif->SequenceNumber = dtoh32o(data, offset); + if (!ptp_unpack_string(params, data, &offset, datalen, &oif->Filename)) goto tooshort; @@ -3080,49 +3043,50 @@ ptp_unpack_ptp11_manifest ( static inline void ptp_unpack_chdk_lv_data_header (PTPParams *params, const unsigned char* data, lv_data_header *header) { - int off = 0; + uint32_t offset = 0; if (data==NULL) return; - header->version_major = dtoh32a(&data[off]); - header->version_minor = dtoh32a(&data[off+=4]); - header->lcd_aspect_ratio = dtoh32a(&data[off+=4]); - header->palette_type = dtoh32a(&data[off+=4]); - header->palette_data_start = dtoh32a(&data[off+=4]); - header->vp_desc_start = dtoh32a(&data[off+=4]); - header->bm_desc_start = dtoh32a(&data[off+=4]); + header->version_major = dtoh32o(data, offset); + header->version_minor = dtoh32o(data, offset); + header->lcd_aspect_ratio = dtoh32o(data, offset); + header->palette_type = dtoh32o(data, offset); + header->palette_data_start = dtoh32o(data, offset); + header->vp_desc_start = dtoh32o(data, offset); + header->bm_desc_start = dtoh32o(data, offset); if (header->version_minor > 1) - header->bmo_desc_start = dtoh32a(&data[off+=4]); + header->bmo_desc_start = dtoh32o(data, offset); } static inline void ptp_unpack_chdk_lv_framebuffer_desc (PTPParams *params, const unsigned char* data, lv_framebuffer_desc *fd) { - int off = 0; + uint32_t offset = 0; if (data==NULL) return; - fd->fb_type = dtoh32a(&data[off]); - fd->data_start = dtoh32a(&data[off+=4]); - fd->buffer_width = dtoh32a(&data[off+=4]); - fd->visible_width = dtoh32a(&data[off+=4]); - fd->visible_height = dtoh32a(&data[off+=4]); - fd->margin_left = dtoh32a(&data[off+=4]); - fd->margin_top = dtoh32a(&data[off+=4]); - fd->margin_right = dtoh32a(&data[off+=4]); - fd->margin_bot = dtoh32a(&data[off+=4]); + fd->fb_type = dtoh32o(data, offset); + fd->data_start = dtoh32o(data, offset); + fd->buffer_width = dtoh32o(data, offset); + fd->visible_width = dtoh32o(data, offset); + fd->visible_height = dtoh32o(data, offset); + fd->margin_left = dtoh32o(data, offset); + fd->margin_top = dtoh32o(data, offset); + fd->margin_right = dtoh32o(data, offset); + fd->margin_bot = dtoh32o(data, offset); } static inline int ptp_unpack_StreamInfo (PTPParams *params, const unsigned char *data, PTPStreamInfo *si, unsigned int size) { + uint32_t offset = 0; if (!data) return PTP_RC_GeneralError; if (size < 36) return PTP_RC_GeneralError; - si->DatasetSize = dtoh64ap(params,data+0); - si->TimeResolution = dtoh64ap(params,data+8); - si->FrameHeaderSize = dtoh32ap(params,data+16); - si->FrameMaxSize = dtoh32ap(params,data+20); - si->PacketHeaderSize = dtoh32ap(params,data+24); - si->PacketMaxSize = dtoh32ap(params,data+28); - si->PacketAlignment = dtoh32ap(params,data+32); + si->DatasetSize = dtoh64o(data, offset); + si->TimeResolution = dtoh64o(data, offset); + si->FrameHeaderSize = dtoh32o(data, offset); + si->FrameMaxSize = dtoh32o(data, offset); + si->PacketHeaderSize = dtoh32o(data, offset); + si->PacketMaxSize = dtoh32o(data, offset); + si->PacketAlignment = dtoh32o(data, offset); return PTP_RC_OK; } diff --git a/camlibs/ptp2/ptp.c b/camlibs/ptp2/ptp.c index 6fd67865b..82b933ab7 100644 --- a/camlibs/ptp2/ptp.c +++ b/camlibs/ptp2/ptp.c @@ -2584,7 +2584,7 @@ ptp_nikon_getobjectsize (PTPParams* params, uint32_t handle, uint64_t *objectsiz return PTP_RC_GeneralError; } - *objectsize = dtoh64ap(params, data); + *objectsize = dtoh64a(data); free (data); return PTP_RC_OK; } @@ -2771,7 +2771,7 @@ ptp_getdevicepropdesc (PTPParams* params, uint32_t propcode, PTPContainer ptp; uint16_t ret = PTP_RC_OK; unsigned char *data = NULL; - unsigned int size, newoffset; + unsigned int size, offset = 0; PTP_CNT_INIT(ptp, PTP_OC_GetDevicePropDesc, propcode); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); @@ -2806,7 +2806,7 @@ ptp_getdevicepropdesc (PTPParams* params, uint32_t propcode, } #endif } else { - if (!ptp_unpack_DPD(params, data, devicepropertydesc, size, &newoffset)) { + if (!ptp_unpack_DPD(params, data, devicepropertydesc, size, &offset)) { ptp_debug(params,"failed to unpack DPD of propcode 0x%04x, likely corrupted?", propcode); free (data); return PTP_RC_InvalidDevicePropFormat; @@ -3183,14 +3183,12 @@ ptp_canon_gettreesize (PTPParams* params, PTP_CNT_INIT(ptp, PTP_OC_CANON_GetTreeSize); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); - *cnt = dtoh32a(data); - offset += 4; + *cnt = dtoh32o(data, offset); *entries = calloc((*cnt), sizeof(PTPCanon_directtransfer_entry)); if (!*entries) goto error; for (i=0;i<*cnt;i++) { - (*entries)[i].oid = dtoh32a(data + offset); - offset += 4; + (*entries)[i].oid = dtoh32o(data, offset); if (!ptp_unpack_string(params, data, &offset, size, &(*entries)[i].str)) break; } @@ -5172,7 +5170,7 @@ ptp_nikon_getwifiprofilelist (PTPParams* params) { PTPContainer ptp; unsigned char *data = NULL; - unsigned int size, pos, profn, n; + unsigned int size, pos = 0, profn, n; char *buffer; PTP_CNT_INIT(ptp, PTP_OC_NIKON_GetProfileAllData); @@ -5181,33 +5179,31 @@ ptp_nikon_getwifiprofilelist (PTPParams* params) if (size < 2) goto error; - params->wifi_profiles_version = data[0]; - params->wifi_profiles_number = data[1]; + params->wifi_profiles_version = dtoh8o(data, pos); + params->wifi_profiles_number = dtoh8o(data, pos); free(params->wifi_profiles); params->wifi_profiles = calloc(params->wifi_profiles_number,sizeof(PTPNIKONWifiProfile)); if (!params->wifi_profiles) goto error; - pos = 2; profn = 0; while (profn < params->wifi_profiles_number && pos < size) { if (pos+6 >= size) goto error; - params->wifi_profiles[profn].id = data[pos++]; - params->wifi_profiles[profn].valid = data[pos++]; + params->wifi_profiles[profn].id = dtoh8o(data, pos); + params->wifi_profiles[profn].valid = dtoh8o(data, pos); - n = dtoh32a(&data[pos]); - pos += 4; + n = dtoh32o(data, pos); if (pos+n+4 >= size) goto error; strncpy(params->wifi_profiles[profn].profile_name, (char*)&data[pos], n); params->wifi_profiles[profn].profile_name[16] = '\0'; pos += n; - params->wifi_profiles[profn].display_order = data[pos++]; - params->wifi_profiles[profn].device_type = data[pos++]; - params->wifi_profiles[profn].icon_type = data[pos++]; + params->wifi_profiles[profn].display_order = dtoh8o(data, pos); + params->wifi_profiles[profn].device_type = dtoh8o(data, pos); + params->wifi_profiles[profn].icon_type = dtoh8o(data, pos); if (!ptp_unpack_string(params, data, &pos, size, &buffer)) goto error; @@ -5223,11 +5219,10 @@ ptp_nikon_getwifiprofilelist (PTPParams* params) if (pos+5 >= size) goto error; - n = dtoh32a(&data[pos]); - pos += 4; + n = dtoh32o(data, pos); if (pos+n >= size) goto error; - strncpy(params->wifi_profiles[profn].essid, (char*)&data[pos], n); + strncpy(params->wifi_profiles[profn].essid, (char*)data + pos, n); params->wifi_profiles[profn].essid[32] = '\0'; pos += n; pos += 1; @@ -5916,9 +5911,8 @@ uint16_t ptp_fuji_getdeviceinfo (PTPParams* params, uint16_t **props, unsigned int *numprops) { PTPContainer ptp; - unsigned char *xdata; unsigned char *data = NULL; - unsigned int nums, i, newoffset, xsize, size = 0; + unsigned int nums, i, offset = 0, size = 0; PTP_CNT_INIT(ptp, PTP_OC_FUJI_GetDeviceInfo); CHECK_PTP_RC(ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &data, &size)); @@ -5926,9 +5920,7 @@ ptp_fuji_getdeviceinfo (PTPParams* params, uint16_t **props, unsigned int *numpr if (size < 8) goto error; - nums = dtoh32a(data); - xdata = data + 4; - xsize = size - 4; + nums = dtoh32o(data, offset); *props = calloc(nums, sizeof(uint16_t)); if (!*props) @@ -5936,13 +5928,11 @@ ptp_fuji_getdeviceinfo (PTPParams* params, uint16_t **props, unsigned int *numpr *numprops = nums; for (i=0;i