From 55dbc4f8535520faa7ffda1b5ae96aac17ef4547 Mon Sep 17 00:00:00 2001 From: "g00536918 (GeorgeT)" Date: Thu, 19 Dec 2024 15:18:30 +0800 Subject: [PATCH] cjapi: contact: fixup memory leak Change-Id: I8bec3f868d33e515f8b6b68f5c7d4443c8362c11 Signed-off-by: gtimoshenko --- contactsCJ/include/contacts_utils.h | 54 ++++++++++++++++++----------- contactsCJ/src/contacts_utils.cpp | 45 ++++++++---------------- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/contactsCJ/include/contacts_utils.h b/contactsCJ/include/contacts_utils.h index 686dcee..14e2464 100644 --- a/contactsCJ/include/contacts_utils.h +++ b/contactsCJ/include/contacts_utils.h @@ -57,31 +57,32 @@ constexpr int PERMISSION_ERROR = 201; constexpr int PARAMETER_ERROR = 401; struct ValuesBucket { - char** key = NULL; - DataShare::CValueType* value = NULL; - int64_t size = 0; + char** key = nullptr; + DataShare::CValueType* value = nullptr; + uint64_t size = 0; void freeContent() { - for (int64_t i = 0; i < size; i++) { - if (key != nullptr && key[i] != nullptr) { + bool hasKey = key != nullptr; + bool hasValue = value != nullptr; + for (uint64_t i = 0; i < size; i++) { + if (hasKey) { free(key[i]); key[i] = nullptr; } - if (value != nullptr && + if (hasValue && value[i].tag == OHOS::DataShare::DataShareValueObjectType::TYPE_STRING) { free(value[i].string); value[i].string = nullptr; } } - if (key != nullptr) { - free(key); - key = nullptr; - } - if (value != nullptr) { - free(value); - value = nullptr; - } + + free(key); + key = nullptr; + + free(value); + value = nullptr; + size = 0; } }; @@ -89,8 +90,8 @@ struct ValuesBucket { using RawContact = ValuesBucket; struct Buckets { - ValuesBucket* data = NULL; - int64_t bucketCount = 0; + ValuesBucket* data = nullptr; + uint64_t bucketCount = 0; void freeContent() { @@ -111,8 +112,21 @@ using HoldersData = Buckets; struct ContactsData { - ContactData* contactsData = NULL; - int64_t contactsCount = 0; + ContactData* contactsData = nullptr; + uint64_t contactsCount = 0; + + void freeContent() + { + if (contactsData != nullptr) { + for (int i = 0; i < contactsCount; i++) { + ContactData contactData = contactsData[i]; + contactData.freeContent(); + } + free(contactsData); + contactsData = nullptr; + contactsCount = 0; + } + } }; char* TransformFromString(std::string &str, int32_t* errCode); @@ -120,8 +134,8 @@ char* TransformFromString(std::string &str, int32_t* errCode); // this is a pair of key and a kind of DataShare::CValueType but with std::string string struct KeyWithValueType { std::string key; - int64_t integer; - double dou; + int64_t integer = 0; + double dou = 0.0; std::string string; uint8_t tag; diff --git a/contactsCJ/src/contacts_utils.cpp b/contactsCJ/src/contacts_utils.cpp index 57056eb..8014ac7 100644 --- a/contactsCJ/src/contacts_utils.cpp +++ b/contactsCJ/src/contacts_utils.cpp @@ -24,7 +24,7 @@ namespace OHOS { namespace ContactsFfi { // return true if succeeded; after it b is fully allocated or completely empty with errCode set -bool allocBucket(ValuesBucket* b, int total, int32_t *errCode) +bool allocBucket(ValuesBucket* b, size_t total, int32_t *errCode) { if (*errCode != SUCCESS) { return false; @@ -110,7 +110,7 @@ void copyBucket(ValuesBucket* dst, int dstIdx, ValuesBucket &src) char* TransformFromString(std::string &str, int32_t* errCode) { - int64_t len = str.size() + 1; + size_t len = str.size() + 1; char* retValue = static_cast(malloc(len)); if (retValue == nullptr) { *errCode = ERROR; @@ -127,14 +127,14 @@ char* TransformFromString(std::string &str, int32_t* errCode) ValuesBucket allocBucketData(std::vector &bucketData, int32_t *errCode) { struct ValuesBucket b; - int total = bucketData.size(); + size_t total = bucketData.size(); if (total > 0) { if (!allocBucket(&b, total, errCode)) { return b; } // Let's increment b.size one by one for b.freeContent() call in case of error b.size = 0; - for (int i = 0; i < total; i++) { + for (size_t i = 0; i < total; i++) { bucketData[i].allocToBucket(&b, 0, i, errCode); if (*errCode != SUCCESS) { b.freeContent(); @@ -451,24 +451,6 @@ bool allocateDataForContact(ContactsData* allContacts, int contactIndex, int con return true; } -void releaseAllContacts(ContactsData* allContacts) -{ - for (int i = 0; i < allContacts->contactsCount; i++) { - if (allContacts->contactsData[i].data != nullptr) { - for (int b = 0; b < allContacts->contactsData[i].bucketCount; b++) { - ValuesBucket bucket = allContacts->contactsData[i].data[b]; - bucket.freeContent(); - } - free(allContacts->contactsData[i].data); - allContacts->contactsData[i].data = nullptr; - allContacts->contactsData[i].bucketCount = 0; - } - } - free(allContacts->contactsData); - allContacts->contactsData = nullptr; - allContacts->contactsCount = 0; -} - void releaseRresultSetMapBuckets(std::map> resultSetMap) { std::map>::iterator it; @@ -491,8 +473,8 @@ ContactsData* allocCollectedContacts(std::map> &r return nullptr; } - int totalContacts = resultSetMap.size(); - if (totalContacts <= 0 || totalContacts > MAX_CONTACTS) { + size_t totalContacts = resultSetMap.size(); + if (totalContacts == 0 || totalContacts > MAX_CONTACTS) { free(allContacts); return nullptr; } @@ -518,7 +500,7 @@ ContactsData* allocCollectedContacts(std::map> &r allContacts->contactsData[contactIndex].data = nullptr; continue; } - int totalBuckets = 2 + contactDataVector.size(); // 2 more for contactId and searchKey buckets + size_t totalBuckets = 2 + contactDataVector.size(); // 2 more for contactId and searchKey buckets allContacts->contactsData[contactIndex].bucketCount = totalBuckets; allContacts->contactsData[contactIndex].data = (struct ValuesBucket*) malloc(totalBuckets * sizeof(struct ValuesBucket)); @@ -530,13 +512,16 @@ ContactsData* allocCollectedContacts(std::map> &r allocateDataForContact(allContacts, contactIndex, contactId, searchKey, contactDataVector, errCode); } - if (*errCode != SUCCESS) { - releaseAllContacts(allContacts); - releaseRresultSetMapBuckets(resultSetMap); - return nullptr; + if (*errCode == SUCCESS) { + return allContacts; } - return allContacts; + allContacts->freeContent(); + free(allContacts); + allContacts = nullptr; + releaseRresultSetMapBuckets(resultSetMap); + + return nullptr; } // it closes resultSet after parse -- Gitee