From 472f010e81dc09a1f3a29ff3656e9348ce114ec9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 20 Mar 2018 11:44:53 +0100 Subject: [PATCH 1/4] Fixed leak of LinphoneContent --- src/c-wrapper/api/c-chat-message.cpp | 2 +- src/chat/modifier/file-transfer-chat-message-modifier.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index c9ee6184b..b191027ed 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -291,7 +291,7 @@ int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text) { LinphoneContent *linphone_chat_message_get_file_transfer_information(LinphoneChatMessage *msg) { const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); - if (content) return linphone_content_ref(L_GET_C_BACK_PTR(content)); + if (content) return L_GET_C_BACK_PTR(content); return NULL; } diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index 14733e4c8..6bebbfa0b 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -723,6 +723,7 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t // Legacy: call back given by application level linphone_core_notify_file_transfer_recv(message->getCore()->getCCore(), msg, content, (const char *)buffer, size); } + linphone_content_unref(content); } } else { lWarning() << "File transfer decrypt failed with code " << (int)retval; From 61b45fd7a413eedd1d5000e0a05149e7878f1b71 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 20 Mar 2018 14:20:11 +0100 Subject: [PATCH 2/4] Fixed issue with server presence & content headers --- src/c-wrapper/api/c-content.cpp | 22 ++++++++++++++++++++-- src/content/content-manager.cpp | 18 ++++++++++-------- src/content/content-type.cpp | 3 +++ src/content/content-type.h | 2 ++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 211985bbb..30021cbb7 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -159,7 +159,7 @@ void linphone_content_set_name(LinphoneContent *content, const char *name) { } bool_t linphone_content_is_multipart(const LinphoneContent *content) { - return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType() == LinphonePrivate::ContentType::Multipart; + return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().isMultipart(); } LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { @@ -244,6 +244,13 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler * for (const belle_sip_list_t *parts = belle_sip_multipart_body_handler_get_parts(mpbh); parts; parts = parts->next) { belle_sip_body_handler_t *part = BELLE_SIP_BODY_HANDLER(parts->data); LinphoneContent *part_content = linphone_content_new_with_body_handler((SalBodyHandler *)part); + + const belle_sip_list_t *headers = belle_sip_body_handler_get_headers(part); + for (; headers != NULL; headers = headers->next) { + belle_sip_header_t *header = BELLE_SIP_HEADER(headers->data); + L_GET_CPP_PTR_FROM_C_OBJECT(part_content)->addHeader(belle_sip_header_get_name(header), belle_sip_header_get_unparsed_value(header)); + } + contents.push_back(*L_GET_CPP_PTR_FROM_C_OBJECT(part_content)); } LinphonePrivate::Content multipartContent = LinphonePrivate::ContentManager::contentListToMultipart(contents); @@ -281,7 +288,7 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { if (content == NULL) return NULL; SalBodyHandler *body_handler; - if (L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType() == LinphonePrivate::ContentType::Multipart) { + if (L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().isMultipart()) { size_t size = linphone_content_get_size(content); char *buffer = ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String().c_str()); const char *boundary = L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getParameter()); @@ -291,6 +298,17 @@ SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { body_handler = sal_body_handler_new(); sal_body_handler_set_data(body_handler, belle_sip_strdup(linphone_content_get_string_buffer(content))); } + + for (const auto &header : L_GET_CPP_PTR_FROM_C_OBJECT(content)->getHeaders()) { + belle_sip_header_t *additionalHeader = BELLE_SIP_HEADER( + belle_sip_header_create( + header.first.c_str(), + header.second.c_str() + ) + ); + belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), additionalHeader); + } + sal_body_handler_set_type(body_handler, linphone_content_get_type(content)); sal_body_handler_set_subtype(body_handler, linphone_content_get_subtype(content)); sal_body_handler_set_size(body_handler, linphone_content_get_size(content)); diff --git a/src/content/content-manager.cpp b/src/content/content-manager.cpp index 94ee69ce9..d4c286c79 100644 --- a/src/content/content-manager.cpp +++ b/src/content/content-manager.cpp @@ -45,23 +45,25 @@ list ContentManager::multipartToContentList (const Content &content) { list contents; for (const belle_sip_list_t *parts = belle_sip_multipart_body_handler_get_parts(mpbh); parts; parts = parts->next) { belle_sip_body_handler_t *part = BELLE_SIP_BODY_HANDLER(parts->data); - belle_sip_header_content_type_t *partContentType = nullptr; + Content content; + for (const belle_sip_list_t *it = belle_sip_body_handler_get_headers(part); it; it = it->next) { belle_sip_header_t *header = BELLE_SIP_HEADER(it->data); if (strcasecmp("Content-Type", belle_sip_header_get_name(header)) == 0) { - partContentType = BELLE_SIP_HEADER_CONTENT_TYPE(header); - break; + belle_sip_header_content_type_t * partContentType = BELLE_SIP_HEADER_CONTENT_TYPE(header); + content.setContentType(ContentType( + belle_sip_header_content_type_get_type(partContentType), + belle_sip_header_content_type_get_subtype(partContentType) + )); + } else { + content.addHeader(belle_sip_header_get_name(header), belle_sip_header_get_unparsed_value(header)); } } - Content content; content.setBody(static_cast( belle_sip_memory_body_handler_get_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(part)) )); - content.setContentType(ContentType( - belle_sip_header_content_type_get_type(partContentType), - belle_sip_header_content_type_get_subtype(partContentType) - )); + contents.push_back(move(content)); } diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index 78c356af6..e457ff828 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -172,6 +172,9 @@ string ContentType::asString () const { return ""; } +bool ContentType::isMultipart() const { + return getType() == "multipart"; +} bool ContentType::isFile () const { // TODO Remove when not needed anymore in step 2.1 of maindb diff --git a/src/content/content-type.h b/src/content/content-type.h index b13063115..bdf51c75d 100644 --- a/src/content/content-type.h +++ b/src/content/content-type.h @@ -60,6 +60,8 @@ public: std::string asString () const; + bool isMultipart() const; + static bool isFile (const ContentType &contentType); static const ContentType ConferenceInfo; From fd6b049203f3502ac1ad1086580517468e7898c8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 20 Mar 2018 14:46:45 +0100 Subject: [PATCH 3/4] Fixed LinphoneContent leak --- src/c-wrapper/api/c-content.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 30021cbb7..d487e8847 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -252,6 +252,7 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler * } contents.push_back(*L_GET_CPP_PTR_FROM_C_OBJECT(part_content)); + linphone_content_unref(part_content); } LinphonePrivate::Content multipartContent = LinphonePrivate::ContentManager::contentListToMultipart(contents); linphone_content_set_string_buffer(content, multipartContent.getBodyAsUtf8String().c_str()); From cf2b6ca2bf87a2333c02d093362981fb25dfbd57 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 21 Mar 2018 10:51:19 +0100 Subject: [PATCH 4/4] Fixed content type parameters between SalBodyHandler and Content --- coreapi/bellesip_sal/sal_impl.c | 20 ++++++++++++++++++++ src/c-wrapper/api/c-content.cpp | 24 ++++++++++++++++++------ src/c-wrapper/internal/c-sal.h | 2 ++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index ad11525fb..71578364b 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -348,6 +348,26 @@ void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subt belle_sip_header_content_type_set_subtype(content_type, subtype); } +char * sal_body_handler_get_content_type_parameters(const SalBodyHandler *body_handler) { + belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type")); + if (content_type != NULL) { + char buff[2048]; + size_t buff_size = sizeof(buff); + size_t offset = 0; + belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(content_type), buff, buff_size, &offset); + buff[offset]='\0'; + return strdup(buff); + } + return NULL; +} + +void sal_body_handler_set_content_type_parameters(SalBodyHandler *body_handler, const char *params) { + belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type")); + if (content_type != NULL) { + belle_sip_parameters_set(BELLE_SIP_PARAMETERS(content_type), params); + } +} + const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler) { belle_sip_header_t *content_encoding = sal_body_handler_find_header(body_handler, "Content-Encoding"); if (content_encoding != NULL) { diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index d487e8847..572444ddf 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -233,9 +233,14 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler * content->cryptoContext = NULL; LinphonePrivate::Content *c = new LinphonePrivate::Content(); L_SET_CPP_PTR_FROM_C_OBJECT(content, c); + if (body_handler != NULL) { - linphone_content_set_type(content, sal_body_handler_get_type(body_handler)); - linphone_content_set_subtype(content, sal_body_handler_get_subtype(body_handler)); + LinphonePrivate::ContentType ct = c->getContentType(); + ct.setType(sal_body_handler_get_type(body_handler)); + ct.setSubType(sal_body_handler_get_subtype(body_handler)); + ct.setParameter(sal_body_handler_get_content_type_parameters(body_handler)); + c->setContentType(ct); + if (!sal_body_handler_is_multipart(body_handler)) { linphone_content_set_string_buffer(content, (char *)sal_body_handler_get_data(body_handler)); } else { @@ -257,8 +262,10 @@ static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler * LinphonePrivate::Content multipartContent = LinphonePrivate::ContentManager::contentListToMultipart(contents); linphone_content_set_string_buffer(content, multipartContent.getBodyAsUtf8String().c_str()); } + if (sal_body_handler_get_encoding(body_handler)) linphone_content_set_encoding(content, sal_body_handler_get_encoding(body_handler)); } + return content; } @@ -288,11 +295,14 @@ LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_ha SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { if (content == NULL) return NULL; + SalBodyHandler *body_handler; - if (L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().isMultipart()) { + LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + + if (contentType.isMultipart()) { size_t size = linphone_content_get_size(content); char *buffer = ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String().c_str()); - const char *boundary = L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getParameter()); + const char *boundary = L_STRING_TO_C(contentType.getParameter()); belle_sip_multipart_body_handler_t *bh = belle_sip_multipart_body_handler_new_from_buffer(buffer, size, boundary); body_handler = (SalBodyHandler *)BELLE_SIP_BODY_HANDLER(bh); } else { @@ -310,9 +320,11 @@ SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), additionalHeader); } - sal_body_handler_set_type(body_handler, linphone_content_get_type(content)); - sal_body_handler_set_subtype(body_handler, linphone_content_get_subtype(content)); + sal_body_handler_set_type(body_handler, contentType.getType().c_str()); + sal_body_handler_set_subtype(body_handler, contentType.getSubType().c_str()); sal_body_handler_set_size(body_handler, linphone_content_get_size(content)); + sal_body_handler_set_content_type_parameters(body_handler, contentType.getParameter().c_str()); if (content->encoding) sal_body_handler_set_encoding(body_handler, linphone_content_get_encoding(content)); + return body_handler; } diff --git a/src/c-wrapper/internal/c-sal.h b/src/c-wrapper/internal/c-sal.h index 4aeca0042..3f53db90c 100644 --- a/src/c-wrapper/internal/c-sal.h +++ b/src/c-wrapper/internal/c-sal.h @@ -636,6 +636,8 @@ const char * sal_body_handler_get_type(const SalBodyHandler *body_handler); void sal_body_handler_set_type(SalBodyHandler *body_handler, const char *type); const char * sal_body_handler_get_subtype(const SalBodyHandler *body_handler); void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subtype); +char * sal_body_handler_get_content_type_parameters(const SalBodyHandler *body_handler); +void sal_body_handler_set_content_type_parameters(SalBodyHandler *body_handler, const char *params); const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler); void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding); void * sal_body_handler_get_data(const SalBodyHandler *body_handler);