Fix static analysis issue
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_appinfo.c
index 0e8cf33..b50e08d 100644 (file)
@@ -52,6 +52,9 @@ static const char join_app_control[] =
 static const char join_metadata[] =
        " LEFT OUTER JOIN package_app_app_metadata"
        "  ON ai.app_id=package_app_app_metadata.app_id ";
+static const char join_privilege[] =
+       " LEFT OUTER JOIN package_privilege_info"
+       " ON ai.package=package_privilege_info.package ";
 
 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
        const char *locale, uid_t uid, char **query, GList **bind_params)
@@ -104,6 +107,8 @@ static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
                strncat(tmp_query, join_app_control, sizeof(tmp_query) - strlen(tmp_query) - 1);
        if (joined & E_PMINFO_APPINFO_JOIN_METADATA)
                strncat(tmp_query, join_metadata, sizeof(tmp_query) - strlen(tmp_query) - 1);
+       if (joined & E_PMINFO_APPINFO_JOIN_PRIVILEGE)
+               strncat(tmp_query, join_privilege, sizeof(tmp_query) - strlen(tmp_query) - 1);
 
        strncat(tmp_query, buf, sizeof(tmp_query) - strlen(tmp_query) - 1);
 
@@ -149,7 +154,8 @@ static int _appinfo_get_category(sqlite3 *db, const char *appid,
        return PMINFO_R_OK;
 }
 
-static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str)
+static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str,
+               char *visibility, char *id)
 {
        char *dup;
        char *token;
@@ -160,6 +166,11 @@ static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str)
                return;
 
        dup = strdup(appcontrol_str);
+       if (dup == NULL) {
+               _LOGE("out of memory");
+               return;
+       }
+
        do {
                ac = calloc(1, sizeof(appcontrol_x));
                if (ac == NULL) {
@@ -175,6 +186,8 @@ static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str)
                token = strtok_r(NULL, "|", &ptr);
                if (token && strcmp(token, "NULL"))
                        ac->mime = strdup(token);
+               ac->visibility = strdup(visibility);
+               ac->id = strdup(id);
                *appcontrol = g_list_append(*appcontrol, ac);
        } while ((token = strtok_r(NULL, ";", &ptr)));
 
@@ -185,12 +198,15 @@ static int _appinfo_get_app_control(sqlite3 *db, const char *appid,
                GList **appcontrol)
 {
        static const char query_raw[] =
-               "SELECT app_control FROM package_app_app_control "
-               "WHERE app_id=%Q";
+               "SELECT app_control, visibility, app_control_id "
+               "FROM package_app_app_control WHERE app_id=%Q";
        int ret;
+       int idx;
        char *query;
        sqlite3_stmt *stmt;
        char *str;
+       char *visibility;
+       char *id;
 
        query = sqlite3_mprintf(query_raw, appid);
        if (query == NULL) {
@@ -207,10 +223,17 @@ static int _appinfo_get_app_control(sqlite3 *db, const char *appid,
 
        while (sqlite3_step(stmt) == SQLITE_ROW) {
                str = NULL;
-               _save_column_str(stmt, 0, &str);
+               visibility = NULL;
+               id = NULL;
+               idx = 0;
+               _save_column_str(stmt, idx++, &str);
+               _save_column_str(stmt, idx++, &visibility);
+               _save_column_str(stmt, idx++, &id);
                /* TODO: revise */
-               __parse_appcontrol(appcontrol, str);
+               __parse_appcontrol(appcontrol, str, visibility, id);
                free(str);
+               free(visibility);
+               free(id);
        }
 
        sqlite3_finalize(stmt);
@@ -598,6 +621,7 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
                        info->background_category = __get_background_category(
                                        bg_category_str);
                        free(bg_category_str);
+                       bg_category_str = NULL;
                }
 
                info->for_all_users =
@@ -613,6 +637,8 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
                                                strcasecmp(tmp_record, "false") == 0) {
                                        free(info->is_disabled);
                                        info->is_disabled = tmp_record;
+                               } else {
+                                       free(tmp_record);
                                }
                        }
                        tmp_record = NULL;
@@ -622,6 +648,8 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
                                                strcasecmp(tmp_record, "false") == 0) {
                                        free(info->splash_screen_display);
                                        info->splash_screen_display = tmp_record;
+                               } else {
+                                       free(tmp_record);
                                }
                        }
                }
@@ -691,6 +719,9 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
        ret = PMINFO_R_OK;
 
 catch:
+       sqlite3_finalize(stmt);
+       sqlite3_close_v2(db);
+
        if (constraint)
                free(constraint);
 
@@ -698,8 +729,6 @@ catch:
                pkgmgrinfo_basic_free_application(info);
 
        g_list_free_full(bind_params, free);
