Fix memory release issue in tts_parser_unload_config
[platform/core/uifw/tts.git] / common / tts_config_parser.c
old mode 100644 (file)
new mode 100755 (executable)
index 7c5a3e2..17c4a27
@@ -1,5 +1,5 @@
 /*
-*  Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved 
+*  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
@@ -61,6 +61,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
 
        doc = xmlParseFile(path);
        if (doc == NULL) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse xml file");
                return -1;
        }
 
@@ -68,12 +69,14 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
        if (cur == NULL) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
        if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_BASE_TAG)) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT 'tts-engine'");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
@@ -81,12 +84,18 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
        if (cur == NULL) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
        /* alloc engine info */
        tts_engine_info_s* temp;
        temp = (tts_engine_info_s*)calloc(1, sizeof(tts_engine_info_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
+               xmlFreeDoc(doc);
+               return -1;
+       }
 
        temp->name = NULL;
        temp->uuid = NULL;
@@ -128,8 +137,11 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
 
                        while (NULL != voice_node) {
                                if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
-
                                        tts_config_voice_s* temp_voice = (tts_config_voice_s*)calloc(1, sizeof(tts_config_voice_s));
+                                       if (NULL == temp_voice) {
+                                               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
+                                               break;
+                                       }
 
                                        attr = xmlGetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE);
                                        if (NULL != attr) {
@@ -145,6 +157,9 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                                xmlFree(attr);
                                        } else {
                                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
+                                               free(temp_voice);
+                                               temp_voice = NULL;
+                                               continue;
                                        }
 
                                        key = xmlNodeGetContent(voice_node);
@@ -152,11 +167,14 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                                if (NULL != temp_voice->language)       free(temp_voice->language);
                                                temp_voice->language = strdup((char*)key);
                                                xmlFree(key);
+                                               temp->voices = g_slist_append(temp->voices, temp_voice);
                                        } else {
                                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
+                                               if (NULL != temp_voice) {
+                                                       free(temp_voice);
+                                                       temp_voice = NULL;
+                                               }
                                        }
-
-                                       temp->voices = g_slist_append(temp->voices, temp_voice);
                                }
                                voice_node = voice_node->next;
                        }
@@ -167,6 +185,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
                                        temp->pitch_support = true;
                                }
                                xmlFree(key);
+                               key = NULL;
                        } else {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
                        }
@@ -175,6 +194,7 @@ int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info
        }
 
        xmlFreeDoc(doc);
+       doc = NULL;
 
        if (NULL == temp->name || NULL == temp->uuid) {
                /* Invalid engine */
@@ -271,6 +291,9 @@ int tts_parser_load_config(tts_config_s** config_info)
        xmlChar *key;
        bool is_default_open = false;
 
+       /* For Thread safety */
+       xmlInitParser();
+
        if (0 != access(TTS_CONFIG, F_OK)) {
                doc = xmlParseFile(TTS_DEFAULT_CONFIG);
                if (doc == NULL) {
@@ -287,9 +310,9 @@ int tts_parser_load_config(tts_config_s** config_info)
                                break;
                        }
                        retry_count++;
-                       usleep(1000);
+                       usleep(10000);
 
-                       if (100 == retry_count) {
+                       if (TTS_RETRY_COUNT == retry_count) {
                                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
                                return -1;
                        }
@@ -300,12 +323,14 @@ int tts_parser_load_config(tts_config_s** config_info)
        if (cur == NULL) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
        if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
@@ -313,12 +338,18 @@ int tts_parser_load_config(tts_config_s** config_info)
        if (cur == NULL) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
        /* alloc engine info */
        tts_config_s* temp;
        temp = (tts_config_s*)calloc(1, sizeof(tts_config_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
+               xmlFreeDoc(doc);
+               return -1;
+       }
 
        temp->engine_id = NULL;
        temp->setting = NULL;
@@ -437,14 +468,58 @@ int tts_parser_load_config(tts_config_s** config_info)
 
 int tts_parser_unload_config(tts_config_s* config_info)
 {
-       if (NULL != g_config_doc)       xmlFreeDoc(g_config_doc);
+       if (NULL != g_config_doc) {
+               xmlFreeDoc(g_config_doc);
+               g_config_doc = NULL;
+       }
        if (NULL != config_info) {
-               if (NULL != config_info->engine_id)     free(config_info->engine_id);
-               if (NULL != config_info->setting)       free(config_info->setting);
-               if (NULL != config_info->language)      free(config_info->language);
+               if (NULL != config_info->engine_id)     {
+                       free(config_info->engine_id);
+                       config_info->engine_id = NULL;
+               }
+               if (NULL != config_info->setting) {
+                       free(config_info->setting);
+                       config_info->setting = NULL;
+               }
+               if (NULL != config_info->language) {
+                       free(config_info->language);
+                       config_info->language = NULL;
+               }
                free(config_info);
+               config_info = NULL;
+       }
+
+       return 0;
+}
+
+
+int tts_parser_copy_xml(const char* original, const char* destination)
+{
+       if (NULL == original || NULL == destination) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       xmlDocPtr doc = NULL;
+       doc = xmlParseFile(original);
+       if (doc == NULL) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", original);
+               return -1;
+       }
+
+       int ret = xmlSaveFile(destination, doc);
+       if (0 > ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
+       }
+
+       /* Set mode */
+       if (0 > chmod(destination, 0666)) {
+               SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
        }
 
+       xmlFreeDoc(doc);
+       SLOG(LOG_DEBUG, tts_tag(), "[SUCCESS] Copying xml");
+
        return 0;
 }
 
@@ -707,9 +782,9 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                        break;
                }
                retry_count++;
-               usleep(1000);
+               usleep(10000);
 
-               if (100 == retry_count) {
+               if (TTS_RETRY_COUNT == retry_count) {
                        SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
                        return -1;
                }
@@ -720,6 +795,7 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
        if (cur_new == NULL || cur_old == NULL) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
@@ -727,6 +803,7 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
        xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG)) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
@@ -735,6 +812,7 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
        if (cur_new == NULL || cur_old == NULL) {
                SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
                xmlFreeDoc(doc);
+               doc = NULL;
                return -1;
        }
 
@@ -887,9 +965,12 @@ int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voic
                cur_new = cur_new->next;
                cur_old = cur_old->next;
        }
-       
-       xmlFreeDoc(g_config_doc);
+
+       if (NULL != g_config_doc) {
+               xmlFreeDoc(g_config_doc);
+               g_config_doc = NULL;
+       }
        g_config_doc = doc;
 
        return 0;
-}
\ No newline at end of file
+}