<commit_before>/*
 * Copyright 2019 The Imaging Source Europe GmbH
 *
 * 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
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "tcamgstjson.h"

#include "../../../external/json/json.hpp"
#include "../../logging.h"

// for convenience
using json = nlohmann::json;

std::string tcam::gst::create_device_settings(TcamPropertyProvider* tcam)
{
    if (!tcam)
    {
        return {};
    }

    json j;

    auto& write_obj = j;

    GError* err_get_name = nullptr;
    GSList* names = tcam_property_provider_get_tcam_property_names(tcam, &err_get_name);
    if (err_get_name)
    {
        SPDLOG_ERROR("Failed to read property names from , err={}.", err_get_name->message);
        g_error_free(err_get_name);
        return {};
    }

    /**
     * If err is set, reports the error and returns true. Otherwise false is returned.
     */
    auto is_prop_error_consume = [](GError* err, const char* property_name) -> bool
    {
        if (!err)
        {
            return false;
        }
        SPDLOG_ERROR("Reading '{}' caused an error: {}", property_name, err->message);
        g_error_free(err);
        return true;
    };

    for (unsigned int i = 0; i < g_slist_length(names); ++i)
    {
        GError* err_get_prop = nullptr;

        const char* prop_name = static_cast<const char*>(g_slist_nth_data(names, i));

        auto prop_base = tcam_property_provider_get_tcam_property(tcam, prop_name, &err_get_prop);
        if (is_prop_error_consume(err_get_prop, prop_name))
        {
            continue;
        }

        if (tcam_property_base_get_access(prop_base) == TCAM_PROPERTY_ACCESS_WO)
            continue;
        if (!tcam_property_base_is_available(prop_base, nullptr))
            continue;

        switch (tcam_property_base_get_property_type(prop_base))
        {
            case TCAM_PROPERTY_TYPE_INTEGER:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_integer_get_value(TCAM_PROPERTY_INTEGER(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_FLOAT:
            {
                GError* err = nullptr;
                auto value = tcam_property_float_get_value(TCAM_PROPERTY_FLOAT(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_ENUMERATION:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_enumeration_get_value(TCAM_PROPERTY_ENUMERATION(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_BOOLEAN:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_boolean_get_value(TCAM_PROPERTY_BOOLEAN(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_COMMAND:
            {
                // Nothing to do here
                break;
            }
            case TCAM_PROPERTY_TYPE_STRING:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_string_get_value(TCAM_PROPERTY_STRING(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                g_free(value);
                break;
            }
        }

        g_object_unref(prop_base);
    }
    g_slist_free_full(names, ::g_free);

    int indent = 4;
    return j.dump(indent);
}

enum class apply_single_json_entry_rval<commit_msg>gst/json: Add security check for value handling<commit_after>/*
 * Copyright 2019 The Imaging Source Europe GmbH
 *
 * 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
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "tcamgstjson.h"

#include "../../../external/json/json.hpp"
#include "../../logging.h"

// for convenience
using json = nlohmann::json;

std::string tcam::gst::create_device_settings(TcamPropertyProvider* tcam)
{
    if (!tcam)
    {
        return {};
    }

    json j;

    auto& write_obj = j;

    GError* err_get_name = nullptr;
    GSList* names = tcam_property_provider_get_tcam_property_names(tcam, &err_get_name);
    if (err_get_name)
    {
        SPDLOG_ERROR("Failed to read property names from , err={}.", err_get_name->message);
        g_error_free(err_get_name);
        return {};
    }

    /**
     * If err is set, reports the error and returns true. Otherwise false is returned.
     */
    auto is_prop_error_consume = [](GError* err, const char* property_name) -> bool
    {
        if (!err)
        {
            return false;
        }
        SPDLOG_ERROR("Reading '{}' caused an error: {}", property_name, err->message);
        g_error_free(err);
        return true;
    };

    for (unsigned int i = 0; i < g_slist_length(names); ++i)
    {
        GError* err_get_prop = nullptr;

        const char* prop_name = static_cast<const char*>(g_slist_nth_data(names, i));

        auto prop_base = tcam_property_provider_get_tcam_property(tcam, prop_name, &err_get_prop);
        if (is_prop_error_consume(err_get_prop, prop_name))
        {
            continue;
        }

        if (tcam_property_base_get_access(prop_base) == TCAM_PROPERTY_ACCESS_WO)
            continue;
        if (!tcam_property_base_is_available(prop_base, nullptr))
            continue;

        switch (tcam_property_base_get_property_type(prop_base))
        {
            case TCAM_PROPERTY_TYPE_INTEGER:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_integer_get_value(TCAM_PROPERTY_INTEGER(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_FLOAT:
            {
                GError* err = nullptr;
                auto value = tcam_property_float_get_value(TCAM_PROPERTY_FLOAT(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_ENUMERATION:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_enumeration_get_value(TCAM_PROPERTY_ENUMERATION(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_BOOLEAN:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_boolean_get_value(TCAM_PROPERTY_BOOLEAN(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    write_obj.push_back(json::object_t::value_type(prop_name, value));
                }
                break;
            }
            case TCAM_PROPERTY_TYPE_COMMAND:
            {
                // Nothing to do here
                break;
            }
            case TCAM_PROPERTY_TYPE_STRING:
            {
                GError* err = nullptr;
                auto value =
                    tcam_property_string_get_value(TCAM_PROPERTY_STRING(prop_base), &err);
                if (!is_prop_error_consume(err, prop_name))
                {
                    if (value)
                    {
                        write_obj.push_back(json::object_t::value_type(prop_name, value));
                    }
                }
                g_free(value);
                break;
            }
        }

        g_object_unref(prop_base);
    }
    g_slist_free_full(names, ::g_free);

    int indent = 4;
    return j.dump(indent);
}

enum class apply_single_json_entry_rval
{'fraction_non_alphanumeric': 0.08991742277500255, 'fraction_numerical': 0.0020389438270975633, 'mean_word_length': 1.828719723183391, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4730831', 'n_tokens_mistral': 2932, 'n_tokens_neox': 2840, 'n_words': 591}