-       sqlite3_close_v2(db);
-       sqlite3_finalize(stmt);
 
        return ret;
 }
@@ -757,8 +786,21 @@ static int _pkgmgrinfo_get_appinfo(const char *appid, uid_t uid,
        }
 
        info->app_info = (application_x *)g_hash_table_lookup(list, appid);
+       if (!info->app_info || !info->app_info->package) {
+               _LOGD("appinfo for [%s] is not existed for user [%d]",
+                               appid, uid);
+               g_hash_table_destroy(list);
+               free(locale);
+               return PMINFO_R_ENOENT;
+       }
        info->locale = locale;
        info->package = strdup(info->app_info->package);
+       if (!info->package) {
+               _LOGE("out of memory");
+               g_hash_table_destroy(list);
+               free(locale);
+               return PMINFO_R_ERROR;
+       }
 
        /* just free list only */
        g_hash_table_steal(list, (gconstpointer)appid);
@@ -1697,6 +1739,8 @@ static pkgmgrinfo_app_component __appcomponent_convert(const char *comp)
                return PMINFO_WIDGET_APP;
        else if (strcasecmp(comp, "watchapp") == 0)
                return PMINFO_WATCH_APP;
+       else if (strcasecmp(comp, "componentbasedapp") == 0)
+               return PMINFO_COMPONENT_BASED_APP;
        else
                return -1;
 }
@@ -1712,6 +1756,8 @@ static const char *__appcomponent_str(pkgmgrinfo_app_component comp)
                return "widgetapp";
        case PMINFO_WATCH_APP:
                return "watchapp";
+       case PMINFO_COMPONENT_BASED_APP:
+               return "componentbasedapp";
        default:
                return NULL;
        }
@@ -2687,14 +2733,19 @@ API int pkgmgrinfo_appinfo_foreach_metadata(pkgmgrinfo_appinfo_h handle,
 }
 
 static int _appinfo_foreach_appcontrol_privileges(sqlite3 *db,
-               const char *appid, const char *app_control,
+               const char *appid, const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb callback, void *user_data)
 {
        static const char query[] =
-               "SELECT privilege FROM package_app_app_control_privilege "
-               "WHERE app_id=? AND app_control=?";
+               "SELECT app_control, privilege FROM package_app_app_control_privilege "
+               "WHERE app_id=?";
        int ret;
        sqlite3_stmt *stmt;
+       const char *app_control;
+       char *dup_app_control;
+       char *token;
+       char *saveptr = NULL;
+       const char *privilege;
        int count = 0;
 
        ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
@@ -2710,19 +2761,26 @@ static int _appinfo_foreach_appcontrol_privileges(sqlite3 *db,
                return PMINFO_R_ERROR;
        }
 
-       ret = sqlite3_bind_text(stmt, 2, app_control, -1, SQLITE_STATIC);
-       if (ret != SQLITE_OK) {
-               LOGE("bind failed: %s", sqlite3_errmsg(db));
-               sqlite3_finalize(stmt);
-               return PMINFO_R_ERROR;
-       }
-
        while (sqlite3_step(stmt) == SQLITE_ROW) {
-               count++;
-               ret = callback((const char *)sqlite3_column_text(stmt, 0),
-                               user_data);
-               if (ret < 0)
-                       break;
+               app_control = (const char *)sqlite3_column_text(stmt, 0);
+               if (!app_control)
+                       continue;
+
+               dup_app_control = strdup(app_control);
+               if (!dup_app_control)
+                       continue;
+
+               token = strtok_r(dup_app_control, "|", &saveptr);
+               if (token && !strcmp(token, operation)) {
+                       count++;
+                       privilege = (const char *)sqlite3_column_text(stmt, 1);
+                       ret = callback(privilege, user_data);
+                       if (ret < 0) {
+                               free(dup_app_control);
+                               break;
+                       }
+               }
+               free(dup_app_control);
        }
 
        sqlite3_finalize(stmt);
@@ -2731,7 +2789,7 @@ static int _appinfo_foreach_appcontrol_privileges(sqlite3 *db,
 }
 
 static int _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid_t uid,
-               const char *appid, const char *app_control,
+               const char *appid, const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb callback, void *user_data)
 {
        int ret;
@@ -2749,7 +2807,7 @@ static int _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid_t uid,
                return PMINFO_R_ERROR;
        }
 
