Fix resource leak for 'query_list' and retrieve 'sql_str_free' function 50/226550/9
authorjiyong.min <jiyong.min@samsung.com>
Tue, 3 Mar 2020 05:42:19 +0000 (14:42 +0900)
committerjiyong.min <jiyong.min@samsung.com>
Fri, 6 Mar 2020 00:40:09 +0000 (09:40 +0900)
Change-Id: I247fdeaa76fcbc1aa83c2b85be9da3402e31570c

packaging/capi-media-controller.spec
svc/media_controller_db_util.c

index e9a2368f3d8a453f6e98c5f9dcabd444e17cca3d..5db7f366804bd35c0c3c73bde5d7d6dc6b11d76a 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-controller
 Summary:    A media controller library in Tizen Native API
-Version:    0.2.11
+Version:    0.2.12
 Release:    1
 Group:      Multimedia/API
 License:    Apache-2.0
index eed5d54d326d00408e380823a4a11601cc7b2b0a..5eb45845e3709d93cfc32e1bd2e1a879afd4da41 100644 (file)
 #include "mc_util.h"
 
 #define REGULAR_USER   5000
+
+typedef struct {
+       const char *server_name;
+       const char *playlist_name;
+       GSList *query_list;
+       unsigned int query_length;
+} playlist_query_s;
+
 static GMutex tzplatform_mutex;
 
 static char *__mc_db_get_user_path(uid_t uid)
@@ -602,17 +610,17 @@ static const char * __replace_null(const char *data)
                return data;
 }
 
