From 130d4710287df46b36248200c21517dec6a67b1b Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 23 Mar 2017 11:55:39 +0100 Subject: [PATCH] fix crash and memory leaks --- coreapi/error_info.c | 29 +++++----- coreapi/factory.c | 107 +++++++++++++++++++++++++------------ coreapi/linphonecore.c | 9 ++-- coreapi/private.h | 7 ++- gtk/main.c | 12 ++--- gtk/support.c | 3 +- include/linphone/factory.h | 12 ++--- mediastreamer2 | 2 +- tools/auto_answer.c | 3 +- 9 files changed, 106 insertions(+), 78 deletions(-) diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 288b8e793..3add603a9 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -22,22 +22,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneErrorInfo); -#define STRING_RESET(field) if (field) ms_free(field); field = NULL; +static void linphone_error_info_reset(LinphoneErrorInfo *ei); static void error_info_destroy(LinphoneErrorInfo *ei){ - if (ei->protocol) ms_free(ei->protocol); - if (ei->phrase) ms_free(ei->phrase); - if (ei->warnings) ms_free(ei->phrase); - if (ei->full_string) ms_free(ei->full_string); + linphone_error_info_reset(ei); } static void error_info_clone(LinphoneErrorInfo *ei, const LinphoneErrorInfo *other){ - ei->protocol = ms_strdup_safe(other->protocol); - ei->phrase = ms_strdup_safe(other->phrase); - ei->warnings = ms_strdup_safe(other->phrase); - ei->full_string = ms_strdup_safe(other->full_string); + ei->protocol = bctbx_strdup(other->protocol); + ei->phrase = bctbx_strdup(other->phrase); + ei->warnings = bctbx_strdup(other->warnings); + ei->full_string = bctbx_strdup(other->full_string); } BELLE_SIP_INSTANCIATE_VPTR(LinphoneErrorInfo, belle_sip_object_t, @@ -155,7 +152,7 @@ int linphone_reason_to_error_code(LinphoneReason reason) { return 400; } -void linphone_error_info_reset(LinphoneErrorInfo *ei){ +static void linphone_error_info_reset(LinphoneErrorInfo *ei){ ei->reason = LinphoneReasonNone; STRING_RESET(ei->protocol); STRING_RESET(ei->phrase); @@ -170,11 +167,11 @@ void linphone_error_info_reset(LinphoneErrorInfo *ei){ void linphone_error_info_from_sal(LinphoneErrorInfo *ei, const SalErrorInfo *sei){ ei->reason = linphone_reason_from_sal(sei->reason); - ei->phrase = ms_strdup_safe(sei->status_string); - ei->full_string = ms_strdup_safe(sei->full_string); - ei->warnings = ms_strdup_safe(sei->warnings); + ei->phrase = bctbx_strdup(sei->status_string); + ei->full_string = bctbx_strdup(sei->full_string); + ei->warnings = bctbx_strdup(sei->warnings); ei->protocol_code = sei->protocol_code; - ei->protocol = ms_strdup_safe(sei->protocol); + ei->protocol = bctbx_strdup(sei->protocol); } /* If a reason header is provided (in reason_ei), then create a sub LinphoneErrorInfo attached to the first one, unless the reason header @@ -220,8 +217,8 @@ void linphone_error_info_set(LinphoneErrorInfo *ei, LinphoneReason reason, int c linphone_error_info_reset(ei); ei->reason = reason; ei->protocol_code = code; - ei->phrase = ms_strdup_safe(status_string); - ei->warnings = ms_strdup_safe(warning); + ei->phrase = bctbx_strdup(status_string); + ei->warnings = bctbx_strdup(warning); } diff --git a/coreapi/factory.c b/coreapi/factory.c index 867d6be24..b43bd0136 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -39,17 +39,40 @@ typedef belle_sip_object_t_vptr_t LinphoneFactory_vptr_t; struct _LinphoneFactory { belle_sip_object_t base; + /*these are the directories set by the application*/ char *top_resources_dir; char *data_resources_dir; char *sound_resources_dir; char *ring_resources_dir; char *image_resources_dir; char *msplugins_dir; + + /*these are the cached result computed from directories set by the application*/ + char *cached_data_resources_dir; + char *cached_sound_resources_dir; + char *cached_ring_resources_dir; + char *cached_image_resources_dir; + char *cached_msplugins_dir; }; +static void linphone_factory_uninit(LinphoneFactory *obj){ + STRING_RESET(obj->top_resources_dir); + STRING_RESET(obj->data_resources_dir); + STRING_RESET(obj->sound_resources_dir); + STRING_RESET(obj->ring_resources_dir); + STRING_RESET(obj->image_resources_dir); + STRING_RESET(obj->msplugins_dir); + + STRING_RESET(obj->cached_data_resources_dir); + STRING_RESET(obj->cached_sound_resources_dir); + STRING_RESET(obj->cached_ring_resources_dir); + STRING_RESET(obj->cached_image_resources_dir); + STRING_RESET(obj->cached_msplugins_dir); +} + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFactory); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFactory, belle_sip_object_t, - NULL, // destroy + linphone_factory_uninit, // destroy NULL, // clone NULL, // Marshall FALSE @@ -64,9 +87,16 @@ static void _linphone_factory_destroying_cb(void) { } } +static LinphoneFactory *linphone_factory_new(void){ + LinphoneFactory *factory = belle_sip_object_new(LinphoneFactory); + factory->top_resources_dir = bctbx_strdup(PACKAGE_DATA_DIR); + return factory; +} + + LinphoneFactory *linphone_factory_get(void) { if (_factory == NULL) { - _factory = belle_sip_object_new(LinphoneFactory); + _factory = linphone_factory_new(); atexit(_linphone_factory_destroying_cb); } return _factory; @@ -107,65 +137,72 @@ LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory) { return _linphone_vcard_new(); } -char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory) { - if (factory->top_resources_dir) return bctbx_strdup(factory->top_resources_dir); - return bctbx_strdup(PACKAGE_DATA_DIR); +const char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory) { + return factory->top_resources_dir; } void linphone_factory_set_top_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->top_resources_dir) bctbx_free(factory->top_resources_dir); - factory->top_resources_dir = bctbx_strdup(path); + STRING_SET(factory->top_resources_dir, path); } -char * linphone_factory_get_data_resources_dir(const LinphoneFactory *factory) { - if (factory->data_resources_dir) return bctbx_strdup(factory->data_resources_dir); - if (factory->top_resources_dir) return bctbx_strdup_printf("%s/linphone", factory->top_resources_dir); - return bctbx_strdup_printf("%s/linphone", PACKAGE_DATA_DIR); +const char * linphone_factory_get_data_resources_dir(LinphoneFactory *factory) { + if (factory->data_resources_dir) return factory->data_resources_dir; + if (factory->top_resources_dir){ + STRING_TRANSFER(factory->cached_data_resources_dir, bctbx_strdup_printf("%s/linphone", factory->top_resources_dir)); + }else{ + STRING_TRANSFER(factory->cached_data_resources_dir, bctbx_strdup_printf("%s/linphone", PACKAGE_DATA_DIR)); + } + return factory->cached_data_resources_dir; } void linphone_factory_set_data_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->data_resources_dir) bctbx_free(factory->data_resources_dir); - factory->data_resources_dir = bctbx_strdup(path); + STRING_SET(factory->data_resources_dir, path); } -char * linphone_factory_get_sound_resources_dir(const LinphoneFactory *factory) { - if (factory->sound_resources_dir) return bctbx_strdup(factory->sound_resources_dir); - if (factory->top_resources_dir) return bctbx_strdup_printf("%s/sounds/linphone", factory->top_resources_dir); - return bctbx_strdup(PACKAGE_SOUND_DIR); +const char * linphone_factory_get_sound_resources_dir(LinphoneFactory *factory) { + if (factory->sound_resources_dir) return factory->sound_resources_dir; + if (factory->top_resources_dir){ + STRING_TRANSFER(factory->cached_sound_resources_dir, bctbx_strdup_printf("%s/sounds/linphone", factory->top_resources_dir)); + return factory->cached_sound_resources_dir; + } + return PACKAGE_SOUND_DIR; } void linphone_factory_set_sound_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->sound_resources_dir) bctbx_free(factory->sound_resources_dir); - factory->sound_resources_dir = bctbx_strdup(path); + STRING_SET(factory->sound_resources_dir, path); } -char * linphone_factory_get_ring_resources_dir(const LinphoneFactory *factory) { - if (factory->ring_resources_dir) return bctbx_strdup(factory->ring_resources_dir); - if (factory->sound_resources_dir) return bctbx_strdup_printf("%s/rings", factory->sound_resources_dir); - return bctbx_strdup(PACKAGE_RING_DIR); +const char * linphone_factory_get_ring_resources_dir(LinphoneFactory *factory) { + if (factory->ring_resources_dir) return factory->ring_resources_dir; + if (factory->sound_resources_dir){ + STRING_TRANSFER(factory->cached_sound_resources_dir, bctbx_strdup_printf("%s/rings", factory->sound_resources_dir)); + return factory->cached_sound_resources_dir; + } + return PACKAGE_RING_DIR; } void linphone_factory_set_ring_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->ring_resources_dir) bctbx_free(factory->ring_resources_dir); - factory->ring_resources_dir = bctbx_strdup(path); + STRING_SET(factory->ring_resources_dir, path); } -char * linphone_factory_get_image_resources_dir(const LinphoneFactory *factory) { - if (factory->image_resources_dir) return bctbx_strdup(factory->image_resources_dir); - if (factory->top_resources_dir) return bctbx_strdup_printf("%s/images", factory->top_resources_dir); - return bctbx_strdup_printf("%s/images", PACKAGE_DATA_DIR); +const char * linphone_factory_get_image_resources_dir(LinphoneFactory *factory) { + if (factory->image_resources_dir) return factory->image_resources_dir; + if (factory->top_resources_dir) { + STRING_TRANSFER(factory->cached_image_resources_dir, bctbx_strdup_printf("%s/images", factory->top_resources_dir)); + }else{ + STRING_TRANSFER(factory->cached_image_resources_dir, bctbx_strdup_printf("%s/images", PACKAGE_DATA_DIR)); + } + return factory->cached_image_resources_dir; } void linphone_factory_set_image_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->image_resources_dir) bctbx_free(factory->image_resources_dir); - factory->image_resources_dir = bctbx_strdup(path); + STRING_SET(factory->image_resources_dir, path); } -char * linphone_factory_get_msplugins_dir(const LinphoneFactory *factory) { - return bctbx_strdup(factory->msplugins_dir); +const char * linphone_factory_get_msplugins_dir(LinphoneFactory *factory) { + return factory->msplugins_dir; } void linphone_factory_set_msplugins_dir(LinphoneFactory *factory, const char *path) { - if (factory->msplugins_dir) bctbx_free(factory->msplugins_dir); - factory->msplugins_dir = bctbx_strdup(path); + STRING_SET(factory->msplugins_dir, path); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d4c64e416..76bde15aa 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1204,7 +1204,7 @@ static void sound_config_read(LinphoneCore *lc) static void certificates_config_read(LinphoneCore *lc) { LinphoneFactory *factory = linphone_factory_get(); - char *data_dir = linphone_factory_get_data_resources_dir(factory); + const char *data_dir = linphone_factory_get_data_resources_dir(factory); char *root_ca_path = bctbx_strdup_printf("%s/rootca.pem", data_dir); const char *rootca = lp_config_get_string(lc->config,"sip","root_ca", NULL); // If rootca is not existing anymore, we reset it to the default value @@ -1225,7 +1225,6 @@ static void certificates_config_read(LinphoneCore *lc) { linphone_core_verify_server_certificates(lc,lp_config_get_int(lc->config,"sip","verify_server_certs",TRUE)); linphone_core_verify_server_cn(lc,lp_config_get_int(lc->config,"sip","verify_server_cn",TRUE)); bctbx_free(root_ca_path); - bctbx_free(data_dir); } static void sip_config_read(LinphoneCore *lc) { @@ -2076,8 +2075,8 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig const char *remote_provisioning_uri = NULL; LinphoneFactory *lfactory = linphone_factory_get(); LinphoneCoreCbs *internal_cbs = _linphone_core_cbs_new(); - char *msplugins_dir; - char *image_resources_dir; + const char *msplugins_dir; + const char *image_resources_dir; ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); @@ -2109,8 +2108,6 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig msplugins_dir = linphone_factory_get_msplugins_dir(lfactory); image_resources_dir = linphone_factory_get_image_resources_dir(lfactory); lc->factory = ms_factory_new_with_voip_and_directories(msplugins_dir, image_resources_dir); - if (msplugins_dir) bctbx_free(msplugins_dir); - bctbx_free(image_resources_dir); linphone_core_register_default_codecs(lc); linphone_core_register_offer_answer_providers(lc); /* Get the mediastreamer2 event queue */ diff --git a/coreapi/private.h b/coreapi/private.h index dbbb9ccfd..be8e480ea 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -124,8 +124,11 @@ #ifdef __cplusplus extern "C" { #endif - -#define ms_strdup_safe(str) ((str) ? ms_strdup(str) : NULL) + + +#define STRING_RESET(field) if (field) bctbx_free(field); (field) = NULL +#define STRING_SET(field, value) do{ if (field){bctbx_free(field);field=NULL;}; field=bctbx_strdup(value); }while(0) +#define STRING_TRANSFER(field, newvalue) do{ if (field){bctbx_free(field);field=NULL;}; field=newvalue; }while(0) struct _LinphoneCallParams{ belle_sip_object_t base; diff --git a/gtk/main.c b/gtk/main.c index a7b79400e..8d12ac9ee 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -341,13 +341,12 @@ static int get_ui_file(const char *name, char *path, int pathsize){ snprintf(path,pathsize,"%s/%s.ui",BUILD_TREE_XML_DIR,name); if (bctbx_file_exist(path)!=0){ LinphoneFactory *factory = linphone_factory_get(); - char *data_dir = linphone_factory_get_data_resources_dir(factory); + const char *data_dir = linphone_factory_get_data_resources_dir(factory); snprintf(path,pathsize,"%s/%s.ui",data_dir,name); if (bctbx_file_exist(path)!=0){ g_error("Could not locate neither %s/%s.ui nor %s/%s.ui",BUILD_TREE_XML_DIR,name,data_dir,name); return -1; } - bctbx_free(data_dir); } return 0; } @@ -486,7 +485,7 @@ static void about_url_clicked(GtkAboutDialog *dialog, const char *url, gpointer void linphone_gtk_show_about(void){ struct stat filestat; - char *data_dir; + const char *data_dir; char *license_file; GtkWidget *about; const char *tmp; @@ -501,7 +500,6 @@ void linphone_gtk_show_about(void){ data_dir = linphone_factory_get_data_resources_dir(factory); license_file = bctbx_strdup_printf("%s/COPYING", data_dir); - bctbx_free(data_dir); memset(&filestat,0,sizeof(filestat)); if (stat(license_file,&filestat)!=0){ license_file="COPYING"; @@ -2136,7 +2134,7 @@ static void populate_xdg_data_dirs_envvar(void) { int i; gchar *value; gchar **paths; - char *data_dir; + const char *data_dir; LinphoneFactory *factory = linphone_factory_get(); if(g_getenv("XDG_DATA_DIRS") == NULL) { @@ -2152,7 +2150,6 @@ static void populate_xdg_data_dirs_envvar(void) { g_setenv("XDG_DATA_DIRS", new_value, TRUE); g_free(new_value); } - bctbx_free(data_dir); g_strfreev(paths); #endif } @@ -2168,7 +2165,7 @@ int main(int argc, char *argv[]){ char *chat_messages_db_file, *call_logs_db_file, *friends_db_file; GError *error=NULL; const char *tmp; - char *resources_dir; + const char *resources_dir; char *pixmaps_dir; LinphoneFactory *factory; @@ -2271,7 +2268,6 @@ int main(int argc, char *argv[]){ pixmaps_dir = bctbx_strdup_printf("%s/pixmaps/linphone", resources_dir); add_pixmap_directory(pixmaps_dir); bctbx_free(pixmaps_dir); - bctbx_free(resources_dir); /* Now, look for the factory configuration file, we do it this late since we want to have had time to change directory and to parse diff --git a/gtk/support.c b/gtk/support.c index e2fbfc360..df6006ee0 100644 --- a/gtk/support.c +++ b/gtk/support.c @@ -193,7 +193,7 @@ void linphone_gtk_set_ui_config(const char *key , const char * val){ const char *linphone_gtk_get_sound_path(const char *name){ static char *ret=NULL; const char *file; - char *sound_dir; + const char *sound_dir; LinphoneFactory *factory = linphone_factory_get(); file=linphone_gtk_get_ui_config(name,NULL); @@ -212,7 +212,6 @@ const char *linphone_gtk_get_sound_path(const char *name){ } sound_dir = linphone_factory_get_sound_resources_dir(factory); ret=g_build_filename(sound_dir,name,NULL); - bctbx_free(sound_dir); return ret; } diff --git a/include/linphone/factory.h b/include/linphone/factory.h index c24d9005f..8ff784db1 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -123,7 +123,7 @@ LINPHONE_PUBLIC LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *fa * @param[in] factory LinphoneFactory object * @return The path to the top directory where the resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory); /** * Set the top directory where the resources are located. @@ -138,7 +138,7 @@ LINPHONE_PUBLIC void linphone_factory_set_top_resources_dir(LinphoneFactory *fac * @param[in] factory LinphoneFactory object * @return The path to the directory where the data resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_data_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_data_resources_dir(LinphoneFactory *factory); /** * Set the directory where the data resources are located. @@ -152,7 +152,7 @@ LINPHONE_PUBLIC void linphone_factory_set_data_resources_dir(LinphoneFactory *fa * @param[in] factory LinphoneFactory object * @return The path to the directory where the sound resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_sound_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_sound_resources_dir(LinphoneFactory *factory); /** * Set the directory where the sound resources are located. @@ -166,7 +166,7 @@ LINPHONE_PUBLIC void linphone_factory_set_sound_resources_dir(LinphoneFactory *f * @param[in] factory LinphoneFactory object * @return The path to the directory where the ring resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_ring_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_ring_resources_dir(LinphoneFactory *factory); /** * Set the directory where the ring resources are located. @@ -180,7 +180,7 @@ LINPHONE_PUBLIC void linphone_factory_set_ring_resources_dir(LinphoneFactory *fa * @param[in] factory LinphoneFactory object * @return The path to the directory where the image resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_image_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_image_resources_dir(LinphoneFactory *factory); /** * Set the directory where the image resources are located. @@ -194,7 +194,7 @@ LINPHONE_PUBLIC void linphone_factory_set_image_resources_dir(LinphoneFactory *f * @param[in] factory LinphoneFactory object * @return The path to the directory where the mediastreamer2 plugins are located, or NULL if it has not been set */ -LINPHONE_PUBLIC char * linphone_factory_get_msplugins_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_msplugins_dir(LinphoneFactory *factory); /** * Set the directory where the mediastreamer2 plugins are located. diff --git a/mediastreamer2 b/mediastreamer2 index 1f17b3ba2..b5a000c65 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 1f17b3ba22cb662c1c15655c8248036e7a69baf2 +Subproject commit b5a000c65e109312c1f0b72ce5e9122caec72e4f diff --git a/tools/auto_answer.c b/tools/auto_answer.c index 74a3ae292..d0dc9edcc 100644 --- a/tools/auto_answer.c +++ b/tools/auto_answer.c @@ -141,11 +141,10 @@ int main(int argc, char *argv[]){ linphone_core_enable_echo_cancellation(lc, FALSE); /*no need for local echo cancellation when playing files*/ if (!media_file){ LinphoneFactory *factory = linphone_factory_get(); - char *sound_resources_dir = linphone_factory_get_sound_resources_dir(factory); + const char *sound_resources_dir = linphone_factory_get_sound_resources_dir(factory); char *play_file = bctbx_strdup_printf("%s/hello16000.wav", sound_resources_dir); linphone_core_set_play_file(lc, play_file); bctbx_free(play_file); - bctbx_free(sound_resources_dir); linphone_core_set_preferred_framerate(lc,5); }else{ PayloadType *pt = linphone_core_find_payload_type(lc, "opus", 48000, -1);