-       ret = _appinfo_foreach_appcontrol_privileges(db, appid, app_control,
+       ret = _appinfo_foreach_appcontrol_privileges(db, appid, operation,
                        callback, user_data);
        sqlite3_close_v2(db);
 
@@ -2757,26 +2815,22 @@ static int _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid_t uid,
 }
 
 API int pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(const char *appid,
-               const char *operation, const char *uri, const char *mime,
+               const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb privilege_func,
                void *user_data, uid_t uid)
 {
        int ret;
-       char app_control[BUFSIZE];
 
        if (appid == NULL || operation == NULL || privilege_func == NULL) {
                LOGE("invalid parameter");
                return PMINFO_R_EINVAL;
        }
 
-       snprintf(app_control, sizeof(app_control), "%s|%s|%s", operation,
-                       uri ? uri : "NULL", mime ? mime : "NULL");
-
        ret = _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(GLOBAL_USER,
-                       appid, app_control, privilege_func, user_data);
+                       appid, operation, privilege_func, user_data);
        if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
                ret = _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid,
-                               appid, app_control, privilege_func, user_data);
+                               appid, operation, privilege_func, user_data);
 
        if (ret == PMINFO_R_ENOENT)
                ret = PMINFO_R_OK;
@@ -2785,13 +2839,12 @@ API int pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(const char *appid,
 }
 
 API int pkgmgrinfo_appinfo_foreach_appcontrol_privileges(const char *appid,
-               const char *operation, const char *uri, const char *mime,
+               const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb privilege_func,
                void *user_data)
 {
        return pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(appid,
-                       operation, uri, mime, privilege_func, user_data,
-                       _getuid());
+                       operation, privilege_func, user_data, _getuid());
 }
 
 API int pkgmgrinfo_appinfo_foreach_appcontrol(pkgmgrinfo_appinfo_h handle,
@@ -2809,7 +2862,32 @@ API int pkgmgrinfo_appinfo_foreach_appcontrol(pkgmgrinfo_appinfo_h handle,
 
        for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
                appcontrol = (appcontrol_x *)tmp->data;
-               if (appcontrol == NULL)
+               if (appcontrol == NULL || !strcasecmp(appcontrol->visibility, "remote-only"))
+                       continue;
+               ret = appcontrol_func(appcontrol->operation, appcontrol->uri, appcontrol->mime, user_data);
+               if (ret < 0)
+                       break;
+       }
+
+       return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_appinfo_foreach_remote_appcontrol(pkgmgrinfo_appinfo_h handle,
+                       pkgmgrinfo_app_control_list_cb appcontrol_func, void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+       retvm_if(appcontrol_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+       int ret;
+       pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+       appcontrol_x *appcontrol;
+       GList *tmp;
+
+       if (info->app_info == NULL)
+               return PMINFO_R_ERROR;
+
+       for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
+               appcontrol = (appcontrol_x *)tmp->data;
+               if (appcontrol == NULL || !strcasecmp(appcontrol->visibility, "local-only"))
                        continue;
                ret = appcontrol_func(appcontrol->operation, appcontrol->uri, appcontrol->mime, user_data);
                if (ret < 0)
@@ -3570,3 +3648,60 @@ API int pkgmgrinfo_appinfo_is_guestmode_visibility(pkgmgrinfo_appinfo_h handle,
        *status = _get_bool_value(val);
        return PMINFO_R_OK;
 }
+
+API int pkgmgrinfo_appinfo_foreach_appcontrol_v2(pkgmgrinfo_appinfo_h handle,
+               pkgmgrinfo_app_control_list_cb_v2 appcontrol_func,
+               void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+       retvm_if(appcontrol_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+       int ret;
+       pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+       appcontrol_x *appcontrol;
+       GList *tmp;
+
+       if (info->app_info == NULL)
+               return PMINFO_R_ERROR;
+
+       for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
+               appcontrol = (appcontrol_x *)tmp->data;
+               if (appcontrol == NULL ||
+                               !strcasecmp(appcontrol->visibility, "remote-only"))
+                       continue;
+               ret = appcontrol_func(appcontrol->operation, appcontrol->uri,
+                               appcontrol->mime, appcontrol->id, user_data);
+               if (ret < 0)
+                       break;
+       }
+
+       return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_appinfo_foreach_remote_appcontrol_v2(
+               pkgmgrinfo_appinfo_h handle,
+               pkgmgrinfo_app_control_list_cb_v2 appcontrol_func,
+               void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+       retvm_if(appcontrol_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+       int ret;
+       pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+       appcontrol_x *appcontrol;
+       GList *tmp;
+
+       if (info->app_info == NULL)
+               return PMINFO_R_ERROR;
+
+       for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
+               appcontrol = (appcontrol_x *)tmp->data;
+               if (appcontrol == NULL ||
+                               !strcasecmp(appcontrol->visibility, "local-only"))
+                       continue;
+               ret = appcontrol_func(appcontrol->operation, appcontrol->uri,
+                               appcontrol->mime, appcontrol->id, user_data);
+               if (ret < 0)
+                       break;
+       }
+
+       return PMINFO_R_OK;
+}