-static void  __playlist_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
+static void  __make_playlist_query_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
 {
        void *basic_val = NULL;
        size_t basic_size = 0;
        gchar **params = NULL;
-       GList **query_list = (GList**)user_data;
+       playlist_query_s *query = (playlist_query_s *)user_data;
        char *sql_str = NULL;
 
        mc_retm_if(!key, "invalid key");
        mc_retm_if(!kv, "invalid kv");
-       mc_retm_if(!query_list, "invalid query_list");
+       mc_retm_if(!query, "invalid query");
 
        bundle_keyval_get_basic_val((bundle_keyval_t *)kv, &basic_val, &basic_size);
 
@@ -622,7 +630,7 @@ static void  __playlist_cb(const char *key, const int type, const bundle_keyval_
        mc_retm_if(params == NULL, "invalid playlist data");
 
        sql_str = sqlite3_mprintf("INSERT INTO %q(server_name, playlist_name, item_index, %s) VALUES (%Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q);",
-                               MC_DB_TABLE_PLAYLIST, META_LIST, g_list_nth_data(*query_list, 0), g_list_nth_data(*query_list, 1), key,
+                               MC_DB_TABLE_PLAYLIST, META_LIST, query->server_name, query->playlist_name, key,
                                __replace_null(params[0]), __replace_null(params[1]), __replace_null(params[2]), __replace_null(params[3]), __replace_null(params[4]),
                                __replace_null(params[5]), __replace_null(params[6]), __replace_null(params[7]), __replace_null(params[8]), __replace_null(params[9]),
                                __replace_null(params[10]), __replace_null(params[11]), __replace_null(params[12]), __replace_null(params[13]));
@@ -631,7 +639,13 @@ static void  __playlist_cb(const char *key, const int type, const bundle_keyval_
 
        mc_secure_debug("sql_str [%s]", sql_str);
 
-       *query_list = g_list_append(*query_list, sql_str);
+       query->query_list = g_slist_append(query->query_list, sql_str);
+       query->query_length += strlen(sql_str);
+}
+
+static void __sqlite3_safe_free(gpointer data)
+{
+       SQLITE3_SAFE_FREE(data);
 }
 
 static int __parse_db_request(gchar **params, char **sql_str)
@@ -699,10 +713,8 @@ static int __parse_db_request(gchar **params, char **sql_str)
 
        } else if (strncmp(MC_DB_CMD_UPDATE_PLAYLIST, params[0], strlen(MC_DB_CMD_UPDATE_PLAYLIST)) == 0) {
                bundle *bundle = NULL;
-               GList *query_list = NULL;
-               int list_len = 0;
-               int total_query_len = 0;
-               int i = 0;
+               playlist_query_s playlist_query = { NULL, NULL, NULL, 0 };
+               GSList *iter = NULL;
 
                mc_retvm_if((!params[2] || !params[3] || !params[4]),
                                        MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "invalid query");
@@ -713,37 +725,27 @@ static int __parse_db_request(gchar **params, char **sql_str)
 
                mc_debug("bundle item count [%d]", bundle_get_count(bundle));
 
-               query_list = g_list_append(query_list, params[1]);      //server_name
-               query_list = g_list_append(query_list, params[2]);      //playlist_name
+               playlist_query.server_name = params[1];
+               playlist_query.playlist_name = params[2];
 
-               bundle_foreach(bundle, __playlist_cb, &query_list);
+               bundle_foreach(bundle, __make_playlist_query_cb, &playlist_query);
                bundle_free(bundle);
 
-               list_len = g_list_length(query_list);
-               if (list_len < 3) {
-                       mc_error("invalid query_list len [%d]", list_len);
-                       return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
-               }
+               mc_retvm_if(!playlist_query.query_list, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "invalid query_list");
 
-               for (i = 2; i < list_len; i++) {
-                       char *query = NULL;
-                       query = g_list_nth_data(query_list, i);
-                       if (query != NULL)
-                               total_query_len += strlen(query);
+               _sql_str = (char *)sqlite3_malloc(playlist_query.query_length + 1);
+               if (!_sql_str) {
+                       mc_error("invalid _sql_str");
+                       g_slist_free_full(playlist_query.query_list, __sqlite3_safe_free);
+                       return MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY;
                }
+               memset(_sql_str, 0, playlist_query.query_length + 1);
+               for (iter = playlist_query.query_list; (iter && iter->data); iter = g_slist_next(iter))
+                       g_strlcat(_sql_str, (char *)iter->data, playlist_query.query_length + 1);
 
-               _sql_str = (char *)calloc(1, total_query_len + 1);
-
-               for (i = 2; i < list_len; i++) {
-                       char *query = NULL;
-                       query = g_list_nth_data(query_list, i);
-                       if (query != NULL) {
-                               g_strlcat(_sql_str, query, total_query_len + 1);
-                               SQLITE3_SAFE_FREE(query);
-                       }
-               }
+               g_slist_free_full(playlist_query.query_list, __sqlite3_safe_free);
+               playlist_query.query_list = NULL;
 
-               query_list = NULL;
        } else if (strncmp(MC_DB_CMD_UPDATE_ICON, params[0], strlen(MC_DB_CMD_UPDATE_ICON)) == 0) {
                if (params[2])
                        _sql_str = sqlite3_mprintf("UPDATE %q SET icon_uri=%Q WHERE name=%Q", MC_DB_TABLE_SERVER_INFO, params[2], params[1]);
@@ -848,12 +850,8 @@ int mc_db_request(uid_t uid, const char *data, int data_size)
        mc_retvm_if(!params, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail to parsing query");
 
        ret = __parse_db_request(params, &sql_str);
-       if (ret == MEDIA_CONTROLLER_ERROR_NONE)
+       if (ret == MEDIA_CONTROLLER_ERROR_NONE) {
                ret = __update_db_request(uid, params, sql_str);
-
-       if (strncmp(MC_DB_CMD_UPDATE_PLAYLIST, params[0], strlen(MC_DB_CMD_UPDATE_PLAYLIST)) == 0) {
-               MC_SAFE_FREE(sql_str);
-       } else {
                SQLITE3_SAFE_FREE(sql_str);
        }
        g_strfreev(params);