ENGINE-320 COM-72: Keep ownership of blobs, freeing them after the engine call ENGINE-320 COM-72
authorMarkus Schaber <markus@pep-security.net>
Sun, 17 Dec 2017 11:03:41 +0100
branchENGINE-320 COM-72
changeset 265d13ae58b6862
parent 264 aa6bd84bd6c3
child 266 c68b8488ac36
ENGINE-320 COM-72: Keep ownership of blobs, freeing them after the engine call

First implementation - keep the blobs in a list which will be freed at the end
of the function.
CpEpEngine.cpp
pEp_utility.cpp
pEp_utility.h
     1.1 --- a/CpEpEngine.cpp	Fri Dec 01 19:38:09 2017 +0100
     1.2 +++ b/CpEpEngine.cpp	Sun Dec 17 11:03:41 2017 +0100
     1.3 @@ -257,10 +257,11 @@
     1.4      ::stringlist_t *_keylist = NULL;
     1.5      string _lang;
     1.6      *words = NULL;
     1.7 +	blob_buffers _buffers;
     1.8  
     1.9      try {
    1.10          _received_by = new_identity(receivedBy);
    1.11 -        _msg = text_message_to_C(msg);
    1.12 +        _msg = text_message_to_C(msg, _buffers);
    1.13  
    1.14          if (keylist) {
    1.15              _keylist = new_stringlist(keylist);
    1.16 @@ -837,7 +838,9 @@
    1.17      if (!(src && dst))
    1.18          return E_INVALIDARG;
    1.19  
    1.20 -    ::message *_src = text_message_to_C(src);
    1.21 +	blob_buffers _buffers;
    1.22 +
    1.23 +    ::message *_src = text_message_to_C(src, _buffers);
    1.24  
    1.25      // COM-19: Initialize msg_dst to NULL, or we end up calling
    1.26      // free_message() below with a pointer to random garbage in
    1.27 @@ -891,7 +894,9 @@
    1.28  
    1.29      ::pEp_identity *_target_id = new_identity(targetId);
    1.30  
    1.31 -    ::message *_src = text_message_to_C(src);
    1.32 +	blob_buffers _buffers;
    1.33 +
    1.34 +    ::message *_src = text_message_to_C(src, _buffers);
    1.35  
    1.36      // COM-19: Initialize msg_dst to NULL, or we end up calling
    1.37      // free_message() below with a pointer to random garbage in
    1.38 @@ -933,7 +938,9 @@
    1.39      *keylist = NULL;
    1.40      *rating = pEpRatingUndefined;
    1.41  
    1.42 -    ::message *_src = text_message_to_C(src);
    1.43 +	blob_buffers _buffers;
    1.44 +
    1.45 +    ::message *_src = text_message_to_C(src, _buffers);
    1.46      ::message *msg_dst = NULL;
    1.47      ::stringlist_t *_keylist = NULL;
    1.48      ::PEP_rating _rating;
    1.49 @@ -970,7 +977,9 @@
    1.50  
    1.51      *rating = pEpRatingUndefined;
    1.52  
    1.53 -    ::message *_msg = text_message_to_C(msg);
    1.54 +	blob_buffers _buffers;
    1.55 +
    1.56 +    ::message *_msg = text_message_to_C(msg, _buffers);
    1.57      ::stringlist_t *_keylist = new_stringlist(x_KeyList);
    1.58      ::PEP_rating _rating = PEP_rating_undefined;
    1.59  
    1.60 @@ -992,10 +1001,14 @@
    1.61      if (!(msg  && pVal))
    1.62          return E_INVALIDARG;
    1.63  
    1.64 -    ::message *_msg = text_message_to_C(msg);
    1.65 +	blob_buffers _buffers;
    1.66 +
    1.67 +    ::message *_msg = text_message_to_C(msg, _buffers);
    1.68  
    1.69      PEP_rating _rating;
    1.70      PEP_STATUS status = ::outgoing_message_rating(get_session(), _msg, &_rating);
    1.71 +
    1.72 +	::free_message(_msg);
    1.73      if (status != PEP_STATUS_OK)
    1.74          return FAIL(L"cannot get message rating", status);
    1.75  
     2.1 --- a/pEp_utility.cpp	Fri Dec 01 19:38:09 2017 +0100
     2.2 +++ b/pEp_utility.cpp	Sun Dec 17 11:03:41 2017 +0100
     2.3 @@ -367,7 +367,7 @@
     2.4              memset(&b, 0, sizeof(Blob));
     2.5          }
     2.6  
     2.7 -        bloblist_t *bloblist(SAFEARRAY *sa)
     2.8 +        bloblist_t *bloblist(SAFEARRAY *sa, blob_buffers& buffers)
     2.9          {
    2.10              if (sa == NULL)
    2.11                  return NULL;
    2.12 @@ -397,7 +397,7 @@
    2.13  
    2.14                  char *buffer;
    2.15                  if (size) {
    2.16 -                    buffer = (char *) malloc(size + 1);
    2.17 +                    buffer = buffers.allocate(size + 1);
    2.18                      if (buffer == NULL)
    2.19                          throw bad_alloc();
    2.20  
    2.21 @@ -535,7 +535,7 @@
    2.22              return il;
    2.23          }
    2.24          
    2.25 -        ::message * text_message_to_C(TextMessage *msg)
    2.26 +        ::message * text_message_to_C(TextMessage *msg, blob_buffers& buffers)
    2.27          {
    2.28              assert(msg);
    2.29  			if (!msg)
    2.30 @@ -549,7 +549,7 @@
    2.31              msg2->shortmsg = str(msg->ShortMsg);
    2.32              msg2->longmsg = str(msg->LongMsg);
    2.33              msg2->longmsg_formatted = str(msg->LongMsgFormatted);
    2.34 -            msg2->attachments = bloblist(msg->Attachments);
    2.35 +            msg2->attachments = bloblist(msg->Attachments, buffers);
    2.36              msg2->sent = new_timestamp(msg->Sent);
    2.37              msg2->recv = new_timestamp(msg->Recv);
    2.38              msg2->from = new_identity(&msg->From);
     3.1 --- a/pEp_utility.h	Fri Dec 01 19:38:09 2017 +0100
     3.2 +++ b/pEp_utility.h	Sun Dec 17 11:03:41 2017 +0100
     3.3 @@ -7,80 +7,99 @@
     3.4  using namespace std;
     3.5  
     3.6  namespace pEp {
     3.7 -    namespace utility {
     3.8 +	namespace utility {
     3.9  
    3.10 -        struct pEp_identity_cpp {
    3.11 -            string address;
    3.12 -            string fpr;
    3.13 -            string user_id;
    3.14 -            string username;
    3.15 -            pEpComType comm_type;
    3.16 -            string lang;
    3.17 +		struct pEp_identity_cpp {
    3.18 +			string address;
    3.19 +			string fpr;
    3.20 +			string user_id;
    3.21 +			string username;
    3.22 +			pEpComType comm_type;
    3.23 +			string lang;
    3.24  			int flags;
    3.25  
    3.26 -            pEp_identity_cpp(
    3.27 -                string _address = string(),
    3.28 -                string _fpr = string(),
    3.29 -                string _user_id = string(),
    3.30 -                string _username = string(),
    3.31 -                pEpComType _comm_type = pEpCtUnknown,
    3.32 -                string _lang = string()
    3.33 -                ) : address(_address), fpr(_fpr), user_id(_user_id), username(_username), comm_type(_comm_type), lang(_lang)
    3.34 -            { }
    3.35 +			pEp_identity_cpp(
    3.36 +				string _address = string(),
    3.37 +				string _fpr = string(),
    3.38 +				string _user_id = string(),
    3.39 +				string _username = string(),
    3.40 +				pEpComType _comm_type = pEpCtUnknown,
    3.41 +				string _lang = string()
    3.42 +			) : address(_address), fpr(_fpr), user_id(_user_id), username(_username), comm_type(_comm_type), lang(_lang)
    3.43 +			{ }
    3.44  
    3.45 -            pEp_identity_cpp(const ::pEp_identity *_ident);
    3.46 -            pEp_identity_cpp(const pEpIdentity *_ident);
    3.47 +			pEp_identity_cpp(const ::pEp_identity *_ident);
    3.48 +			pEp_identity_cpp(const pEpIdentity *_ident);
    3.49  
    3.50 -            pEp_identity * to_pEp_identity();
    3.51 -            pEpIdentity * to_pEp_identity_s();
    3.52 -        };
    3.53 +			pEp_identity * to_pEp_identity();
    3.54 +			pEpIdentity * to_pEp_identity_s();
    3.55 +		};
    3.56  
    3.57 -        void copy_identity(pEpIdentity * ident_s, const pEp_identity * ident);
    3.58 -        void free_identity_strings(pEpIdentity * ident_s);
    3.59 -        void clear_identity_s(pEpIdentity& ident);
    3.60 -        void clear_text_message(TextMessage *msg);
    3.61 -        ::pEp_identity *new_identity(const pEpIdentity * ident);
    3.62 +		void copy_identity(pEpIdentity * ident_s, const pEp_identity * ident);
    3.63 +		void clear_identity_s(pEpIdentity& ident);
    3.64 +		void clear_text_message(TextMessage *msg);
    3.65 +		::pEp_identity *new_identity(const pEpIdentity * ident);
    3.66  
    3.67  		void opt_field_array_from_C(stringpair_list_t* spair_list, LPSAFEARRAY* pair_list_out);
    3.68  		void clear_opt_field_array(LPSAFEARRAY* pair_list);
    3.69  		template< class T2, class T > SAFEARRAY * array_from_C(T *tl);
    3.70  
    3.71 -        static LPTYPELIB pTypelib = NULL;
    3.72 +		static LPTYPELIB pTypelib = NULL;
    3.73  
    3.74 -        template< class UDType > static IRecordInfo *getRecordInfo()
    3.75 -        {
    3.76 -            LPTYPEINFO pTypeInfo = NULL;
    3.77 -            LPSAFEARRAY psaUDType = NULL;
    3.78 -            IRecordInfo* pRecInfo = NULL;
    3.79 +		template< class UDType > static IRecordInfo *getRecordInfo()
    3.80 +		{
    3.81 +			LPTYPEINFO pTypeInfo = NULL;
    3.82 +			LPSAFEARRAY psaUDType = NULL;
    3.83 +			IRecordInfo* pRecInfo = NULL;
    3.84  
    3.85 -            // Fetch the IRecordInfo interface describing the UDT
    3.86 -            if (pTypelib == NULL)
    3.87 -                LoadRegTypeLib(LIBID_pEpCOMServerAdapterLib, 1, 0, GetUserDefaultLCID(), &pTypelib);
    3.88 +			// Fetch the IRecordInfo interface describing the UDT
    3.89 +			if (pTypelib == NULL)
    3.90 +				LoadRegTypeLib(LIBID_pEpCOMServerAdapterLib, 1, 0, GetUserDefaultLCID(), &pTypelib);
    3.91  
    3.92 -            assert(pTypelib);
    3.93 +			assert(pTypelib);
    3.94  
    3.95 -            GUID guid = __uuidof(UDType);
    3.96 -            HRESULT hr = pTypelib->GetTypeInfoOfGuid(guid, &pTypeInfo);
    3.97 -            assert(SUCCEEDED(hr) && pTypeInfo);
    3.98 -            hr = GetRecordInfoFromTypeInfo(pTypeInfo, &pRecInfo);
    3.99 -            assert(SUCCEEDED(hr) && pRecInfo);
   3.100 -            pTypeInfo->Release();
   3.101 +			GUID guid = __uuidof(UDType);
   3.102 +			HRESULT hr = pTypelib->GetTypeInfoOfGuid(guid, &pTypeInfo);
   3.103 +			assert(SUCCEEDED(hr) && pTypeInfo);
   3.104 +			hr = GetRecordInfoFromTypeInfo(pTypeInfo, &pRecInfo);
   3.105 +			assert(SUCCEEDED(hr) && pRecInfo);
   3.106 +			pTypeInfo->Release();
   3.107  
   3.108 -            return pRecInfo;
   3.109 -        }
   3.110 +			return pRecInfo;
   3.111 +		}
   3.112  
   3.113 -        template< class UDType > LPSAFEARRAY newSafeArray(ULONG cElements)
   3.114 -        {
   3.115 -            IRecordInfo *pRecInfo = getRecordInfo< UDType >();
   3.116 -            SAFEARRAYBOUND rgbounds = { cElements, 0 };
   3.117 -            LPSAFEARRAY psaUDType = SafeArrayCreateEx(VT_RECORD, 1, &rgbounds, pRecInfo);
   3.118 -            pRecInfo->Release();
   3.119 -            assert(psaUDType);
   3.120 +		template< class UDType > LPSAFEARRAY newSafeArray(ULONG cElements)
   3.121 +		{
   3.122 +			IRecordInfo *pRecInfo = getRecordInfo< UDType >();
   3.123 +			SAFEARRAYBOUND rgbounds = { cElements, 0 };
   3.124 +			LPSAFEARRAY psaUDType = SafeArrayCreateEx(VT_RECORD, 1, &rgbounds, pRecInfo);
   3.125 +			pRecInfo->Release();
   3.126 +			assert(psaUDType);
   3.127  
   3.128 -            return psaUDType;
   3.129 -        }
   3.130 +			return psaUDType;
   3.131 +		}
   3.132  
   3.133 -        ::message * text_message_to_C(TextMessage *msg);
   3.134 -        void text_message_from_C(TextMessage *msg2, const ::message *msg);
   3.135 -    }
   3.136 +		class blob_buffers {
   3.137 +		private:
   3.138 +			std::vector<char*> buffers;
   3.139 +
   3.140 +		public:
   3.141 +			char* allocate(size_t size) 
   3.142 +			{
   3.143 +				char* buffer = (char*)malloc(size);
   3.144 +				buffers.push_back(buffer);
   3.145 +				return buffer;
   3.146 +			}
   3.147 +			
   3.148 +			~blob_buffers() {
   3.149 +				for (auto it = buffers.begin(); it != buffers.end(); it += 1) 
   3.150 +				{
   3.151 +					free(*it);
   3.152 +				}
   3.153 +			}
   3.154 +		};
   3.155 +
   3.156 +		::message * text_message_to_C(TextMessage *msg, blob_buffers& buffers);
   3.157 +		void text_message_from_C(TextMessage *msg2, const ::message *msg);
   3.158 +	}
   3.159  }